112 DMBoundaryType xperiod = (simCtx->
i_periodic) ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
113 DMBoundaryType yperiod = (simCtx->
j_periodic) ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
114 DMBoundaryType zperiod = (simCtx->
k_periodic) ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
115 PetscInt stencil_width = 2;
117 PetscInt *lx = NULL, *ly = NULL, *lz = NULL;
120 PetscFunctionBeginUser;
126 DMDAGetInfo(coarse_user->
da, NULL, NULL, NULL, NULL, &m, &n, &p, NULL, NULL, NULL, NULL, NULL, NULL);
130 PetscInt *lx_contrib, *ly_contrib, *lz_contrib;
131 ierr = PetscMalloc3(m, &lx_contrib, n, &ly_contrib, p, &lz_contrib); CHKERRQ(ierr);
132 ierr = PetscMemzero(lx_contrib, m *
sizeof(PetscInt)); CHKERRQ(ierr);
133 ierr = PetscMemzero(ly_contrib, n *
sizeof(PetscInt)); CHKERRQ(ierr);
134 ierr = PetscMemzero(lz_contrib, p *
sizeof(PetscInt)); CHKERRQ(ierr);
137 DMDAGetLocalInfo(coarse_user->
da, &info);
138 PetscInt xs = info.xs, xe = info.xs + info.xm, mx = info.mx;
139 PetscInt ys = info.ys, ye = info.ys + info.ym, my = info.my;
140 PetscInt zs = info.zs, ze = info.zs + info.zm, mz = info.mz;
143 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
144 PetscInt proc_i = rank % m;
145 PetscInt proc_j = (rank / m) % n;
146 PetscInt proc_k = rank / (m * n);
149 if (user->
isc) lx_contrib[proc_i] = (xe - xs);
151 if (m == 1) lx_contrib[0] = user->
IM + 1;
152 else if (xs == 0) lx_contrib[0] = 2 * xe - 1;
153 else if (xe == mx) lx_contrib[proc_i] = user->
IM + 1 - (2 * xs - 1);
154 else lx_contrib[proc_i] = (xe - xs) * 2;
158 if (user->
jsc) ly_contrib[proc_j] = (ye - ys);
160 if (n == 1) ly_contrib[0] = user->
JM + 1;
161 else if (ys == 0) ly_contrib[0] = 2 * ye - 1;
162 else if (ye == my) ly_contrib[proc_j] = user->
JM + 1 - (2 * ys - 1);
163 else ly_contrib[proc_j] = (ye - ys) * 2;
167 if (user->
ksc) lz_contrib[proc_k] = (ze - zs);
169 if (p == 1) lz_contrib[0] = user->
KM + 1;
170 else if (zs == 0) lz_contrib[0] = 2 * ze - 1;
171 else if (ze == mz) lz_contrib[proc_k] = user->
KM + 1 - (2 * zs - 1);
172 else lz_contrib[proc_k] = (ze - zs) * 2;
174 LOG_ALLOW_SYNC(
LOCAL,
LOG_DEBUG,
"Rank %d: Calculated this rank's node contribution to fine grid: lx=%d, ly=%d, lz=%d\n", simCtx->
rank, lx_contrib[proc_i], ly_contrib[proc_j], lz_contrib[proc_k]);
177 ierr = PetscMalloc3(m, &lx, n, &ly, p, &lz); CHKERRQ(ierr);
178 ierr = MPI_Allreduce(lx_contrib, lx, m, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
179 ierr = MPI_Allreduce(ly_contrib, ly, n, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
180 ierr = MPI_Allreduce(lz_contrib, lz, p, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
182 ierr = PetscFree3(lx_contrib, ly_contrib, lz_contrib); CHKERRQ(ierr);
195 ierr = DMDACreate3d(PETSC_COMM_WORLD, xperiod, yperiod, zperiod, DMDA_STENCIL_BOX,
196 user->
IM + 1, user->
JM + 1, user->
KM + 1,
198 1, stencil_width, lx, ly, lz, &user->
da); CHKERRQ(ierr);
201 ierr = PetscFree3(lx, ly, lz); CHKERRQ(ierr);
205 ierr = DMSetUp(user->
da); CHKERRQ(ierr);
206 ierr = DMGetCoordinateDM(user->
da, &user->
fda); CHKERRQ(ierr);
207 ierr = DMDASetUniformCoordinates(user->
da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0); CHKERRQ(ierr);
208 ierr = DMDAGetLocalInfo(user->
da, &user->
info); CHKERRQ(ierr);
211 PetscFunctionReturn(0);
237 PetscFunctionBeginUser;
242 for (PetscInt level = usermg->
mglevels - 2; level >= 0; level--) {
243 for (PetscInt bi = 0; bi < nblk; bi++) {
247 user_coarse->
IM = user_fine->
isc ? user_fine->
IM : (user_fine->
IM + 1) / 2;
248 user_coarse->
JM = user_fine->
jsc ? user_fine->
JM : (user_fine->
JM + 1) / 2;
249 user_coarse->
KM = user_fine->
ksc ? user_fine->
KM : (user_fine->
KM + 1) / 2;
252 simCtx->
rank, bi, level, user_coarse->
IM, user_coarse->
JM, user_coarse->
KM);
255 PetscInt check_i = user_coarse->
IM * (2 - user_coarse->
isc) - (user_fine->
IM + 1 - user_coarse->
isc);
256 PetscInt check_j = user_coarse->
JM * (2 - user_coarse->
jsc) - (user_fine->
JM + 1 - user_coarse->
jsc);
257 PetscInt check_k = user_coarse->
KM * (2 - user_coarse->
ksc) - (user_fine->
KM + 1 - user_coarse->
ksc);
259 if (check_i + check_j + check_k != 0) {
263 LOG(
GLOBAL,
LOG_WARNING,
"WARNING: Grid at level %d, block %d can't be consistently coarsened further.\n", level, bi);
269 for (PetscInt bi = 0; bi < nblk; bi++) {
276 for (PetscInt level = 1; level < usermg->
mglevels; level++) {
284 ierr = DMView(mgctx[usermg->
mglevels - 1].
user[0].
da, PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
288 PetscFunctionReturn(0);
372 PetscFunctionBeginUser;
380 FILE *grid_file_handle = NULL;
382 if (simCtx->
rank == 0) {
383 grid_file_handle = fopen(simCtx->
grid_file,
"r");
384 if (!grid_file_handle) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Cannot open file: %s", simCtx->
grid_file);
389 char dummy_buffer[2048];
390 for (PetscInt s = 0; s < headerLines; ++s) {
391 if (!fgets(dummy_buffer,
sizeof(dummy_buffer), grid_file_handle)) {
392 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
"Unexpected EOF while skipping grid header");
403 if (simCtx->
rank == 0) {
404 fclose(grid_file_handle);
412 ierr = DMGetCoordinates(user->
da, &gCoor); CHKERRQ(ierr);
413 ierr = DMGetCoordinatesLocal(user->
da, &lCoor); CHKERRQ(ierr);
416 ierr = DMLocalToGlobalBegin(user->
fda, lCoor, INSERT_VALUES, gCoor); CHKERRQ(ierr);
417 ierr = DMLocalToGlobalEnd(user->
fda, lCoor, INSERT_VALUES, gCoor); CHKERRQ(ierr);
419 ierr = DMGlobalToLocalBegin(user->
fda, gCoor, INSERT_VALUES, lCoor); CHKERRQ(ierr);
420 ierr = DMGlobalToLocalEnd(user->
fda, gCoor, INSERT_VALUES, lCoor); CHKERRQ(ierr);
422 PetscFunctionReturn(0);
539 PetscMPIInt rank = simCtx->
rank;
540 PetscInt block_index = user->
_this;
541 PetscInt IM = user->
IM, JM = user->
JM, KM = user->
KM;
545 PetscReal *gc = NULL;
547 PetscFunctionBeginUser;
549 simCtx->
rank, block_index);
553 PetscInt n_nodes = (IM) * (JM) * (KM);
554 ierr = PetscMalloc1(3 * n_nodes, &gc); CHKERRQ(ierr);
558 if (!fd) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Recieved a NULL file handle.\n");
561 for (PetscInt k = 0; k < KM; k++) {
562 for (PetscInt j = 0; j < JM; j++) {
563 for (PetscInt i = 0; i < IM; i++) {
564 PetscInt base_index = 3 * ((k * (JM) + j) * (IM) + i);
565 if (fscanf(fd,
"%le %le %le\n", &gc[base_index], &gc[base_index + 1], &gc[base_index + 2]) != 3) {
566 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
"Error reading coordinates for node (i,j,k)=(%d,%d,%d) in block %d", i, j, k, block_index);
575 ierr = MPI_Bcast(gc, 3 * n_nodes, MPIU_REAL, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
578 ierr = DMDAGetLocalInfo(user->
da, &info); CHKERRQ(ierr);
579 ierr = DMGetCoordinatesLocal(user->
da, &lCoor); CHKERRQ(ierr);
580 ierr = DMDAVecGetArray(user->
fda, lCoor, &coor); CHKERRQ(ierr);
582 for (PetscInt k = info.zs; k < info.zs + info.zm; k++) {
583 for (PetscInt j = info.ys; j < info.ys + info.ym; j++) {
584 for (PetscInt i = info.xs; i < info.xs + info.xm; i++) {
585 if(k< KM && j < JM && i < IM){
587 PetscInt base_idx = 3 * ((k * (JM) + j) * (IM) + i);
588 coor[k][j][i].
x = gc[base_idx];
589 coor[k][j][i].
y = gc[base_idx + 1];
590 coor[k][j][i].
z = gc[base_idx + 2];
597 ierr = DMDAVecRestoreArray(user->
fda, lCoor, &coor); CHKERRQ(ierr);
598 ierr = PetscFree(gc); CHKERRQ(ierr);
599 PetscFunctionReturn(0);
620 Vec c_lCoor, f_lCoor;
623 DMDALocalInfo c_info;
626 PetscFunctionBeginUser;
630 ierr = DMDAGetLocalInfo(coarse_user->
da, &c_info); CHKERRQ(ierr);
632 ierr = DMGetCoordinatesLocal(coarse_user->
da, &c_lCoor); CHKERRQ(ierr);
633 ierr = DMGetCoordinatesLocal(fine_user->
da, &f_lCoor); CHKERRQ(ierr);
635 ierr = DMDAVecGetArray(coarse_user->
fda, c_lCoor, &c_coor); CHKERRQ(ierr);
636 ierr = DMDAVecGetArrayRead(fine_user->
fda, f_lCoor, &f_coor); CHKERRQ(ierr);
639 PetscInt xs = c_info.xs, xe = c_info.xs + c_info.xm;
640 PetscInt ys = c_info.ys, ye = c_info.ys + c_info.ym;
641 PetscInt zs = c_info.zs, ze = c_info.zs + c_info.zm;
644 PetscInt mx = c_info.mx, my = c_info.my, mz = c_info.mz;
652 for (PetscInt k = zs; k < ze; k++) {
653 for (PetscInt j = ys; j < ye; j++) {
654 for (PetscInt i = xs; i < xe; i++) {
657 ih = coarse_user->
isc ? i : 2 * i;
658 jh = coarse_user->
jsc ? j : 2 * j;
659 kh = coarse_user->
ksc ? k : 2 * k;
663 c_coor[k][j][i] = f_coor[kh][jh][ih];
668 ierr = DMDAVecRestoreArray(coarse_user->
fda, c_lCoor, &c_coor); CHKERRQ(ierr);
669 ierr = DMDAVecRestoreArrayRead(fine_user->
fda, f_lCoor, &f_coor); CHKERRQ(ierr);
673 ierr = DMGetCoordinates(coarse_user->
da, &c_gCoor); CHKERRQ(ierr);
674 ierr = DMLocalToGlobalBegin(coarse_user->
fda, c_lCoor, INSERT_VALUES, c_gCoor); CHKERRQ(ierr);
675 ierr = DMLocalToGlobalEnd(coarse_user->
fda, c_lCoor, INSERT_VALUES, c_gCoor); CHKERRQ(ierr);
676 ierr = DMGlobalToLocalBegin(coarse_user->
fda, c_gCoor, INSERT_VALUES, c_lCoor); CHKERRQ(ierr);
677 ierr = DMGlobalToLocalEnd(coarse_user->
fda, c_gCoor, INSERT_VALUES, c_lCoor); CHKERRQ(ierr);
679 PetscFunctionReturn(0);
707 PetscInt xs, ys, zs, xe, ye, ze;
711 Cmpnts minCoords, maxCoords;
719 return PETSC_ERR_ARG_NULL;
723 return PETSC_ERR_ARG_NULL;
727 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
730 ierr = DMGetCoordinatesLocal(user->
da, &coordinates);
738 return PETSC_ERR_ARG_NULL;
742 ierr = DMDAVecGetArrayRead(user->
fda, coordinates, &coordArray);
749 ierr = DMDAGetLocalInfo(user->
da, &info);
756 xs = info.gxs; xe = xs + info.gxm;
757 ys = info.gys; ye = ys + info.gym;
758 zs = info.gzs; ze = zs + info.gzm;
767 minCoords.
x = minCoords.
y = minCoords.
z = PETSC_MAX_REAL;
768 maxCoords.
x = maxCoords.
y = maxCoords.
z = PETSC_MIN_REAL;
770 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"[Rank %d] Grid indices (Including Ghosts): xs=%d, xe=%d, ys=%d, ye=%d, zs=%d, ze=%d.\n",rank, xs, xe, ys, ye, zs, ze);
773 for (k = zs; k < ze; k++) {
774 for (j = ys; j < ye; j++) {
775 for (i = xs; i < xe; i++) {
776 Cmpnts coord = coordArray[k][j][i];
779 if (coord.
x < minCoords.
x) minCoords.
x = coord.
x;
780 if (coord.
y < minCoords.
y) minCoords.
y = coord.
y;
781 if (coord.
z < minCoords.
z) minCoords.
z = coord.
z;
783 if (coord.
x > maxCoords.
x) maxCoords.
x = coord.
x;
784 if (coord.
y > maxCoords.
y) maxCoords.
y = coord.
y;
785 if (coord.
z > maxCoords.
z) maxCoords.
z = coord.
z;
803 LOG_ALLOW(
LOCAL,
LOG_INFO,
"[Rank %d]minCoords=(%.6f, %.6f, %.6f), maxCoords=(%.6f, %.6f, %.6f).\n",rank,minCoords.
x, minCoords.
y, minCoords.
z, maxCoords.
x, maxCoords.
y, maxCoords.
z);
808 ierr = DMDAVecRestoreArrayRead(user->
fda, coordinates, &coordArray);
819 user->
bbox = *localBBox;