15#ifndef ERROR_MSG_BUFFER_SIZE
16#define ERROR_MSG_BUFFER_SIZE 256
45 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
47 "Rank %d starting InterpolateFieldFromCornerToCenter_Vector.\n", rank);
52 DMDALocalInfo info_nodes_fda;
53 ierr = DMDAGetLocalInfo(user->
fda, &info_nodes_fda); CHKERRQ(ierr);
56 PetscInt xs_cell_global_i, xm_cell_local_i;
57 PetscInt ys_cell_global_j, ym_cell_local_j;
58 PetscInt zs_cell_global_k, zm_cell_local_k;
61 ierr =
GetOwnedCellRange(&info_nodes_fda, 0, &xs_cell_global_i, &xm_cell_local_i); CHKERRQ(ierr);
62 ierr =
GetOwnedCellRange(&info_nodes_fda, 1, &ys_cell_global_j, &ym_cell_local_j); CHKERRQ(ierr);
63 ierr =
GetOwnedCellRange(&info_nodes_fda, 2, &zs_cell_global_k, &zm_cell_local_k); CHKERRQ(ierr);
66 PetscInt xe_cell_global_i_excl = xs_cell_global_i + xm_cell_local_i;
67 PetscInt ye_cell_global_j_excl = ys_cell_global_j + ym_cell_local_j;
68 PetscInt ze_cell_global_k_excl = zs_cell_global_k + zm_cell_local_k;
70 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Rank %d : Processing Owned Cells (global indices) k=%d..%d (count %d), j=%d..%d (count %d), i=%d..%d (count %d)\n",
72 zs_cell_global_k, ze_cell_global_k_excl -1, zm_cell_local_k,
73 ys_cell_global_j, ye_cell_global_j_excl -1, ym_cell_local_j,
74 xs_cell_global_i, xe_cell_global_i_excl -1, xm_cell_local_i);
78 for (PetscInt k_glob_cell = zs_cell_global_k; k_glob_cell < ze_cell_global_k_excl; k_glob_cell++) {
79 PetscInt k_local = k_glob_cell - zs_cell_global_k;
81 for (PetscInt j_glob_cell = ys_cell_global_j; j_glob_cell < ye_cell_global_j_excl; j_glob_cell++) {
82 PetscInt j_local = j_glob_cell - ys_cell_global_j;
84 for (PetscInt i_glob_cell = xs_cell_global_i; i_glob_cell < xe_cell_global_i_excl; i_glob_cell++) {
85 PetscInt i_local = i_glob_cell - xs_cell_global_i;
87 Cmpnts sum = {0.0, 0.0, 0.0};
92 for (PetscInt dk = 0; dk < 2; dk++) {
93 for (PetscInt dj = 0; dj < 2; dj++) {
94 for (PetscInt di = 0; di < 2; di++) {
95 PetscInt ni_glob = i_glob_cell + di;
96 PetscInt nj_glob = j_glob_cell + dj;
97 PetscInt nk_glob = k_glob_cell + dk;
102 sum.
x += field_arr[nk_glob][nj_glob][ni_glob].
x;
103 sum.
y += field_arr[nk_glob][nj_glob][ni_glob].
y;
104 sum.
z += field_arr[nk_glob][nj_glob][ni_glob].
z;
112 center_value.
x = sum.
x / 8.0;
113 center_value.
y = sum.
y / 8.0;
114 center_value.
z = sum.
z / 8.0;
119 if (i_local < 0 || i_local >= xm_cell_local_i ||
120 j_local < 0 || j_local >= ym_cell_local_j ||
121 k_local < 0 || k_local >= zm_cell_local_k) {
122 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Local index out of bounds for centfield_arr write!");
124 centfield_arr[k_local][j_local][i_local] = center_value;
131 "Rank %d completed InterpolateFieldFromCornerToCenter_Vector.\n", rank);
158 PetscReal ***field_arr,
159 PetscReal ***centfield_arr,
164 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
166 "Rank %d starting InterpolateFieldFromCornerToCenter_Scalar.\n", rank);
169 DMDALocalInfo info_da_nodes;
170 ierr = DMDAGetLocalInfo(user->
da, &info_da_nodes); CHKERRQ(ierr);
173 PetscInt xs_cell_global_i, xm_cell_local_i;
174 PetscInt ys_cell_global_j, ym_cell_local_j;
175 PetscInt zs_cell_global_k, zm_cell_local_k;
177 ierr =
GetOwnedCellRange(&info_da_nodes, 0, &xs_cell_global_i, &xm_cell_local_i); CHKERRQ(ierr);
178 ierr =
GetOwnedCellRange(&info_da_nodes, 1, &ys_cell_global_j, &ym_cell_local_j); CHKERRQ(ierr);
179 ierr =
GetOwnedCellRange(&info_da_nodes, 2, &zs_cell_global_k, &zm_cell_local_k); CHKERRQ(ierr);
182 PetscInt xe_cell_global_i_excl = xs_cell_global_i + xm_cell_local_i;
183 PetscInt ye_cell_global_j_excl = ys_cell_global_j + ym_cell_local_j;
184 PetscInt ze_cell_global_k_excl = zs_cell_global_k + zm_cell_local_k;
186 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Rank %d (IFCTCS): Processing Owned Cells (global indices) k=%d..%d (count %d), j=%d..%d (count %d), i=%d..%d (count %d)\n",
188 zs_cell_global_k, ze_cell_global_k_excl -1, zm_cell_local_k,
189 ys_cell_global_j, ye_cell_global_j_excl -1, ym_cell_local_j,
190 xs_cell_global_i, xe_cell_global_i_excl -1, xm_cell_local_i);
194 for (PetscInt k_glob_cell = zs_cell_global_k; k_glob_cell < ze_cell_global_k_excl; k_glob_cell++) {
195 PetscInt k_local = k_glob_cell - zs_cell_global_k;
197 for (PetscInt j_glob_cell = ys_cell_global_j; j_glob_cell < ye_cell_global_j_excl; j_glob_cell++) {
198 PetscInt j_local = j_glob_cell - ys_cell_global_j;
200 for (PetscInt i_glob_cell = xs_cell_global_i; i_glob_cell < xe_cell_global_i_excl; i_glob_cell++) {
201 PetscInt i_local = i_glob_cell - xs_cell_global_i;
208 for (PetscInt dk = 0; dk < 2; dk++) {
209 for (PetscInt dj = 0; dj < 2; dj++) {
210 for (PetscInt di = 0; di < 2; di++) {
211 PetscInt ni_glob = i_glob_cell + di;
212 PetscInt nj_glob = j_glob_cell + dj;
213 PetscInt nk_glob = k_glob_cell + dk;
216 sum += field_arr[nk_glob][nj_glob][ni_glob];
222 PetscReal center_value = sum / 8.0;
227 if (i_local < 0 || i_local >= xm_cell_local_i ||
228 j_local < 0 || j_local >= ym_cell_local_j ||
229 k_local < 0 || k_local >= zm_cell_local_k) {
230 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Local index out of bounds for centfield_arr write in Scalar version!");
232 centfield_arr[k_local][j_local][i_local] = center_value;
239 "Rank %d completed InterpolateFieldFromCornerToCenter_Scalar.\n", rank);
266 PetscReal ***centfield_arr,
267 PetscReal ***field_arr,
272 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
274 "Rank %d starting interpolation.\n", rank);
278 ierr = DMDAGetLocalInfo(user->
da, &info); CHKERRQ(ierr);
281 PetscInt xs_node = info.xs;
282 PetscInt xm_node = info.xm;
283 PetscInt xe_node = xs_node + xm_node;
284 PetscInt ys_node = info.ys;
285 PetscInt ym_node = info.ym;
286 PetscInt ye_node = ys_node + ym_node;
287 PetscInt zs_node = info.zs;
288 PetscInt zm_node = info.zm;
289 PetscInt ze_node = zs_node + zm_node;
292 PetscInt IM = info.mx - 1;
293 PetscInt JM = info.my - 1;
294 PetscInt KM = info.mz - 1;
298 rank, zs_node, ze_node, ys_node, ye_node, xs_node, xe_node);
301 for (PetscInt k = zs_node; k < ze_node; k++) {
302 for (PetscInt j = ys_node; j < ye_node; j++) {
303 for (PetscInt i = xs_node; i < xe_node; i++) {
310 for (PetscInt dk = -1; dk <= 0; dk++) {
311 for (PetscInt dj = -1; dj <= 0; dj++) {
312 for (PetscInt di = -1; di <= 0; di++) {
314 PetscInt ci = i + di;
315 PetscInt cj = j + dj;
316 PetscInt ck = k + dk;
319 if (ci >= 0 && ci <= IM-1 &&
320 cj >= 0 && cj <= JM-1 &&
321 ck >= 0 && ck <= KM-1)
325 sum += centfield_arr[ck][cj][ci];
339 field_arr[k][j][i] = sum / (PetscReal)count;
343 "Rank %d: Node (i=%d,j=%d,k=%d) had count=0 surrounding cells! Check logic/ghosting.\n", rank, i, j, k);
345 field_arr[k][j][i] = 0.0;
352 "Rank %d completed interpolation.\n", rank);
388 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
390 DMDALocalInfo info_nodes;
391 ierr = DMDAGetLocalInfo(user->
fda, &info_nodes); CHKERRQ(ierr);
394 PetscInt xs_node = info_nodes.xs, xm_node = info_nodes.xm, xe_node = xs_node + xm_node;
395 PetscInt ys_node = info_nodes.ys, ym_node = info_nodes.ym, ye_node = ys_node + ym_node;
396 PetscInt zs_node = info_nodes.zs, zm_node = info_nodes.zm, ze_node = zs_node + zm_node;
399 PetscInt MX_node = user->
IM;
400 PetscInt MY_node = user->
JM;
401 PetscInt MZ_node = user->
KM;
402 PetscInt IM = MX_node - 1;
403 PetscInt JM = MY_node - 1;
404 PetscInt KM = MZ_node - 1;
408 PetscInt gxs_node = info_nodes.gxs, gxm_node = info_nodes.gxm, gxe_node = gxs_node + gxm_node;
409 PetscInt gys_node = info_nodes.gys, gym_node = info_nodes.gym, gye_node = gys_node + gym_node;
410 PetscInt gzs_node = info_nodes.gzs, gzm_node = info_nodes.gzm, gze_node = gzs_node + gzm_node;
414 rank, zs_node, ze_node-1, ys_node, ye_node-1, xs_node, xe_node-1);
420 DMView(user->
fda, PETSC_VIEWER_STDOUT_SELF);
423 PetscMPIInt rank_check;
424 MPI_Comm_rank(PETSC_COMM_WORLD, &rank_check);
425 if (rank_check == 1) {
427 Cmpnts test_val_owned_interior = centfield_arr[7][1][1];
431 Cmpnts test_val_owned_boundary = centfield_arr[7][0][0];
435 Cmpnts test_val_ghost = centfield_arr[7][0][0];
441 ierr = PetscBarrier(NULL);
445 for (PetscInt k = zs_node; k < ze_node; k++) {
446 for (PetscInt j = ys_node; j < ye_node; j++) {
447 for (PetscInt i = xs_node; i < xe_node; i++) {
460 Cmpnts sum = {0.0, 0.0, 0.0};
462 PetscBool attempted_read = PETSC_FALSE;
465 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
466 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
467 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
470 PetscInt node_idx_k = k + dk_offset;
471 PetscInt node_idx_j = j + dj_offset;
472 PetscInt node_idx_i = i + di_offset;
476 PetscInt cell_idx_k = node_idx_k;
477 PetscInt cell_idx_j = node_idx_j;
478 PetscInt cell_idx_i = node_idx_i;
482 if (cell_idx_i >= 0 && cell_idx_i <= MX_node &&
483 cell_idx_j >= 0 && cell_idx_j <= MY_node &&
484 cell_idx_k >= 0 && cell_idx_k <= MZ_node)
497 if (node_idx_i >= gxs_node && node_idx_i < gxe_node &&
498 node_idx_j >= gys_node && node_idx_j < gye_node &&
499 node_idx_k >= gzs_node && node_idx_k < gze_node)
502 LOG_LOOP_ALLOW_EXACT(
LOCAL,
LOG_DEBUG,k,6,
"PRE-READ: Rank %d targeting Node(k,j,i)=%d,%d,%d. Reading input centfield_arr[%d][%d][%d] (for cell C(%d,%d,%d))\n",
505 node_idx_k,node_idx_j,node_idx_i,
506 cell_idx_k, cell_idx_j, cell_idx_i);
508 attempted_read = PETSC_TRUE;
511 PetscInt k_local_read = node_idx_k - gzs_node;
512 PetscInt j_local_read = node_idx_j - gys_node;
513 PetscInt i_local_read = node_idx_i - gxs_node;
515 Cmpnts cell_val = centfield_arr[k_local_read][j_local_read][i_local_read];
521 node_idx_k,node_idx_j,node_idx_i,
522 cell_val.
x, cell_val.
y, cell_val.
z);
541 PetscInt k_local = k - zs_node;
542 PetscInt j_local = j - ys_node;
543 PetscInt i_local = i - xs_node;
546 LOG_LOOP_ALLOW_EXACT(
LOCAL,
LOG_DEBUG,k,6,
"PRE-WRITE: Rank %d targeting Node(k,j,i)=%d,%d,%d. Writing avg (count=%d)\n", rank,k,j,i, count);
549 if (k_local < 0 || k_local >= info_nodes.zm ||
550 j_local < 0 || j_local >= info_nodes.ym ||
551 i_local < 0 || i_local >= info_nodes.xm) {
552 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Calculated local write index out of bounds!");
557 field_arr[k_local][j_local][i_local].
x = sum.
x / (PetscReal)count;
558 field_arr[k_local][j_local][i_local].
y = sum.
y / (PetscReal)count;
559 field_arr[k_local][j_local][i_local].
z = sum.
z / (PetscReal)count;
567 "Rank %d: Node (i=%d,j=%d,k=%d) had count=0 surrounding valid cells! Check logic/ghosting. Writing zero.\n", rank, i, j, k);
568 field_arr[k_local][j_local][i_local] = (
Cmpnts){0.0, 0.0, 0.0};
571 if (!attempted_read && count==0) {
572 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"NODE-COMPLETE: Rank %d Node(k,j,i)=%d,%d,%d finished loops, no valid cells/reads attempted.\n", rank, k, j, i);
573 }
else if (count == 0 && attempted_read) {
575 LOG_ALLOW(
LOCAL,
LOG_ERROR,
"NODE-COMPLETE: Rank %d Node(k,j,i)=%d,%d,%d finished loops, attempted reads but count=0!\n", rank, k, j, i);
578 LOG_LOOP_ALLOW_EXACT(
LOCAL,
LOG_DEBUG,k,6,
"NODE-COMPLETE: Rank %d Node(k,j,i)=%d,%d,%d finished loops and write.\n", rank, k, j, i);
586 "Rank %d completed interpolation function.\n", rank);
609 DMDALocalInfo info_nodes;
611 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
612 ierr = DMDAGetLocalInfo(user->
fda, &info_nodes); CHKERRQ(ierr);
615 PetscInt xs_node = info_nodes.xs, xm_node = info_nodes.xm, xe_node = xs_node + xm_node;
616 PetscInt ys_node = info_nodes.ys, ym_node = info_nodes.ym, ye_node = ys_node + ym_node;
617 PetscInt zs_node = info_nodes.zs, zm_node = info_nodes.zm, ze_node = zs_node + zm_node;
620 PetscInt IM = info_nodes.mx;
621 PetscInt JM = info_nodes.my;
622 PetscInt KM = info_nodes.mz;
625 PetscInt gxs = info_nodes.gxs;
626 PetscInt gys = info_nodes.gys;
627 PetscInt gzs = info_nodes.gzs;
630 for (PetscInt k = zs_node; k < ze_node; k++) {
631 for (PetscInt j = ys_node; j < ye_node; j++) {
632 for (PetscInt i = xs_node; i < xe_node; i++) {
633 Cmpnts sum = {0.0, 0.0, 0.0};
637 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
638 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
639 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
642 PetscInt global_cell_k = k + dk_offset;
643 PetscInt global_cell_j = j + dj_offset;
644 PetscInt global_cell_i = i + di_offset;
647 if (global_cell_i >= 0 && global_cell_i < IM - 1 &&
648 global_cell_j >= 0 && global_cell_j < JM - 1 &&
649 global_cell_k >= 0 && global_cell_k < KM - 1)
653 Cmpnts cell_val = centfield_arr[global_cell_k][global_cell_j][global_cell_i];
656 rank,global_cell_k,global_cell_j,global_cell_i,cell_val.
x, cell_val.
y, cell_val.
z);
671 corner_arr[k][j][i].
x = sum.
x / (PetscReal)count;
672 corner_arr[k][j][i].
y = sum.
y / (PetscReal)count;
673 corner_arr[k][j][i].
z = sum.
z / (PetscReal)count;
676 corner_arr[k][j][i] = (
Cmpnts){0.0, 0.0, 0.0};
679 LOG_LOOP_ALLOW_EXACT(
LOCAL,
LOG_DEBUG,k,6,
"[Rank %d] Node(k,j,i)=%d,%d,%d finished loops and write.\n", rank, k, j, i);
700 PetscReal ***centfield_arr,
701 PetscReal ***corner_arr,
705 DMDALocalInfo info_nodes;
706 ierr = DMDAGetLocalInfo(user->
fda, &info_nodes); CHKERRQ(ierr);
709 PetscInt xs_node = info_nodes.xs, xe_node = info_nodes.xs + info_nodes.xm;
710 PetscInt ys_node = info_nodes.ys, ye_node = info_nodes.ys + info_nodes.ym;
711 PetscInt zs_node = info_nodes.zs, ze_node = info_nodes.zs + info_nodes.zm;
714 PetscInt IM = info_nodes.mx;
715 PetscInt JM = info_nodes.my;
716 PetscInt KM = info_nodes.mz;
719 for (PetscInt k = zs_node; k < ze_node; k++) {
720 for (PetscInt j = ys_node; j < ye_node; j++) {
721 for (PetscInt i = xs_node; i < xe_node; i++) {
726 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
727 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
728 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
730 PetscInt cell_idx_k = k + dk_offset;
731 PetscInt cell_idx_j = j + dj_offset;
732 PetscInt cell_idx_i = i + di_offset;
736 if (cell_idx_i >= 0 && cell_idx_i < IM - 1 &&
737 cell_idx_j >= 0 && cell_idx_j < JM - 1 &&
738 cell_idx_k >= 0 && cell_idx_k < KM - 1)
740 sum += centfield_arr[cell_idx_k][cell_idx_j][cell_idx_i];
749 corner_arr[k][j][i] = sum / (PetscReal)count;
751 corner_arr[k][j][i] = 0.0;
773 const char *fieldName,
774 PetscReal ***fieldScal,
781 *val = fieldScal[kCell][jCell][iCell];
785 "PieceWiseLinearInterpolation_Scalar: Field '%s' at (i=%d, j=%d, k=%d) => val=%.6f\n",
786 fieldName, iCell, jCell, kCell, *val);
788 PetscFunctionReturn(0);
809 const char *fieldName,
817 vec->
x = fieldVec[kCell][jCell][iCell].
x;
818 vec->
y = fieldVec[kCell][jCell][iCell].
y;
819 vec->
z = fieldVec[kCell][jCell][iCell].
z;
823 "PieceWiseLinearInterpolation_Vector: Field '%s' at (i=%d, j=%d, k=%d) => (x=%.6f, y=%.6f, z=%.6f)\n",
824 fieldName, iCell, jCell, kCell, vec->
x, vec->
y, vec->
z);
826 PetscFunctionReturn(0);
848 a1 = PetscMax(0.0, PetscMin(1.0, a1));
849 a2 = PetscMax(0.0, PetscMin(1.0, a2));
850 a3 = PetscMax(0.0, PetscMin(1.0, a3));
852 const PetscReal oa1 = 1.0 - a1;
853 const PetscReal oa2 = 1.0 - a2;
854 const PetscReal oa3 = 1.0 - a3;
856 w[0] = oa1 * oa2 * oa3;
857 w[1] = a1 * oa2 * oa3;
858 w[2] = oa1 * a2 * oa3;
859 w[3] = a1 * a2 * oa3;
860 w[4] = oa1 * oa2 * a3;
861 w[5] = a1 * oa2 * a3;
862 w[6] = oa1 * a2 * a3;
867 "w0=%f, w1=%f, w2=%f, w3=%f, w4=%f, w5=%f, w6=%f, w7=%f. \n",
868 w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
885 const char *fieldName,
886 PetscReal ***fieldScal,
898 PetscReal wcorner[8];
910 sum += wcorner[0] * fieldScal[k ][j ][i ];
912 sum += wcorner[1] * fieldScal[k ][j ][i1];
914 sum += wcorner[2] * fieldScal[k ][j1][i ];
916 sum += wcorner[3] * fieldScal[k ][j1][i1];
918 sum += wcorner[4] * fieldScal[k1][j ][i ];
920 sum += wcorner[5] * fieldScal[k1][j ][i1];
922 sum += wcorner[6] * fieldScal[k1][j1][i ];
924 sum += wcorner[7] * fieldScal[k1][j1][i1];
930 "TrilinearInterpolation_Scalar: Field '%s' at (i=%d, j=%d, k=%d), "
931 "a1=%.6f, a2=%.6f, a3=%.6f -> val=%.6f.\n",
932 fieldName, i, j, k, a1, a2, a3, *val);
938 PetscFunctionReturn(0);
963 const char *fieldName,
977 PetscReal wcorner[8];
980 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
989 PetscReal sumW = 0.0;
990 Cmpnts accum = {0.0, 0.0, 0.0};
995 const PetscInt cornerOffsets[8][3] = {
1007 for (PetscInt c = 0; c < 8; c++) {
1008 const PetscInt di = cornerOffsets[c][0];
1009 const PetscInt dj = cornerOffsets[c][1];
1010 const PetscInt dk = cornerOffsets[c][2];
1011 PetscInt iC = i + di;
1012 PetscInt jC = j + dj;
1013 PetscInt kC = k + dk;
1028 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"[Rank %d] %s[%d][%d][%d] = (%.4f,%.4f,%.4f).\n",rank,fieldName,kC,jC,iC,fieldVec[kC][jC][iC].x,fieldVec[kC][jC][iC].y,fieldVec[kC][jC][iC].z);
1031 accum.
x += wcorner[c] * fieldVec[kC][jC][iC].
x;
1032 accum.
y += wcorner[c] * fieldVec[kC][jC][iC].
y;
1033 accum.
z += wcorner[c] * fieldVec[kC][jC][iC].
z;
1038 if (sumW > 1.0e-14) {
1039 vec->
x = accum.
x / sumW;
1040 vec->
y = accum.
y / sumW;
1041 vec->
z = accum.
z / sumW;
1043 vec->
x = 0.0; vec->
y = 0.0; vec->
z = 0.0;
1046 PetscFunctionReturn(0);
1081 const char *fieldName,
1093 PetscErrorCode ierr;
1098 "InterpolateEulerFieldToSwarmForParticle: field='%s', blockSize=%d, "
1099 "cell IDs=(%d,%d,%d), weights=(%.4f,%.4f,%.4f)\n",
1100 fieldName, blockSize, iCell, jCell, kCell, a1, a2, a3);
1106 if (blockSize == 1) {
1108 PetscReal ***fieldScal = (PetscReal ***) fieldPtr;
1113 iCell, jCell, kCell,
1126 ((PetscReal*)swarmOut)[p] = val;
1129 "InterpolateEulerFieldToSwarmForParticle [Scalar]: field='%s', result=%.6f "
1130 "stored at swarmOut index p=%d.\n", fieldName, val, (PetscInt)p);
1132 else if (blockSize == 3) {
1149 iCell, jCell, kCell,
1155 ((PetscReal*)swarmOut)[3*p + 0] = vec.
x;
1156 ((PetscReal*)swarmOut)[3*p + 1] = vec.
y;
1157 ((PetscReal*)swarmOut)[3*p + 2] = vec.
z;
1160 "InterpolateEulerFieldToSwarmForParticle [Vector]: field='%s', result=(%.6f,%.6f,%.6f) "
1161 "stored at swarmOut[3p..3p+2], p=%d.\n",
1162 fieldName, vec.
x, vec.
y, vec.
z, (PetscInt)p);
1172 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
1173 "InterpolateEulerFieldToSwarmForParticle: only blockSize=1 or 3 supported, got %d.",
1174 (PetscInt)blockSize);
1177 PetscFunctionReturn(0);
1212 Vec fieldLocal_cellCentered,
1213 const char *fieldName,
1214 const char *swarmOutFieldName)
1216 PetscErrorCode ierr;
1218 DM swarm = user->
swarm;
1224 Vec cornerGlobal, cornerLocal;
1227 void *cellCenterPtr_read;
1228 void *cornerPtr_read_with_ghosts;
1231 PetscInt *cellIDs = NULL;
1232 PetscReal *weights = NULL;
1233 PetscInt *pids = NULL;
1234 void *swarmOut = NULL;
1238 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1239 ierr = DMDAGetLocalInfo(fda, &info); CHKERRQ(ierr);
1240 ierr = VecGetBlockSize(fieldLocal_cellCentered, &bs); CHKERRQ(ierr);
1241 if (bs != 1 && bs != 3) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
"BlockSize must be 1 or 3.");
1248 ierr = DMGetGlobalVector(fda, &cornerGlobal); CHKERRQ(ierr);
1249 ierr = DMGetLocalVector(fda, &cornerLocal); CHKERRQ(ierr);
1251 ierr = VecSet(cornerGlobal,0.0); CHKERRQ(ierr);
1252 ierr = VecSet(cornerLocal,0.0); CHKERRQ(ierr);
1255 ierr = DMDAVecGetArrayRead(fda, fieldLocal_cellCentered, &cellCenterPtr_read); CHKERRQ(ierr);
1258 void *cornerPtr_write = NULL;
1259 ierr = DMDAVecGetArray(fda, cornerLocal, &cornerPtr_write); CHKERRQ(ierr);
1261 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"[Rank %d] Starting center-to-corner interpolation for '%s'.\n", rank, fieldName);
1266 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"[Rank %d] Finished center-to-corner interpolation for '%s'.\n", rank, fieldName);
1267 ierr = DMDAVecRestoreArray(fda, cornerLocal, &cornerPtr_write); CHKERRQ(ierr);
1269 ierr = DMDAVecRestoreArrayRead(fda, fieldLocal_cellCentered, &cellCenterPtr_read); CHKERRQ(ierr);
1291 ierr = DMLocalToGlobalBegin(fda, cornerLocal, INSERT_VALUES, cornerGlobal); CHKERRQ(ierr);
1292 ierr = DMLocalToGlobalEnd(fda, cornerLocal, INSERT_VALUES, cornerGlobal); CHKERRQ(ierr);
1294 ierr = DMGlobalToLocalBegin(fda, cornerGlobal, INSERT_VALUES, cornerLocal); CHKERRQ(ierr);
1295 ierr = DMGlobalToLocalEnd(fda, cornerGlobal, INSERT_VALUES, cornerLocal); CHKERRQ(ierr);
1301 ierr = DMView(user->
fda, PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
1336 ierr = DMDAVecGetArrayRead(fda, cornerLocal, &cornerPtr_read_with_ghosts); CHKERRQ(ierr);
1339 ierr = DMSwarmGetLocalSize(swarm, &nLocal); CHKERRQ(ierr);
1340 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
1341 ierr = DMSwarmGetField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&pids); CHKERRQ(ierr);
1342 ierr = DMSwarmGetField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
1343 ierr = DMSwarmGetField(swarm, swarmOutFieldName, NULL, NULL, &swarmOut); CHKERRQ(ierr);
1346 for (PetscInt p = 0; p < nLocal; p++) {
1347 PetscInt iCell_global = cellIDs[3 * p + 0];
1348 PetscInt jCell_global = cellIDs[3 * p + 1];
1349 PetscInt kCell_global = cellIDs[3 * p + 2];
1352 PetscInt iCell_local = iCell_global;
1353 PetscInt jCell_local = jCell_global;
1354 PetscInt kCell_local = kCell_global;
1359 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
" The ghosted max of current rank %d are: %d,%d,%d.\n",rank,info.gxs + info.gxm,info.gys+info.gym,info.gzs+info.gzm);
1361 if (iCell_local < 0 || iCell_local >= info.gxs + info.gxm - 1 ||
1362 jCell_local < 0 || jCell_local >= info.gys + info.gym - 1 ||
1363 kCell_local < 0 || kCell_local >= info.gzs + info.gzm - 1)
1366 "[Rank %d] Particle PID %lld in global cell (%d,%d,%d) is in an un-interpolatable region (requires ghosts of ghosts or is out of bounds). Zeroing field '%s'.\n",
1367 rank, (
long long)pids[p], iCell_global, jCell_global, kCell_global, fieldName);
1370 ((PetscReal*)swarmOut)[3*p + 0] = 0.0;
1371 ((PetscReal*)swarmOut)[3*p + 1] = 0.0;
1372 ((PetscReal*)swarmOut)[3*p + 2] = 0.0;
1374 ((PetscReal*)swarmOut)[p] = 0.0;
1379 PetscReal a1 = weights[3 * p + 0];
1380 PetscReal a2 = weights[3 * p + 1];
1381 PetscReal a3 = weights[3 * p + 2];
1385 cornerPtr_read_with_ghosts,
1386 iCell_local, jCell_local, kCell_local,
1393 ierr = DMDAVecRestoreArrayRead(fda, cornerLocal, &cornerPtr_read_with_ghosts); CHKERRQ(ierr);
1394 ierr = DMSwarmRestoreField(swarm, swarmOutFieldName, NULL, NULL, &swarmOut); CHKERRQ(ierr);
1395 ierr = DMSwarmRestoreField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
1396 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&pids); CHKERRQ(ierr);
1397 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
1399 ierr = DMRestoreLocalVector(fda, &cornerLocal); CHKERRQ(ierr);
1400 ierr = DMRestoreGlobalVector(fda, &cornerGlobal); CHKERRQ(ierr);
1403 PetscFunctionReturn(0);
1647#define __FUNCT__ "InterpolateAllFieldsToSwarm"
1669 PetscErrorCode ierr;
1675 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
1689 "InterpolateteAllFieldsToSwarm: Interpolation of ucat to velocity begins on rank %d.\n",rank);
1693 "velocity"); CHKERRQ(ierr);
1715 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1717 "[rank %d]Completed Interpolateting all fields to the swarm.\n",rank);
1721 PetscFunctionReturn(0);
1785 DM *targetDM, PetscInt *expected_dof)
1788 PetscFunctionBeginUser;
1792 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx pointer is NULL.");
1793 if (!user->
da) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->da is NULL.");
1794 if (!user->
fda) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->fda is NULL.");
1795 if (!particleFieldName) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"particleFieldName is NULL.");
1796 if (!targetDM) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output targetDM pointer is NULL.");
1797 if (!expected_dof) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output expected_dof pointer is NULL.");
1801 if (strcmp(particleFieldName,
"Psi") == 0 || strcmp(particleFieldName,
"Nvert") == 0) {
1803 *targetDM = user->
da;
1807 else if (strcmp(particleFieldName,
"Ucat") == 0 || strcmp(particleFieldName,
"Ucont") == 0) {
1809 *targetDM = user->
fda;
1820 PetscSNPrintf(msg,
sizeof(msg),
"GetScatterTargetInfo: Field name '%s' is not recognized for automatic DM selection.", particleFieldName);
1822 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1825 PetscFunctionReturn(0);
1850 DM gridSumDM, Vec gridSumVec)
1852 PetscErrorCode ierr;
1855 const PetscReal *particle_arr = NULL;
1856 const PetscInt *cell_id_arr = NULL;
1857 PetscScalar *sum_arr_ptr = NULL;
1858 PetscInt gxs, gys, gzs;
1859 PetscInt gxm, gym, gzm;
1863 PetscFunctionBeginUser;
1864 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1867 ierr = DMDAGetInfo(gridSumDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1869 if (dof != 1 && dof != 3) {
1870 PetscSNPrintf(msg,
sizeof(msg),
"AccumulateParticleField: gridSumDM DOF must be 1 or 3, got %d.", dof);
1871 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1876 ierr = DMSwarmGetField(swarm, particleFieldName, NULL, NULL, (
void **)&particle_arr); CHKERRQ(ierr);
1877 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void **)&cell_id_arr); CHKERRQ(ierr);
1880 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1883 ierr = VecGetArray(gridSumVec, &sum_arr_ptr); CHKERRQ(ierr);
1885 ierr = DMDAGetGhostCorners(gridSumDM, &gxs, &gys, &gzs, &gxm, &gym, &gzm); CHKERRQ(ierr);
1888 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"AccumulateParticleField (Rank %d): Accumulating '%s' (DOF=%d) from %d particles using CellID field 'DMSwarm_CellID'.\n", rank, particleFieldName, dof, nlocal);
1890 for (p = 0; p < nlocal; ++p) {
1893 PetscInt pidx = cell_id_arr[p * 3 + 0];
1894 PetscInt pidy = cell_id_arr[p * 3 + 1];
1895 PetscInt pidz = cell_id_arr[p * 3 + 2];
1898 if (pidx >= 0 && pidx < gxm && pidy >= 0 && pidy < gym && pidz >= 0 && pidz < gzm)
1903 PetscInt cell_flat_idx = (pidz * gym + pidy) * gxm + pidx;
1906 PetscInt particle_base_idx = p * dof;
1908 PetscInt grid_base_idx = cell_flat_idx * dof;
1911 for (PetscInt c = 0; c < dof; ++c) {
1912 sum_arr_ptr[grid_base_idx + c] += particle_arr[particle_base_idx + c];
1917 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"AccumulateParticleField (Rank %d): Particle %d (field '%s') has out-of-bounds CellID (%d, %d, %d). Ghosted dims: %dx%dx%d. Skipping.\n",
1918 rank, p, particleFieldName, pidx, pidy, pidz, gxm, gym, gzm);
1923 ierr = VecRestoreArray(gridSumVec, &sum_arr_ptr); CHKERRQ(ierr);
1924 ierr = DMSwarmRestoreField(swarm, particleFieldName, NULL, NULL, (
void **)&particle_arr); CHKERRQ(ierr);
1925 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void **)&cell_id_arr); CHKERRQ(ierr);
1929 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"AccumulateParticleField: Assembling global sum vector for '%s'.\n", particleFieldName);
1930 ierr = VecAssemblyBegin(gridSumVec); CHKERRQ(ierr);
1931 ierr = VecAssemblyEnd(gridSumVec); CHKERRQ(ierr);
1933 PetscFunctionReturn(0);
1955 DM dataDM, Vec sumVec, Vec avgVec)
1957 PetscErrorCode ierr;
1964 PetscScalar ***count_arr_3d = NULL;
1965 PetscScalar ***sum_arr_scalar = NULL;
1966 PetscScalar ***avg_arr_scalar = NULL;
1967 PetscScalar ***sum_arr_vector = NULL;
1968 PetscScalar ***avg_arr_vector = NULL;
1971 PetscFunctionBeginUser;
1972 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1975 ierr = DMDAGetInfo(countDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &count_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1976 ierr = DMDAGetInfo(dataDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &data_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1977 if (count_dof != 1) { PetscSNPrintf(msg,
sizeof(msg),
"countDM must have DOF=1, got %d.", count_dof); SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg); }
1978 if (data_dof != 1 && data_dof != 3) { PetscSNPrintf(msg,
sizeof(msg),
"dataDM DOF must be 1 or 3, got %d.", data_dof); SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg); }
1981 ierr = DMDAVecGetArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1983 if (data_dof == 1) {
1984 ierr = DMDAVecGetArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1985 ierr = DMDAVecGetArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1987 ierr = DMDAVecGetArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1988 ierr = DMDAVecGetArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1992 PetscInt xs, ys, zs, xm, ym, zm;
1993 ierr = DMDAGetCorners(countDM, &xs, &ys, &zs, &xm, &ym, &zm); CHKERRQ(ierr);
1996 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"NormalizeGridVectorByCount (Rank %d): Normalizing DOF=%d data over owned range [%d:%d, %d:%d, %d:%d].\n",
1997 rank, data_dof, xs, xs+xm, ys, ys+ym, zs, zs+zm);
2000 for (PetscInt k = zs; k < zs + zm; ++k) {
2001 for (PetscInt j = ys; j < ys + ym; ++j) {
2002 for (PetscInt i = xs; i < xs + xm; ++i) {
2005 PetscScalar count = count_arr_3d[k][j][i];
2007 if (PetscRealPart(count) > 0.5) {
2008 if (data_dof == 1) {
2010 avg_arr_scalar[k][j][i] = sum_arr_scalar[k][j][i] / count;
2013 for (PetscInt c = 0; c < data_dof; ++c) {
2014 avg_arr_vector[k][j][i * data_dof + c] = sum_arr_vector[k][j][i * data_dof + c] / count;
2019 if (data_dof == 1) {
2020 avg_arr_scalar[k][j][i] = 0.0;
2022 for (PetscInt c = 0; c < data_dof; ++c) {
2023 avg_arr_vector[k][j][i * data_dof + c] = 0.0;
2032 ierr = DMDAVecRestoreArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
2033 if (data_dof == 1) {
2034 ierr = DMDAVecRestoreArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
2035 ierr = DMDAVecRestoreArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
2037 ierr = DMDAVecRestoreArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
2038 ierr = DMDAVecRestoreArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
2043 ierr = VecAssemblyBegin(avgVec); CHKERRQ(ierr);
2044 ierr = VecAssemblyEnd(avgVec); CHKERRQ(ierr);
2046 PetscFunctionReturn(0);
2075 const char *particleFieldName,
2077 PetscInt expected_dof,
2078 Vec eulerFieldAverageVec)
2080 PetscErrorCode ierr;
2084 PetscFunctionBeginUser;
2086 if (!user || !user->
swarm || !user->
ParticleCount || !particleFieldName || !targetDM || !eulerFieldAverageVec)
2087 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"NULL input provided to ScatterParticleFieldToEulerField_Internal.");
2106 ierr = VecDuplicate(eulerFieldAverageVec, &sumVec); CHKERRQ(ierr);
2107 ierr = VecSet(sumVec, 0.0); CHKERRQ(ierr);
2108 ierr = PetscSNPrintf(msg,
sizeof(msg),
"TempSum_%s", particleFieldName); CHKERRQ(ierr);
2109 ierr = PetscObjectSetName((PetscObject)sumVec, msg); CHKERRQ(ierr);
2124 ierr = VecDestroy(&sumVec); CHKERRQ(ierr);
2126 PetscFunctionReturn(0);
2152 const char *particleFieldName,
2153 Vec eulerFieldAverageVec)
2155 PetscErrorCode ierr;
2157 PetscInt expected_dof = 0;
2160 PetscFunctionBeginUser;
2163 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx pointer is NULL.");
2164 if (!user->
swarm) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->swarm is NULL.");
2165 if (!user->
ParticleCount) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->ParticleCount is NULL.");
2166 if (!eulerFieldAverageVec) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output eulerFieldAverageVec is NULL.");
2177 ierr = VecGetDM(eulerFieldAverageVec, &vec_dm); CHKERRQ(ierr);
2179 PetscSNPrintf(msg,
sizeof(msg),
"Provided eulerFieldAverageVec for field '%s' does not have an associated DM.", particleFieldName);
2180 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, msg);
2183 ierr = VecGetBlockSize(eulerFieldAverageVec, &vec_dof); CHKERRQ(ierr);
2185 if (vec_dm != targetDM) {
2186 const char *target_dm_name =
"targetDM", *vec_dm_name =
"vec_dm";
2188 PetscObjectGetName((PetscObject)targetDM, &target_dm_name);
2189 PetscObjectGetName((PetscObject)vec_dm, &vec_dm_name);
2190 PetscSNPrintf(msg,
sizeof(msg),
"Provided eulerFieldAverageVec associated with DM '%s', but field '%s' requires scatter to DM '%s'.", vec_dm_name, particleFieldName, target_dm_name);
2191 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg);
2194 if (vec_dof != expected_dof) {
2195 PetscSNPrintf(msg,
sizeof(msg),
"Field '%s' requires DOF %d, but provided eulerFieldAverageVec has DOF %d.", particleFieldName, expected_dof, vec_dof);
2196 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg);
2201 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"ScatterParticleFieldToEulerField: Scattering field '%s' (DOF=%d).\n", particleFieldName, expected_dof);
2206 eulerFieldAverageVec);
2209 LOG_ALLOW(
GLOBAL,
LOG_INFO,
"ScatterParticleFieldToEulerField: Successfully scattered field '%s'.\n", particleFieldName);
2210 PetscFunctionReturn(0);
2214#define __FUNCT__ "ScatterAllParticleFieldsToEulerFields"
2237 PetscErrorCode ierr;
2238 PetscFunctionBeginUser;
2245 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"UserCtx->ParticleCount is NULL. Compute counts before calling ScatterAllParticleFieldsToEulerFields.");
2257 PetscReal Avg_Psi,Avg_swarm_Psi;
2259 ierr = VecMean(user->
P,&Avg_Psi);
2262 ierr = DMSwarmCreateGlobalVectorFromField(user->
swarm,
"Psi",&swarm_Psi);
2263 ierr = VecMean(swarm_Psi,&Avg_swarm_Psi);
2267 ierr = DMSwarmDestroyGlobalVectorFromField(user->
swarm,
"Psi",&swarm_Psi);
2274 ierr = VecMean(user->
Psi,&Avg_Psi);
2326 PetscFunctionReturn(0);
2349 PetscReal ***corner_arr,
2350 PetscReal ***faceX_arr,
2351 PetscReal ***faceY_arr,
2352 PetscReal ***faceZ_arr,
2355 PetscErrorCode ierr;
2357 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
2360 PetscInt xs, xm, ys, ym, zs, zm;
2366 PetscInt xe = xs + xm;
2367 PetscInt ye = ys + ym;
2368 PetscInt ze = zs + zm;
2371 for (PetscInt k = zs; k < ze; ++k) {
2372 PetscInt k_loc = k - zs;
2373 for (PetscInt j = ys; j < ye; ++j) {
2374 PetscInt j_loc = j - ys;
2375 for (PetscInt i = xs; i <= xe; ++i) {
2376 PetscInt i_loc = i - xs;
2378 PetscReal sum = corner_arr[k ][j ][i]
2379 + corner_arr[k+1][j ][i]
2380 + corner_arr[k ][j+1][i]
2381 + corner_arr[k+1][j+1][i];
2382 faceX_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2388 for (PetscInt k = zs; k < ze; ++k) {
2389 PetscInt k_loc = k - zs;
2390 for (PetscInt j = ys; j <= ye; ++j) {
2391 PetscInt j_loc = j - ys;
2392 for (PetscInt i = xs; i < xe; ++i) {
2393 PetscInt i_loc = i - xs;
2395 PetscReal sum = corner_arr[k ][j][i ]
2396 + corner_arr[k+1][j][i ]
2397 + corner_arr[k ][j][i+1]
2398 + corner_arr[k+1][j][i+1];
2399 faceY_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2405 for (PetscInt k = zs; k <= ze; ++k) {
2406 PetscInt k_loc = k - zs;
2407 for (PetscInt j = ys; j < ye; ++j) {
2408 PetscInt j_loc = j - ys;
2409 for (PetscInt i = xs; i < xe; ++i) {
2410 PetscInt i_loc = i - xs;
2412 PetscReal sum = corner_arr[k][j ][i ]
2413 + corner_arr[k][j ][i+1]
2414 + corner_arr[k][j+1][i ]
2415 + corner_arr[k][j+1][i+1];
2416 faceZ_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2445 PetscErrorCode ierr;
2449 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
2451 "Rank %d starting InterpolateFieldFromCornerToFaceCenter_Vector.\n", rank);
2453 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
2455 PetscInt xs, xm, ys, ym, zs, zm;
2460 PetscInt xe = xs + xm;
2461 PetscInt ye = ys + ym;
2462 PetscInt ze = zs + zm;
2465 for (PetscInt k = zs; k < ze; ++k) {
2466 PetscInt k_loc = k - zs;
2467 for (PetscInt j = ys; j < ye; ++j) {
2468 PetscInt j_loc = j - ys;
2469 for (PetscInt i = xs; i <= xe; ++i) {
2470 PetscInt i_loc = i - xs;
2472 sum.
x = corner_arr[k ][j ][i].
x + corner_arr[k+1][j ][i].
x
2473 + corner_arr[k ][j+1][i].
x + corner_arr[k+1][j+1][i].
x;
2474 sum.
y = corner_arr[k ][j ][i].
y + corner_arr[k+1][j ][i].
y
2475 + corner_arr[k ][j+1][i].
y + corner_arr[k+1][j+1][i].
y;
2476 sum.
z = corner_arr[k ][j ][i].
z + corner_arr[k+1][j ][i].
z
2477 + corner_arr[k ][j+1][i].
z + corner_arr[k+1][j+1][i].
z;
2478 faceX_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2479 faceX_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2480 faceX_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2486 "Rank %d x-face Interpolation complete.\n", rank);
2489 for (PetscInt k = zs; k < ze; ++k) {
2490 PetscInt k_loc = k - zs;
2491 for (PetscInt j = ys; j <= ye; ++j) {
2492 PetscInt j_loc = j - ys;
2493 for (PetscInt i = xs; i < xe; ++i) {
2494 PetscInt i_loc = i - xs;
2496 sum.
x = corner_arr[k ][j][i ].
x + corner_arr[k+1][j][i ].
x
2497 + corner_arr[k ][j][i+1].
x + corner_arr[k+1][j][i+1].
x;
2498 sum.
y = corner_arr[k ][j][i ].
y + corner_arr[k+1][j][i ].
y
2499 + corner_arr[k ][j][i+1].
y + corner_arr[k+1][j][i+1].
y;
2500 sum.
z = corner_arr[k ][j][i ].
z + corner_arr[k+1][j][i ].
z
2501 + corner_arr[k ][j][i+1].
z + corner_arr[k+1][j][i+1].
z;
2502 faceY_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2503 faceY_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2504 faceY_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2510 "Rank %d y-face Interpolation complete.\n", rank);
2513 for (PetscInt k = zs; k <= ze; ++k) {
2514 PetscInt k_loc = k - zs;
2515 for (PetscInt j = ys; j < ye; ++j) {
2516 PetscInt j_loc = j - ys;
2517 for (PetscInt i = xs; i < xe; ++i) {
2518 PetscInt i_loc = i - xs;
2520 sum.
x = corner_arr[k][j ][i ].
x + corner_arr[k][j ][i+1].
x
2521 + corner_arr[k][j+1][i ].
x + corner_arr[k][j+1][i+1].
x;
2522 sum.
y = corner_arr[k][j ][i ].
y + corner_arr[k][j ][i+1].
y
2523 + corner_arr[k][j+1][i ].
y + corner_arr[k][j+1][i+1].
y;
2524 sum.
z = corner_arr[k][j ][i ].
z + corner_arr[k][j ][i+1].
z
2525 + corner_arr[k][j+1][i ].
z + corner_arr[k][j+1][i+1].
z;
2526 faceZ_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2527 faceZ_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2528 faceZ_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2534 "Rank %d z-face Interpolation complete.\n", rank);
PetscErrorCode GetScatterTargetInfo(UserCtx *user, const char *particleFieldName, DM *targetDM, PetscInt *expected_dof)
Determines the target Eulerian DM and expected DOF for scattering a given particle field.
PetscErrorCode NormalizeGridVectorByCount(DM countDM, Vec countVec, DM dataDM, Vec sumVec, Vec avgVec)
Normalizes a grid vector of sums by a grid vector of counts to produce an average.
PetscErrorCode AccumulateParticleField(DM swarm, const char *particleFieldName, DM gridSumDM, Vec gridSumVec)
Accumulates a particle field (scalar or vector) into a target grid sum vector.
static PetscErrorCode ScatterParticleFieldToEulerField_Internal(UserCtx *user, const char *particleFieldName, DM targetDM, PetscInt expected_dof, Vec eulerFieldAverageVec)
Internal helper function to orchestrate the scatter operation (accumulate + normalize).
PetscErrorCode CalculateParticleCountPerCell(UserCtx *user)
Counts particles in each cell of the DMDA 'da' and stores the result in user->ParticleCount.
PetscErrorCode ScatterAllParticleFieldsToEulerFields(UserCtx *user)
Scatters a predefined set of particle fields to their corresponding Eulerian fields.
PetscErrorCode ScatterParticleFieldToEulerField(UserCtx *user, const char *particleFieldName, Vec eulerFieldAverageVec)
Scatters a particle field (scalar or vector) to the corresponding Eulerian field average.
PetscErrorCode InterpolateFieldFromCornerToCenter_Vector(Cmpnts ***field_arr, Cmpnts ***centfield_arr, UserCtx *user)
Interpolates a vector field from corner nodes to cell centers.
PetscErrorCode InterpolateCornerToFaceCenter_Vector(Cmpnts ***corner_arr, Cmpnts ***faceX_arr, Cmpnts ***faceY_arr, Cmpnts ***faceZ_arr, UserCtx *user)
Interpolates a vector field from corner nodes to all face centers.
PetscErrorCode InterpolateFieldFromCornerToCenter_Scalar(PetscReal ***field_arr, PetscReal ***centfield_arr, UserCtx *user)
Interpolates a scalar field from corner nodes to cell centers.
PetscErrorCode InterpolateAllFieldsToSwarm(UserCtx *user)
Interpolates all relevant fields from the DMDA to the DMSwarm.
PetscErrorCode TrilinearInterpolation_Vector(const char *fieldName, Cmpnts ***fieldVec, PetscInt i, PetscInt j, PetscInt k, PetscReal a1, PetscReal a2, PetscReal a3, Cmpnts *vec)
Computes the trilinear Interpolateted vector (e.g., velocity) at a given point.
PetscErrorCode InterpolateFieldFromCenterToCorner_Scalar(PetscReal ***centfield_arr, PetscReal ***field_arr, UserCtx *user)
Interpolates a scalar field from cell centers to corner nodes.
static PetscErrorCode InterpolateEulerFieldToSwarmForParticle(const char *fieldName, void *fieldPtr, PetscInt iCell, PetscInt jCell, PetscInt kCell, PetscReal a1, PetscReal a2, PetscReal a3, void *swarmOut, PetscInt p, PetscInt blockSize)
Interpolates a single field (scalar or vector) for one particle, storing the result in a swarm array.
PetscErrorCode InterpolateFieldFromCenterToCorner_Vector_Petsc(Cmpnts ***centfield_arr, Cmpnts ***corner_arr, UserCtx *user)
Interpolates a vector field from cell centers to corner nodes.
PetscErrorCode TrilinearInterpolation_Scalar(const char *fieldName, PetscReal ***fieldScal, PetscInt i, PetscInt j, PetscInt k, PetscReal a1, PetscReal a2, PetscReal a3, PetscReal *val)
Computes the trilinear Interpolateted scalar at a given point.
PetscErrorCode PieceWiseLinearInterpolation_Scalar(const char *fieldName, PetscReal ***fieldScal, PetscInt iCell, PetscInt jCell, PetscInt kCell, PetscReal *val)
Retrieves the scalar value at the cell (iCell, jCell, kCell).
#define ERROR_MSG_BUFFER_SIZE
PetscErrorCode InterpolateFieldFromCenterToCorner_Vector(Cmpnts ***centfield_arr, Cmpnts ***field_arr, UserCtx *user)
Interpolates a vector field from cell centers to corner nodes.
static void ComputeTrilinearWeights(PetscReal a1, PetscReal a2, PetscReal a3, PetscReal *w)
Computes the trilinear Interpolatetion weights from the Interpolatetion coefficients.
PetscErrorCode InterpolateCornerToFaceCenter_Scalar(PetscReal ***corner_arr, PetscReal ***faceX_arr, PetscReal ***faceY_arr, PetscReal ***faceZ_arr, UserCtx *user)
Interpolates a scalar field from corner nodes to all face centers.
PetscErrorCode InterpolateEulerFieldToSwarm(UserCtx *user, Vec fieldLocal_cellCentered, const char *fieldName, const char *swarmOutFieldName)
Interpolates a cell-centered field (scalar or vector) onto DMSwarm particles, using a robust,...
PetscErrorCode InterpolateFieldFromCenterToCorner_Scalar_Petsc(PetscReal ***centfield_arr, PetscReal ***corner_arr, UserCtx *user)
Interpolates a scalar field from cell centers to corner nodes.
PetscErrorCode PieceWiseLinearInterpolation_Vector(const char *fieldName, Cmpnts ***fieldVec, PetscInt iCell, PetscInt jCell, PetscInt kCell, Cmpnts *vec)
Retrieves the vector (Cmpnts) at the cell (iCell, jCell, kCell).
#define TrilinearInterpolation(fieldName, fieldPtr, i, j, k, a1, a2, a3, outPtr)
Macro that calls either the scalar or vector trilinear interpolation function based on the type of th...
#define InterpolateFieldFromCenterToCorner(blockSize, centfield_ptr, corner_ptr, user_ctx)
Macro to dispatch to the correct scalar or vector center-to-corner function based on a runtime block ...
PetscBool is_function_allowed(const char *functionName)
Checks if a given function is in the allow-list.
#define LOG_ALLOW_SYNC(scope, level, fmt,...)
----— DEBUG ---------------------------------------— #define LOG_ALLOW(scope, level,...
#define LOCAL
Logging scope definitions for controlling message output.
#define GLOBAL
Scope for global logging across all processes.
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
LogLevel get_log_level()
Retrieves the current logging level from the environment variable LOG_LEVEL.
#define LOG_LOOP_ALLOW_EXACT(scope, level, var, val, fmt,...)
Logs a custom message if a variable equals a specific value.
@ LOG_ERROR
Critical errors that may halt the program.
@ LOG_INFO
Informational messages about program execution.
@ LOG_WARNING
Non-critical issues that warrant attention.
@ LOG_DEBUG
Detailed debugging information.
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
PetscErrorCode GetOwnedCellRange(const DMDALocalInfo *info_nodes, PetscInt dim, PetscInt *xs_cell_global, PetscInt *xm_cell_local)
Determines the global starting index and number of CELLS owned by the current processor in a specifie...
A 3D point or vector with PetscScalar components.
User-defined context containing data specific to a single computational grid level.