PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
|
#include <petsc.h>
#include <petscdmswarm.h>
#include <stdbool.h>
#include <petscsys.h>
#include <math.h>
#include "variables.h"
#include "logging.h"
#include "walkingsearch.h"
Go to the source code of this file.
Functions | |
PetscErrorCode | UpdateParticlePosition (UserCtx *user, Cmpnts *position, const Cmpnts *velocity) |
Updates a particle's position based on its velocity and the timestep dt (stored in user->dt). | |
PetscErrorCode | UpdateAllParticlePositions (UserCtx *user) |
Loops over all local particles in the DMSwarm, updating their positions based on velocity and the global timestep user->dt. | |
PetscErrorCode | CheckAndRemoveOutOfBoundsParticles (UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal, const BoundingBox *bboxlist) |
Checks for particles outside the physical domain boundaries and removes them using DMSwarmRemovePointAtIndex. | |
PetscErrorCode | CheckAndRemoveLostParticles (UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal) |
Removes particles that have been definitively flagged as LOST by the location algorithm. | |
PetscErrorCode | DefineBasicMigrationPattern (UserCtx *user) |
Defines the basic migration pattern for particles within the swarm. | |
PetscErrorCode | PerformBasicMigration (UserCtx *user) |
Performs the basic migration of particles based on the defined migration pattern. | |
PetscErrorCode | IdentifyMigratingParticles (UserCtx *user, const BoundingBox *bboxlist, MigrationInfo **migrationList, PetscInt *migrationCount, PetscInt *listCapacity) |
Identifies particles leaving the local bounding box and finds their target neighbor rank. | |
PetscErrorCode | SetMigrationRanks (UserCtx *user, const MigrationInfo *migrationList, PetscInt migrationCount) |
Sets the target rank field (DMSwarmPICField_rank) for particles scheduled for migration. | |
PetscErrorCode | PerformMigration (UserCtx *user) |
Performs particle migration based on the pre-populated DMSwarmPICField_rank field. | |
PetscErrorCode | CalculateParticleCountPerCell (UserCtx *user) |
Counts particles in each cell of the DMDA 'da' and stores the result in user->ParticleCount. | |
PetscErrorCode | ResizeSwarmGlobally (DM swarm, PetscInt N_target) |
PetscErrorCode | PreCheckAndResizeSwarm (UserCtx *user, PetscInt ti, const char *ext) |
Checks particle count in the reference file and resizes the swarm if needed. | |
PetscErrorCode | PerformSingleParticleMigrationCycle (UserCtx *user, const BoundingBox *bboxlist, MigrationInfo **migrationList_p, PetscInt *migrationCount_p, PetscInt *migrationListCapacity_p, PetscReal currentTime, PetscInt step, const char *migrationCycleName, PetscInt *globalMigrationCount_out) |
Performs one full cycle of particle migration: identify, set ranks, and migrate. | |
PetscErrorCode | ReinitializeParticlesOnInletSurface (UserCtx *user, PetscReal currentTime, PetscInt step) |
Re-initializes the positions of particles currently on this rank if this rank owns part of the designated inlet surface. | |
PetscErrorCode | GetLocalPIDSnapshot (const PetscInt64 pid_field[], PetscInt n_local, PetscInt64 **pids_snapshot_out) |
Creates a sorted snapshot of all Particle IDs (PIDs) from a raw data array. | |
PetscErrorCode | AddToMigrationList (MigrationInfo **migration_list_p, PetscInt *capacity_p, PetscInt *count_p, PetscInt particle_local_idx, PetscMPIInt destination_rank) |
Safely adds a new migration task to a dynamically sized list. | |
PetscErrorCode | FlagNewcomersForLocation (DM swarm, PetscInt n_local_before, const PetscInt64 pids_before[]) |
Identifies newly arrived particles after migration and flags them for a location search. | |
PetscErrorCode | LocateAllParticlesInGrid (UserCtx *user) |
Locates all particles within the grid and calculates their interpolation weights. | |
PetscErrorCode | LocateAllParticlesInGrid_TEST (UserCtx *user, BoundingBox *bboxlist) |
Orchestrates the complete particle location and migration process for one timestep. | |
PetscErrorCode | ResetAllParticleStatuses (UserCtx *user) |
This function is designed to be called at the end of a full timestep, after all particle-based calculations are complete. | |
PetscErrorCode UpdateParticlePosition | ( | UserCtx * | user, |
Cmpnts * | position, | ||
const Cmpnts * | velocity | ||
) |
Updates a particle's position based on its velocity and the timestep dt (stored in user->dt).
[in] | user | Pointer to your UserCtx (must contain user->dt). |
[in,out] | position | Pointer to the particle's current position (Cmpnts). |
[in] | velocity | Pointer to the particle's velocity (Cmpnts). |
Definition at line 19 of file ParticleMotion.c.
PetscErrorCode UpdateAllParticlePositions | ( | UserCtx * | user | ) |
Loops over all local particles in the DMSwarm, updating their positions based on velocity and the global timestep user->dt.
[in,out] | user | Pointer to UserCtx (must contain dt). |
Definition at line 42 of file ParticleMotion.c.
PetscErrorCode CheckAndRemoveOutOfBoundsParticles | ( | UserCtx * | user, |
PetscInt * | removedCountLocal, | ||
PetscInt * | removedCountGlobal, | ||
const BoundingBox * | bboxlist | ||
) |
Checks for particles outside the physical domain boundaries and removes them using DMSwarmRemovePointAtIndex.
This function iterates through all particles local to the current MPI rank. It checks if a particle's position (x, y, or z) is outside the specified physical domain boundaries [xMin, xMax], [yMin, yMax], [zMin, zMax].
If a particle is found out of bounds, it is removed using DMSwarmRemovePointAtIndex. NOTE: Removing points changes the indices of subsequent points in the iteration. Therefore, it's crucial to iterate BACKWARDS or carefully manage indices after a removal. Iterating backwards is generally safer.
user | Pointer to the UserCtx structure. | |
[out] | removedCountLocal | Pointer to store the number of particles removed on this rank. |
[out] | removedCountGlobal | Pointer to store the total number of particles removed across all ranks. |
[in] | bboxlist | An array of BoundingBox structures for ALL MPI ranks, indexed 0 to (size-1). This array must be up-to-date and available on all ranks. |
Checks for particles outside the physical domain boundaries and removes them using DMSwarmRemovePointAtIndex.
This function iterates through all particles local to the current MPI rank. It checks if a particle's position is inside ANY of the bounding boxes that define the subdomains of the MPI ranks. The list of all bounding boxes must be available on all ranks.
If a particle is not found within any of the provided bounding boxes, it is considered to be "out of bounds" and is permanently removed from the simulation using DMSwarmRemovePointAtIndex().
This function uses a robust "Restore-Remove-Reacquire" pattern for modifying the swarm. When a particle is removed, all pointers to swarm data are restored, the removal operation is performed, and then the pointers are reacquired if the loop needs to continue. This is the safest way to modify the swarm's structure during iteration.
LOST
status) and a corresponding cleanup function (e.g., CheckAndRemoveLostParticles
) are already in use. Using both can introduce complexity.[in,out] | user | Pointer to the UserCtx structure containing the swarm and MPI info. |
[out] | removedCountLocal | Pointer to store the number of particles removed on THIS rank. |
[out] | removedCountGlobal | Pointer to store the total number of particles removed ACROSS ALL ranks. |
[in] | bboxlist | An array of BoundingBox structures for ALL MPI ranks, indexed 0 to (size-1). This array must be up-to-date and available on all ranks. |
Checks for particles outside the global physical domain and removes them.
This function iterates through all particles local to the current MPI rank. It determines if a particle's physical position is outside of ALL subdomains owned by the MPI processes. To perform this check, it requires a list of the bounding boxes for every MPI rank's subdomain.
If a particle is not found within any of the subdomains, it is considered "out of bounds" and is permanently removed from the simulation using DMSwarmRemovePointAtIndex().
The function is carefully designed to handle modifications to the DMSwarm during iteration safely. It does this by:
LOST
status) and a corresponding cleanup function are already in use.[in,out] | user | Pointer to the UserCtx structure containing the swarm and MPI info. |
[out] | removedCountLocal | Pointer to an integer that will store the number of particles removed on THIS rank. |
[out] | removedCountGlobal | Pointer to an integer that will store the total number of particles removed ACROSS ALL ranks. |
[in] | bboxlist | An array of BoundingBox structures for ALL MPI ranks, indexed 0 to (size-1). This array must be up-to-date and available on every rank. |
Definition at line 291 of file ParticleMotion.c.
PetscErrorCode CheckAndRemoveLostParticles | ( | UserCtx * | user, |
PetscInt * | removedCountLocal, | ||
PetscInt * | removedCountGlobal | ||
) |
Removes particles that have been definitively flagged as LOST by the location algorithm.
This function is the designated cleanup utility. It should be called after the LocateAllParticlesInGrid
orchestrator has run and every particle's status has been definitively determined.
It iterates through all locally owned particles and checks their DMSwarm_location_status
field. If a particle's status is LOST
, it is permanently removed from the simulation using DMSwarmRemovePointAtIndex
.
This approach centralizes the removal logic, making the DMSwarm_location_status
the single source of truth for a particle's validity, which is more robust than relying on secondary geometric checks (like bounding boxes).
[in,out] | user | Pointer to the UserCtx structure containing the swarm. |
[out] | removedCountLocal | Pointer to store the number of particles removed on this rank. |
[out] | removedCountGlobal | Pointer to store the total number of particles removed across all ranks. |
This function is the designated cleanup utility for particles that have exited the physical domain or could not be located for any other reason. It should be called after a particle location and migration phase is complete.
It iterates through all locally owned particles and checks their DMSwarm_location_status
field. If a particle's status is LOST
, it is permanently removed from the simulation using DMSwarmRemovePointAtIndex
.
The function is carefully designed to handle modifications to the DMSwarm during iteration safely. It does this by:
[in,out] | user | Pointer to the UserCtx structure containing the swarm. |
[out] | removedCountLocal | Pointer to an integer that will store the number of particles removed on THIS rank. |
[out] | removedCountGlobal | Pointer to an integer that will store the total number of particles removed ACROSS ALL ranks. |
Definition at line 542 of file ParticleMotion.c.
PetscErrorCode DefineBasicMigrationPattern | ( | UserCtx * | user | ) |
Defines the basic migration pattern for particles within the swarm.
This function establishes the migration pattern that dictates how particles move between different MPI ranks in the simulation. It initializes a migration list where each particle is assigned a target rank based on predefined conditions. The migration pattern can be customized to implement various migration behaviors.
[in,out] | user | Pointer to the UserCtx structure containing simulation context. |
PetscErrorCode PerformBasicMigration | ( | UserCtx * | user | ) |
Performs the basic migration of particles based on the defined migration pattern.
This function updates the positions of particles within the swarm by migrating them to target MPI ranks as specified in the migration list. It handles the migration process by setting the 'DMSwarm_rank' field for each particle and invokes the DMSwarm migration mechanism to relocate particles across MPI processes. After migration, it cleans up allocated resources and ensures synchronization across all MPI ranks.
[in,out] | user | Pointer to the UserCtx structure containing simulation context. |
PetscErrorCode IdentifyMigratingParticles | ( | UserCtx * | user, |
const BoundingBox * | bboxlist, | ||
MigrationInfo ** | migrationList, | ||
PetscInt * | migrationCount, | ||
PetscInt * | listCapacity | ||
) |
Identifies particles leaving the local bounding box and finds their target neighbor rank.
Iterates local particles, checks against local bounding box. If outside, checks the pre-computed immediate neighbors (user->neighbors) using the global bboxlist to see if the particle landed in one of them. Populates the migrationList. Does NOT handle particles leaving the global domain (assumes CheckAndRemove was called).
user | Pointer to the UserCtx (contains local bbox and neighbors). |
bboxlist | Array of BoundingBox structs for all ranks (for checking neighbor boxes). |
migrationList | Pointer to an array of MigrationInfo structs (output, allocated/reallocated by this func). |
migrationCount | Pointer to the number of particles marked for migration (output). |
listCapacity | Pointer to the current allocated capacity of migrationList (in/out). |
PetscErrorCode SetMigrationRanks | ( | UserCtx * | user, |
const MigrationInfo * | migrationList, | ||
PetscInt | migrationCount | ||
) |
Sets the target rank field (DMSwarmPICField_rank) for particles scheduled for migration.
user | Pointer to UserCtx pa(contains swarm). |
migrationList | Array of MigrationInfo structs containing local indices and target ranks. |
migrationCount | Number of particles in the migrationList. |
Definition at line 648 of file ParticleMotion.c.
PetscErrorCode PerformMigration | ( | UserCtx * | user | ) |
Performs particle migration based on the pre-populated DMSwarmPICField_rank field.
Assumes SetMigrationRanks has already been called to mark particles with their target ranks. Calls DMSwarmMigrate to execute the communication and removal of un-migrated particles.
user | Pointer to the UserCtx structure containing the swarm. |
Definition at line 679 of file ParticleMotion.c.
PetscErrorCode ResizeSwarmGlobally | ( | DM | swarm, |
PetscInt | N_target | ||
) |
Definition at line 857 of file ParticleMotion.c.
PetscErrorCode PreCheckAndResizeSwarm | ( | UserCtx * | user, |
PetscInt | ti, | ||
const char * | ext | ||
) |
Checks particle count in the reference file and resizes the swarm if needed.
Reads the specified field file (e.g., position) into a temporary Vec to determine the number of particles (N_file
) represented in that file for the given timestep. Compares N_file
with the current swarm size (N_current
). If they differ, resizes the swarm globally (adds or removes particles) to match N_file
. Removal assumes excess particles are the globally last ones.
[in,out] | user | Pointer to the UserCtx structure containing the DMSwarm. |
[in] | fieldName | Name of the reference field (e.g., "position"). |
[in] | ti | Time index for constructing the file name. |
[in] | ext | File extension (e.g., "dat"). |
[out] | skipStep | Pointer to boolean flag, set to PETSC_TRUE if the step should be skipped (e.g., file not found), PETSC_FALSE otherwise. |
Checks particle count in the reference file and resizes the swarm if needed.
This function uses a robust parallel pattern: only Rank 0 reads the reference position file to determine the total number of particles saved (N_file
). This count is then broadcast to all other ranks. Finally, each rank compares N_file with the current swarm size and participates in resizing if necessary.
[in,out] | user | Pointer to the UserCtx structure containing the DMSwarm. |
[in] | ti | Time index for constructing the file name. |
[in] | ext | File extension (e.g., "dat"). |
Definition at line 951 of file ParticleMotion.c.
PetscErrorCode PerformSingleParticleMigrationCycle | ( | UserCtx * | user, |
const BoundingBox * | bboxlist, | ||
MigrationInfo ** | migrationList_p, | ||
PetscInt * | migrationCount_p, | ||
PetscInt * | migrationListCapacity_p, | ||
PetscReal | currentTime, | ||
PetscInt | step, | ||
const char * | migrationCycleName, | ||
PetscInt * | globalMigrationCount_out | ||
) |
Performs one full cycle of particle migration: identify, set ranks, and migrate.
This function encapsulates the three main steps of migrating particles between MPI ranks:
bboxlist
).DMSwarmMigrate
. It also calculates and logs the global number of particles migrated.user | Pointer to the UserCtx structure. | |
bboxlist | Array of BoundingBox structures defining the spatial domain of each MPI rank. | |
migrationList_p | Pointer to a pointer for the MigrationInfo array. This array will be allocated/reallocated by IdentifyMigratingParticles if necessary. The caller is responsible for freeing this list eventually. | |
migrationCount_p | Pointer to store the number of particles identified for migration on the local rank. This is reset to 0 after migration for the current cycle. | |
migrationListCapacity_p | Pointer to store the current capacity of the migrationList_p array. | |
currentTime | Current simulation time (used for logging). | |
step | Current simulation step number (used for logging). | |
migrationCycleName | A descriptive name for this migration cycle (e.g., "Preliminary Sort", "Main Loop") for logging purposes. | |
[out] | globalMigrationCount_out | Pointer to store the total number of particles migrated across all MPI ranks during this cycle. |
PetscErrorCode ReinitializeParticlesOnInletSurface | ( | UserCtx * | user, |
PetscReal | currentTime, | ||
PetscInt | step | ||
) |
Re-initializes the positions of particles currently on this rank if this rank owns part of the designated inlet surface.
This function is intended for user->ParticleInitialization == 0
(Surface Initialization mode) and is typically called after an initial migration step (e.g., in PerformInitialSetup
). It ensures that all particles that should originate from the inlet surface and are now on the correct MPI rank are properly distributed across that rank's portion of the inlet.
user | Pointer to the UserCtx structure, containing simulation settings and grid information. |
currentTime | Current simulation time (used for logging). |
step | Current simulation step number (used for logging). |
Definition at line 1059 of file ParticleMotion.c.
PetscErrorCode GetLocalPIDSnapshot | ( | const PetscInt64 | pid_field[], |
PetscInt | n_local, | ||
PetscInt64 ** | pids_snapshot_out | ||
) |
Creates a sorted snapshot of all Particle IDs (PIDs) from a raw data array.
This function is a crucial helper for the migration process. It captures the state of which particles are on the current MPI rank before migration occurs by taking a pointer to the swarm's raw PID data array. The resulting sorted array can then be used with an efficient binary search to quickly identify newcomer particles after migration.
This function does NOT call DMSwarmGetField/RestoreField. It is the caller's responsibility to acquire the pid_field
pointer before calling and restore it afterward.
[in] | pid_field | A read-only pointer to the raw array of PIDs for the local swarm. |
[in] | n_local | The number of particles currently on the local rank. |
[out] | pids_snapshot_out | A pointer to a PetscInt64* array. This function will allocate memory for this array, and the caller is responsible for freeing it with PetscFree() when it is no longer needed. |
Definition at line 1215 of file ParticleMotion.c.
PetscErrorCode AddToMigrationList | ( | MigrationInfo ** | migration_list_p, |
PetscInt * | capacity_p, | ||
PetscInt * | count_p, | ||
PetscInt | particle_local_idx, | ||
PetscMPIInt | destination_rank | ||
) |
Safely adds a new migration task to a dynamically sized list.
This utility function manages a dynamic array of MigrationInfo structs. It appends a new entry to the list and automatically doubles the array's capacity using PetscRealloc
if the current capacity is exceeded. This prevents buffer overflows and avoids the need to know the number of migrating particles in advance.
[in,out] | migration_list_p | A pointer to the MigrationInfo array pointer. The function will update this pointer if the array is reallocated. |
[in,out] | capacity_p | A pointer to an integer holding the current allocated capacity of the list (in number of elements). This will be updated upon reallocation. |
[in,out] | count_p | A pointer to an integer holding the current number of items in the list. This will be incremented by one. |
[in] | particle_local_idx | The local index (from 0 to nlocal-1) of the particle that needs to be migrated. |
[in] | destination_rank | The target MPI rank for the particle. |
Definition at line 1280 of file ParticleMotion.c.
PetscErrorCode FlagNewcomersForLocation | ( | DM | swarm, |
PetscInt | n_local_before, | ||
const PetscInt64 | pids_before[] | ||
) |
Identifies newly arrived particles after migration and flags them for a location search.
This function is a critical component of the iterative migration process managed by the main particle settlement orchestrator (e.g., SettleParticles
). After a DMSwarmMigrate
call, each rank's local particle list is a new mix of resident particles and newly received ones. This function's job is to efficiently identify these "newcomers" and set their DMSwarm_location_status
field to NEEDS_LOCATION
.
This ensures that in the subsequent pass of the migration do-while
loop, only the newly arrived particles are processed by the expensive location algorithm, preventing redundant work on particles that are already settled on the current rank.
The identification is done by comparing the PIDs of particles currently on the rank against a "snapshot" of PIDs taken before the migration occurred.
[in] | swarm | The DMSwarm object, which has just completed a migration. |
[in] | n_local_before | The number of particles that were on this rank before the migration was performed. |
[in] | pids_before | A pre-sorted array of the PIDs that were on this rank before the migration. This is used for fast lookups. |
pids_before
array is sorted in ascending order to enable the use of an efficient binary search. Definition at line 1355 of file ParticleMotion.c.
PetscErrorCode LocateAllParticlesInGrid | ( | UserCtx * | user | ) |
Locates all particles within the grid and calculates their interpolation weights.
This function iterates through all particles currently local to this MPI rank. For each particle, it first checks if the particle is within the rank's pre-calculated bounding box (user->bbox
). If it is, it calls the LocateParticleInGrid
function to perform the walking search.
LocateParticleInGrid
is responsible for finding the containing cell (i,j,k)
and calculating the corresponding interpolation weights (w1,w2,w3)
. It updates the particle->cell
and particle->weights
fields directly upon success. If the search fails (particle not found within MAX_TRAVERSAL, goes out of bounds, or gets stuck without resolution), LocateParticleInGrid
sets the particle's cell
to {-1,-1,-1}
and weights
to {0.0, 0.0, 0.0}
.
After attempting location, this function updates the corresponding entries in the DMSwarm's "DMSwarm_CellID" and "weight" fields using the potentially modified data from the particle
struct.
[in] | user | Pointer to the UserCtx structure containing grid, swarm, and bounding box info. |
0
on success, non-zero on failure (e.g., errors accessing DMSwarm fields).user->bbox
is correctly initialized for the local rank. InitializeParticle
correctly populates the temporary particle
struct. UpdateSwarmFields
correctly writes data back to the DMSwarm. PetscErrorCode LocateAllParticlesInGrid_TEST | ( | UserCtx * | user, |
BoundingBox * | bboxlist | ||
) |
Orchestrates the complete particle location and migration process for one timestep.
This function is the master orchestrator for ensuring every particle is on its correct MPI rank and has a valid host cell index. It is designed to be called once per timestep after particle positions have been updated.
The function uses a robust, iterative "Guess and Verify" strategy within a do-while loop to handle complex particle motion across processor boundaries, especially on curvilinear grids.
LocateParticleOrFindMigrationTarget
) that determines the particle's status: located locally, needs migration, or is lost.SetMigrationRanks
and PerformMigration
helpers.do-while
loop until a pass occurs where no particles migrate, ensuring the entire swarm is in a stable, consistent state.[in,out] | user | Pointer to the UserCtx, containing the swarm and all necessary domain topology information (bboxlist, RankCellInfoMap, etc.). |
[in] | bboxlist | An array of BoundingBox structures for ALL MPI ranks, indexed 0 to (size-1). This array must be up-to-date and available on all ranks. |
Definition at line 1598 of file ParticleMotion.c.
PetscErrorCode ResetAllParticleStatuses | ( | UserCtx * | user | ) |
This function is designed to be called at the end of a full timestep, after all particle-based calculations are complete.
It prepares the swarm for the next timestep by ensuring that after the next position update, every particle will be re-evaluated by the LocateAllParticlesInGrid orchestrator.
It iterates through all locally owned particles and sets their DMSwarm_location_status
field to NEEDS_LOCATION
.
[in,out] | user | Pointer to the UserCtx containing the swarm. |
Definition at line 1818 of file ParticleMotion.c.