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
19#include "logging.h" // Logging macros and definitions
20#include "walkingsearch.h"
21#include "Metric.h"
22#include "io.h"
23// --------------------- Function Declarations ---------------------
24
25/**
26 * @brief Creates and initializes a Particle Swarm.
27 *
28 * This function sets up a DMSwarm within the provided UserCtx structure, initializes
29 * particle fields, and distributes particles across MPI processes. It ensures that
30 * the number of particles is evenly divided among the available MPI ranks. If the total
31 * number of particles isn't divisible by the number of processes, the remainder is distributed
32 * to the first few ranks.
33 *
34 * Additionally, it now takes a 'bboxlist' array as an input parameter and passes it on to
35 * AssignInitialProperties(), enabling particle initialization at the midpoint of each rank's
36 * bounding box if ParticleInitialization is set to 0.
37 *
38 * @param[in,out] user Pointer to the UserCtx structure containing the simulation context.
39 * @param[in] numParticles Total number of particles to create across all MPI processes.
40 * @param[out] particlesPerProcess Number of particles assigned to the local rank.
41 * @param[in] bboxlist Pointer to an array of BoundingBox structures, one per rank.
42 *
43 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
44 *
45 * @note
46 * - Ensure that `numParticles` is a positive integer.
47 * - The `control.dat` file should contain necessary PETSc options.
48 * - The `bboxlist` array should be properly populated before calling this function.
49 */
50PetscErrorCode CreateParticleSwarm(UserCtx *user, PetscInt numParticles, PetscInt *particlesPerProcess, BoundingBox *bboxlist);
51
52/**
53 * @brief Initializes the DMSwarm object within the UserCtx structure.
54 *
55 * This function creates the DMSwarm, sets its type and dimension, and configures basic swarm properties.
56 *
57 * @param[in,out] user Pointer to the UserCtx structure containing simulation context.
58 *
59 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
60 */
61PetscErrorCode InitializeSwarm(UserCtx* user);
62
63/**
64 * @brief Registers a swarm field without finalizing registration.
65 *
66 * This function calls DMSwarmRegisterPetscDatatypeField for the given field,
67 * but does not finalize the registration. The finalization is deferred until
68 * all fields have been registered.
69 *
70 * @param swarm [in] The DMSwarm object.
71 * @param fieldName [in] Name of the field to register.
72 * @param fieldDim [in] Dimension of the field (1 for scalar, 3 for vector, etc.).
73 * @param dtype [in] The datatype of the swarm field being registered.
74 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
75 */
76PetscErrorCode RegisterSwarmField(DM swarm, const char *fieldName, PetscInt fieldDim, PetscDataType dtype);
77
78/**
79 * @brief Registers necessary particle fields within the DMSwarm.
80 *
81 * This function registers fields such as position, velocity, CellID, and weight for each particle.
82 *
83 * @param[in,out] swarm The DMSwarm object managing the particle swarm.
84 *
85 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
86 */
87PetscErrorCode RegisterParticleFields(DM swarm);
88
89/**
90 * @brief Initializes all particle properties in the swarm.
91 *
92 * This function orchestrates the initialization of particle properties.
93 * It first determines the inlet face if surface initialization (Mode 0) is selected
94 * by parsing "bcs.dat".
95 * Then, it initializes basic particle properties (physical position, Particle ID,
96 * and placeholder Cell IDs) by calling `InitializeParticleBasicProperties`. This call
97 * uses the provided `rand_logic_i/j/k` RNGs, which must be pre-initialized for [0,1).
98 * The `rand_phys_x/y/z` RNGs (physically bounded) are passed but may not be used by
99 * `InitializeParticleBasicProperties` for position setting if all initialization paths
100 * use logical-to-physical mapping.
101 * Finally, it calls helper functions to initialize other registered swarm fields
102 * like "velocity", "weight", and "P" (pressure) to default values.
103 *
104 * @param[in,out] user Pointer to the `UserCtx` structure.
105 * @param[in] particlesPerProcess Number of particles assigned to this MPI process.
106 * @param[in] rand_phys_x RNG for physical x-coordinates (from `InitializeRandomGenerators`).
107 * @param[in] rand_phys_y RNG for physical y-coordinates (from `InitializeRandomGenerators`).
108 * @param[in] rand_phys_z RNG for physical z-coordinates (from `InitializeRandomGenerators`).
109 * @param[in] rand_logic_i RNG for i-logical dimension tasks [0,1) (from `InitializeLogicalSpaceRNGs`).
110 * @param[in] rand_logic_j RNG for j-logical dimension tasks [0,1) (from `InitializeLogicalSpaceRNGs`).
111 * @param[in] rand_logic_k RNG for k-logical dimension tasks [0,1) (from `InitializeLogicalSpaceRNGs`).
112 * @param[in] bboxlist Array of BoundingBox structures (potentially unused by IPBP).
113 *
114 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
115 */
116PetscErrorCode AssignInitialPropertiesToSwarm(UserCtx* user,
117 PetscInt particlesPerProcess,
118 PetscRandom *rand_phys_x, // RNG from original InitializeRandomGenerators
119 PetscRandom *rand_phys_y, // RNG from original InitializeRandomGenerators
120 PetscRandom *rand_phys_z, // RNG from original InitializeRandomGenerators
121 PetscRandom *rand_logic_i, // RNG from InitializeLogicalSpaceRNGs
122 PetscRandom *rand_logic_j, // RNG from InitializeLogicalSpaceRNGs
123 PetscRandom *rand_logic_k, // RNG from InitializeLogicalSpaceRNGs
124 BoundingBox *bboxlist);
125
126/**
127 * @brief Distributes particles evenly across MPI processes, handling any remainders.
128 *
129 * This function calculates the number of particles each MPI process should handle,
130 * distributing the remainder particles to the first few ranks if necessary.
131 *
132 * @param[in] numParticles Total number of particles to create across all MPI processes.
133 * @param[in] rank MPI rank of the current process.
134 * @param[in] size Total number of MPI processes.
135 * @param[out] particlesPerProcess Number of particles assigned to the current MPI process.
136 * @param[out] remainder Remainder particles when dividing numParticles by size.
137 *
138 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
139 */
140PetscErrorCode DistributeParticles(PetscInt numParticles, PetscMPIInt rank, PetscMPIInt size, PetscInt* particlesPerProcess, PetscInt* remainder);
141
142/**
143 * @brief Finalizes the swarm setup by destroying random generators and logging completion.
144 *
145 * This function cleans up resources by destroying random number generators and LOG_ALLOWs the completion of swarm setup.
146 *
147 * @param[in] randx Random number generator for the x-coordinate.
148 * @param[in] randy Random number generator for the y-coordinate.
149 * @param[in] randz Random number generator for the z-coordinate.
150 * @param[in] rand_logic_i Random number generator for the xi-coordinate.
151 * @param[in] rand_logic_j Random number generator for the eta-coordinate.
152 * @param[in] rand_logic_k Random number generator for the zeta-coordinate.
153 *
154 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
155 */
156PetscErrorCode FinalizeSwarmSetup(PetscRandom *randx, PetscRandom *randy, PetscRandom *randz, PetscRandom *rand_logic_i, PetscRandom *rand_logic_j, PetscRandom *rand_logic_k);
157
158/**
159 * @brief Initializes a Particle struct with data from DMSwarm fields.
160 *
161 * This helper function populates a Particle structure using data retrieved from DMSwarm fields.
162 *
163 * @param[in] i Index of the particle in the DMSwarm.
164 * @param[in] PIDs Pointer to the array of particle IDs.
165 * @param[in] weights Pointer to the array of particle weights.
166 * @param[in] positions Pointer to the array of particle positions.
167 * @param[in] cellIndices Pointer to the array of particle cell indices.
168 * @param[in] velocities Pointer to the array of particle velocities.
169 * @param[in] LocStatus Pointer to the array of cell location status indicators.
170 * @param[in] diffusivity Pointer to the array of particle diffusivities.
171 * @param[in] diffusivitygradient Pointer to the array of particle diffusivity gradients.
172 * @param[in] psi Pointer to the array of particle psi values.
173 * @param[out] particle Pointer to the Particle struct to initialize.
174 *
175 * @return PetscErrorCode Returns `0` on success, non-zero on failure.
176 */
177PetscErrorCode UnpackSwarmFields(PetscInt i, const PetscInt64 *PIDs, const PetscReal *weights,
178 const PetscReal *positions, const PetscInt *cellIndices,
179 PetscReal *velocities,PetscInt *LocStatus,PetscReal *diffusivity, Cmpnts *diffusivitygradient, PetscReal *psi, Particle *particle);
180
181/**
182 * @brief Updates DMSwarm data arrays from a Particle struct.
183 *
184 * This function writes data from the `Particle` struct back into the raw DMSwarm arrays.
185 * It is robust: if any array pointer is NULL, that specific field is skipped.
186 * This allows selective updating (e.g., update position but not velocity).
187 *
188 * @param[in] i Index of the particle in the local swarm arrays.
189 * @param[in] particle Pointer to the Particle struct containing updated data.
190 * @param[in,out] positions (Optional) Array of particle positions (size 3*n).
191 * @param[in,out] velocities (Optional) Array of particle velocities (size 3*n).
192 * @param[in,out] weights (Optional) Array of particle weights (size 3*n).
193 * @param[in,out] cellIndices (Optional) Array of particle cell indices (size 3*n).
194 * @param[in,out] status (Optional) Array of location status (size 1*n).
195 * @param[in,out] diffusivity (Optional) Array of diffusivity values (size 1*n).
196 * @param[in,out] diffusivitygradient (Optional) Array of diffusivity gradient values (size 3*n).
197 * @param[in,out] psi (Optional) Array of scalar Psi values (size 1*n).
198 *
199 * @return PetscErrorCode Returns 0 on success.
200 */
201PetscErrorCode UpdateSwarmFields(PetscInt i, const Particle *particle,
202 PetscReal *positions,
203 PetscReal *velocities,
204 PetscReal *weights,
205 PetscInt *cellIndices,
206 PetscInt *status,
207 PetscReal *diffusivity,
208 Cmpnts *diffusivitygradient,
209 PetscReal *psi);
210
211/**
212 * @brief Checks if a particle's location is within a specified bounding box.
213 *
214 * This function determines whether the given particle's location lies inside the provided bounding box.
215 * It performs an axis-aligned bounding box (AABB) check by comparing the particle's coordinates to the
216 * minimum and maximum coordinates of the bounding box in each dimension (x, y, z).
217 *
218 * Logging statements are included to provide detailed information about the function's execution.
219 *
220 * @param[in] bbox Pointer to the BoundingBox structure containing minimum and maximum coordinates.
221 * @param[in] particle Pointer to the Particle structure containing the particle's location and identifier.
222 *
223 * @return PetscBool Returns `PETSC_TRUE` if the particle is inside the bounding box, `PETSC_FALSE` otherwise.
224 *
225 * @note
226 * - The function assumes that the `bbox` and `particle` pointers are valid and non-NULL.
227 * - The function includes logging statements that start with the function name.
228 * - Be cautious when logging in performance-critical code sections, especially if the function is called frequently.
229 */
230PetscBool IsParticleInsideBoundingBox(const BoundingBox *bbox, const Particle *particle);
231
232/**
233 * @brief Updates a particle's interpolation weights based on distances to cell faces.
234 *
235 * This function computes interpolation weights using distances to the six
236 * cell faces (`d`) and updates the `weight` field of the provided particle.
237 *
238 * @param[in] d Pointer to an array of distances to the six cell faces.
239 * @param[out] particle Pointer to the Particle structure whose weights are to be updated.
240 *
241 * @return PetscErrorCode Returns 0 on success, or a non-zero error code on failure.
242 */
243PetscErrorCode UpdateParticleWeights(PetscReal *d, Particle *particle);
244
245/**
246 * @brief High-level particle initialization orchestrator for a simulation run.
247 *
248 * This routine drives end-to-end swarm setup from the top-level simulation context:
249 * creation/registration of particle fields, initial placement according to configured
250 * mode, initial localization on the Eulerian grid, and startup interpolation needed
251 * before entering the main run loop.
252 *
253 * @param[in,out] simCtx Master simulation context containing all blocks and run settings.
254 *
255 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
256 */
257PetscErrorCode InitializeParticleSwarm(SimCtx *simCtx);
258
259#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.
PetscBool IsParticleInsideBoundingBox(const BoundingBox *bbox, const Particle *particle)
Checks if a particle's location is within a specified bounding box.
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 InitializeSwarm(UserCtx *user)
Initializes the DMSwarm object within the UserCtx structure.
PetscErrorCode UpdateSwarmFields(PetscInt i, const Particle *particle, PetscReal *positions, PetscReal *velocities, PetscReal *weights, PetscInt *cellIndices, PetscInt *status, PetscReal *diffusivity, Cmpnts *diffusivitygradient, PetscReal *psi)
Updates DMSwarm data arrays from a Particle struct.
PetscErrorCode InitializeParticleSwarm(SimCtx *simCtx)
High-level particle initialization orchestrator for a simulation run.
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.
Typed identities and metadata for persistent solver-particle fields.
Main header file for a complex fluid dynamics solver.
Defines a 3D axis-aligned bounding box.
Definition variables.h:171
A 3D point or vector with PetscScalar components.
Definition variables.h:102
Defines a particle's core properties for Lagrangian tracking.
Definition variables.h:182
The master context for the entire simulation.
Definition variables.h:695
User-defined context containing data specific to a single computational grid level.
Definition variables.h:906
Header file for particle location functions using the walking search algorithm.