112 PetscInt dim = 0, M = 0, N = 0, P = 0, m = 0, n = 0, p = 0, source_dof = 0, stencil_width = 0;
113 DMBoundaryType bx = DM_BOUNDARY_NONE, by = DM_BOUNDARY_NONE, bz = DM_BOUNDARY_NONE;
114 DMDAStencilType stencil_type = DMDA_STENCIL_BOX;
115 const PetscInt *lx = NULL, *ly = NULL, *lz = NULL;
117 PetscFunctionBeginUser;
119 PetscCheck(source != NULL && result != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
120 "Source DM and output pointer are required.");
121 PetscCheck(dof > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
122 "A compatible DM needs a positive degree of freedom, got %" PetscInt_FMT
".", dof);
124 ierr = DMDAGetInfo(source, &dim, &M, &N, &P, &m, &n, &p, &source_dof, &stencil_width,
125 &bx, &by, &bz, &stencil_type); CHKERRQ(ierr);
126 ierr = DMDAGetOwnershipRanges(source, &lx, &ly, &lz); CHKERRQ(ierr);
127 ierr = DMDACreate3d(PetscObjectComm((PetscObject)source), bx, by, bz, stencil_type,
128 M, N, P, m, n, p, dof, stencil_width, lx, ly, lz, result); CHKERRQ(ierr);
129 ierr = DMSetUp(*result); CHKERRQ(ierr);
131 "Created a dof-%d DM mirroring the block decomposition (%dx%dx%d ranks).\n",
132 (
int)dof, (
int)m, (
int)n, (
int)p);
134 PetscFunctionReturn(0);
147 DMBoundaryType xperiod = (simCtx->
i_periodic) ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
148 DMBoundaryType yperiod = (simCtx->
j_periodic) ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
149 DMBoundaryType zperiod = (simCtx->
k_periodic) ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
152 PetscInt *lx = NULL, *ly = NULL, *lz = NULL;
155 PetscFunctionBeginUser;
163 DMDAGetInfo(coarse_user->
da, NULL, NULL, NULL, NULL, &m, &n, &p, NULL, NULL, NULL, NULL, NULL, NULL);
167 PetscInt *lx_contrib, *ly_contrib, *lz_contrib;
168 ierr = PetscMalloc3(m, &lx_contrib, n, &ly_contrib, p, &lz_contrib); CHKERRQ(ierr);
169 ierr = PetscMemzero(lx_contrib, m *
sizeof(PetscInt)); CHKERRQ(ierr);
170 ierr = PetscMemzero(ly_contrib, n *
sizeof(PetscInt)); CHKERRQ(ierr);
171 ierr = PetscMemzero(lz_contrib, p *
sizeof(PetscInt)); CHKERRQ(ierr);
174 DMDAGetLocalInfo(coarse_user->
da, &info);
175 PetscInt xs = info.xs, xe = info.xs + info.xm, mx = info.mx;
176 PetscInt ys = info.ys, ye = info.ys + info.ym, my = info.my;
177 PetscInt zs = info.zs, ze = info.zs + info.zm, mz = info.mz;
180 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
181 PetscInt proc_i = rank % m;
182 PetscInt proc_j = (rank / m) % n;
183 PetscInt proc_k = rank / (m * n);
186 if (user->
isc) lx_contrib[proc_i] = (xe - xs);
188 if (m == 1) lx_contrib[0] = user->
IM + 1;
189 else if (xs == 0) lx_contrib[0] = 2 * xe - 1;
190 else if (xe == mx) lx_contrib[proc_i] = user->
IM + 1 - (2 * xs - 1);
191 else lx_contrib[proc_i] = (xe - xs) * 2;
195 if (user->
jsc) ly_contrib[proc_j] = (ye - ys);
197 if (n == 1) ly_contrib[0] = user->
JM + 1;
198 else if (ys == 0) ly_contrib[0] = 2 * ye - 1;
199 else if (ye == my) ly_contrib[proc_j] = user->
JM + 1 - (2 * ys - 1);
200 else ly_contrib[proc_j] = (ye - ys) * 2;
204 if (user->
ksc) lz_contrib[proc_k] = (ze - zs);
206 if (p == 1) lz_contrib[0] = user->
KM + 1;
207 else if (zs == 0) lz_contrib[0] = 2 * ze - 1;
208 else if (ze == mz) lz_contrib[proc_k] = user->
KM + 1 - (2 * zs - 1);
209 else lz_contrib[proc_k] = (ze - zs) * 2;
211 LOG_ALLOW_SYNC(
LOCAL,
LOG_VERBOSE,
"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]);
214 ierr = PetscMalloc3(m, &lx, n, &ly, p, &lz); CHKERRQ(ierr);
215 ierr = MPI_Allreduce(lx_contrib, lx, m, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
216 ierr = MPI_Allreduce(ly_contrib, ly, n, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
217 ierr = MPI_Allreduce(lz_contrib, lz, p, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
219 ierr = PetscFree3(lx_contrib, ly_contrib, lz_contrib); CHKERRQ(ierr);
234 m = n = p = PETSC_DECIDE;
242 ierr = DMDACreate3d(PETSC_COMM_WORLD, xperiod, yperiod, zperiod, DMDA_STENCIL_BOX,
243 user->
IM + 1, user->
JM + 1, user->
KM + 1,
245 1, stencil_width, lx, ly, lz, &user->
da); CHKERRQ(ierr);
248 ierr = PetscFree3(lx, ly, lz); CHKERRQ(ierr);
252 ierr = DMSetUp(user->
da); CHKERRQ(ierr);
253 ierr = DMGetCoordinateDM(user->
da, &user->
fda); CHKERRQ(ierr);
260 ierr = DMDASetUniformCoordinates(user->
da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0); CHKERRQ(ierr);
261 ierr = DMDAGetLocalInfo(user->
da, &user->
info); CHKERRQ(ierr);
266 PetscFunctionReturn(0);
425 const char axis_names[3] = {
'X',
'Y',
'Z'};
426 const Cmpnts ***coor = NULL;
430 PetscFunctionBeginUser;
432 PetscCall(DMDAGetLocalInfo(user->
da, &info));
433 PetscCall(DMGetCoordinatesLocal(user->
da, &lcoor));
434 PetscCheck(lcoor != NULL, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
435 "Cannot validate periodic geometry before local coordinates are assigned.");
436 for (PetscInt axis = 0; axis < 3; axis++) {
437 const PetscBool neg_periodic =
439 const PetscBool pos_periodic =
441 PetscReal local_min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
442 PetscReal local_max[3] = {-PETSC_MAX_REAL, -PETSC_MAX_REAL, -PETSC_MAX_REAL};
443 PetscReal global_min[3], global_max[3];
444 PetscInt local_count = 0, global_count = 0;
448 if (!neg_periodic && !pos_periodic)
continue;
450 PetscCheck(neg_periodic && pos_periodic, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
451 "Periodic geometry in the %c direction requires paired negative and positive faces.",
453 const PetscInt axis_size = axis == 0 ? info.mx : (axis == 1 ? info.my : info.mz);
454 PetscCheck(axis_size >= 5, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
455 "%c-periodic geometry on block %d level %d requires at least four physical "
456 "nodes in that direction; found %d.",
459 PetscCall(DMDAVecGetArrayRead(user->
fda, lcoor, &coor));
460 if (axis == 0 && info.xs == 0) {
461 for (PetscInt k = PetscMax(info.zs, 0); k < PetscMin(info.zs + info.zm, info.mz - 1); k++) {
462 for (PetscInt j = PetscMax(info.ys, 0); j < PetscMin(info.ys + info.ym, info.my - 1); j++) {
464 coor[k][j][-2].
x - coor[k][j][0].
x,
465 coor[k][j][-2].
y - coor[k][j][0].
y,
466 coor[k][j][-2].
z - coor[k][j][0].
z
468 for (PetscInt c = 0; c < 3; c++) {
475 }
else if (axis == 1 && info.ys == 0) {
476 for (PetscInt k = PetscMax(info.zs, 0); k < PetscMin(info.zs + info.zm, info.mz - 1); k++) {
477 for (PetscInt i = PetscMax(info.xs, 0); i < PetscMin(info.xs + info.xm, info.mx - 1); i++) {
479 coor[k][-2][i].
x - coor[k][0][i].
x,
480 coor[k][-2][i].
y - coor[k][0][i].
y,
481 coor[k][-2][i].
z - coor[k][0][i].
z
483 for (PetscInt c = 0; c < 3; c++) {
490 }
else if (axis == 2 && info.zs == 0) {
491 for (PetscInt j = PetscMax(info.ys, 0); j < PetscMin(info.ys + info.ym, info.my - 1); j++) {
492 for (PetscInt i = PetscMax(info.xs, 0); i < PetscMin(info.xs + info.xm, info.mx - 1); i++) {
494 coor[-2][j][i].
x - coor[0][j][i].
x,
495 coor[-2][j][i].
y - coor[0][j][i].
y,
496 coor[-2][j][i].
z - coor[0][j][i].
z
498 for (PetscInt c = 0; c < 3; c++) {
506 PetscCall(DMDAVecRestoreArrayRead(user->
fda, lcoor, &coor));
508 PetscCallMPI(MPI_Allreduce(local_min, global_min, 3, MPIU_REAL, MPI_MIN, PETSC_COMM_WORLD));
509 PetscCallMPI(MPI_Allreduce(local_max, global_max, 3, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD));
510 PetscCallMPI(MPI_Allreduce(&local_count, &global_count, 1, MPIU_INT, MPI_SUM, PETSC_COMM_WORLD));
511 PetscCheck(global_count > 0, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
512 "No physical seam nodes were available to validate %c-periodic geometry.",
515 PetscReal translation[3];
516 PetscReal scale = 1.0;
517 PetscReal max_mismatch = 0.0;
518 for (PetscInt c = 0; c < 3; c++) {
519 translation[c] = 0.5 * (global_min[c] + global_max[c]);
520 scale = PetscMax(scale, PetscAbsReal(translation[c]));
521 max_mismatch = PetscMax(max_mismatch, global_max[c] - global_min[c]);
523 const PetscReal tolerance = 1.0e-9 * scale + 100.0 * PETSC_MACHINE_EPSILON;
524 const PetscReal magnitude = PetscSqrtReal(
525 PetscSqr(translation[0]) + PetscSqr(translation[1]) + PetscSqr(translation[2]));
527 PetscCheck(max_mismatch <= tolerance, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
528 "Unsupported %c-periodic geometry on block %d level %d: opposite physical "
529 "surfaces are not related by one constant translation. Maximum component "
530 "mismatch is %.12e (tolerance %.12e).",
532 (
double)max_mismatch, (
double)tolerance);
533 PetscCheck(magnitude > tolerance, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
534 "Unsupported %c-periodic geometry on block %d level %d: seam translation "
535 "magnitude %.12e is zero or too small.",
536 axis_names[axis], user->
_this, user->
thislevel, (
double)magnitude);
539 (
Cmpnts){translation[0], translation[1], translation[2]};
542 "Validated %c-periodic geometry for block %d level %d with translation "
543 "(%.12e, %.12e, %.12e).\n",
545 (
double)translation[0], (
double)translation[1], (
double)translation[2]);
549 PetscFunctionReturn(0);
701 PetscMPIInt rank = simCtx->
rank;
702 PetscInt block_index = user->
_this;
703 PetscInt IM = user->
IM, JM = user->
JM, KM = user->
KM;
707 PetscReal *gc = NULL;
709 PetscFunctionBeginUser;
714 simCtx->
rank, block_index);
718 PetscInt n_nodes = (IM) * (JM) * (KM);
719 ierr = PetscMalloc1(3 * n_nodes, &gc); CHKERRQ(ierr);
723 if (!fd) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Recieved a NULL file handle.\n");
726 for (PetscInt k = 0; k < KM; k++) {
727 for (PetscInt j = 0; j < JM; j++) {
728 for (PetscInt i = 0; i < IM; i++) {
729 PetscInt base_index = 3 * ((k * (JM) + j) * (IM) + i);
730 if (fscanf(fd,
"%le %le %le\n", &gc[base_index], &gc[base_index + 1], &gc[base_index + 2]) != 3) {
731 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);
740 ierr = MPI_Bcast(gc, 3 * n_nodes, MPIU_REAL, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
743 ierr = DMDAGetLocalInfo(user->
da, &info); CHKERRQ(ierr);
744 ierr = DMGetCoordinates(user->
da, &gCoor); CHKERRQ(ierr);
745 ierr = VecSet(gCoor, 0.0); CHKERRQ(ierr);
746 ierr = DMDAVecGetArray(user->
fda, gCoor, &coor); CHKERRQ(ierr);
748 for (PetscInt k = info.zs; k < info.zs + info.zm; k++) {
749 for (PetscInt j = info.ys; j < info.ys + info.ym; j++) {
750 for (PetscInt i = info.xs; i < info.xs + info.xm; i++) {
751 if(k< KM && j < JM && i < IM){
752 PetscInt base_idx = 3 * ((k * (JM) + j) * (IM) + i);
753 coor[k][j][i].
x = gc[base_idx];
754 coor[k][j][i].
y = gc[base_idx + 1];
755 coor[k][j][i].
z = gc[base_idx + 2];
762 ierr = DMDAVecRestoreArray(user->
fda, gCoor, &coor); CHKERRQ(ierr);
763 ierr = PetscFree(gc); CHKERRQ(ierr);
767 PetscFunctionReturn(0);
778 Vec c_gCoor, f_lCoor;
781 DMDALocalInfo c_info;
784 PetscFunctionBeginUser;
791 ierr = DMDAGetLocalInfo(coarse_user->
da, &c_info); CHKERRQ(ierr);
793 ierr = DMGetCoordinates(coarse_user->
da, &c_gCoor); CHKERRQ(ierr);
794 ierr = DMGetCoordinatesLocal(fine_user->
da, &f_lCoor); CHKERRQ(ierr);
796 ierr = VecSet(c_gCoor, 0.0); CHKERRQ(ierr);
797 ierr = DMDAVecGetArray(coarse_user->
fda, c_gCoor, &c_coor); CHKERRQ(ierr);
798 ierr = DMDAVecGetArrayRead(fine_user->
fda, f_lCoor, &f_coor); CHKERRQ(ierr);
801 PetscInt xs = c_info.xs, xe = c_info.xs + c_info.xm;
802 PetscInt ys = c_info.ys, ye = c_info.ys + c_info.ym;
803 PetscInt zs = c_info.zs, ze = c_info.zs + c_info.zm;
806 PetscInt mx = c_info.mx, my = c_info.my, mz = c_info.mz;
815 for (PetscInt k = zs; k < ze; k++) {
816 for (PetscInt j = ys; j < ye; j++) {
817 for (PetscInt i = xs; i < xe; i++) {
820 ih = coarse_user->
isc ? i : 2 * i;
821 jh = coarse_user->
jsc ? j : 2 * j;
822 kh = coarse_user->
ksc ? k : 2 * k;
826 c_coor[k][j][i] = f_coor[kh][jh][ih];
831 ierr = DMDAVecRestoreArray(coarse_user->
fda, c_gCoor, &c_coor); CHKERRQ(ierr);
832 ierr = DMDAVecRestoreArrayRead(fine_user->
fda, f_lCoor, &f_coor); CHKERRQ(ierr);
839 PetscFunctionReturn(0);
1208 Cmpnts *face_center, PetscReal *face_area)
1210 PetscErrorCode ierr;
1216 PetscReal local_sum[3] = {0.0, 0.0, 0.0};
1217 PetscReal localAreaSum = 0.0;
1218 PetscCount local_n_points = 0;
1223 PetscReal global_sum[3] = {0.0, 0.0, 0.0};
1224 PetscReal globalAreaSum = 0.0;
1225 PetscCount global_n_points = 0;
1233 PetscInt xs = info.xs, xe = info.xs + info.xm;
1234 PetscInt ys = info.ys, ye = info.ys + info.ym;
1235 PetscInt zs = info.zs, ze = info.zs + info.zm;
1238 PetscInt mx = info.mx, my = info.my, mz = info.mz;
1239 PetscInt IM = user->
IM;
1240 PetscInt JM = user->
JM;
1241 PetscInt KM = user->
KM;
1247 PetscInt lxs = xs;
if(xs == 0) lxs = xs + 1;
1248 PetscInt lxe = xe;
if(xe == mx) lxe = xe - 1;
1249 PetscInt lys = ys;
if(ys == 0) lys = ys + 1;
1250 PetscInt lye = ye;
if(ye == my) lye = ye - 1;
1251 PetscInt lzs = zs;
if(zs == 0) lzs = zs + 1;
1252 PetscInt lze = ze;
if(ze == mz) lze = ze - 1;
1258 PetscInt i_max = (xe == mx) ? mx - 1 : xe;
1259 PetscInt j_max = (ye == my) ? my - 1 : ye;
1260 PetscInt k_max = (ze == mz) ? mz - 1 : ze;
1267 Cmpnts ***csi, ***eta, ***zet;
1270 PetscFunctionBeginUser;
1276 PetscBool owns_face = PETSC_FALSE;
1282 ierr = DMGetCoordinatesLocal(user->
da, &lCoor); CHKERRQ(ierr);
1283 ierr = DMDAVecGetArrayRead(user->
fda, lCoor, &coor); CHKERRQ(ierr);
1284 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, &nvert); CHKERRQ(ierr);
1285 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, &csi); CHKERRQ(ierr);
1286 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, &eta); CHKERRQ(ierr);
1287 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, &zet); CHKERRQ(ierr);
1304 for (PetscInt k = zs; k < k_max; k++) {
1305 for (PetscInt j = ys; j < j_max; j++) {
1307 local_sum[0] += coor[k][j][i].
x;
1308 local_sum[1] += coor[k][j][i].
y;
1309 local_sum[2] += coor[k][j][i].
z;
1317 for (PetscInt k = lzs; k < lze; k++) {
1318 for (PetscInt j = lys; j < lye; j++) {
1322 if (nvert[k][j][i+1] < 0.1) {
1325 localAreaSum += sqrt(csi[k][j][i].x * csi[k][j][i].x +
1326 csi[k][j][i].y * csi[k][j][i].y +
1327 csi[k][j][i].z * csi[k][j][i].z);
1339 PetscInt i = mx - 2;
1342 for (PetscInt k = zs; k < k_max; k++) {
1343 for (PetscInt j = ys; j < j_max; j++) {
1344 local_sum[0] += coor[k][j][i].
x;
1345 local_sum[1] += coor[k][j][i].
y;
1346 local_sum[2] += coor[k][j][i].
z;
1352 for (PetscInt k = lzs; k < lze; k++) {
1353 for (PetscInt j = lys; j < lye; j++) {
1357 if (nvert[k][j][i] < 0.1) {
1359 localAreaSum += sqrt(csi[k][j][i].x * csi[k][j][i].x +
1360 csi[k][j][i].y * csi[k][j][i].y +
1361 csi[k][j][i].z * csi[k][j][i].z);
1377 for (PetscInt k = zs; k < k_max; k++) {
1378 for (PetscInt i = xs; i < i_max; i++) {
1379 local_sum[0] += coor[k][j][i].
x;
1380 local_sum[1] += coor[k][j][i].
y;
1381 local_sum[2] += coor[k][j][i].
z;
1388 for (PetscInt k = lzs; k < lze; k++) {
1389 for (PetscInt i = lxs; i < lxe; i++) {
1391 if (nvert[k][j+1][i] < 0.1) {
1393 localAreaSum += sqrt(eta[k][j][i].x * eta[k][j][i].x +
1394 eta[k][j][i].y * eta[k][j][i].y +
1395 eta[k][j][i].z * eta[k][j][i].z);
1407 PetscInt j = my - 2;
1410 for (PetscInt k = zs; k < k_max; k++) {
1411 for (PetscInt i = xs; i < i_max; i++) {
1412 local_sum[0] += coor[k][j][i].
x;
1413 local_sum[1] += coor[k][j][i].
y;
1414 local_sum[2] += coor[k][j][i].
z;
1420 for (PetscInt k = lzs; k < lze; k++) {
1421 for (PetscInt i = lxs; i < lxe; i++) {
1423 if (nvert[k][j][i] < 0.1) {
1425 localAreaSum += sqrt(eta[k][j][i].x * eta[k][j][i].x +
1426 eta[k][j][i].y * eta[k][j][i].y +
1427 eta[k][j][i].z * eta[k][j][i].z);
1443 for (PetscInt j = ys; j < j_max; j++) {
1444 for (PetscInt i = xs; i < i_max; i++) {
1445 local_sum[0] += coor[k][j][i].
x;
1446 local_sum[1] += coor[k][j][i].
y;
1447 local_sum[2] += coor[k][j][i].
z;
1454 for (PetscInt j = lys; j < lye; j++) {
1455 for (PetscInt i = lxs; i < lxe; i++) {
1458 if (nvert[k+1][j][i] < 0.1) {
1460 localAreaSum += sqrt(zet[k][j][i].x * zet[k][j][i].x +
1461 zet[k][j][i].y * zet[k][j][i].y +
1462 zet[k][j][i].z * zet[k][j][i].z);
1474 PetscInt k = mz - 2;
1478 for (PetscInt j = ys; j < j_max; j++) {
1479 for (PetscInt i = xs; i < i_max; i++) {
1480 local_sum[0] += coor[k][j][i].
x;
1481 local_sum[1] += coor[k][j][i].
y;
1482 local_sum[2] += coor[k][j][i].
z;
1489 for (PetscInt j = lys; j < lye; j++) {
1490 for (PetscInt i = lxs; i < lxe; i++) {
1493 if (nvert[k][j][i] < 0.1) {
1495 localAreaSum += sqrt(zet[k][j][i].x * zet[k][j][i].x +
1496 zet[k][j][i].y * zet[k][j][i].y +
1497 zet[k][j][i].z * zet[k][j][i].z);
1505 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE,
1506 "Unknown face_id %d in CalculateFaceCenterAndArea", face_id);
1512 ierr = DMDAVecRestoreArrayRead(user->
fda, lCoor, &coor); CHKERRQ(ierr);
1513 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, &nvert); CHKERRQ(ierr);
1514 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, &csi); CHKERRQ(ierr);
1515 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, &eta); CHKERRQ(ierr);
1516 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, &zet); CHKERRQ(ierr);
1522 ierr = MPI_Allreduce(local_sum, global_sum, 3, MPI_DOUBLE, MPI_SUM,
1523 PETSC_COMM_WORLD); CHKERRQ(ierr);
1526 ierr = MPI_Allreduce(&local_n_points, &global_n_points, 1, MPI_COUNT, MPI_SUM,
1527 PETSC_COMM_WORLD); CHKERRQ(ierr);
1530 ierr = MPI_Allreduce(&localAreaSum, &globalAreaSum, 1, MPI_DOUBLE, MPI_SUM,
1531 PETSC_COMM_WORLD); CHKERRQ(ierr);
1536 if (global_n_points > 0) {
1537 face_center->
x = global_sum[0] / global_n_points;
1538 face_center->
y = global_sum[1] / global_n_points;
1539 face_center->
z = global_sum[2] / global_n_points;
1541 "Calculated center for Face %s: (x=%.4f, y=%.4f, z=%.4f) from %lld nodes\n",
1543 face_center->
x, face_center->
y, face_center->
z,
1544 (
long long)global_n_points);
1548 "WARNING: Face %s identified but no grid points found. Center not calculated.\n",
1550 face_center->
x = face_center->
y = face_center->
z = 0.0;
1556 *face_area = globalAreaSum;
1558 "Calculated area for Face %s: Area=%.6f\n",
1562 PetscFunctionReturn(0);