PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
ParticleSwarm.h
Go to the documentation of this file.
1/**
2 * @file ParticleSwarm.h
3 * @brief Header file for Particle Swarm management functions.
4 *
5 * This file contains declarations of functions responsible for creating, managing,
6 * initializing, migrating, and printing particle swarms within a simulation using PETSc's DMSwarm.
7 */
8
9#ifndef PARTICLE_SWARM_H
10#define PARTICLE_SWARM_H
11
12// Include necessary headers
13#include <petsc.h> // PETSc library header
14#include <petscdmswarm.h> // PETSc DMSwarm header
15#include <stdbool.h>
16#include <math.h>
17#include "variables.h" // Common type definitions
18#include "logging.h" // Logging macros and definitions
19#include "walkingsearch.h"
20#include "Metric.h"
21#include "io.h"
22// --------------------- Function Declarations ---------------------
23
24/**
25 * @brief Creates and initializes a Particle Swarm.
26 *
27 * This function sets up a DMSwarm within the provided UserCtx structure, initializes
28 * particle fields, and distributes particles across MPI processes. It ensures that
29 * the number of particles is evenly divided among the available MPI ranks. If the total
30 * number of particles isn't divisible by the number of processes, the remainder is distributed
31 * to the first few ranks.
32 *
33 * Additionally, it now takes a 'bboxlist' array as an input parameter and passes it on to
34 * AssignInitialProperties(), enabling particle initialization at the midpoint of each rank's
35 * bounding box if ParticleInitialization is set to 0.
36 *
37 * @param[in,out] user Pointer to the UserCtx structure containing the simulation context.
38 * @param[in] numParticles Total number of particles to create across all MPI processes.
39 * @param[in] bboxlist Pointer to an array of BoundingBox structures, one per rank.
40 *
41 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
42 *
43 * @note
44 * - Ensure that `numParticles` is a positive integer.
45 * - The `control.dat` file should contain necessary PETSc options.
46 * - The `bboxlist` array should be properly populated before calling this function.
47 */
48PetscErrorCode CreateParticleSwarm(UserCtx *user, PetscInt numParticles, PetscInt *particlesPerProcess, BoundingBox *bboxlist);
49
50/**
51 * @brief Initializes the DMSwarm object within the UserCtx structure.
52 *
53 * This function creates the DMSwarm, sets its type and dimension, and configures basic swarm properties.
54 *
55 * @param[in,out] user Pointer to the UserCtx structure containing simulation context.
56 *
57 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
58 */
59PetscErrorCode InitializeSwarm(UserCtx* user);
60
61/**
62 * @brief Registers a swarm field without finalizing registration.
63 *
64 * This function calls DMSwarmRegisterPetscDatatypeField for the given field,
65 * but does not finalize the registration. The finalization is deferred until
66 * all fields have been registered.
67 *
68 * @param swarm [in] The DMSwarm object.
69 * @param fieldName [in] Name of the field to register.
70 * @param fieldDim [in] Dimension of the field (1 for scalar, 3 for vector, etc.).
71 * @param dtype [in] The datatype of the swarm field being registered.
72 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
73 */
74PetscErrorCode RegisterSwarmField(DM swarm, const char *fieldName, PetscInt fieldDim, PetscDataType dtype);
75
76/**
77 * @brief Registers necessary particle fields within the DMSwarm.
78 *
79 * This function registers fields such as position, velocity, CellID, and weight for each particle.
80 *
81 * @param[in,out] swarm The DMSwarm object managing the particle swarm.
82 *
83 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
84 */
85PetscErrorCode RegisterParticleFields(DM swarm);
86
87/**
88 * @brief Initializes random number generators for assigning particle properties.
89 *
90 * This function creates and configures separate PETSc random number generators for the x, y, and z coordinates.
91 *
92 * @param[in,out] user Pointer to the UserCtx structure containing simulation context.
93 * @param[out] randx Pointer to store the RNG for the x-coordinate.
94 * @param[out] randy Pointer to store the RNG for the y-coordinate.
95 * @param[out] randz Pointer to store the RNG for the z-coordinate.
96 *
97 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
98 */
99PetscErrorCode InitializeRandomGenerators(UserCtx *user, PetscRandom *randx, PetscRandom *randy, PetscRandom *randz);
100
101/**
102 * @brief Initializes random number generators for logical space operations [0.0, 1.0).
103 *
104 * This function creates and configures three separate PETSc random number generators,
105 * one for each logical dimension (i, j, k or xi, eta, zeta equivalent).
106 * Each RNG is configured to produce uniformly distributed real numbers in the interval [0.0, 1.0).
107 * These are typically used for selecting owned cells or generating intra-cell logical coordinates.
108 *
109 * @param[out] rand_logic_i Pointer to store the RNG for the i-logical dimension.
110 * @param[out] rand_logic_j Pointer to store the RNG for the j-logical dimension.
111 * @param[out] rand_logic_k Pointer to store the RNG for the k-logical dimension.
112 *
113 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
114 */
115PetscErrorCode InitializeLogicalSpaceRNGs(PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k);
116
117/**
118 * @brief Initializes all particle properties in the swarm.
119 *
120 * This function orchestrates the initialization of particle properties.
121 * It first determines the inlet face if surface initialization (Mode 0) is selected
122 * by parsing "bcs.dat".
123 * Then, it initializes basic particle properties (physical position, Particle ID,
124 * and placeholder Cell IDs) by calling `InitializeParticleBasicProperties`. This call
125 * uses the provided `rand_logic_i/j/k` RNGs, which must be pre-initialized for [0,1).
126 * The `rand_phys_x/y/z` RNGs (physically bounded) are passed but may not be used by
127 * `InitializeParticleBasicProperties` for position setting if all initialization paths
128 * use logical-to-physical mapping.
129 * Finally, it calls helper functions to initialize other registered swarm fields
130 * like "velocity", "weight", and "P" (pressure) to default values.
131 *
132 * @param[in,out] user Pointer to the `UserCtx` structure.
133 * @param[in] particlesPerProcess Number of particles assigned to this MPI process.
134 * @param[in] rand_phys_x RNG for physical x-coordinates (from `InitializeRandomGenerators`).
135 * @param[in] rand_phys_y RNG for physical y-coordinates (from `InitializeRandomGenerators`).
136 * @param[in] rand_phys_z RNG for physical z-coordinates (from `InitializeRandomGenerators`).
137 * @param[in] rand_logic_i RNG for i-logical dimension tasks [0,1) (from `InitializeLogicalSpaceRNGs`).
138 * @param[in] rand_logic_j RNG for j-logical dimension tasks [0,1) (from `InitializeLogicalSpaceRNGs`).
139 * @param[in] rand_logic_k RNG for k-logical dimension tasks [0,1) (from `InitializeLogicalSpaceRNGs`).
140 * @param[in] bboxlist Array of BoundingBox structures (potentially unused by IPBP).
141 *
142 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
143 */
144PetscErrorCode AssignInitialPropertiesToSwarm(UserCtx* user,
145 PetscInt particlesPerProcess,
146 PetscRandom *rand_phys_x, // RNG from original InitializeRandomGenerators
147 PetscRandom *rand_phys_y, // RNG from original InitializeRandomGenerators
148 PetscRandom *rand_phys_z, // RNG from original InitializeRandomGenerators
149 PetscRandom *rand_logic_i, // RNG from InitializeLogicalSpaceRNGs
150 PetscRandom *rand_logic_j, // RNG from InitializeLogicalSpaceRNGs
151 PetscRandom *rand_logic_k, // RNG from InitializeLogicalSpaceRNGs
152 BoundingBox *bboxlist);
153
154/**
155 * @brief Distributes particles evenly across MPI processes, handling any remainders.
156 *
157 * This function calculates the number of particles each MPI process should handle,
158 * distributing the remainder particles to the first few ranks if necessary.
159 *
160 * @param[in] numParticles Total number of particles to create across all MPI processes.
161 * @param[in] rank MPI rank of the current process.
162 * @param[in] size Total number of MPI processes.
163 * @param[out] particlesPerProcess Number of particles assigned to the current MPI process.
164 * @param[out] remainder Remainder particles when dividing numParticles by size.
165 *
166 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
167 */
168PetscErrorCode DistributeParticles(PetscInt numParticles, PetscMPIInt rank, PetscMPIInt size, PetscInt* particlesPerProcess, PetscInt* remainder);
169
170/**
171 * @brief Finalizes the swarm setup by destroying random generators and logging completion.
172 *
173 * This function cleans up resources by destroying random number generators and LOG_ALLOWs the completion of swarm setup.
174 *
175 * @param[in] randx Random number generator for the x-coordinate.
176 * @param[in] randy Random number generator for the y-coordinate.
177 * @param[in] randz Random number generator for the z-coordinate.
178 * @param[in] rand_logic_i Random number generator for the xi-coordinate.
179 * @param[in] rand_logic_j Random number generator for the eta-coordinate.
180 * @param[in] rand_logic_k Random number generator for the zeta-coordinate.
181 *
182 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
183 */
184PetscErrorCode FinalizeSwarmSetup(PetscRandom *randx, PetscRandom *randy, PetscRandom *randz, PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k);
185
186/**
187 * @brief Initializes a Particle struct with data from DMSwarm fields.
188 *
189 * This helper function populates a Particle structure using data retrieved from DMSwarm fields.
190 *
191 * @param[in] i Index of the particle in the DMSwarm.
192 * @param[in] PIDs Pointer to the array of particle IDs.
193 * @param[in] weights Pointer to the array of particle weights.
194 * @param[in] positions Pointer to the array of particle positions.
195 * @param[in] cellIndices Pointer to the array of particle cell indices.
196 * @param[in] velocities Pointer to the array of particle velocities.
197 * @param[in] LocStatus Pointer to the array of cell location status indicators.
198 * @param[out] particle Pointer to the Particle struct to initialize.
199 *
200 * @return PetscErrorCode Returns `0` on success, non-zero on failure.
201 */
202PetscErrorCode UnpackSwarmFields(PetscInt i, const PetscInt64 *PIDs, const PetscReal *weights,
203 const PetscReal *positions, const PetscInt *cellIndices,
204 PetscReal *velocities,PetscInt *LocStatus,Particle *particle);
205
206/**
207 * @brief Updates DMSwarm fields with data from a Particle struct.
208 *
209 * This helper function writes back the modified Particle data to the corresponding DMSwarm fields.
210 *
211 * @param[in] i Index of the particle in the DMSwarm.
212 * @param[in] particle Pointer to the Particle struct containing updated data.
213 * @param[in,out] weights Pointer to the array of particle weights.
214 * @param[in,out] cellIndices Pointer to the array of particle cell indices.
215 * @param[in,out] LocStatus Pointer to the array of cell location status indicators.
216 *
217 * @return PetscErrorCode Returns `0` on success, non-zero on failure.
218 */
219PetscErrorCode UpdateSwarmFields(PetscInt i, const Particle *particle,
220 PetscReal *weights, PetscInt *cellIndices, PetscInt *status_field);
221
222/**
223 * @brief Checks if a particle's location is within a specified bounding box.
224 *
225 * This function determines whether the given particle's location lies inside the provided bounding box.
226 * It performs an axis-aligned bounding box (AABB) check by comparing the particle's coordinates to the
227 * minimum and maximum coordinates of the bounding box in each dimension (x, y, z).
228 *
229 * Logging statements are included to provide detailed information about the function's execution.
230 *
231 * @param[in] bbox Pointer to the BoundingBox structure containing minimum and maximum coordinates.
232 * @param[in] particle Pointer to the Particle structure containing the particle's location and identifier.
233 *
234 * @return PetscBool Returns `PETSC_TRUE` if the particle is inside the bounding box, `PETSC_FALSE` otherwise.
235 *
236 * @note
237 * - The function assumes that the `bbox` and `particle` pointers are valid and non-NULL.
238 * - The function includes logging statements that start with the function name.
239 * - Be cautious when logging in performance-critical code sections, especially if the function is called frequently.
240 */
241PetscBool IsParticleInsideBoundingBox(const BoundingBox *bbox, const Particle *particle);
242
243/**
244 * @brief Updates a particle's interpolation weights based on distances to cell faces.
245 *
246 * This function computes interpolation weights using distances to the six
247 * cell faces (`d`) and updates the `weight` field of the provided particle.
248 *
249 * @param[in] d Pointer to an array of distances to the six cell faces.
250 * @param[out] particle Pointer to the Particle structure whose weights are to be updated.
251 *
252 * @return PetscErrorCode Returns 0 on success, or a non-zero error code on failure.
253 */
254PetscErrorCode UpdateParticleWeights(PetscReal *d, Particle *particle);
255
256/**
257 * @brief Resets the location-dependent state of a loaded swarm to force relocation.
258 * @ingroup ParticleRestart
259 *
260 * This function is a critical part of the simulation restart procedure. It must be
261 * called immediately after `ReadAllSwarmFields` has populated a swarm from restart
262 * files. Its purpose is to invalidate the "location" state of the loaded particles,
263 * ensuring that the `LocateAllParticlesInGrid_TEST` orchestrator performs a fresh,
264 * comprehensive search for every particle based on its loaded position.
265 *
266 * It does this by performing two actions on every locally-owned particle:
267 * 1. It resets the `DMSwarm_CellID` field to a sentinel value of `(-1, -1, -1)`.
268 * This invalidates any cell index that might have been loaded or defaulted to 0.
269 * 2. It sets the `DMSwarm_location_status` field to `NEEDS_LOCATION`.
270 *
271 * This guarantees that the location logic will not mistakenly use a stale cell index
272 * from a previous run and will instead use the robust "Guess -> Verify" strategy
273 * appropriate for particles with unknown locations.
274 *
275 * @param[in,out] user Pointer to the UserCtx structure which contains the `DMSwarm` object
276 * that has just been loaded with data from restart files.
277 * @return PetscErrorCode 0 on success, or a non-zero PETSc error code if field access fails.
278 */
279PetscErrorCode PrepareLoadedSwarmForRelocation(UserCtx *user);
280
281/**
282 * @brief Perform particle swarm initialization, particle-grid interaction, and related operations.
283 *
284 * This function handles the following tasks:
285 * 1. Initializes the particle swarm using the provided bounding box list (bboxlist) to determine initial placement
286 * if ParticleInitialization is 0.
287 * 2. Locates particles within the computational grid.
288 * 3. Updates particle positions based on grid interactions (if such logic exists elsewhere in the code).
289 * 4. Interpolates particle velocities from grid points using trilinear interpolation.
290 *
291 * @param[in,out] user Pointer to the UserCtx structure containing grid and particle swarm information.
292 * @param[in] np Number of particles to initialize in the swarm.
293 * @param[in] bboxlist Pointer to an array of BoundingBox structures, one per MPI rank.
294 *
295 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
296 *
297 * @note
298 * - Ensure that `np` (number of particles) is positive.
299 * - The `bboxlist` array must be correctly computed and passed in before calling this function.
300 * - If ParticleInitialization == 0, particles will be placed at the midpoint of the local bounding box.
301 */
302PetscErrorCode InitializeParticleSwarm(SimCtx *simCtx);
303
304#endif // PARTICLE_SWARM_H
PetscErrorCode UpdateParticleWeights(PetscReal *d, Particle *particle)
Updates a particle's interpolation weights based on distances to cell faces.
PetscErrorCode CreateParticleSwarm(UserCtx *user, PetscInt numParticles, PetscInt *particlesPerProcess, BoundingBox *bboxlist)
Creates and initializes a Particle Swarm.
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.
PetscErrorCode InitializeRandomGenerators(UserCtx *user, PetscRandom *randx, PetscRandom *randy, PetscRandom *randz)
Initializes random number generators for assigning particle properties.
PetscBool IsParticleInsideBoundingBox(const BoundingBox *bbox, const Particle *particle)
Checks if a particle's location is within a specified bounding box.
PetscErrorCode PrepareLoadedSwarmForRelocation(UserCtx *user)
Resets the location-dependent state of a loaded swarm to force relocation.
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.
PetscErrorCode InitializeLogicalSpaceRNGs(PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k)
Initializes random number generators for logical space operations [0.0, 1.0).
PetscErrorCode InitializeSwarm(UserCtx *user)
Initializes the DMSwarm object within the UserCtx structure.
PetscErrorCode UpdateSwarmFields(PetscInt i, const Particle *particle, PetscReal *weights, PetscInt *cellIndices, PetscInt *status_field)
Updates DMSwarm fields with data from a Particle struct.
PetscErrorCode InitializeParticleSwarm(SimCtx *simCtx)
Perform particle swarm initialization, particle-grid interaction, and related operations.
PetscErrorCode RegisterSwarmField(DM swarm, const char *fieldName, PetscInt fieldDim, PetscDataType dtype)
Registers a swarm field without finalizing registration.
PetscErrorCode RegisterParticleFields(DM swarm)
Registers necessary particle fields within the DMSwarm.
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.
Public interface for data input/output routines.
Logging utilities and macros for PETSc-based applications.
Main header file for a complex fluid dynamics solver.
Defines a 3D axis-aligned bounding box.
Definition variables.h:153
Defines a particle's core properties for Lagrangian tracking.
Definition variables.h:164
The master context for the entire simulation.
Definition variables.h:513
User-defined context containing data specific to a single computational grid level.
Definition variables.h:630
Header file for particle location functions using the walking search algorithm.