15#ifndef ERROR_MSG_BUFFER_SIZE
16#define ERROR_MSG_BUFFER_SIZE 256
20#define __FUNCT__ "InterpolateFieldFromCornerToCenter_Vector"
46 PetscFunctionBeginUser;
48 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
51 PetscInt xs = info.xs, xe = info.xs + info.xm;
52 PetscInt ys = info.ys, ye = info.ys + info.ym;
53 PetscInt zs = info.zs, ze = info.zs + info.zm;
54 PetscInt mx = info.mx, my = info.my, mz = info.mz;
58 PetscInt is = (xs == 0) ? 1 : xs;
59 PetscInt js = (ys == 0) ? 1 : ys;
60 PetscInt ks = (zs == 0) ? 1 : zs;
63 PetscInt ie = (xe == mx) ? xe - 1 : xe;
64 PetscInt je = (ye == my) ? ye - 1 : ye;
65 PetscInt ke = (ze == mz) ? ze - 1 : ze;
68 for (PetscInt k = ks; k < ke; k++) {
69 for (PetscInt j = js; j < je; j++) {
70 for (PetscInt i = is; i < ie; i++) {
72 centfield_arr[k][j][i].
x = 0.125 * (field_arr[k][j][i].
x + field_arr[k][j-1][i].
x +
73 field_arr[k-1][j][i].
x + field_arr[k-1][j-1][i].
x +
74 field_arr[k][j][i-1].
x + field_arr[k][j-1][i-1].
x +
75 field_arr[k-1][j][i-1].
x + field_arr[k-1][j-1][i-1].
x);
77 centfield_arr[k][j][i].
y = 0.125 * (field_arr[k][j][i].
y + field_arr[k][j-1][i].
y +
78 field_arr[k-1][j][i].
y + field_arr[k-1][j-1][i].
y +
79 field_arr[k][j][i-1].
y + field_arr[k][j-1][i-1].
y +
80 field_arr[k-1][j][i-1].
y + field_arr[k-1][j-1][i-1].
y);
82 centfield_arr[k][j][i].
z = 0.125 * (field_arr[k][j][i].
z + field_arr[k][j-1][i].
z +
83 field_arr[k-1][j][i].
z + field_arr[k-1][j-1][i].
z +
84 field_arr[k][j][i-1].
z + field_arr[k][j-1][i-1].
z +
85 field_arr[k-1][j][i-1].
z + field_arr[k-1][j-1][i-1].
z);
90 PetscFunctionReturn(0);
94#define __FUNCT__ "InterpolateFieldFromCornerToCenter_Scalar"
112 PetscReal ***field_arr,
113 PetscReal ***centfield_arr,
119 PetscFunctionBeginUser;
121 ierr = DMDAGetLocalInfo(user->
da, &info); CHKERRQ(ierr);
124 PetscInt xs = info.xs, xe = info.xs + info.xm;
125 PetscInt ys = info.ys, ye = info.ys + info.ym;
126 PetscInt zs = info.zs, ze = info.zs + info.zm;
127 PetscInt mx = info.mx, my = info.my, mz = info.mz;
131 PetscInt is = (xs == 0) ? 1 : xs;
132 PetscInt js = (ys == 0) ? 1 : ys;
133 PetscInt ks = (zs == 0) ? 1 : zs;
136 PetscInt ie = (xe == mx) ? xe - 1 : xe;
137 PetscInt je = (ye == my) ? ye - 1 : ye;
138 PetscInt ke = (ze == mz) ? ze - 1 : ze;
141 for (PetscInt k = ks; k < ke; k++) {
142 for (PetscInt j = js; j < je; j++) {
143 for (PetscInt i = is; i < ie; i++) {
145 centfield_arr[k][j][i] = 0.125 * (field_arr[k][j][i] + field_arr[k][j-1][i] +
146 field_arr[k-1][j][i] + field_arr[k-1][j-1][i] +
147 field_arr[k][j][i-1] + field_arr[k][j-1][i-1] +
148 field_arr[k-1][j][i-1] + field_arr[k-1][j-1][i-1]);
153 PetscFunctionReturn(0);
157#define __FUNCT__ "TestCornerToCenterInterpolation"
178 Vec lCoords, TestCent;
179 Cmpnts ***coor_arr, ***test_cent_arr;
182 PetscFunctionBeginUser;
186 ierr = VecDuplicate(user->
Cent, &TestCent); CHKERRQ(ierr);
189 ierr = DMGetCoordinatesLocal(user->
da, &lCoords); CHKERRQ(ierr);
190 ierr = DMDAVecGetArrayRead(user->
fda, lCoords, &coor_arr); CHKERRQ(ierr);
191 ierr = DMDAVecGetArray(user->
fda, TestCent, &test_cent_arr); CHKERRQ(ierr);
199 ierr = DMDAVecRestoreArrayRead(user->
fda, lCoords, &coor_arr); CHKERRQ(ierr);
200 ierr = DMDAVecRestoreArray(user->
fda, TestCent, &test_cent_arr); CHKERRQ(ierr);
204 ierr = VecAssemblyBegin(TestCent); CHKERRQ(ierr);
205 ierr = VecAssemblyEnd(TestCent); CHKERRQ(ierr);
210 ierr = VecAXPY(TestCent, -1.0, user->
Cent); CHKERRQ(ierr);
214 ierr = VecNorm(TestCent, NORM_2, &diff_norm); CHKERRQ(ierr);
217 if (diff_norm < 1.0e-12) {
223 ierr = VecDestroy(&TestCent); CHKERRQ(ierr);
225 PetscFunctionReturn(0);
229#define __FUNCT__ "InterpolateFieldFromCenterToCorner_Vector"
250 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
251 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
254 PetscInt xs_node = info.xs, xm_node = info.xm, xe_node = xs_node + xm_node;
255 PetscInt ys_node = info.ys, ym_node = info.ym, ye_node = ys_node + ym_node;
256 PetscInt zs_node = info.zs, zm_node = info.zm, ze_node = zs_node + zm_node;
258 PetscInt nCellsX = info.mx - 2;
259 PetscInt nCellsY = info.my - 2;
260 PetscInt nCellsZ = info.mz - 2;
264 PetscInt IM = info.mx - 1;
265 PetscInt JM = info.my - 1;
266 PetscInt KM = info.mz - 1;
269 PetscInt gxs = info.gxs;
270 PetscInt gys = info.gys;
271 PetscInt gzs = info.gzs;
273 PetscInt xs = info.xs;
274 PetscInt ys = info.ys;
275 PetscInt zs = info.zs;
278 "[Rank %d] Starting -- Node ownership k=%d..%d, j=%d..%d, i=%d..%d\n",
279 rank, zs_node, ze_node-1, ys_node, ye_node-1, xs_node, xe_node-1);
282 for (PetscInt k = zs_node; k < ze_node; k++) {
283 for (PetscInt j = ys_node; j < ye_node; j++) {
284 for (PetscInt i = xs_node; i < xe_node; i++) {
285 Cmpnts sum = {0.0, 0.0, 0.0};
306 if(i >= IM || j >= JM || k >= KM){
311 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
312 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
313 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
316 PetscInt global_cell_k = k + dk_offset;
317 PetscInt global_cell_j = j + dj_offset;
318 PetscInt global_cell_i = i + di_offset;
321 if (global_cell_i >= 0 && global_cell_i < nCellsX &&
322 global_cell_j >= 0 && global_cell_j < nCellsY &&
323 global_cell_k >= 0 && global_cell_k < nCellsZ)
325 Cmpnts cell_val = centfield_arr[global_cell_k + 1][global_cell_j + 1][global_cell_i + 1];
328 rank,global_cell_k,global_cell_j,global_cell_i,cell_val.
x, cell_val.
y, cell_val.
z);
339 PetscInt i_global_write = i;
340 PetscInt j_global_write = j;
341 PetscInt k_global_write = k;
345 corner_arr[k_global_write][j_global_write][i_global_write].
x = sum.
x / (PetscReal)count;
346 corner_arr[k_global_write][j_global_write][i_global_write].
y = sum.
y / (PetscReal)count;
347 corner_arr[k_global_write][j_global_write][i_global_write].
z = sum.
z / (PetscReal)count;
350 corner_arr[k_global_write][j_global_write][i_global_write] = (
Cmpnts){0.0, 0.0, 0.0};
380#define __FUNCT__ "InterpolateFieldFromCenterToCorner_Scalar"
393 PetscReal ***centfield_arr,
394 PetscReal ***corner_arr,
401 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
402 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
405 PetscInt xs_node = info.xs, xm_node = info.xm, xe_node = xs_node + xm_node;
406 PetscInt ys_node = info.ys, ym_node = info.ym, ye_node = ys_node + ym_node;
407 PetscInt zs_node = info.zs, zm_node = info.zm, ze_node = zs_node + zm_node;
409 PetscInt nCellsX = info.mx - 2;
410 PetscInt nCellsY = info.my - 2;
411 PetscInt nCellsZ = info.mz - 2;
415 PetscInt IM = info.mx - 1;
416 PetscInt JM = info.my - 1;
417 PetscInt KM = info.mz - 1;
420 PetscInt gxs = info.gxs;
421 PetscInt gys = info.gys;
422 PetscInt gzs = info.gzs;
424 PetscInt xs = info.xs;
425 PetscInt ys = info.ys;
426 PetscInt zs = info.zs;
429 "[Rank %d] Starting -- Node ownership k=%d..%d, j=%d..%d, i=%d..%d\n",
430 rank, zs_node, ze_node-1, ys_node, ye_node-1, xs_node, xe_node-1);
433 for (PetscInt k = zs_node; k < ze_node; k++) {
434 for (PetscInt j = ys_node; j < ye_node; j++) {
435 for (PetscInt i = xs_node; i < xe_node; i++) {
457 if(i >= IM || j >= JM || k >= KM){
462 for (PetscInt dk_offset = -1; dk_offset <= 0; dk_offset++) {
463 for (PetscInt dj_offset = -1; dj_offset <= 0; dj_offset++) {
464 for (PetscInt di_offset = -1; di_offset <= 0; di_offset++) {
467 PetscInt global_cell_k = k + dk_offset;
468 PetscInt global_cell_j = j + dj_offset;
469 PetscInt global_cell_i = i + di_offset;
472 if (global_cell_i >= 0 && global_cell_i < nCellsX &&
473 global_cell_j >= 0 && global_cell_j < nCellsY &&
474 global_cell_k >= 0 && global_cell_k < nCellsZ)
476 PetscReal cell_val = centfield_arr[global_cell_k + 1][global_cell_j + 1][global_cell_i + 1];
479 rank,global_cell_k,global_cell_j,global_cell_i,cell_val);
488 PetscInt i_global_write = i;
489 PetscInt j_global_write = j;
490 PetscInt k_global_write = k;
494 corner_arr[k_global_write][j_global_write][i_global_write] = sum / (PetscReal)count;
497 corner_arr[k_global_write][j_global_write][i_global_write] = 0.0;
527#define __FUNCT "PiecWiseLinearInterpolation_Scalar"
542 const char *fieldName,
543 PetscReal ***fieldScal,
550 *val = fieldScal[kCell][jCell][iCell];
554 "Field '%s' at (i=%d, j=%d, k=%d) => val=%.6f\n",
555 fieldName, iCell, jCell, kCell, *val);
557 PetscFunctionReturn(0);
561#define __FUNCT "PiecWiseLinearInterpolation_Vector"
579 const char *fieldName,
587 vec->
x = fieldVec[kCell][jCell][iCell].
x;
588 vec->
y = fieldVec[kCell][jCell][iCell].
y;
589 vec->
z = fieldVec[kCell][jCell][iCell].
z;
593 "Field '%s' at (i=%d, j=%d, k=%d) => (x=%.6f, y=%.6f, z=%.6f)\n",
594 fieldName, iCell, jCell, kCell, vec->
x, vec->
y, vec->
z);
596 PetscFunctionReturn(0);
601#define __FUNCT "ComputeTrilinearWeights"
622 a1 = PetscMax(0.0, PetscMin(1.0, a1));
623 a2 = PetscMax(0.0, PetscMin(1.0, a2));
624 a3 = PetscMax(0.0, PetscMin(1.0, a3));
626 const PetscReal oa1 = 1.0 - a1;
627 const PetscReal oa2 = 1.0 - a2;
628 const PetscReal oa3 = 1.0 - a3;
630 w[0] = oa1 * oa2 * oa3;
631 w[1] = a1 * oa2 * oa3;
632 w[2] = oa1 * a2 * oa3;
633 w[3] = a1 * a2 * oa3;
634 w[4] = oa1 * oa2 * a3;
635 w[5] = a1 * oa2 * a3;
636 w[6] = oa1 * a2 * a3;
641 "w0=%f, w1=%f, w2=%f, w3=%f, w4=%f, w5=%f, w6=%f, w7=%f. \n",
642 w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
646#define __FUNCT "TrilinearInterpolation_Scalar"
662 const char *fieldName,
663 PetscReal ***fieldScal,
675 PetscReal wcorner[8];
687 sum += wcorner[0] * fieldScal[k ][j ][i ];
689 sum += wcorner[1] * fieldScal[k ][j ][i1];
691 sum += wcorner[2] * fieldScal[k ][j1][i ];
693 sum += wcorner[3] * fieldScal[k ][j1][i1];
695 sum += wcorner[4] * fieldScal[k1][j ][i ];
697 sum += wcorner[5] * fieldScal[k1][j ][i1];
699 sum += wcorner[6] * fieldScal[k1][j1][i ];
701 sum += wcorner[7] * fieldScal[k1][j1][i1];
707 "Field '%s' at (i=%d, j=%d, k=%d), "
708 "a1=%.6f, a2=%.6f, a3=%.6f -> val=%.6f.\n",
709 fieldName, i, j, k, a1, a2, a3, *val);
715 PetscFunctionReturn(0);
720#define __FUNCT "TrilinearInterpolation_Vector"
742 const char *fieldName,
756 PetscReal wcorner[8];
759 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
768 PetscReal sumW = 0.0;
769 Cmpnts accum = {0.0, 0.0, 0.0};
774 const PetscInt cornerOffsets[8][3] = {
786 for (PetscInt c = 0; c < 8; c++) {
787 const PetscInt di = cornerOffsets[c][0];
788 const PetscInt dj = cornerOffsets[c][1];
789 const PetscInt dk = cornerOffsets[c][2];
790 PetscInt iC = i + di;
791 PetscInt jC = j + dj;
792 PetscInt kC = k + dk;
807 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);
810 accum.
x += wcorner[c] * fieldVec[kC][jC][iC].
x;
811 accum.
y += wcorner[c] * fieldVec[kC][jC][iC].
y;
812 accum.
z += wcorner[c] * fieldVec[kC][jC][iC].
z;
817 if (sumW > 1.0e-14) {
818 vec->
x = accum.
x / sumW;
819 vec->
y = accum.
y / sumW;
820 vec->
z = accum.
z / sumW;
822 vec->
x = 0.0; vec->
y = 0.0; vec->
z = 0.0;
825 PetscFunctionReturn(0);
830#define __FUNCT "InterpolateEulerFieldToSwarmForParticle"
860 const char *fieldName,
870 PetscInt iCell = particle->
cell[0];
871 PetscInt jCell = particle->
cell[1];
872 PetscInt kCell = particle->
cell[2];
881 "field='%s', blockSize=%d, "
882 "cell IDs=(%d,%d,%d), weights=(%.4f,%.4f,%.4f)\n",
883 fieldName, blockSize, iCell, jCell, kCell, a1, a2, a3);
889 if (blockSize == 1) {
891 PetscReal ***fieldScal = (PetscReal ***) fieldPtr;
909 ((PetscReal*)swarmOut)[p] = val;
912 "field='%s', result=%.6f "
913 "stored at swarmOut index p=%d.\n", fieldName, val, (PetscInt)p);
915 else if (blockSize == 3) {
938 ((PetscReal*)swarmOut)[3*p + 0] = vec.
x;
939 ((PetscReal*)swarmOut)[3*p + 1] = vec.
y;
940 ((PetscReal*)swarmOut)[3*p + 2] = vec.
z;
943 "field='%s', result=(%.6f,%.6f,%.6f) "
944 "stored at swarmOut[3p..3p+2], p=%d.\n",
945 fieldName, vec.
x, vec.
y, vec.
z, (PetscInt)p);
955 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
956 "InterpolateEulerFieldToSwarmForParticle: only blockSize=1 or 3 supported, got %d.",
957 (PetscInt)blockSize);
961 PetscFunctionReturn(0);
965#define __FUNCT__ "InterpolateEulerFieldToSwarm"
999 Vec fieldLocal_cellCentered,
1000 const char *fieldName,
1001 const char *swarmOutFieldName)
1003 PetscErrorCode ierr;
1005 DM swarm = user->
swarm;
1011 void *cellCenterPtr_read;
1012 void *cornerPtr_read_with_ghosts;
1015 PetscInt *cellIDs = NULL;
1016 PetscReal *weights = NULL;
1017 PetscInt64 *pids = NULL;
1018 void *swarmOut = NULL;
1019 PetscReal *pos = NULL;
1020 PetscInt *status = NULL;
1025 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1026 ierr = DMDAGetLocalInfo(fda, &info); CHKERRQ(ierr);
1027 ierr = VecGetBlockSize(fieldLocal_cellCentered, &bs); CHKERRQ(ierr);
1028 if (bs != 1 && bs != 3) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
"BlockSize must be 1 or 3.");
1032 DM dm_corner = (bs == 3) ? user->
fda : user->
da;
1040 if(cached_bs != bs){
1041 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"[Rank %d] Block size mismatch for existing corner vector and current field %s(Cached: %d, New: %d). Replacing.\n", rank, fieldName, cached_bs, bs);
1050 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Creating new global corner vector for field '%s'.\n", rank, fieldName);
1051 ierr = DMCreateGlobalVector(dm_corner, &user->
CellFieldAtCorner); CHKERRQ(ierr);
1053 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Reusing existing global corner vector for field '%s'.\n", rank, fieldName);
1063 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Reusing existing local corner vector for field '%s'.\n", rank, fieldName);
1070 ierr = DMDAVecGetArrayRead(dm_corner, fieldLocal_cellCentered, &cellCenterPtr_read); CHKERRQ(ierr);
1073 ierr = VecGetSize(cornerGlobal, &size); CHKERRQ(ierr);
1074 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Corner global vector size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1078 ierr = VecGetSize(cornerLocal, &size); CHKERRQ(ierr);
1079 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Corner local vector size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1083 ierr = VecGetSize(fieldLocal_cellCentered, &size); CHKERRQ(ierr);
1084 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Cell-centered local vector size for field '%s': %d.\n", rank, fieldName, (PetscInt)size);
1086 PetscInt xs,ys,zs,gxs,gys,gzs;
1088 ierr = DMDAGetCorners(dm_corner,&xs,&ys,&zs,NULL,NULL,NULL); CHKERRQ(ierr);
1089 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);
1091 ierr = DMDAGetGhostCorners(dm_corner,&gxs,&gys,&gzs,NULL,NULL,NULL); CHKERRQ(ierr);
1092 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);
1151 void *cornerPtr_write = NULL;
1152 ierr = DMDAVecGetArray(dm_corner, cornerGlobal, &cornerPtr_write); CHKERRQ(ierr);
1154 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Starting center-to-corner interpolation for '%s'.\n", rank, fieldName);
1159 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"[Rank %d] Finished center-to-corner interpolation for '%s'.\n", rank, fieldName);
1160 ierr = DMDAVecRestoreArray(dm_corner, cornerGlobal, &cornerPtr_write); CHKERRQ(ierr);
1162 ierr = DMDAVecRestoreArrayRead(dm_corner, fieldLocal_cellCentered, &cellCenterPtr_read); CHKERRQ(ierr);
1164 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1187 ierr = DMGlobalToLocalBegin(dm_corner, cornerGlobal, INSERT_VALUES, cornerLocal); CHKERRQ(ierr);
1188 ierr = DMGlobalToLocalEnd(dm_corner, cornerGlobal, INSERT_VALUES, cornerLocal); CHKERRQ(ierr);
1196 ierr =
LOG_FIELD_ANATOMY(user,
"CornerField",
"After Corner Velocity Interpolated"); CHKERRQ(ierr);
1233 ierr = DMDAVecGetArrayRead(dm_corner, cornerLocal, &cornerPtr_read_with_ghosts); CHKERRQ(ierr);
1236 ierr = DMSwarmGetLocalSize(swarm, &nLocal); CHKERRQ(ierr);
1237 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
1238 ierr = DMSwarmGetField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&pids); CHKERRQ(ierr);
1239 ierr = DMSwarmGetField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
1240 ierr = DMSwarmGetField(swarm,
"position", NULL, NULL, (
void**)&pos); CHKERRQ(ierr);
1241 ierr = DMSwarmGetField(swarm,
"DMSwarm_location_status", NULL, NULL, (
void**)&status); CHKERRQ(ierr);
1242 ierr = DMSwarmGetField(swarm, swarmOutFieldName, NULL, NULL, &swarmOut); CHKERRQ(ierr);
1244 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);
1247 for (PetscInt p = 0; p < nLocal; p++) {
1251 ierr =
UnpackSwarmFields(p,pids,weights,pos,cellIDs,NULL,status,NULL,NULL,NULL,&particle); CHKERRQ(ierr);
1254 "[Rank %d] Particle PID %lld: global cell=(%d,%d,%d), weights=(%.4f,%.4f,%.4f)\n",
1255 rank, (
long long)particle.
PID, particle.
cell[0], particle.
cell[1], particle.
cell[2],
1260 if (particle.
cell[0] < info.gxs || particle.
cell[0] >= info.gxs + info.gxm - 1 ||
1261 particle.
cell[1] < info.gys || particle.
cell[1] >= info.gys + info.gym - 1 ||
1262 particle.
cell[2] < info.gzs || particle.
cell[2] >= info.gzs + info.gzm - 1)
1265 "[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",
1266 rank, (
long long)particle.
PID, particle.
cell[0], particle.
cell[1], particle.
cell[2], fieldName);
1268 ((PetscReal*)swarmOut)[3*p + 0] = 0.0;
1269 ((PetscReal*)swarmOut)[3*p + 1] = 0.0;
1270 ((PetscReal*)swarmOut)[3*p + 2] = 0.0;
1272 ((PetscReal*)swarmOut)[p] = 0.0;
1279 cornerPtr_read_with_ghosts,
1286 ierr = DMDAVecRestoreArrayRead(dm_corner, cornerLocal, &cornerPtr_read_with_ghosts); CHKERRQ(ierr);
1289 ierr = DMSwarmRestoreField(swarm, swarmOutFieldName, NULL, NULL, &swarmOut); CHKERRQ(ierr);
1290 ierr = DMSwarmRestoreField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
1291 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&pids); CHKERRQ(ierr);
1292 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
1293 ierr = DMSwarmRestoreField(swarm,
"position", NULL, NULL, (
void**)&pos); CHKERRQ(ierr);
1294 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_location_status", NULL, NULL, (
void**)&status); CHKERRQ(ierr);
1297 PetscFunctionReturn(0);
1301#define __FUNCT__ "InterpolateAllFieldsToSwarm"
1323 PetscErrorCode ierr;
1329 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
1343 " Interpolation of ucat to velocity begins on rank %d.\n",rank);
1347 "velocity"); CHKERRQ(ierr);
1349 "Diffusivity",
"Diffusivity"); CHKERRQ(ierr);
1352 "DiffusivityGradient",
"DiffusivityGradient"); CHKERRQ(ierr);
1355 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1357 "[rank %d]Completed Interpolateting all fields to the swarm.\n",rank);
1361 PetscFunctionReturn(0);
1408#define __FUNCT__ "GetScatterTargetInfo"
1427 DM *targetDM, PetscInt *expected_dof)
1430 PetscFunctionBeginUser;
1436 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx pointer is NULL.");
1437 if (!user->
da) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->da is NULL.");
1438 if (!user->
fda) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->fda is NULL.");
1439 if (!particleFieldName) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"particleFieldName is NULL.");
1440 if (!targetDM) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output targetDM pointer is NULL.");
1441 if (!expected_dof) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output expected_dof pointer is NULL.");
1445 if (strcmp(particleFieldName,
"Psi") == 0 || strcmp(particleFieldName,
"Nvert") == 0) {
1447 *targetDM = user->
da;
1451 else if (strcmp(particleFieldName,
"Ucat") == 0 || strcmp(particleFieldName,
"Ucont") == 0) {
1453 *targetDM = user->
fda;
1464 PetscSNPrintf(msg,
sizeof(msg),
"Field name '%s' is not recognized for automatic DM selection.", particleFieldName);
1466 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1471 PetscFunctionReturn(0);
1475#define __FUNCT__ "GetPersistentLocalVector"
1486 PetscFunctionBeginUser;
1488 if (!user || !fieldName || !localVec)
1489 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Null input in GetPersistentLocalVector");
1491 if (strcmp(fieldName,
"Psi") == 0) {
1492 if (!user->
lPsi) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"user->lPsi is not initialized");
1493 *localVec = user->
lPsi;
1495 else if (strcmp(fieldName,
"Ucat") == 0) {
1496 if (!user->
lUcat) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"user->lUcat is not initialized");
1497 *localVec = user->
lUcat;
1499 else if (strcmp(fieldName,
"Ucont") == 0) {
1500 if (!user->
lUcont) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"user->lUcont is not initialized");
1501 *localVec = user->
lUcont;
1503 else if (strcmp(fieldName,
"Nvert") == 0) {
1504 if (!user->
lNvert) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"user->lNvert is not initialized");
1505 *localVec = user->
lNvert;
1509 PetscSNPrintf(msg,
sizeof(msg),
"Field '%s' does not have a mapped persistent local vector.", fieldName);
1510 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1513 PetscFunctionReturn(0);
1517#define __FUNCT__ "AccumulateParticleField"
1539 DM gridSumDM, Vec localAccumulatorVec)
1541 PetscErrorCode ierr;
1544 const PetscReal *particle_arr = NULL;
1545 const PetscInt *cell_id_arr = NULL;
1548 PetscScalar ***arr_1d = NULL;
1549 PetscScalar ****arr_3d = NULL;
1552 PetscInt gxs, gys, gzs, gxm, gym, gzm;
1556 PetscFunctionBeginUser;
1559 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1562 if (!swarm || !gridSumDM || !localAccumulatorVec)
1563 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Null input in AccumulateParticleField.");
1566 ierr = DMDAGetInfo(gridSumDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1568 ierr = DMDAGetGhostCorners(gridSumDM, &gxs, &gys, &gzs, &gxm, &gym, &gzm); CHKERRQ(ierr);
1573 PetscInt expectedLocalSize = gxm * gym * gzm * dof;
1574 ierr = VecGetSize(localAccumulatorVec, &vecSize); CHKERRQ(ierr);
1576 if (vecSize != expectedLocalSize) {
1577 PetscSNPrintf(msg,
sizeof(msg),
1578 "Vector dimension mismatch! Expected Ghosted Local Vector size %d (gxm*gym*gzm*dof), got %d. "
1579 "Did you pass a Global Vector instead of a Local Vector?",
1580 expectedLocalSize, vecSize);
1581 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1586 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1588 ierr = DMSwarmGetField(swarm, particleFieldName, NULL, NULL, (
void **)&particle_arr); CHKERRQ(ierr);
1589 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void **)&cell_id_arr); CHKERRQ(ierr);
1594 ierr = DMDAVecGetArray(gridSumDM, localAccumulatorVec, &arr_1d); CHKERRQ(ierr);
1595 }
else if (dof == 3) {
1596 ierr = DMDAVecGetArrayDOF(gridSumDM, localAccumulatorVec, &arr_3d); CHKERRQ(ierr);
1598 PetscSNPrintf(msg,
sizeof(msg),
"Unsupported DOF=%d. AccumulateParticleField supports DOF 1 or 3.", dof);
1599 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, msg);
1604 for (p = 0; p < nlocal; ++p) {
1606 PetscInt i_geom = cell_id_arr[p * 3 + 0];
1607 PetscInt j_geom = cell_id_arr[p * 3 + 1];
1608 PetscInt k_geom = cell_id_arr[p * 3 + 2];
1611 PetscInt i = i_geom + 1;
1612 PetscInt j = j_geom + 1;
1613 PetscInt k = k_geom + 1;
1617 if (i >= gxs && i < gxs + gxm &&
1618 j >= gys && j < gys + gym &&
1619 k >= gzs && k < gzs + gzm)
1622 arr_1d[k][j][i] += particle_arr[p];
1625 arr_3d[k][j][i][0] += particle_arr[p * 3 + 0];
1626 arr_3d[k][j][i][1] += particle_arr[p * 3 + 1];
1627 arr_3d[k][j][i][2] += particle_arr[p * 3 + 2];
1636 ierr = DMDAVecRestoreArray(gridSumDM, localAccumulatorVec, &arr_1d); CHKERRQ(ierr);
1638 ierr = DMDAVecRestoreArrayDOF(gridSumDM, localAccumulatorVec, &arr_3d); CHKERRQ(ierr);
1641 ierr = DMSwarmRestoreField(swarm, particleFieldName, NULL, NULL, (
void **)&particle_arr); CHKERRQ(ierr);
1642 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void **)&cell_id_arr); CHKERRQ(ierr);
1645 PetscFunctionReturn(0);
1776#define __FUNCT__ "NormalizeGridVectorByCount"
1796 DM dataDM, Vec sumVec, Vec avgVec)
1798 PetscErrorCode ierr;
1805 PetscScalar ***count_arr_3d = NULL;
1806 PetscScalar ***sum_arr_scalar = NULL;
1807 PetscScalar ***avg_arr_scalar = NULL;
1808 PetscScalar ****sum_arr_vector = NULL;
1809 PetscScalar ****avg_arr_vector = NULL;
1812 PetscFunctionBeginUser;
1816 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1819 ierr = DMDAGetInfo(countDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &count_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1820 ierr = DMDAGetInfo(dataDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &data_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1821 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); }
1822 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); }
1825 ierr = DMDAVecGetArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1827 if (data_dof == 1) {
1828 ierr = DMDAVecGetArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1829 ierr = DMDAVecGetArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1831 ierr = DMDAVecGetArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1832 ierr = DMDAVecGetArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1836 PetscInt xs, ys, zs, xm, ym, zm;
1837 ierr = DMDAGetCorners(countDM, &xs, &ys, &zs, &xm, &ym, &zm); CHKERRQ(ierr);
1841 rank, data_dof, xs, xs+xm, ys, ys+ym, zs, zs+zm);
1844 for (PetscInt k = zs; k < zs + zm; ++k) {
1845 for (PetscInt j = ys; j < ys + ym; ++j) {
1846 for (PetscInt i = xs; i < xs + xm; ++i) {
1849 PetscScalar count = count_arr_3d[k][j][i];
1851 if (PetscRealPart(count) > 0.5) {
1852 if (data_dof == 1) {
1854 avg_arr_scalar[k][j][i] = sum_arr_scalar[k][j][i] / count;
1857 for (PetscInt c = 0; c < data_dof; ++c) {
1858 avg_arr_vector[k][j][i][c] = sum_arr_vector[k][j][i][c] / count;
1863 if (data_dof == 1) {
1864 avg_arr_scalar[k][j][i] = 0.0;
1866 for (PetscInt c = 0; c < data_dof; ++c) {
1867 avg_arr_vector[k][j][i][c] = 0.0;
1876 ierr = DMDAVecRestoreArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1877 if (data_dof == 1) {
1878 ierr = DMDAVecRestoreArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1879 ierr = DMDAVecRestoreArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1881 ierr = DMDAVecRestoreArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1882 ierr = DMDAVecRestoreArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1887 ierr = VecAssemblyBegin(avgVec); CHKERRQ(ierr);
1888 ierr = VecAssemblyEnd(avgVec); CHKERRQ(ierr);
1893 PetscFunctionReturn(0);
1906#define __FUNCT__ "ScatterParticleFieldToEulerField_Internal"
1925 const char *particleFieldName,
1927 PetscInt expected_dof,
1928 Vec eulerFieldAverageVec)
1930 PetscErrorCode ierr;
1931 Vec globalsumVec = NULL;
1932 Vec localsumVec = NULL;
1935 PetscFunctionBeginUser;
1939 if (!user || !user->
swarm || !user->
ParticleCount || !particleFieldName || !targetDM || !eulerFieldAverageVec)
1940 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"NULL input provided to ScatterParticleFieldToEulerField_Internal.");
1959 ierr = VecDuplicate(eulerFieldAverageVec, &globalsumVec); CHKERRQ(ierr);
1960 ierr = VecSet(globalsumVec, 0.0); CHKERRQ(ierr);
1961 ierr = PetscSNPrintf(msg,
sizeof(msg),
"TempSum_%s", particleFieldName); CHKERRQ(ierr);
1962 ierr = PetscObjectSetName((PetscObject)globalsumVec, msg); CHKERRQ(ierr);
1965 ierr = DMGetLocalVector(targetDM, &localsumVec); CHKERRQ(ierr);
1966 ierr = VecSet(localsumVec, 0.0); CHKERRQ(ierr);
1967 ierr = PetscSNPrintf(msg,
sizeof(msg),
"LocalTempSum_%s", particleFieldName); CHKERRQ(ierr);
1968 ierr = PetscObjectSetName((PetscObject)localsumVec, msg); CHKERRQ(ierr);
1978 ierr = DMLocalToGlobalBegin(targetDM, localsumVec, ADD_VALUES, globalsumVec); CHKERRQ(ierr);
1979 ierr = DMLocalToGlobalEnd(targetDM, localsumVec, ADD_VALUES, globalsumVec); CHKERRQ(ierr);
1981 ierr = DMRestoreLocalVector(targetDM, &localsumVec); CHKERRQ(ierr);
1989 ierr = VecDestroy(&globalsumVec); CHKERRQ(ierr);
1994 PetscFunctionReturn(0);
1998#define __FUNCT__ "ScatterParticleFieldToEulerField"
2023 const char *particleFieldName,
2024 Vec eulerFieldAverageVec)
2026 PetscErrorCode ierr;
2028 PetscInt expected_dof = 0;
2031 PetscFunctionBeginUser;
2036 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx pointer is NULL.");
2037 if (!user->
swarm) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->swarm is NULL.");
2038 if (!user->
ParticleCount) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx->ParticleCount is NULL.");
2039 if (!eulerFieldAverageVec) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output eulerFieldAverageVec is NULL.");
2050 ierr = VecGetDM(eulerFieldAverageVec, &vec_dm); CHKERRQ(ierr);
2052 PetscSNPrintf(msg,
sizeof(msg),
"Provided eulerFieldAverageVec for field '%s' does not have an associated DM.", particleFieldName);
2053 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, msg);
2056 ierr = VecGetBlockSize(eulerFieldAverageVec, &vec_dof); CHKERRQ(ierr);
2058 if (vec_dm != targetDM) {
2059 const char *target_dm_name =
"targetDM", *vec_dm_name =
"vec_dm";
2061 PetscObjectGetName((PetscObject)targetDM, &target_dm_name);
2062 PetscObjectGetName((PetscObject)vec_dm, &vec_dm_name);
2063 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);
2064 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg);
2067 if (vec_dof != expected_dof) {
2068 PetscSNPrintf(msg,
sizeof(msg),
"Field '%s' requires DOF %d, but provided eulerFieldAverageVec has DOF %d.", particleFieldName, expected_dof, vec_dof);
2069 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg);
2079 eulerFieldAverageVec);
2086 PetscFunctionReturn(0);
2090#define __FUNCT__ "ScatterAllParticleFieldsToEulerFields"
2113 PetscErrorCode ierr;
2114 PetscFunctionBeginUser;
2121 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"UserCtx->ParticleCount is NULL. Compute counts before calling ScatterAllParticleFieldsToEulerFields.");
2133 PetscReal Avg_Psi,Avg_swarm_Psi;
2135 ierr = VecMean(user->
Psi,&Avg_Psi);
2138 ierr = DMSwarmCreateGlobalVectorFromField(user->
swarm,
"Psi",&swarm_Psi);
2139 ierr = VecMean(swarm_Psi,&Avg_swarm_Psi);
2143 ierr = DMSwarmDestroyGlobalVectorFromField(user->
swarm,
"Psi",&swarm_Psi);
2150 ierr = VecMean(user->
Psi,&Avg_Psi);
2202 PetscFunctionReturn(0);
2209#define __FUNCT__ "InterpolateCornerToFaceCenter_Scalar"
2229 PetscReal ***corner_arr,
2230 PetscReal ***faceX_arr,
2231 PetscReal ***faceY_arr,
2232 PetscReal ***faceZ_arr,
2235 PetscErrorCode ierr;
2238 PetscFunctionBeginUser;
2242 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
2245 PetscInt xs, xm, ys, ym, zs, zm;
2251 PetscInt xe = xs + xm;
2252 PetscInt ye = ys + ym;
2253 PetscInt ze = zs + zm;
2256 for (PetscInt k = zs; k < ze; ++k) {
2257 PetscInt k_loc = k - zs;
2258 for (PetscInt j = ys; j < ye; ++j) {
2259 PetscInt j_loc = j - ys;
2260 for (PetscInt i = xs; i <= xe; ++i) {
2261 PetscInt i_loc = i - xs;
2263 PetscReal sum = corner_arr[k ][j ][i]
2264 + corner_arr[k+1][j ][i]
2265 + corner_arr[k ][j+1][i]
2266 + corner_arr[k+1][j+1][i];
2267 faceX_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2273 for (PetscInt k = zs; k < ze; ++k) {
2274 PetscInt k_loc = k - zs;
2275 for (PetscInt j = ys; j <= ye; ++j) {
2276 PetscInt j_loc = j - ys;
2277 for (PetscInt i = xs; i < xe; ++i) {
2278 PetscInt i_loc = i - xs;
2280 PetscReal sum = corner_arr[k ][j][i ]
2281 + corner_arr[k+1][j][i ]
2282 + corner_arr[k ][j][i+1]
2283 + corner_arr[k+1][j][i+1];
2284 faceY_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2290 for (PetscInt k = zs; k <= ze; ++k) {
2291 PetscInt k_loc = k - zs;
2292 for (PetscInt j = ys; j < ye; ++j) {
2293 PetscInt j_loc = j - ys;
2294 for (PetscInt i = xs; i < xe; ++i) {
2295 PetscInt i_loc = i - xs;
2297 PetscReal sum = corner_arr[k][j ][i ]
2298 + corner_arr[k][j ][i+1]
2299 + corner_arr[k][j+1][i ]
2300 + corner_arr[k][j+1][i+1];
2301 faceZ_arr[k_loc][j_loc][i_loc] = sum * 0.25;
2308 PetscFunctionReturn(0);
2312#define __FUNCT__ "InterpolateCornerToFaceCenter_Vector"
2335 PetscErrorCode ierr;
2339 PetscFunctionBeginUser;
2343 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
2345 "Rank %d starting InterpolateFieldFromCornerToFaceCenter_Vector.\n", rank);
2347 ierr = DMDAGetLocalInfo(user->
fda, &info); CHKERRQ(ierr);
2349 PetscInt xs, xm, ys, ym, zs, zm;
2354 PetscInt xe = xs + xm;
2355 PetscInt ye = ys + ym;
2356 PetscInt ze = zs + zm;
2359 for (PetscInt k = zs; k < ze; ++k) {
2360 PetscInt k_loc = k - zs;
2361 for (PetscInt j = ys; j < ye; ++j) {
2362 PetscInt j_loc = j - ys;
2363 for (PetscInt i = xs; i <= xe; ++i) {
2364 PetscInt i_loc = i - xs;
2366 sum.
x = corner_arr[k ][j ][i].
x + corner_arr[k+1][j ][i].
x
2367 + corner_arr[k ][j+1][i].
x + corner_arr[k+1][j+1][i].
x;
2368 sum.
y = corner_arr[k ][j ][i].
y + corner_arr[k+1][j ][i].
y
2369 + corner_arr[k ][j+1][i].
y + corner_arr[k+1][j+1][i].
y;
2370 sum.
z = corner_arr[k ][j ][i].
z + corner_arr[k+1][j ][i].
z
2371 + corner_arr[k ][j+1][i].
z + corner_arr[k+1][j+1][i].
z;
2372 faceX_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2373 faceX_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2374 faceX_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2380 "Rank %d x-face Interpolation complete.\n", rank);
2383 for (PetscInt k = zs; k < ze; ++k) {
2384 PetscInt k_loc = k - zs;
2385 for (PetscInt j = ys; j <= ye; ++j) {
2386 PetscInt j_loc = j - ys;
2387 for (PetscInt i = xs; i < xe; ++i) {
2388 PetscInt i_loc = i - xs;
2390 sum.
x = corner_arr[k ][j][i ].
x + corner_arr[k+1][j][i ].
x
2391 + corner_arr[k ][j][i+1].
x + corner_arr[k+1][j][i+1].
x;
2392 sum.
y = corner_arr[k ][j][i ].
y + corner_arr[k+1][j][i ].
y
2393 + corner_arr[k ][j][i+1].
y + corner_arr[k+1][j][i+1].
y;
2394 sum.
z = corner_arr[k ][j][i ].
z + corner_arr[k+1][j][i ].
z
2395 + corner_arr[k ][j][i+1].
z + corner_arr[k+1][j][i+1].
z;
2396 faceY_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2397 faceY_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2398 faceY_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2404 "Rank %d y-face Interpolation complete.\n", rank);
2407 for (PetscInt k = zs; k <= ze; ++k) {
2408 PetscInt k_loc = k - zs;
2409 for (PetscInt j = ys; j < ye; ++j) {
2410 PetscInt j_loc = j - ys;
2411 for (PetscInt i = xs; i < xe; ++i) {
2412 PetscInt i_loc = i - xs;
2414 sum.
x = corner_arr[k][j ][i ].
x + corner_arr[k][j ][i+1].
x
2415 + corner_arr[k][j+1][i ].
x + corner_arr[k][j+1][i+1].
x;
2416 sum.
y = corner_arr[k][j ][i ].
y + corner_arr[k][j ][i+1].
y
2417 + corner_arr[k][j+1][i ].
y + corner_arr[k][j+1][i+1].
y;
2418 sum.
z = corner_arr[k][j ][i ].
z + corner_arr[k][j ][i+1].
z
2419 + corner_arr[k][j+1][i ].
z + corner_arr[k][j+1][i+1].
z;
2420 faceZ_arr[k_loc][j_loc][i_loc].
x = sum.
x * 0.25;
2421 faceZ_arr[k_loc][j_loc][i_loc].
y = sum.
y * 0.25;
2422 faceZ_arr[k_loc][j_loc][i_loc].
z = sum.
z * 0.25;
2428 "Rank %d z-face Interpolation complete.\n", rank);
2431 PetscFunctionReturn(0);
PetscErrorCode UnpackSwarmFields(PetscInt i, const PetscInt64 *PIDs, const PetscReal *weights, const PetscReal *positions, const PetscInt *cellIndices, PetscReal *velocities, PetscInt *LocStatus, PetscReal *diffusivity, Cmpnts *diffusivitygradient, PetscReal *psi, Particle *particle)
Initializes a Particle struct with data from DMSwarm fields.
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 GetPersistentLocalVector(UserCtx *user, const char *fieldName, Vec *localVec)
Retrieves the persistent local vector (e.g., lPsi, lUcat) for a given field name.
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, respecting application conventions.
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, respecting application conventions.
PetscErrorCode InterpolateAllFieldsToSwarm(UserCtx *user)
Interpolates all relevant fields from the DMDA to the DMSwarm.
static PetscErrorCode InterpolateEulerFieldToSwarmForParticle(const char *fieldName, void *fieldPtr, Particle *particle, void *swarmOut, PetscInt p, PetscInt blockSize)
Interpolates a single field (scalar or vector) for one particle, storing the result in a swarm array.
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 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 TestCornerToCenterInterpolation(UserCtx *user)
Tests the InterpolateFieldFromCornerToCenter function by reproducing the Cent vector.
PetscErrorCode InterpolateFieldFromCenterToCorner_Vector(Cmpnts ***centfield_arr, Cmpnts ***corner_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 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 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).
PetscErrorCode InterpolateFieldFromCenterToCorner_Scalar(PetscReal ***centfield_arr, PetscReal ***corner_arr, UserCtx *user)
Interpolates a scalar field from cell centers to corner nodes.
#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 ...
#define InterpolateFieldFromCornerToCenter(field, centfield, user)
Generic macro to call the appropriate interpolation function based on the field type.
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.
Defines a particle's core properties for Lagrangian tracking.
User-defined context containing data specific to a single computational grid level.