161 PetscFunctionBeginUser;
163 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
166 ierr = PetscRandomCreate(PETSC_COMM_SELF, rand_logic_i); CHKERRQ(ierr);
167 ierr = PetscRandomSetType((*rand_logic_i), PETSCRAND48); CHKERRQ(ierr);
168 ierr = PetscRandomSetInterval(*rand_logic_i, 0.0, 1.0); CHKERRQ(ierr);
169 ierr = PetscRandomSetSeed(*rand_logic_i, rank + 202401); CHKERRQ(ierr);
170 ierr = PetscRandomSeed(*rand_logic_i); CHKERRQ(ierr);
174 ierr = PetscRandomCreate(PETSC_COMM_SELF, rand_logic_j); CHKERRQ(ierr);
175 ierr = PetscRandomSetType((*rand_logic_j), PETSCRAND48); CHKERRQ(ierr);
176 ierr = PetscRandomSetInterval(*rand_logic_j, 0.0, 1.0); CHKERRQ(ierr);
177 ierr = PetscRandomSetSeed(*rand_logic_j, rank + 202402); CHKERRQ(ierr);
178 ierr = PetscRandomSeed(*rand_logic_j); CHKERRQ(ierr);
182 ierr = PetscRandomCreate(PETSC_COMM_SELF, rand_logic_k); CHKERRQ(ierr);
183 ierr = PetscRandomSetType((*rand_logic_k), PETSCRAND48); CHKERRQ(ierr);
184 ierr = PetscRandomSetInterval(*rand_logic_k, 0.0, 1.0); CHKERRQ(ierr);
185 ierr = PetscRandomSetSeed(*rand_logic_k, rank + 202403); CHKERRQ(ierr);
186 ierr = PetscRandomSeed(*rand_logic_k); CHKERRQ(ierr);
189 PetscFunctionReturn(0);
231 UserCtx *user, DMDALocalInfo *info,
232 PetscInt xs_gnode, PetscInt ys_gnode, PetscInt zs_gnode,
233 PetscRandom *rand_logic_i_ptr, PetscRandom *rand_logic_j_ptr, PetscRandom *rand_logic_k_ptr,
234 PetscInt *ci_metric_lnode_out, PetscInt *cj_metric_lnode_out, PetscInt *ck_metric_lnode_out,
235 PetscReal *xi_metric_logic_out, PetscReal *eta_metric_logic_out, PetscReal *zta_metric_logic_out,
236 PetscBool *can_place_in_volume_out)
238 PetscErrorCode ierr = 0;
240 PetscInt local_owned_cell_idx_i, local_owned_cell_idx_j, local_owned_cell_idx_k;
241 PetscMPIInt rank_for_logging;
243 PetscFunctionBeginUser;
244 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank_for_logging); CHKERRQ(ierr);
246 *can_place_in_volume_out = PETSC_FALSE;
249 *xi_metric_logic_out = 0.5; *eta_metric_logic_out = 0.5; *zta_metric_logic_out = 0.5;
250 *ci_metric_lnode_out = xs_gnode; *cj_metric_lnode_out = ys_gnode; *ck_metric_lnode_out = zs_gnode;
255 PetscInt num_owned_cells_i = (info->mx > 1) ? info->mx - 1 : 0;
256 PetscInt num_owned_cells_j = (info->my > 1) ? info->my - 1 : 0;
257 PetscInt num_owned_cells_k = (info->mz > 1) ? info->mz - 1 : 0;
259 if (num_owned_cells_i > 0 && num_owned_cells_j > 0 && num_owned_cells_k > 0) {
260 *can_place_in_volume_out = PETSC_TRUE;
266 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val); CHKERRQ(ierr);
267 local_owned_cell_idx_i = (PetscInt)(r_val * num_owned_cells_i);
269 local_owned_cell_idx_i = PetscMin(PetscMax(0, local_owned_cell_idx_i), num_owned_cells_i - 1);
270 *ci_metric_lnode_out = xs_gnode + local_owned_cell_idx_i;
273 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val); CHKERRQ(ierr);
274 local_owned_cell_idx_j = (PetscInt)(r_val * num_owned_cells_j);
275 local_owned_cell_idx_j = PetscMin(PetscMax(0, local_owned_cell_idx_j), num_owned_cells_j - 1);
276 *cj_metric_lnode_out = ys_gnode + local_owned_cell_idx_j;
279 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val); CHKERRQ(ierr);
280 local_owned_cell_idx_k = (PetscInt)(r_val * num_owned_cells_k);
281 local_owned_cell_idx_k = PetscMin(PetscMax(0, local_owned_cell_idx_k), num_owned_cells_k - 1);
282 *ck_metric_lnode_out = zs_gnode + local_owned_cell_idx_k;
284 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"DVP - Rank %d: Selected Cell (Owned Idx: %d,%d,%d -> LNodeStart: %d,%d,%d). OwnedCells(i,j,k): (%d,%d,%d). GhostNodeStarts(xs,ys,zs): (%d,%d,%d) \n",
285 rank_for_logging, local_owned_cell_idx_i, local_owned_cell_idx_j, local_owned_cell_idx_k,
286 *ci_metric_lnode_out, *cj_metric_lnode_out, *ck_metric_lnode_out,
287 num_owned_cells_i, num_owned_cells_j, num_owned_cells_k,
288 xs_gnode, ys_gnode, zs_gnode);
292 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
293 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
294 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
297 *xi_metric_logic_out = PetscMin(*xi_metric_logic_out, 1.0 - 1.0e-7);
298 *eta_metric_logic_out = PetscMin(*eta_metric_logic_out, 1.0 - 1.0e-7);
299 *zta_metric_logic_out = PetscMin(*zta_metric_logic_out, 1.0 - 1.0e-7);
301 *xi_metric_logic_out = PetscMax(*xi_metric_logic_out, 0.0);
302 *eta_metric_logic_out = PetscMax(*eta_metric_logic_out, 0.0);
303 *zta_metric_logic_out = PetscMax(*zta_metric_logic_out, 0.0);
309 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"DVP - Rank %d: Cannot place particle volumetrically. Rank has zero owned cells in at least one dimension (owned cells i,j,k: %d,%d,%d).\n",
310 rank_for_logging, num_owned_cells_i, num_owned_cells_j, num_owned_cells_k);
312 PetscFunctionReturn(0);
342 PetscInt particlesPerProcess,
343 PetscRandom *rand_logic_i,
344 PetscRandom *rand_logic_j,
345 PetscRandom *rand_logic_k,
349 DM swarm = user->
swarm;
350 PetscReal *positions_field = NULL;
351 PetscReal *pos_phy_field = NULL;
352 PetscInt64 *particleIDs = NULL;
353 PetscInt *cellIDs_petsc = NULL;
354 PetscInt *status_field = NULL;
355 PetscMPIInt rank,size;
356 const Cmpnts ***coor_nodes_local_array;
359 PetscInt xs_gnode_rank, ys_gnode_rank, zs_gnode_rank;
360 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
363 PetscBool can_this_rank_service_inlet = PETSC_FALSE;
365 PetscFunctionBeginUser;
370 if (!user || !rand_logic_i || !rand_logic_j || !rand_logic_k) {
371 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"InitializeParticleBasicProperties - Null user or RNG pointer.");
373 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
374 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); CHKERRQ(ierr);
377 ierr = DMGetCoordinatesLocal(user->
da, &Coor_local); CHKERRQ(ierr);
378 if (!Coor_local) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"DMGetCoordinatesLocal for user->da returned NULL Coor_local.");
379 ierr = DMDAVecGetArrayRead(user->
fda, Coor_local, (
void*)&coor_nodes_local_array); CHKERRQ(ierr);
380 ierr = DMDAGetLocalInfo(user->
da, &info); CHKERRQ(ierr);
381 ierr = DMDAGetGhostCorners(user->
da, &xs_gnode_rank, &ys_gnode_rank, &zs_gnode_rank, NULL, NULL, NULL); CHKERRQ(ierr);
382 ierr = DMDAGetInfo(user->
da, NULL, &IM_nodes_global, &JM_nodes_global, &KM_nodes_global, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); CHKERRQ(ierr);
384 LOG_ALLOW(
LOCAL,
LOG_INFO,
"InitializeParticleBasicProperties - Rank %d: Initializing %d particles. Mode: %d.\n",
389 ierr =
CanRankServiceInletFace(user, &info, IM_nodes_global, JM_nodes_global, KM_nodes_global, &can_this_rank_service_inlet); CHKERRQ(ierr);
390 if (can_this_rank_service_inlet) {
398 ierr = DMSwarmGetField(swarm,
"position", NULL, NULL, (
void**)&positions_field); CHKERRQ(ierr);
399 ierr = DMSwarmGetField(swarm,
"pos_phy", NULL, NULL, (
void**)&pos_phy_field); CHKERRQ(ierr);
400 ierr = DMSwarmGetField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&particleIDs); CHKERRQ(ierr);
401 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs_petsc); CHKERRQ(ierr);
402 ierr = DMSwarmGetField(swarm,
"DMSwarm_location_status",NULL,NULL,(
void**)&status_field); CHKERRQ(ierr);
405 PetscInt particles_per_rank_ideal = simCtx->
np / size;
406 PetscInt remainder_particles = simCtx->
np % size;
407 PetscInt base_pid_for_rank = rank * particles_per_rank_ideal + PetscMin(rank, remainder_particles);
411 for (PetscInt p = 0; p < particlesPerProcess; p++) {
412 PetscInt ci_metric_lnode, cj_metric_lnode, ck_metric_lnode;
413 PetscReal xi_metric_logic, eta_metric_logic, zta_metric_logic;
414 Cmpnts phys_coords = {0.0, 0.0, 0.0};
415 PetscBool particle_placed_by_this_rank = PETSC_FALSE;
418 if (can_this_rank_service_inlet) {
420 IM_nodes_global, JM_nodes_global, KM_nodes_global,
421 rand_logic_i, rand_logic_j, rand_logic_k,
422 &ci_metric_lnode, &cj_metric_lnode, &ck_metric_lnode,
423 &xi_metric_logic, &eta_metric_logic, &zta_metric_logic); CHKERRQ(ierr);
425 ci_metric_lnode, cj_metric_lnode, ck_metric_lnode,
426 xi_metric_logic, eta_metric_logic, zta_metric_logic,
427 &phys_coords); CHKERRQ(ierr);
428 particle_placed_by_this_rank = PETSC_TRUE;
431 PetscBool can_place_volumetrically;
433 rand_logic_i, rand_logic_j, rand_logic_k,
434 &ci_metric_lnode, &cj_metric_lnode, &ck_metric_lnode,
435 &xi_metric_logic, &eta_metric_logic, &zta_metric_logic,
436 &can_place_volumetrically); CHKERRQ(ierr);
437 if(can_place_volumetrically){
439 ci_metric_lnode, cj_metric_lnode, ck_metric_lnode,
440 xi_metric_logic, eta_metric_logic, zta_metric_logic,
441 &phys_coords); CHKERRQ(ierr);
442 particle_placed_by_this_rank = PETSC_TRUE;
445 "InitProps - Rank %d: PID %lld (idx %ld) (Volumetric Mode %d) - DetermineVolumetric... returned false. Default Phys: (%.2f,%.2f,%.2f).\n",
446 rank, (
long long)(base_pid_for_rank + p), (
long)p, simCtx->
ParticleInitialization, phys_coords.
x, phys_coords.
y, phys_coords.
z);
451 positions_field[3*p+0] = phys_coords.
x;
452 positions_field[3*p+1] = phys_coords.
y;
453 positions_field[3*p+2] = phys_coords.
z;
454 pos_phy_field[3*p+0] = phys_coords.
x;
455 pos_phy_field[3*p+1] = phys_coords.
y;
456 pos_phy_field[3*p+2] = phys_coords.
z;
457 particleIDs[p] = (PetscInt64)base_pid_for_rank + p;
458 cellIDs_petsc[3*p+0] = -1; cellIDs_petsc[3*p+1] = -1; cellIDs_petsc[3*p+2] = -1;
462 if (particle_placed_by_this_rank) {
464 "InitProps - Rank %d: PID %lld (idx %ld) PLACED. Mode %d. CellOriginNode(locDAIdx):(%d,%d,%d). LogicCoords: (%.2e,%.2f,%.2f). PhysCoords: (%.6f,%.6f,%.6f).\n",
466 ci_metric_lnode, cj_metric_lnode, ck_metric_lnode,
467 xi_metric_logic, eta_metric_logic, zta_metric_logic,
468 phys_coords.
x, phys_coords.
y, phys_coords.
z);
471 "InitProps - Rank %d: PID %lld (idx %ld) Mode %d NOT placed by this rank's logic. Default Phys: (%.2f,%.2f,%.2f). Relies on migration.\n",
473 phys_coords.
x, phys_coords.
y, phys_coords.
z);
478 ierr = DMSwarmRestoreField(swarm,
"position", NULL, NULL, (
void**)&positions_field); CHKERRQ(ierr);
479 ierr = DMSwarmRestoreField(swarm,
"pos_phy", NULL, NULL, (
void**)&pos_phy_field); CHKERRQ(ierr);
480 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&particleIDs); CHKERRQ(ierr);
481 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs_petsc); CHKERRQ(ierr);
482 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_location_status", NULL, NULL, (
void**)&status_field); CHKERRQ(ierr);
483 ierr = DMDAVecRestoreArrayRead(user->
fda, Coor_local, (
void*)&coor_nodes_local_array); CHKERRQ(ierr);
485 LOG_ALLOW(
LOCAL,
LOG_INFO,
"InitializeParticleBasicProperties - Rank %d: Completed processing for %d particles.\n",
486 rank, particlesPerProcess);
487 PetscFunctionReturn(0);
PetscErrorCode FinalizeSwarmSetup(PetscRandom *randx, PetscRandom *randy, PetscRandom *randz, PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k)
Finalizes the swarm setup by destroying random generators and logging completion.
PetscErrorCode DistributeParticles(PetscInt numParticles, PetscMPIInt rank, PetscMPIInt size, PetscInt *particlesPerProcess, PetscInt *remainder)
Distributes particles evenly across MPI processes, handling any remainders.
static PetscErrorCode InitializeParticleBasicProperties(UserCtx *user, PetscInt particlesPerProcess, PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k, BoundingBox *bboxlist)
Initializes basic properties for particles on the local process.
PetscErrorCode UnpackSwarmFields(PetscInt i, const PetscInt64 *PIDs, const PetscReal *weights, const PetscReal *positions, const PetscInt *cellIndices, PetscReal *velocities, PetscInt *LocStatus, Particle *particle)
Initializes a Particle struct with data from DMSwarm fields.
static PetscErrorCode DetermineVolumetricInitializationParameters(UserCtx *user, DMDALocalInfo *info, PetscInt xs_gnode, PetscInt ys_gnode, PetscInt zs_gnode, PetscRandom *rand_logic_i_ptr, PetscRandom *rand_logic_j_ptr, PetscRandom *rand_logic_k_ptr, PetscInt *ci_metric_lnode_out, PetscInt *cj_metric_lnode_out, PetscInt *ck_metric_lnode_out, PetscReal *xi_metric_logic_out, PetscReal *eta_metric_logic_out, PetscReal *zta_metric_logic_out, PetscBool *can_place_in_volume_out)
Determines cell selection and intra-cell logical coordinates for volumetric initialization (Mode 1).
PetscErrorCode AssignInitialPropertiesToSwarm(UserCtx *user, PetscInt particlesPerProcess, PetscRandom *rand_phys_x, PetscRandom *rand_phys_y, PetscRandom *rand_phys_z, PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k, BoundingBox *bboxlist)
Initializes all particle properties in the swarm.