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