10#define MAX_TRAVERSAL 1000
11#define DISTANCE_THRESHOLD 1e-11
12#define REPEAT_COUNT_THRESHOLD 5
15#define __FUNCT__ "GetCellCharacteristicSize"
24 PetscErrorCode ierr = 0;
25 PetscFunctionBeginUser;
27 if (!cell || !cellSize) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
28 "GetCellCharacteristicSize: Null pointer(s).");
35 PetscInt edges[12][2] = {
36 {0,1},{1,2},{2,3},{3,0},
37 {4,5},{5,6},{6,7},{7,4},
38 {0,7},{1,6},{2,5},{3,4}
41 PetscReal totalEdgeLen = 0.0;
42 for (PetscInt i=0; i<12; i++) {
43 PetscInt vA = edges[i][0];
44 PetscInt vB = edges[i][1];
47 PetscReal dx = B.
x - A.
x;
48 PetscReal dy = B.
y - A.
y;
49 PetscReal dz = B.
z - A.
z;
50 PetscReal edgeLen = sqrt(dx*dx + dy*dy + dz*dz);
51 totalEdgeLen += edgeLen;
55 *cellSize = totalEdgeLen / 12.0;
58 PetscFunctionReturn(ierr);
63#define __FUNCT__ "ComputeSignedDistanceToPlane"
70 PetscReal *d_signed,
const PetscReal threshold)
72 PetscErrorCode ierr = 0;
75 PetscFunctionBeginUser;
78 if (d_signed == NULL) {
79 ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank); CHKERRQ(ierr);
81 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output pointer 'd_signed' must not be NULL.");
93 PetscReal edge1_x = v2.
x - v1.
x;
94 PetscReal edge1_y = v2.
y - v1.
y;
95 PetscReal edge1_z = v2.
z - v1.
z;
97 PetscReal edge2_x = v4.
x - v1.
x;
98 PetscReal edge2_y = v4.
y - v1.
y;
99 PetscReal edge2_z = v4.
z - v1.
z;
104 PetscReal normal_x_initial = edge1_y * edge2_z - edge1_z * edge2_y;
105 PetscReal normal_y_initial = edge1_z * edge2_x - edge1_x * edge2_z;
106 PetscReal normal_z_initial = edge1_x * edge2_y - edge1_y * edge2_x;
107 LOG_ALLOW(
LOCAL,
LOG_VERBOSE,
" Initial Raw Normal (edge1 x edge2): (%.6e, %.6e, %.6e)\n", normal_x_initial, normal_y_initial, normal_z_initial);
109 PetscReal normal_magnitude = sqrt(normal_x_initial * normal_x_initial +
110 normal_y_initial * normal_y_initial +
111 normal_z_initial * normal_z_initial);
114 if (normal_magnitude < 1.0e-12) {
115 ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank); CHKERRQ(ierr);
117 "Degenerate plane detected on rank %d. Normal magnitude (%.3e) is too small.\n",
118 rank, normal_magnitude);
119 LOG_ALLOW(
LOCAL,
LOG_ERROR,
" Offending vertices for normal: v1(%.3e,%.3e,%.3e), v2(%.3e,%.3e,%.3e), v4(%.3e,%.3e,%.3e)\n",
120 v1.
x,v1.
y,v1.
z, v2.
x,v2.
y,v2.
z, v4.
x,v4.
y,v4.
z);
121 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER,
"Degenerate plane detected (normal vector is near zero).");
125 PetscReal face_centroid_x = 0.25 * (v1.
x + v2.
x + v3.
x + v4.
x);
126 PetscReal face_centroid_y = 0.25 * (v1.
y + v2.
y + v3.
y + v4.
y);
127 PetscReal face_centroid_z = 0.25 * (v1.
z + v2.
z + v3.
z + v4.
z);
128 LOG_ALLOW(
LOCAL,
LOG_VERBOSE,
" Face Centroid: (%.6e, %.6e, %.6e)\n", face_centroid_x, face_centroid_y, face_centroid_z);
132 PetscReal vec_fc_to_cc_x = cell_centroid.
x - face_centroid_x;
133 PetscReal vec_fc_to_cc_y = cell_centroid.
y - face_centroid_y;
134 PetscReal vec_fc_to_cc_z = cell_centroid.
z - face_centroid_z;
135 LOG_ALLOW(
LOCAL,
LOG_VERBOSE,
" Vec (FaceCentroid -> CellCentroid): (%.6e, %.6e, %.6e)\n", vec_fc_to_cc_x, vec_fc_to_cc_y, vec_fc_to_cc_z);
138 PetscReal dot_prod_orientation = normal_x_initial * vec_fc_to_cc_x +
139 normal_y_initial * vec_fc_to_cc_y +
140 normal_z_initial * vec_fc_to_cc_z;
143 PetscReal normal_x = normal_x_initial;
144 PetscReal normal_y = normal_y_initial;
145 PetscReal normal_z = normal_z_initial;
148 if (dot_prod_orientation > 1.0e-9) {
149 normal_x = -normal_x_initial;
150 normal_y = -normal_y_initial;
151 normal_z = -normal_z_initial;
153 }
else if (dot_prod_orientation == 0.0 && normal_magnitude > 1e-12) {
158 ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank); CHKERRQ(ierr);
159 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"Rank %d: Dot product for normal orientation is zero. Normal direction might be ambiguous. Keeping initial normal direction from (v2-v1)x(v4-v1).\n", rank);
167 normal_x /= normal_magnitude;
168 normal_y /= normal_magnitude;
169 normal_z /= normal_magnitude;
174 PetscReal vec_p_to_fc_x = face_centroid_x - p_target.
x;
175 PetscReal vec_p_to_fc_y = face_centroid_y - p_target.
y;
176 PetscReal vec_p_to_fc_z = face_centroid_z - p_target.
z;
179 *d_signed = vec_p_to_fc_x * normal_x +
180 vec_p_to_fc_y * normal_y +
181 vec_p_to_fc_z * normal_z;
186 if (fabs(*d_signed) < threshold) {
194 PetscFunctionReturn(0);
199#define __FUNCT__ "CalculateDistancesToCellFaces"
209 PetscFunctionBeginUser;
215 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"'cell' is NULL.");
221 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"'d' is NULL.");
225 Cmpnts cell_centroid = {0.0, 0.0, 0.0};
226 for (
int i = 0; i < 8; ++i) {
231 cell_centroid.
x /= 8.0;
232 cell_centroid.
y /= 8.0;
233 cell_centroid.
z /= 8.0;
236 cell_centroid.
x, cell_centroid.
y, cell_centroid.
z);
318 "d[LEFT=%d]=%.3e, d[RIGHT=%d]=%.3e, d[BOTTOM=%d]=%.3e, "
319 "d[TOP=%d]=%.3e, d[FRONT=%d]=%.3e, d[BACK=%d]=%.3e\n",
323 "[%.3e, %.3e, %.3e, %.3e, %.3e, %.3e]\n",
324 d[0], d[1], d[2], d[3], d[4], d[5]);
327 PetscFunctionReturn(0);
331#define __FUNCT__ "DeterminePointPosition"
341 PetscFunctionBeginUser;
346 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input parameter 'd' is NULL.");
348 if (result == NULL) {
350 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output parameter 'result' is NULL.");
354 PetscBool isInside = PETSC_TRUE;
355 PetscBool isOnBoundary = PETSC_FALSE;
356 PetscInt IntersectionCount = 0;
361 isInside = PETSC_FALSE;
364 isOnBoundary = PETSC_TRUE;
370 if(isInside && isOnBoundary) {
371 if(IntersectionCount == 1){
375 else if(IntersectionCount == 2){
379 else if(IntersectionCount >= 3){
394 PetscFunctionReturn(0);
398#define __FUNCT__ "GetCellVerticesFromGrid"
409 PetscFunctionBeginUser;
414 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input array 'coor' is NULL.");
418 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output parameter 'cell' is NULL.");
423 cell->
vertices[0] = coor[idz][idy][idx];
424 cell->
vertices[1] = coor[idz][idy][idx+1];
425 cell->
vertices[2] = coor[idz][idy+1][idx+1];
426 cell->
vertices[3] = coor[idz][idy+1][idx];
427 cell->
vertices[4] = coor[idz+1][idy+1][idx];
428 cell->
vertices[5] = coor[idz+1][idy+1][idx+1];
429 cell->
vertices[6] = coor[idz+1][idy][idx+1];
430 cell->
vertices[7] = coor[idz+1][idy][idx];
435 PetscFunctionReturn(0);
439#define __FUNCT__ "InitializeTraversalParameters"
451 PetscFunctionBeginUser;
455 if (user == NULL || particle == NULL || idx == NULL || idy == NULL || idz == NULL || traversal_steps == NULL) {
457 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"One or more input pointers are NULL.");
461 ierr = DMDAGetLocalInfo(user->
da, &info); CHKERRQ(ierr);
465 if (particle->
cell[0] >= 0 && particle->
cell[1] >= 0 && particle->
cell[2] >= 0) {
469 PetscBool is_handoff_cell_valid;
472 if (is_handoff_cell_valid) {
474 *idx = particle->
cell[0];
475 *idy = particle->
cell[1];
476 *idz = particle->
cell[2];
479 (
long long)particle->
PID, *idx, *idy, *idz);
498 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCent, ¢); CHKERRQ(ierr);
501 PetscInt candidates[7][3];
502 const char* candidate_names[7] = {
"X-min face",
"X-max face",
"Y-min face",
503 "Y-max face",
"Z-min face",
"Z-max face",
"Volume center"};
506 PetscInt mid_i = info.xs + (info.xm - 1) / 2;
507 PetscInt mid_j = info.ys + (info.ym - 1) / 2;
508 PetscInt mid_k = info.zs + (info.zm - 1) / 2;
509 PetscInt max_i = info.xs + info.xm - 2;
510 PetscInt max_j = info.ys + info.ym - 2;
511 PetscInt max_k = info.zs + info.zm - 2;
514 if (max_i < info.xs) max_i = info.xs;
515 if (max_j < info.ys) max_j = info.ys;
516 if (max_k < info.zs) max_k = info.zs;
519 candidates[0][0] = info.xs; candidates[0][1] = mid_j; candidates[0][2] = mid_k;
521 candidates[1][0] = max_i; candidates[1][1] = mid_j; candidates[1][2] = mid_k;
523 candidates[2][0] = mid_i; candidates[2][1] = info.ys; candidates[2][2] = mid_k;
525 candidates[3][0] = mid_i; candidates[3][1] = max_j; candidates[3][2] = mid_k;
527 candidates[4][0] = mid_i; candidates[4][1] = mid_j; candidates[4][2] = info.zs;
529 candidates[5][0] = mid_i; candidates[5][1] = mid_j; candidates[5][2] = max_k;
531 candidates[6][0] = mid_i; candidates[6][1] = mid_j; candidates[6][2] = mid_k;
534 PetscReal min_distance = PETSC_MAX_REAL;
535 PetscInt best_candidate = 6;
537 for (PetscInt i = 0; i < 7; i++) {
538 PetscInt ci = candidates[i][0];
539 PetscInt cj = candidates[i][1];
540 PetscInt ck = candidates[i][2];
543 Cmpnts cell_center = cent[ck+1][cj+1][ci+1];
546 PetscReal dx = particle->
loc.
x - cell_center.
x;
547 PetscReal dy = particle->
loc.
y - cell_center.
y;
548 PetscReal dz = particle->
loc.
z - cell_center.
z;
549 PetscReal distance = sqrt(dx*dx + dy*dy + dz*dz);
552 i, candidate_names[i], ci, cj, ck, cell_center.
x, cell_center.
y, cell_center.
z, distance);
554 if (distance < min_distance) {
555 min_distance = distance;
564 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCent, ¢); CHKERRQ(ierr);
566 LOG_ALLOW(
LOCAL,
LOG_INFO,
"Particle %lld has no valid previous cell. Multi-seed search selected %s at cell (%d,%d,%d) with distance %.3e.\n",
567 (
long long)particle->
PID, candidate_names[best_candidate], *idx, *idy, *idz, min_distance);
571 *traversal_steps = 0;
575 (
long long)particle->
PID, *idx, *idy, *idz);
577 PetscFunctionReturn(0);
582#define __FUNCT__ "CheckCellWithinLocalGrid"
592 DMDALocalInfo info_nodes;
594 PetscFunctionBeginUser;
598 if (user == NULL || is_within == NULL) {
600 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input pointer is NULL in CheckCellWithinLocalGrid.");
602 if (user->
fda == NULL) {
604 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"user->fda is NULL. Cannot get ghost info.");
608 ierr = DMDAGetLocalInfo(user->
fda, &info_nodes); CHKERRQ(ierr);
615 PetscInt gxs_cell_global_start = info_nodes.gxs;
616 PetscInt gys_cell_global_start = info_nodes.gys;
617 PetscInt gzs_cell_global_start = info_nodes.gzs;
621 PetscInt gxm_cell_local_count = (info_nodes.gxm > 0) ? info_nodes.gxm - 1 : 0;
622 PetscInt gym_cell_local_count = (info_nodes.gym > 0) ? info_nodes.gym - 1 : 0;
623 PetscInt gzm_cell_local_count = (info_nodes.gzm > 0) ? info_nodes.gzm - 1 : 0;
626 PetscInt gxe_cell_global_end_exclusive = gxs_cell_global_start + gxm_cell_local_count;
627 PetscInt gye_cell_global_end_exclusive = gys_cell_global_start + gym_cell_local_count;
628 PetscInt gze_cell_global_end_exclusive = gzs_cell_global_start + gzm_cell_local_count;
633 if (idx >= gxs_cell_global_start && idx < gxe_cell_global_end_exclusive &&
634 idy >= gys_cell_global_start && idy < gye_cell_global_end_exclusive &&
635 idz >= gzs_cell_global_start && idz < gze_cell_global_end_exclusive) {
636 *is_within = PETSC_TRUE;
638 *is_within = PETSC_FALSE;
641 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Cell (origin node glob idx) (%d, %d, %d) is %s the ghosted local grid (covered cell origins x:[%d..%d), y:[%d..%d), z:[%d..%d)).\n",
642 idx, idy, idz, (*is_within) ?
"within" :
"outside",
643 gxs_cell_global_start, gxe_cell_global_end_exclusive,
644 gys_cell_global_start, gye_cell_global_end_exclusive,
645 gzs_cell_global_start, gze_cell_global_end_exclusive);
648 PetscFunctionReturn(0);
652#define __FUNCT__ "RetrieveCurrentCell"
665 DMDALocalInfo info_nodes;
667 PetscFunctionBeginUser;
671 if (user == NULL || cell == NULL) {
673 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"One or more input pointers are NULL.");
677 ierr = DMGetCoordinatesLocal(user->
da, &Coor); CHKERRQ(ierr);
678 ierr = DMDAVecGetArrayRead(user->
fda, Coor, &coor_array); CHKERRQ(ierr);
682 ierr = DMDAGetLocalInfo(user->
fda, &info_nodes); CHKERRQ(ierr);
684 PetscInt idx_local = idx;
685 PetscInt idy_local = idy;
686 PetscInt idz_local = idz;
688 LOG_ALLOW(
LOCAL,
LOG_VERBOSE,
" [Rank %d] Getting vertex coordinates for cell: %d,%d,%d whose local coordinates are %d,%d,%d.\n",rank,idx,idy,idz,idx_local,idy_local,idz_local);
694 ierr = DMDAVecRestoreArrayRead(user->
fda, Coor, &coor_array); CHKERRQ(ierr);
697 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
704 PetscFunctionReturn(0);
708#define __FUNCT__ "EvaluateParticlePosition"
719 PetscReal cellThreshold;
720 PetscFunctionBeginUser;
724 if (cell == NULL || position == NULL) {
726 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"One or more input pointers are NULL.");
733 cellThreshold = threshold*cellSize;
742 if (ierr == PETSC_ERR_USER) {
744 "Skipping cell due to degenerate face.\n");
765 PetscFunctionReturn(0);
769#define __FUNCT__ "UpdateCellIndicesBasedOnDistances"
777 PetscFunctionBeginUser;
801 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input array 'd' is NULL.");
803 if (idx == NULL || idy == NULL || idz == NULL) {
805 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"One or more index pointers are NULL.");
813 if (d[
FRONT] < 0.0) {
817 else if(d[
BACK] < 0.0){
827 else if (d[
RIGHT] < 0.0) {
837 else if (d[
TOP] < 0.0) {
853 PetscFunctionReturn(0);
858#define __FUNCT__ "FinalizeTraversal"
867 PetscFunctionBeginUser;
869 if (user == NULL || particle == NULL) {
871 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"One or more input pointers are NULL.");
876 idx, idy, idz, traversal_steps);
879 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"Particle could not be located within the grid after %d traversal steps.\n", (PetscInt)traversal_steps);
880 particle->
cell[0] = -1;
881 particle->
cell[1] = -1;
882 particle->
cell[2] = -1;
889 PetscFunctionReturn(0);
893#define __FUNCT__ "FindOwnerOfCell"
903 PetscFunctionBeginUser;
907 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); CHKERRQ(ierr);
911 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"UserCtx or RankCellInfoMap is not initialized in FindOwnerOfCell.");
914 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output pointer owner_rank is NULL in FindOwnerOfCell.");
922 for (PetscMPIInt r = 0; r < size; ++r) {
938 if (*owner_rank == -1) {
939 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"No owner found for global cell (%d, %d, %d). It is likely outside the domain.\n", i, j, k);
945 PetscFunctionReturn(0);
949#define __FUNCT__ "LocateParticleOrFindMigrationTarget"
965 PetscInt idx, idy, idz;
966 PetscInt traversal_steps;
967 PetscBool search_concluded = PETSC_FALSE;
970 PetscInt repeatedIndexCount = 0;
971 PetscInt prevIdx = PETSC_MIN_INT, prevIdy = PETSC_MIN_INT, prevIdz = PETSC_MIN_INT;
972 PetscInt last_position_result = -999;
974 PetscFunctionBeginUser;
976 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
977 if (user && user->
simCtx) {
989 LOG_ALLOW(
LOCAL,
LOG_TRACE,
" [PID %lld]Traversal Initiated at : i = %d, j = %d, k = %d.\n",(
long long)particle->
PID,idx,idy,idz);
992 while (!search_concluded && traversal_steps <
MAX_TRAVERSAL) {
999 PetscBool hit_boundary = PETSC_FALSE;
1002 hit_boundary = PETSC_TRUE;
1006 if (idx >= (user->
IM - 1)) {
1008 hit_boundary = PETSC_TRUE;
1014 hit_boundary = PETSC_TRUE;
1018 if (idy >= (user->
JM - 1)) {
1020 hit_boundary = PETSC_TRUE;
1026 hit_boundary = PETSC_TRUE;
1030 if (idz >= (user->
KM - 1)) {
1032 hit_boundary = PETSC_TRUE;
1038 LOG_ALLOW(
LOCAL,
LOG_INFO,
"[PID %lld]: Hit GLOBAL domain boundary. Clamped to boundary cell (%d,%d,%d) and continuing search.\n",
1039 (
long long)particle->
PID, idx, idy, idz);
1044 PetscBool is_cell_local;
1046 if (!is_cell_local) {
1050 LOG_ALLOW(
LOCAL,
LOG_INFO,
"[PID %lld]: Walked outside local ghost region to cell (%d,%d,%d). Concluding search for handoff.\n",
1051 (
long long)particle->
PID, idx, idy, idz);
1052 search_concluded = PETSC_TRUE;
1057 if (idx == prevIdx && idy == prevIdy && idz == prevIdz) {
1058 repeatedIndexCount++;
1061 if (last_position_result >= 1) {
1063 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"[PID %lld]: Stuck on boundary of cell (%d,%d,%d) for %d steps. Applying enhanced tie-breaker.\n",
1064 (
long long)particle->
PID, idx, idy, idz, repeatedIndexCount);
1069 PetscInt final_position;
1076 search_concluded = PETSC_TRUE;
1078 LOG_ALLOW(
LOCAL,
LOG_ERROR,
"[PID %lld]: Tie-breaker failed during final evaluation at cell (%d,%d,%d). Search fails.\n",
1079 (
long long)particle->
PID, idx, idy, idz);
1081 search_concluded = PETSC_TRUE;
1084 LOG_ALLOW(
LOCAL,
LOG_ERROR,
"[PID %lld]: Search is stuck at cell (%d,%d,%d) but not on a boundary. This indicates a logic error. Failing search.\n",
1085 (
long long)particle->
PID, idx, idy, idz);
1087 search_concluded = PETSC_TRUE;
1089 if(search_concluded)
continue;
1092 repeatedIndexCount = 0;
1094 prevIdx = idx; prevIdy = idy; prevIdz = idz;
1099 PetscInt position_in_cell;
1103 last_position_result = position_in_cell;
1106 if (position_in_cell >= 0) {
1107 search_concluded = PETSC_TRUE;
1119 if (idx == -1 || (!search_concluded && traversal_steps >=
MAX_TRAVERSAL)) {
1126 particle->
cell[0] = -1; particle->
cell[1] = -1; particle->
cell[2] = -1;
1129 PetscMPIInt owner_rank;
1130 ierr =
FindOwnerOfCell(user, idx, idy, idz, &owner_rank); CHKERRQ(ierr);
1135 particle->
cell[0] = idx; particle->
cell[1] = idy; particle->
cell[2] = idz;
1137 if (owner_rank == rank) {
1139 }
else if (owner_rank != -1) {
1145 particle->
cell[0] = -1; particle->
cell[1] = -1; particle->
cell[2] = -1;
1155 PetscFunctionReturn(0);
1160#define __FUNCT__ "ReportSearchOutcome"
1169 PetscInt traversal_steps)
1171 PetscFunctionBeginUser;
1175 LOG_ALLOW(
LOCAL,
LOG_INFO,
"Search SUCCESS [PID %lld]: Located in global cell (%d, %d, %d) after %d steps.\n",
1176 (
long long)particle->
PID, particle->
cell[0], particle->
cell[1], particle->
cell[2], traversal_steps);
1179 LOG_ALLOW(
LOCAL,
LOG_INFO,
"Search SUCCESS [PID %lld]: Identified for migration to Rank %d. Handoff cell is (%d, %d, %d) after %d steps.\n",
1184 (
long long)particle->
PID, traversal_steps);
1191 PetscFunctionReturn(0);
PetscErrorCode UpdateParticleWeights(PetscReal *d, Particle *particle)
Updates a particle's interpolation weights based on distances to cell faces.
Logging utilities and macros for PETSc-based applications.
PetscBool is_function_allowed(const char *functionName)
Checks if a given function is in the allow-list.
#define LOCAL
Logging scope definitions for controlling message output.
#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.
PetscErrorCode LOG_FACE_DISTANCES(PetscReal *d)
Prints the signed distances to each face of the cell.
@ LOG_ERROR
Critical errors that may halt the program.
@ 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 LOG_CELL_VERTICES(const Cell *cell, PetscMPIInt rank)
Prints the coordinates of a cell's vertices.
SimCtx * simCtx
Back-pointer to the master simulation context.
ParticleLocationStatus
Defines the state of a particle with respect to its location and migration status during the iterativ...
PetscInt64 boundaryClampCount
PetscInt64 traversalStepsSum
PetscInt currentSettlementPass
PetscMPIInt destination_rank
RankCellInfo * RankCellInfoMap
PetscInt64 maxTraversalSteps
SearchMetricsState searchMetrics
PetscInt64 searchAttempts
PetscInt64 maxTraversalFailCount
Cmpnts vertices[8]
Coordinates of the eight vertices of the cell.
Defines the vertices of a single hexahedral grid cell.
A 3D point or vector with PetscScalar components.
Defines a particle's core properties for Lagrangian tracking.
A lean struct to hold the global cell ownership range for a single MPI rank.
User-defined context containing data specific to a single computational grid level.
#define DISTANCE_THRESHOLD
PetscErrorCode FinalizeTraversal(UserCtx *user, Particle *particle, PetscInt traversal_steps, PetscBool cell_found, PetscInt idx, PetscInt idy, PetscInt idz)
Implementation of FinalizeTraversal().
PetscErrorCode LocateParticleOrFindMigrationTarget(UserCtx *user, Particle *particle, ParticleLocationStatus *status_out)
Implementation of LocateParticleOrFindMigrationTarget().
PetscErrorCode GetCellCharacteristicSize(const Cell *cell, PetscReal *cellSize)
Implementation of GetCellCharacteristicSize().
PetscErrorCode EvaluateParticlePosition(const Cell *cell, PetscReal *d, const Cmpnts p, PetscInt *position, const PetscReal threshold)
Implementation of EvaluateParticlePosition().
PetscErrorCode ComputeSignedDistanceToPlane(const Cmpnts v1, const Cmpnts v2, const Cmpnts v3, const Cmpnts v4, const Cmpnts cell_centroid, const Cmpnts p_target, PetscReal *d_signed, const PetscReal threshold)
Internal helper implementation: ComputeSignedDistanceToPlane().
PetscErrorCode ReportSearchOutcome(const Particle *particle, ParticleLocationStatus status, PetscInt traversal_steps)
Implementation of ReportSearchOutcome().
#define REPEAT_COUNT_THRESHOLD
PetscErrorCode CalculateDistancesToCellFaces(const Cmpnts p, const Cell *cell, PetscReal *d, const PetscReal threshold)
Implementation of CalculateDistancesToCellFaces().
PetscErrorCode DeterminePointPosition(PetscReal *d, PetscInt *result)
Implementation of DeterminePointPosition().
PetscErrorCode UpdateCellIndicesBasedOnDistances(PetscReal d[NUM_FACES], PetscInt *idx, PetscInt *idy, PetscInt *idz)
Internal helper implementation: UpdateCellIndicesBasedOnDistances().
PetscErrorCode FindOwnerOfCell(UserCtx *user, PetscInt i, PetscInt j, PetscInt k, PetscMPIInt *owner_rank)
Internal helper implementation: FindOwnerOfCell().
PetscErrorCode RetrieveCurrentCell(UserCtx *user, PetscInt idx, PetscInt idy, PetscInt idz, Cell *cell)
Implementation of RetrieveCurrentCell().
PetscErrorCode GetCellVerticesFromGrid(Cmpnts ***coor, PetscInt idx, PetscInt idy, PetscInt idz, Cell *cell)
Implementation of GetCellVerticesFromGrid().
PetscErrorCode InitializeTraversalParameters(UserCtx *user, Particle *particle, PetscInt *idx, PetscInt *idy, PetscInt *idz, PetscInt *traversal_steps)
Implementation of InitializeTraversalParameters().
PetscErrorCode CheckCellWithinLocalGrid(UserCtx *user, PetscInt idx, PetscInt idy, PetscInt idz, PetscBool *is_within)
Implementation of CheckCellWithinLocalGrid().
Header file for particle location functions using the walking search algorithm.