15#ifndef ERROR_MSG_BUFFER_SIZE
16#define ERROR_MSG_BUFFER_SIZE 256
20#define __FUNCT__ "InterpolateFieldFromCornerToCenter_Vector"
46 PetscFunctionBeginUser;
49 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
51 "Rank %d starting InterpolateFieldFromCornerToCenter_Vector.\n", rank);
56 DMDALocalInfo info_fda;
57 ierr = DMDAGetLocalInfo(user->
fda, &info_fda); CHKERRQ(ierr);
60 PetscInt xs_cell_global_i, xm_cell_local_i;
61 PetscInt ys_cell_global_j, ym_cell_local_j;
62 PetscInt zs_cell_global_k, zm_cell_local_k;
65 ierr =
GetOwnedCellRange(&info_fda, 0, &xs_cell_global_i, &xm_cell_local_i); CHKERRQ(ierr);
66 ierr =
GetOwnedCellRange(&info_fda, 1, &ys_cell_global_j, &ym_cell_local_j); CHKERRQ(ierr);
67 ierr =
GetOwnedCellRange(&info_fda, 2, &zs_cell_global_k, &zm_cell_local_k); CHKERRQ(ierr);
70 PetscInt xe_cell_global_i_excl = xs_cell_global_i + xm_cell_local_i;
71 PetscInt ye_cell_global_j_excl = ys_cell_global_j + ym_cell_local_j;
72 PetscInt ze_cell_global_k_excl = zs_cell_global_k + zm_cell_local_k;
74 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"Rank %d : Processing Owned Cells (global indices) k=%d..%d (count %d), j=%d..%d (count %d), i=%d..%d (count %d)\n",
76 zs_cell_global_k, ze_cell_global_k_excl -1, zm_cell_local_k,
77 ys_cell_global_j, ye_cell_global_j_excl -1, ym_cell_local_j,
78 xs_cell_global_i, xe_cell_global_i_excl -1, xm_cell_local_i);
82 for (PetscInt k_glob_cell = zs_cell_global_k; k_glob_cell < ze_cell_global_k_excl; k_glob_cell++) {
83 PetscInt k_local = k_glob_cell - zs_cell_global_k;
85 for (PetscInt j_glob_cell = ys_cell_global_j; j_glob_cell < ye_cell_global_j_excl; j_glob_cell++) {
86 PetscInt j_local = j_glob_cell - ys_cell_global_j;
88 for (PetscInt i_glob_cell = xs_cell_global_i; i_glob_cell < xe_cell_global_i_excl; i_glob_cell++) {
89 PetscInt i_local = i_glob_cell - xs_cell_global_i;
91 Cmpnts sum = {0.0, 0.0, 0.0};
96 for (PetscInt dk = 0; dk < 2; dk++) {
97 for (PetscInt dj = 0; dj < 2; dj++) {
98 for (PetscInt di = 0; di < 2; di++) {
99 PetscInt ni_glob = i_glob_cell + di;
100 PetscInt nj_glob = j_glob_cell + dj;
101 PetscInt nk_glob = k_glob_cell + dk;
106 sum.
x += field_arr[nk_glob][nj_glob][ni_glob].
x;
107 sum.
y += field_arr[nk_glob][nj_glob][ni_glob].
y;
108 sum.
z += field_arr[nk_glob][nj_glob][ni_glob].
z;
116 center_value.
x = sum.
x / 8.0;
117 center_value.
y = sum.
y / 8.0;
118 center_value.
z = sum.
z / 8.0;
123 if (i_local < 0 || i_local >= xm_cell_local_i ||
124 j_local < 0 || j_local >= ym_cell_local_j ||
125 k_local < 0 || k_local >= zm_cell_local_k) {
126 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Local index out of bounds for centfield_arr write!");
128 centfield_arr[k_local][j_local][i_local] = center_value;
135 "Rank %d completed InterpolateFieldFromCornerToCenter_Vector.\n", rank);
139 PetscFunctionReturn(0);
143#define __FUNCT__ "InterpolateFieldFromCornerToCenter_Scalar"
167 PetscReal ***field_arr,
168 PetscReal ***centfield_arr,
173 PetscFunctionBeginUser;
175 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
177 "Rank %d starting InterpolateFieldFromCornerToCenter_Scalar.\n", rank);
180 DMDALocalInfo info_da_nodes;
181 ierr = DMDAGetLocalInfo(user->
da, &info_da_nodes); CHKERRQ(ierr);
184 PetscInt xs_cell_global_i, xm_cell_local_i;
185 PetscInt ys_cell_global_j, ym_cell_local_j;
186 PetscInt zs_cell_global_k, zm_cell_local_k;
188 ierr =
GetOwnedCellRange(&info_da_nodes, 0, &xs_cell_global_i, &xm_cell_local_i); CHKERRQ(ierr);
189 ierr =
GetOwnedCellRange(&info_da_nodes, 1, &ys_cell_global_j, &ym_cell_local_j); CHKERRQ(ierr);
190 ierr =
GetOwnedCellRange(&info_da_nodes, 2, &zs_cell_global_k, &zm_cell_local_k); CHKERRQ(ierr);
193 PetscInt xe_cell_global_i_excl = xs_cell_global_i + xm_cell_local_i;
194 PetscInt ye_cell_global_j_excl = ys_cell_global_j + ym_cell_local_j;
195 PetscInt ze_cell_global_k_excl = zs_cell_global_k + zm_cell_local_k;
197 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"Rank %d: Processing Owned Cells (global indices) k=%d..%d (count %d), j=%d..%d (count %d), i=%d..%d (count %d)\n",
199 zs_cell_global_k, ze_cell_global_k_excl -1, zm_cell_local_k,
200 ys_cell_global_j, ye_cell_global_j_excl -1, ym_cell_local_j,
201 xs_cell_global_i, xe_cell_global_i_excl -1, xm_cell_local_i);
205 for (PetscInt k_glob_cell = zs_cell_global_k; k_glob_cell < ze_cell_global_k_excl; k_glob_cell++) {
206 PetscInt k_local = k_glob_cell - zs_cell_global_k;
208 for (PetscInt j_glob_cell = ys_cell_global_j; j_glob_cell < ye_cell_global_j_excl; j_glob_cell++) {
209 PetscInt j_local = j_glob_cell - ys_cell_global_j;
211 for (PetscInt i_glob_cell = xs_cell_global_i; i_glob_cell < xe_cell_global_i_excl; i_glob_cell++) {
212 PetscInt i_local = i_glob_cell - xs_cell_global_i;
219 for (PetscInt dk = 0; dk < 2; dk++) {
220 for (PetscInt dj = 0; dj < 2; dj++) {
221 for (PetscInt di = 0; di < 2; di++) {
222 PetscInt ni_glob = i_glob_cell + di;
223 PetscInt nj_glob = j_glob_cell + dj;
224 PetscInt nk_glob = k_glob_cell + dk;
227 sum += field_arr[nk_glob][nj_glob][ni_glob];
233 PetscReal center_value = sum / 8.0;
238 if (i_local < 0 || i_local >= xm_cell_local_i ||
239 j_local < 0 || j_local >= ym_cell_local_j ||
240 k_local < 0 || k_local >= zm_cell_local_k) {
241 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Local index out of bounds for centfield_arr write in Scalar version!");
243 centfield_arr[k_local][j_local][i_local] = center_value;
250 "Rank %d completed InterpolateFieldFromCornerToCenter_Scalar.\n", rank);
254 PetscFunctionReturn(0);
258#define __FUNCT__ "InterpolateFieldFromCenterToCorner_Vector_Petsc"
279 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
280 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
283 PetscInt xs_node = info.xs, xm_node = info.xm, xe_node = xs_node + xm_node;
284 PetscInt ys_node = info.ys, ym_node = info.ym, ye_node = ys_node + ym_node;
285 PetscInt zs_node = info.zs, zm_node = info.zm, ze_node = zs_node + zm_node;
287 PetscInt nCellsX = info.mx - 2;
288 PetscInt nCellsY = info.my - 2;
289 PetscInt nCellsZ = info.mz - 2;
293 PetscInt IM = info.mx - 1;
294 PetscInt JM = info.my - 1;
295 PetscInt KM = info.mz - 1;
298 PetscInt gxs = info.gxs;
299 PetscInt gys = info.gys;
300 PetscInt gzs = info.gzs;
302 PetscInt xs = info.xs;
303 PetscInt ys = info.ys;
304 PetscInt zs = info.zs;
307 "[Rank %d] Starting InterpolateFieldFromCenterToCorner_Vector_Petsc: Node ownership k=%d..%d, j=%d..%d, i=%d..%d\n",
308 rank, zs_node, ze_node-1, ys_node, ye_node-1, xs_node, xe_node-1);
311 for (PetscInt k = zs_node; k < ze_node; k++) {
312 for (PetscInt j = ys_node; j < ye_node; j++) {
313 for (PetscInt i = xs_node; i < xe_node; i++) {
314 Cmpnts sum = {0.0, 0.0, 0.0};
335 if(i >= IM || j >= JM || k >= KM){
340 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
341 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
342 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
345 PetscInt global_cell_k = k + dk_offset;
346 PetscInt global_cell_j = j + dj_offset;
347 PetscInt global_cell_i = i + di_offset;
350 if (global_cell_i >= 0 && global_cell_i < nCellsX &&
351 global_cell_j >= 0 && global_cell_j < nCellsY &&
352 global_cell_k >= 0 && global_cell_k < nCellsZ)
354 Cmpnts cell_val = centfield_arr[global_cell_k + 1][global_cell_j + 1][global_cell_i + 1];
357 rank,global_cell_k,global_cell_j,global_cell_i,cell_val.
x, cell_val.
y, cell_val.
z);
368 PetscInt i_global_write = i;
369 PetscInt j_global_write = j;
370 PetscInt k_global_write = k;
374 corner_arr[k_global_write][j_global_write][i_global_write].
x = sum.
x / (PetscReal)count;
375 corner_arr[k_global_write][j_global_write][i_global_write].
y = sum.
y / (PetscReal)count;
376 corner_arr[k_global_write][j_global_write][i_global_write].
z = sum.
z / (PetscReal)count;
379 corner_arr[k_global_write][j_global_write][i_global_write] = (
Cmpnts){0.0, 0.0, 0.0};
410#define __FUNCT__ "InterpolateFieldFromCenterToCorner_Scalar_Petsc"
425 PetscReal ***centfield_arr,
426 PetscReal ***corner_arr,
432 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
435 PetscInt xs_node = info.xs, xe_node = info.xs + info.xm;
436 PetscInt ys_node = info.ys, ye_node = info.ys + info.ym;
437 PetscInt zs_node = info.zs, ze_node = info.zs + info.zm;
440 PetscInt IM = info.mx-1;
441 PetscInt JM = info.my-1;
442 PetscInt KM = info.mz-1;
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++) {
452 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
453 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
454 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
456 PetscInt cell_idx_k = k + dk_offset;
457 PetscInt cell_idx_j = j + dj_offset;
458 PetscInt cell_idx_i = i + di_offset;
462 if (cell_idx_i >= 0 && cell_idx_i < IM - 1 &&
463 cell_idx_j >= 0 && cell_idx_j < JM - 1 &&
464 cell_idx_k >= 0 && cell_idx_k < KM - 1)
466 sum += centfield_arr[cell_idx_k][cell_idx_j][cell_idx_i];
475 corner_arr[k][j][i] = sum / (PetscReal)count;
477 corner_arr[k][j][i] = 0.0;
488#define __FUNCT "PiecWiseLinearInterpolation_Scalar"
503 const char *fieldName,
504 PetscReal ***fieldScal,
511 *val = fieldScal[kCell][jCell][iCell];
515 "Field '%s' at (i=%d, j=%d, k=%d) => val=%.6f\n",
516 fieldName, iCell, jCell, kCell, *val);
518 PetscFunctionReturn(0);
522#define __FUNCT "PiecWiseLinearInterpolation_Vector"
540 const char *fieldName,
548 vec->
x = fieldVec[kCell][jCell][iCell].
x;
549 vec->
y = fieldVec[kCell][jCell][iCell].
y;
550 vec->
z = fieldVec[kCell][jCell][iCell].
z;
554 "Field '%s' at (i=%d, j=%d, k=%d) => (x=%.6f, y=%.6f, z=%.6f)\n",
555 fieldName, iCell, jCell, kCell, vec->
x, vec->
y, vec->
z);
557 PetscFunctionReturn(0);
562#define __FUNCT "ComputeTrilinearWeights"
583 a1 = PetscMax(0.0, PetscMin(1.0, a1));
584 a2 = PetscMax(0.0, PetscMin(1.0, a2));
585 a3 = PetscMax(0.0, PetscMin(1.0, a3));
587 const PetscReal oa1 = 1.0 - a1;
588 const PetscReal oa2 = 1.0 - a2;
589 const PetscReal oa3 = 1.0 - a3;
591 w[0] = oa1 * oa2 * oa3;
592 w[1] = a1 * oa2 * oa3;
593 w[2] = oa1 * a2 * oa3;
594 w[3] = a1 * a2 * oa3;
595 w[4] = oa1 * oa2 * a3;
596 w[5] = a1 * oa2 * a3;
597 w[6] = oa1 * a2 * a3;
602 "w0=%f, w1=%f, w2=%f, w3=%f, w4=%f, w5=%f, w6=%f, w7=%f. \n",
603 w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
607#define __FUNCT "TrilinearInterpolation_Scalar"
623 const char *fieldName,
624 PetscReal ***fieldScal,
636 PetscReal wcorner[8];
648 sum += wcorner[0] * fieldScal[k ][j ][i ];
650 sum += wcorner[1] * fieldScal[k ][j ][i1];
652 sum += wcorner[2] * fieldScal[k ][j1][i ];
654 sum += wcorner[3] * fieldScal[k ][j1][i1];
656 sum += wcorner[4] * fieldScal[k1][j ][i ];
658 sum += wcorner[5] * fieldScal[k1][j ][i1];
660 sum += wcorner[6] * fieldScal[k1][j1][i ];
662 sum += wcorner[7] * fieldScal[k1][j1][i1];
668 "Field '%s' at (i=%d, j=%d, k=%d), "
669 "a1=%.6f, a2=%.6f, a3=%.6f -> val=%.6f.\n",
670 fieldName, i, j, k, a1, a2, a3, *val);
676 PetscFunctionReturn(0);
681#define __FUNCT "TrilinearInterpolation_Vector"
703 const char *fieldName,
717 PetscReal wcorner[8];
720 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
729 PetscReal sumW = 0.0;
730 Cmpnts accum = {0.0, 0.0, 0.0};
735 const PetscInt cornerOffsets[8][3] = {
747 for (PetscInt c = 0; c < 8; c++) {
748 const PetscInt di = cornerOffsets[c][0];
749 const PetscInt dj = cornerOffsets[c][1];
750 const PetscInt dk = cornerOffsets[c][2];
751 PetscInt iC = i + di;
752 PetscInt jC = j + dj;
753 PetscInt kC = k + dk;
768 LOG_ALLOW(
LOCAL,
LOG_VERBOSE,
"[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);
771 accum.
x += wcorner[c] * fieldVec[kC][jC][iC].
x;
772 accum.
y += wcorner[c] * fieldVec[kC][jC][iC].
y;
773 accum.
z += wcorner[c] * fieldVec[kC][jC][iC].
z;
778 if (sumW > 1.0e-14) {
779 vec->
x = accum.
x / sumW;
780 vec->
y = accum.
y / sumW;
781 vec->
z = accum.
z / sumW;
783 vec->
x = 0.0; vec->
y = 0.0; vec->
z = 0.0;
786 PetscFunctionReturn(0);
791#define __FUNCT "InterpolateEulerFieldToSwarmForParticle"
823 const char *fieldName,
842 "field='%s', blockSize=%d, "
843 "cell IDs=(%d,%d,%d), weights=(%.4f,%.4f,%.4f)\n",
844 fieldName, blockSize, iCell, jCell, kCell, a1, a2, a3);
850 if (blockSize == 1) {
852 PetscReal ***fieldScal = (PetscReal ***) fieldPtr;
870 ((PetscReal*)swarmOut)[p] = val;
873 "field='%s', result=%.6f "
874 "stored at swarmOut index p=%d.\n", fieldName, val, (PetscInt)p);
876 else if (blockSize == 3) {
899 ((PetscReal*)swarmOut)[3*p + 0] = vec.
x;
900 ((PetscReal*)swarmOut)[3*p + 1] = vec.
y;
901 ((PetscReal*)swarmOut)[3*p + 2] = vec.
z;
904 "field='%s', result=(%.6f,%.6f,%.6f) "
905 "stored at swarmOut[3p..3p+2], p=%d.\n",
906 fieldName, vec.
x, vec.
y, vec.
z, (PetscInt)p);
916 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
917 "InterpolateEulerFieldToSwarmForParticle: only blockSize=1 or 3 supported, got %d.",
918 (PetscInt)blockSize);
922 PetscFunctionReturn(0);
926#define __FUNCT__ "InterpolateEulerFieldToSwarm"
960 Vec fieldLocal_cellCentered,
961 const char *fieldName,
962 const char *swarmOutFieldName)
966 DM swarm = user->
swarm;
972 void *cellCenterPtr_read;
973 void *cornerPtr_read_with_ghosts;
976 PetscInt *cellIDs = NULL;
977 PetscReal *weights = NULL;
978 PetscInt *pids = NULL;
979 void *swarmOut = NULL;
984 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
985 ierr = DMDAGetLocalInfo(fda, &info); CHKERRQ(ierr);
986 ierr = VecGetBlockSize(fieldLocal_cellCentered, &bs); CHKERRQ(ierr);
987 if (bs != 1 && bs != 3) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
"BlockSize must be 1 or 3.");
998 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Reusing existing global corner vector for field '%s'.\n", rank, fieldName);
1008 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Reusing existing local corner vector for field '%s'.\n", rank, fieldName);
1015 ierr = DMDAVecGetArrayRead(fda, fieldLocal_cellCentered, &cellCenterPtr_read); CHKERRQ(ierr);
1018 ierr = VecGetSize(cornerGlobal, &size); CHKERRQ(ierr);
1019 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Corner global vector size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1023 ierr = VecGetSize(fieldLocal_cellCentered, &size); CHKERRQ(ierr);
1024 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Cell-centered local vector size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1028 ierr = VecGetLocalSize(cornerGlobal, &size); CHKERRQ(ierr);
1029 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Corner global vector LOCAL size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1033 ierr = VecGetLocalSize(fieldLocal_cellCentered, &size); CHKERRQ(ierr);
1034 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Cell-centered local vector LOCAL size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1038 ierr = VecGetSize(cornerLocal, &size); CHKERRQ(ierr);
1039 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Corner local vector size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1041 PetscInt xs,ys,zs,gxs,gys,gzs;
1042 ierr = DMDAGetCorners(fda,&xs,&ys,&zs,NULL,NULL,NULL); CHKERRQ(ierr);
1043 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] DMDAGetCorners for field '%s': xs=%d, ys=%d, zs=%d.\n", rank, fieldName, (PetscInt)xs, (PetscInt)ys, (PetscInt)zs);
1045 ierr = DMDAGetGhostCorners(fda,&gxs,&gys,&gzs,NULL,NULL,NULL); CHKERRQ(ierr);
1046 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] DMDAGetGhostCorners for field '%s': gxs=%d, gys=%d, gzs=%d.\n", rank, fieldName, (PetscInt)gxs, (PetscInt)gys, (PetscInt)gzs);
1105 void *cornerPtr_write = NULL;
1106 ierr = DMDAVecGetArray(fda, cornerGlobal, &cornerPtr_write); CHKERRQ(ierr);
1108 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Starting center-to-corner interpolation for '%s'.\n", rank, fieldName);
1113 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Finished center-to-corner interpolation for '%s'.\n", rank, fieldName);
1114 ierr = DMDAVecRestoreArray(fda, cornerGlobal, &cornerPtr_write); CHKERRQ(ierr);
1116 ierr = DMDAVecRestoreArrayRead(fda, fieldLocal_cellCentered, &cellCenterPtr_read); CHKERRQ(ierr);
1118 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1141 ierr = DMGlobalToLocalBegin(fda, cornerGlobal, INSERT_VALUES, cornerLocal); CHKERRQ(ierr);
1142 ierr = DMGlobalToLocalEnd(fda, cornerGlobal, INSERT_VALUES, cornerLocal); CHKERRQ(ierr);
1150 ierr =
LOG_FIELD_ANATOMY(user,
"CornerField",
"After Corner Velocity Interpolated"); CHKERRQ(ierr);
1187 ierr = DMDAVecGetArrayRead(fda, cornerLocal, &cornerPtr_read_with_ghosts); CHKERRQ(ierr);
1190 ierr = DMSwarmGetLocalSize(swarm, &nLocal); CHKERRQ(ierr);
1191 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
1192 ierr = DMSwarmGetField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&pids); CHKERRQ(ierr);
1193 ierr = DMSwarmGetField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
1194 ierr = DMSwarmGetField(swarm, swarmOutFieldName, NULL, NULL, &swarmOut); CHKERRQ(ierr);
1196 LOG_ALLOW(
LOCAL,
LOG_TRACE,
" Rank %d holds data upto & including %d,%d,%d.\n",rank,info.gxs + info.gxm,info.gys+info.gym,info.gzs+info.gzm);
1199 for (PetscInt p = 0; p < nLocal; p++) {
1200 PetscInt iCell_global = cellIDs[3 * p + 0];
1201 PetscInt jCell_global = cellIDs[3 * p + 1];
1202 PetscInt kCell_global = cellIDs[3 * p + 2];
1206 "[Rank %d] Particle PID %lld: global cell=(%d,%d,%d), weights=(%.4f,%.4f,%.4f)\n",
1207 rank, (
long long)pids[p], iCell_global, jCell_global, kCell_global,
1208 weights[3 * p + 0], weights[3 * p + 1], weights[3 * p + 2]);
1212 if (iCell_global < info.gxs || iCell_global >= info.gxs + info.gxm - 1 ||
1213 jCell_global < info.gxs || jCell_global >= info.gys + info.gym - 1 ||
1214 kCell_global < info.gxs || kCell_global >= info.gzs + info.gzm - 1)
1217 "[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",
1218 rank, (
long long)pids[p], iCell_global, jCell_global, kCell_global, fieldName);
1221 ((PetscReal*)swarmOut)[3*p + 0] = 0.0;
1222 ((PetscReal*)swarmOut)[3*p + 1] = 0.0;
1223 ((PetscReal*)swarmOut)[3*p + 2] = 0.0;
1225 ((PetscReal*)swarmOut)[p] = 0.0;
1230 PetscReal a1 = weights[3 * p + 0];
1231 PetscReal a2 = weights[3 * p + 1];
1232 PetscReal a3 = weights[3 * p + 2];
1236 cornerPtr_read_with_ghosts,
1237 iCell_global, jCell_global, kCell_global,
1244 ierr = DMDAVecRestoreArrayRead(fda, cornerLocal, &cornerPtr_read_with_ghosts); CHKERRQ(ierr);
1245 ierr = DMSwarmRestoreField(swarm, swarmOutFieldName, NULL, NULL, &swarmOut); CHKERRQ(ierr);
1246 ierr = DMSwarmRestoreField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
1247 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&pids); CHKERRQ(ierr);
1248 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
1252 PetscFunctionReturn(0);
1256#define __FUNCT__ "InterpolateAllFieldsToSwarm"
1278 PetscErrorCode ierr;
1284 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
1298 " Interpolation of ucat to velocity begins on rank %d.\n",rank);
1302 "velocity"); CHKERRQ(ierr);
1324 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1326 "[rank %d]Completed Interpolateting all fields to the swarm.\n",rank);
1330 PetscFunctionReturn(0);
1377#define __FUNCT__ "GetScatterTargetInfo"
1396 DM *targetDM, PetscInt *expected_dof)
1399 PetscFunctionBeginUser;
1405 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx pointer is NULL.");
1406 if (!user->
da) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->da is NULL.");
1407 if (!user->
fda) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->fda is NULL.");
1408 if (!particleFieldName) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"particleFieldName is NULL.");
1409 if (!targetDM) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output targetDM pointer is NULL.");
1410 if (!expected_dof) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output expected_dof pointer is NULL.");
1414 if (strcmp(particleFieldName,
"Psi") == 0 || strcmp(particleFieldName,
"Nvert") == 0) {
1416 *targetDM = user->
da;
1420 else if (strcmp(particleFieldName,
"Ucat") == 0 || strcmp(particleFieldName,
"Ucont") == 0) {
1422 *targetDM = user->
fda;
1433 PetscSNPrintf(msg,
sizeof(msg),
"Field name '%s' is not recognized for automatic DM selection.", particleFieldName);
1435 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1440 PetscFunctionReturn(0);
1444#define __FUNCT__ "AccumulateParticleField"
1467 DM gridSumDM, Vec gridSumVec)
1469 PetscErrorCode ierr;
1472 const PetscReal *particle_arr = NULL;
1473 const PetscInt *cell_id_arr = NULL;
1474 PetscScalar *sum_arr_ptr = NULL;
1475 PetscInt gxs, gys, gzs;
1476 PetscInt gxm, gym, gzm;
1480 PetscFunctionBeginUser;
1484 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1487 ierr = DMDAGetInfo(gridSumDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1489 if (dof != 1 && dof != 3) {
1490 PetscSNPrintf(msg,
sizeof(msg),
"gridSumDM DOF must be 1 or 3, got %d.", dof);
1491 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1496 ierr = DMSwarmGetField(swarm, particleFieldName, NULL, NULL, (
void **)&particle_arr); CHKERRQ(ierr);
1497 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void **)&cell_id_arr); CHKERRQ(ierr);
1500 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1503 ierr = VecGetArray(gridSumVec, &sum_arr_ptr); CHKERRQ(ierr);
1505 ierr = DMDAGetGhostCorners(gridSumDM, &gxs, &gys, &gzs, &gxm, &gym, &gzm); CHKERRQ(ierr);
1508 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"(Rank %d): Accumulating '%s' (DOF=%d) from %d particles using CellID field 'DMSwarm_CellID'.\n", rank, particleFieldName, dof, nlocal);
1510 for (p = 0; p < nlocal; ++p) {
1513 PetscInt pidx_geom = cell_id_arr[p * 3 + 0];
1514 PetscInt pidy_geom = cell_id_arr[p * 3 + 1];
1515 PetscInt pidz_geom = cell_id_arr[p * 3 + 2];
1518 PetscInt pidx_field = pidx_geom + 1;
1519 PetscInt pidy_field = pidy_geom + 1;
1520 PetscInt pidz_field = pidz_geom + 1;
1523 if (pidx_field >= 0 && pidx_field < gxm && pidy_field >= 0 && pidy_field < gym && pidz_field >= 0 && pidz_field < gzm)
1528 PetscInt cell_flat_idx = (pidz_field * gym + pidy_field) * gxm + pidx_field;
1531 PetscInt particle_base_idx = p * dof;
1533 PetscInt grid_base_idx = cell_flat_idx * dof;
1536 for (PetscInt c = 0; c < dof; ++c) {
1537 sum_arr_ptr[grid_base_idx + c] += particle_arr[particle_base_idx + c];
1542 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"(Rank %d): Particle %d (field '%s') has out-of-bounds CellID (%d, %d, %d). Ghosted dims: %dx%dx%d. Skipping.\n",
1543 rank, p, particleFieldName, pidx_field, pidy_field, pidz_field, gxm, gym, gzm);
1548 ierr = VecRestoreArray(gridSumVec, &sum_arr_ptr); CHKERRQ(ierr);
1549 ierr = DMSwarmRestoreField(swarm, particleFieldName, NULL, NULL, (
void **)&particle_arr); CHKERRQ(ierr);
1550 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void **)&cell_id_arr); CHKERRQ(ierr);
1555 ierr = VecAssemblyBegin(gridSumVec); CHKERRQ(ierr);
1556 ierr = VecAssemblyEnd(gridSumVec); CHKERRQ(ierr);
1560 PetscFunctionReturn(0);
1565#define __FUNCT__ "NormalizeGridVectorByCount"
1585 DM dataDM, Vec sumVec, Vec avgVec)
1587 PetscErrorCode ierr;
1594 PetscScalar ***count_arr_3d = NULL;
1595 PetscScalar ***sum_arr_scalar = NULL;
1596 PetscScalar ***avg_arr_scalar = NULL;
1597 PetscScalar ***sum_arr_vector = NULL;
1598 PetscScalar ***avg_arr_vector = NULL;
1601 PetscFunctionBeginUser;
1605 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1608 ierr = DMDAGetInfo(countDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &count_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1609 ierr = DMDAGetInfo(dataDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &data_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1610 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); }
1611 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); }
1614 ierr = DMDAVecGetArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1616 if (data_dof == 1) {
1617 ierr = DMDAVecGetArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1618 ierr = DMDAVecGetArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1620 ierr = DMDAVecGetArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1621 ierr = DMDAVecGetArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1625 PetscInt xs, ys, zs, xm, ym, zm;
1626 ierr = DMDAGetCorners(countDM, &xs, &ys, &zs, &xm, &ym, &zm); CHKERRQ(ierr);
1630 rank, data_dof, xs, xs+xm, ys, ys+ym, zs, zs+zm);
1633 for (PetscInt k = zs; k < zs + zm; ++k) {
1634 for (PetscInt j = ys; j < ys + ym; ++j) {
1635 for (PetscInt i = xs; i < xs + xm; ++i) {
1638 PetscScalar count = count_arr_3d[k][j][i];
1640 if (PetscRealPart(count) > 0.5) {
1641 if (data_dof == 1) {
1643 avg_arr_scalar[k][j][i] = sum_arr_scalar[k][j][i] / count;
1646 for (PetscInt c = 0; c < data_dof; ++c) {
1647 avg_arr_vector[k][j][i * data_dof + c] = sum_arr_vector[k][j][i * data_dof + c] / count;
1652 if (data_dof == 1) {
1653 avg_arr_scalar[k][j][i] = 0.0;
1655 for (PetscInt c = 0; c < data_dof; ++c) {
1656 avg_arr_vector[k][j][i * data_dof + c] = 0.0;
1665 ierr = DMDAVecRestoreArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1666 if (data_dof == 1) {
1667 ierr = DMDAVecRestoreArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1668 ierr = DMDAVecRestoreArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1670 ierr = DMDAVecRestoreArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1671 ierr = DMDAVecRestoreArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1676 ierr = VecAssemblyBegin(avgVec); CHKERRQ(ierr);
1677 ierr = VecAssemblyEnd(avgVec); CHKERRQ(ierr);
1682 PetscFunctionReturn(0);
1695#define __FUNCT__ "ScatterParticleFieldToEulerField_Internal"
1714 const char *particleFieldName,
1716 PetscInt expected_dof,
1717 Vec eulerFieldAverageVec)
1719 PetscErrorCode ierr;
1723 PetscFunctionBeginUser;
1727 if (!user || !user->
swarm || !user->
ParticleCount || !particleFieldName || !targetDM || !eulerFieldAverageVec)
1728 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"NULL input provided to ScatterParticleFieldToEulerField_Internal.");
1747 ierr = VecDuplicate(eulerFieldAverageVec, &sumVec); CHKERRQ(ierr);
1748 ierr = VecSet(sumVec, 0.0); CHKERRQ(ierr);
1749 ierr = PetscSNPrintf(msg,
sizeof(msg),
"TempSum_%s", particleFieldName); CHKERRQ(ierr);
1750 ierr = PetscObjectSetName((PetscObject)sumVec, msg); CHKERRQ(ierr);
1765 ierr = VecDestroy(&sumVec); CHKERRQ(ierr);
1770 PetscFunctionReturn(0);
1774#define __FUNCT__ "ScatterParticleFieldToEulerField"
1799 const char *particleFieldName,
1800 Vec eulerFieldAverageVec)
1802 PetscErrorCode ierr;
1804 PetscInt expected_dof = 0;
1807 PetscFunctionBeginUser;
1812 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx pointer is NULL.");
1813 if (!user->
swarm) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->swarm is NULL.");
1814 if (!user->
ParticleCount) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->ParticleCount is NULL.");
1815 if (!eulerFieldAverageVec) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output eulerFieldAverageVec is NULL.");
1826 ierr = VecGetDM(eulerFieldAverageVec, &vec_dm); CHKERRQ(ierr);
1828 PetscSNPrintf(msg,
sizeof(msg),
"Provided eulerFieldAverageVec for field '%s' does not have an associated DM.", particleFieldName);
1829 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, msg);
1832 ierr = VecGetBlockSize(eulerFieldAverageVec, &vec_dof); CHKERRQ(ierr);
1834 if (vec_dm != targetDM) {
1835 const char *target_dm_name =
"targetDM", *vec_dm_name =
"vec_dm";
1837 PetscObjectGetName((PetscObject)targetDM, &target_dm_name);
1838 PetscObjectGetName((PetscObject)vec_dm, &vec_dm_name);
1839 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);
1840 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg);
1843 if (vec_dof != expected_dof) {
1844 PetscSNPrintf(msg,
sizeof(msg),
"Field '%s' requires DOF %d, but provided eulerFieldAverageVec has DOF %d.", particleFieldName, expected_dof, vec_dof);
1845 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg);
1855 eulerFieldAverageVec);
1862 PetscFunctionReturn(0);
1866#define __FUNCT__ "ScatterAllParticleFieldsToEulerFields"
1889 PetscErrorCode ierr;
1890 PetscFunctionBeginUser;
1897 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"UserCtx->ParticleCount is NULL. Compute counts before calling ScatterAllParticleFieldsToEulerFields.");
1909 PetscReal Avg_Psi,Avg_swarm_Psi;
1911 ierr = VecMean(user->
Psi,&Avg_Psi);
1914 ierr = DMSwarmCreateGlobalVectorFromField(user->
swarm,
"Psi",&swarm_Psi);
1915 ierr = VecMean(swarm_Psi,&Avg_swarm_Psi);
1919 ierr = DMSwarmDestroyGlobalVectorFromField(user->
swarm,
"Psi",&swarm_Psi);
1926 ierr = VecMean(user->
Psi,&Avg_Psi);
1978 PetscFunctionReturn(0);
1985#define __FUNCT__ "InterpolateCornerToFaceCenter_Scalar"
2005 PetscReal ***corner_arr,
2006 PetscReal ***faceX_arr,
2007 PetscReal ***faceY_arr,
2008 PetscReal ***faceZ_arr,
2011 PetscErrorCode ierr;
2014 PetscFunctionBeginUser;
2018 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
2021 PetscInt xs, xm, ys, ym, zs, zm;
2027 PetscInt xe = xs + xm;
2028 PetscInt ye = ys + ym;
2029 PetscInt ze = zs + zm;
2032 for (PetscInt k = zs; k < ze; ++k) {
2033 PetscInt k_loc = k - zs;
2034 for (PetscInt j = ys; j < ye; ++j) {
2035 PetscInt j_loc = j - ys;
2036 for (PetscInt i = xs; i <= xe; ++i) {
2037 PetscInt i_loc = i - xs;
2039 PetscReal sum = corner_arr[k ][j ][i]
2040 + corner_arr[k+1][j ][i]
2041 + corner_arr[k ][j+1][i]
2042 + corner_arr[k+1][j+1][i];
2043 faceX_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2049 for (PetscInt k = zs; k < ze; ++k) {
2050 PetscInt k_loc = k - zs;
2051 for (PetscInt j = ys; j <= ye; ++j) {
2052 PetscInt j_loc = j - ys;
2053 for (PetscInt i = xs; i < xe; ++i) {
2054 PetscInt i_loc = i - xs;
2056 PetscReal sum = corner_arr[k ][j][i ]
2057 + corner_arr[k+1][j][i ]
2058 + corner_arr[k ][j][i+1]
2059 + corner_arr[k+1][j][i+1];
2060 faceY_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2066 for (PetscInt k = zs; k <= ze; ++k) {
2067 PetscInt k_loc = k - zs;
2068 for (PetscInt j = ys; j < ye; ++j) {
2069 PetscInt j_loc = j - ys;
2070 for (PetscInt i = xs; i < xe; ++i) {
2071 PetscInt i_loc = i - xs;
2073 PetscReal sum = corner_arr[k][j ][i ]
2074 + corner_arr[k][j ][i+1]
2075 + corner_arr[k][j+1][i ]
2076 + corner_arr[k][j+1][i+1];
2077 faceZ_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2084 PetscFunctionReturn(0);
2088#define __FUNCT__ "InterpolateCornerToFaceCenter_Vector"
2111 PetscErrorCode ierr;
2115 PetscFunctionBeginUser;
2119 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
2121 "Rank %d starting InterpolateFieldFromCornerToFaceCenter_Vector.\n", rank);
2123 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
2125 PetscInt xs, xm, ys, ym, zs, zm;
2130 PetscInt xe = xs + xm;
2131 PetscInt ye = ys + ym;
2132 PetscInt ze = zs + zm;
2135 for (PetscInt k = zs; k < ze; ++k) {
2136 PetscInt k_loc = k - zs;
2137 for (PetscInt j = ys; j < ye; ++j) {
2138 PetscInt j_loc = j - ys;
2139 for (PetscInt i = xs; i <= xe; ++i) {
2140 PetscInt i_loc = i - xs;
2142 sum.
x = corner_arr[k ][j ][i].
x + corner_arr[k+1][j ][i].
x
2143 + corner_arr[k ][j+1][i].
x + corner_arr[k+1][j+1][i].
x;
2144 sum.
y = corner_arr[k ][j ][i].
y + corner_arr[k+1][j ][i].
y
2145 + corner_arr[k ][j+1][i].
y + corner_arr[k+1][j+1][i].
y;
2146 sum.
z = corner_arr[k ][j ][i].
z + corner_arr[k+1][j ][i].
z
2147 + corner_arr[k ][j+1][i].
z + corner_arr[k+1][j+1][i].
z;
2148 faceX_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2149 faceX_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2150 faceX_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2156 "Rank %d x-face Interpolation complete.\n", rank);
2159 for (PetscInt k = zs; k < ze; ++k) {
2160 PetscInt k_loc = k - zs;
2161 for (PetscInt j = ys; j <= ye; ++j) {
2162 PetscInt j_loc = j - ys;
2163 for (PetscInt i = xs; i < xe; ++i) {
2164 PetscInt i_loc = i - xs;
2166 sum.
x = corner_arr[k ][j][i ].
x + corner_arr[k+1][j][i ].
x
2167 + corner_arr[k ][j][i+1].
x + corner_arr[k+1][j][i+1].
x;
2168 sum.
y = corner_arr[k ][j][i ].
y + corner_arr[k+1][j][i ].
y
2169 + corner_arr[k ][j][i+1].
y + corner_arr[k+1][j][i+1].
y;
2170 sum.
z = corner_arr[k ][j][i ].
z + corner_arr[k+1][j][i ].
z
2171 + corner_arr[k ][j][i+1].
z + corner_arr[k+1][j][i+1].
z;
2172 faceY_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2173 faceY_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2174 faceY_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2180 "Rank %d y-face Interpolation complete.\n", rank);
2183 for (PetscInt k = zs; k <= ze; ++k) {
2184 PetscInt k_loc = k - zs;
2185 for (PetscInt j = ys; j < ye; ++j) {
2186 PetscInt j_loc = j - ys;
2187 for (PetscInt i = xs; i < xe; ++i) {
2188 PetscInt i_loc = i - xs;
2190 sum.
x = corner_arr[k][j ][i ].
x + corner_arr[k][j ][i+1].
x
2191 + corner_arr[k][j+1][i ].
x + corner_arr[k][j+1][i+1].
x;
2192 sum.
y = corner_arr[k][j ][i ].
y + corner_arr[k][j ][i+1].
y
2193 + corner_arr[k][j+1][i ].
y + corner_arr[k][j+1][i+1].
y;
2194 sum.
z = corner_arr[k][j ][i ].
z + corner_arr[k][j ][i+1].
z
2195 + corner_arr[k][j+1][i ].
z + corner_arr[k][j+1][i+1].
z;
2196 faceZ_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2197 faceZ_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2198 faceZ_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2204 "Rank %d z-face Interpolation complete.\n", rank);
2207 PetscFunctionReturn(0);
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.
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
static void ComputeTrilinearWeights(PetscReal a1, PetscReal a2, PetscReal a3, PetscReal *w)
Computes the trilinear interpolation weights from the interpolation 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.
PetscErrorCode LOG_FIELD_ANATOMY(UserCtx *user, const char *field_name, const char *stage_name)
Logs the anatomy of a specified field at key boundary locations, respecting the solver's specific gri...
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_TRACE
Very fine-grained tracing information for in-depth debugging.
@ LOG_INFO
Informational messages about program execution.
@ LOG_WARNING
Non-critical issues that warrant attention.
@ LOG_DEBUG
Detailed debugging information.
@ LOG_VERBOSE
Extremely detailed logs, typically for development use only.
#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.