PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
ParticleSwarm.h File Reference

Header file for Particle Motion and migration related functions. More...

#include <petsc.h>
#include <petscdmswarm.h>
#include <stdbool.h>
#include <math.h>
#include "variables.h"
#include "logging.h"
#include "walkingsearch.h"
#include "Metric.h"
#include "io.h"
Include dependency graph for ParticleSwarm.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

PetscErrorCode CreateParticleSwarm (UserCtx *user, PetscInt numParticles, PetscInt *particlesPerProcess, BoundingBox *bboxlist)
 Creates and initializes a Particle Swarm.
 
PetscErrorCode InitializeSwarm (UserCtx *user)
 Initializes the DMSwarm object within the UserCtx structure.
 
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 InitializeRandomGenerators (UserCtx *user, PetscRandom *randx, PetscRandom *randy, PetscRandom *randz)
 Initializes random number generators for assigning particle properties.
 
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 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.
 
PetscErrorCode DistributeParticles (PetscInt numParticles, PetscMPIInt rank, PetscMPIInt size, PetscInt *particlesPerProcess, PetscInt *remainder)
 Distributes particles evenly across MPI processes, handling any remainders.
 
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 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 UpdateSwarmFields (PetscInt i, const Particle *particle, PetscReal *weights, PetscInt *cellIndices, PetscInt *status_field)
 Updates DMSwarm fields with data from a Particle struct.
 
PetscBool IsParticleInsideBoundingBox (const BoundingBox *bbox, const Particle *particle)
 Checks if a particle's location is within a specified bounding box.
 
PetscErrorCode UpdateParticleWeights (PetscReal *d, Particle *particle)
 Updates a particle's interpolation weights based on distances to cell faces.
 
PetscErrorCode PrepareLoadedSwarmForRelocation (UserCtx *user)
 Resets the location-dependent state of a loaded swarm to force relocation.
 
PetscErrorCode InitializeParticleSwarm (SimCtx *simCtx)
 Perform particle swarm initialization, particle-grid interaction, and related operations.
 

Detailed Description

Header file for Particle Motion and migration related functions.

Header file for Particle Swarm management functions.

This file contains declarations of functions responsible for moving and migrating particle swarms within a simulation using PETSc's DMSwarm.

This file contains declarations of functions responsible for creating, managing, initializing, migrating, and printing particle swarms within a simulation using PETSc's DMSwarm.

Definition in file ParticleSwarm.h.

Function Documentation

◆ CreateParticleSwarm()

PetscErrorCode CreateParticleSwarm ( UserCtx user,
PetscInt  numParticles,
PetscInt *  particlesPerProcess,
BoundingBox bboxlist 
)

Creates and initializes a Particle Swarm.

This function sets up a DMSwarm within the provided UserCtx structure, initializes particle fields, and distributes particles across MPI processes. It ensures that the number of particles is evenly divided among the available MPI ranks. If the total number of particles isn't divisible by the number of processes, the remainder is distributed to the first few ranks.

Additionally, it now takes a 'bboxlist' array as an input parameter and passes it on to AssignInitialProperties(), enabling particle initialization at the midpoint of each rank's bounding box if ParticleInitialization is set to 0.

Parameters
[in,out]userPointer to the UserCtx structure containing the simulation context.
[in]numParticlesTotal number of particles to create across all MPI processes.
[in]bboxlistPointer to an array of BoundingBox structures, one per rank.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.
Note
  • Ensure that numParticles is a positive integer.
  • The control.dat file should contain necessary PETSc options.
  • The bboxlist array should be properly populated before calling this function.

    This function sets up a DMSwarm within the provided UserCtx structure, initializes particle fields, and distributes particles across MPI processes. It ensures that the number of particles is evenly divided among the available MPI ranks. If the total number of particles isn't divisible by the number of processes, the remainder is distributed to the first few ranks.

Parameters
[in,out]userPointer to the UserCtx structure containing the simulation context.
[in]numParticlesTotal number of particles to create across all MPI processes.
[in]bboxlistPointer to an array of BoundingBox structures, one per rank.
[in]particlesPerProcess
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.
Note
  • Ensure that numParticles is a positive integer.
  • The control.dat file should contain necessary PETSc options.
  • The bboxlist array should be properly populated before calling this function.

Definition at line 764 of file ParticleSwarm.c.

764 {
765 PetscErrorCode ierr; // PETSc error handling variable
766 PetscMPIInt rank, size; // Variables to store MPI rank and size
767 PetscInt remainder = 0; // Remainder of particles after division
768
769 // Validate input parameters
770 if (numParticles <= 0) {
771 LOG_ALLOW(GLOBAL,LOG_DEBUG, "CreateParticleSwarm - Number of particles must be positive. Given: %d\n", numParticles);
772 return PETSC_ERR_ARG_OUTOFRANGE;
773 }
774
775 // Insert PETSc options from "control.dat" into the PETSc options database
776 // ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD, NULL, "control.dat", PETSC_TRUE); CHKERRQ(ierr);
777 // LOG_ALLOW(LOCAL,LOG_DEBUG,"CreateParticleSwarm - Inserted options from control.dat\n");
778
779 LOG_ALLOW_SYNC(GLOBAL,LOG_DEBUG, "CreateParticleSwarm - Domain dimensions: Min_X=%.2f, Max_X=%.2f,Min_Y=%.2f, Max_Y=%.2f,Min_Z=%.2f, Max_Z=%.2f \n",
780 user->Min_X,user->Max_X,user->Min_Y,user->Max_Y, user->Min_Z,user->Max_Z);
781
782 // Retrieve MPI rank and size
783 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
784 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size); CHKERRQ(ierr);
785 LOG_ALLOW(GLOBAL,LOG_INFO, "CreateParticleSwarm - Rank %d out of %d processes.\n", rank, size);
786
787 // Distribute particles among MPI processes
788 ierr = DistributeParticles(numParticles, rank, size, particlesPerProcess, &remainder); CHKERRQ(ierr);
789
790 // Initialize the DMSwarm - creates the swarm, sets the type and dimension
791 ierr = InitializeSwarm(user); CHKERRQ(ierr);
792
793 if (user->da) {
794 ierr = DMSwarmSetCellDM(user->swarm, user->da); CHKERRQ(ierr);
795 LOG_ALLOW(LOCAL,LOG_INFO,"CreateParticleSwarm - Associated DMSwarm with Cell DM (user->da).\n");
796 } else {
797 // If user->da is essential for your simulation logic with particles, this should be a fatal error.
798 LOG_ALLOW(GLOBAL, LOG_WARNING, "CreateParticleSwarm - user->da (Cell DM for Swarm) is NULL. Cell-based swarm operations might fail.\n");
799 // SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "CreateParticleSwarm - user->da (Cell DM) is NULL but required.");
800 }
801
802 // Register particle fields (position, velocity, CellID, weight, etc.)
803 ierr = RegisterParticleFields(user->swarm); CHKERRQ(ierr);
804
805 // Set the local number of particles for this rank and additional buffer for particle migration
806 ierr = DMSwarmSetLocalSizes(user->swarm, *particlesPerProcess, numParticles); CHKERRQ(ierr);
807 LOG_ALLOW(GLOBAL,LOG_INFO, "CreateParticleSwarm - Set local swarm size: %d particles.\n", *particlesPerProcess);
808
809 // Optionally, LOG_ALLOW detailed DM info in debug mode
810 if (get_log_level() == LOG_DEBUG && is_function_allowed(__func__)) {
811 LOG_ALLOW(LOCAL,LOG_DEBUG,"CreateParticleSwarm - Viewing DMSwarm:\n");
812 ierr = DMView(user->swarm, PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr);
813 }
814
815 LOG_ALLOW(LOCAL,LOG_INFO, "CreateParticleSwarm - Particle swarm creation and initialization complete.\n");
816
817 return 0;
818 }
PetscErrorCode DistributeParticles(PetscInt numParticles, PetscMPIInt rank, PetscMPIInt size, PetscInt *particlesPerProcess, PetscInt *remainder)
Distributes particles evenly across MPI processes, handling any remainders.
PetscErrorCode InitializeSwarm(UserCtx *user)
Initializes the DMSwarm object within the UserCtx structure.
PetscErrorCode RegisterParticleFields(DM swarm)
Registers necessary particle fields within the DMSwarm.
PetscBool is_function_allowed(const char *functionName)
Checks if a given function is in the allow-list.
Definition logging.c:159
#define LOG_ALLOW_SYNC(scope, level, fmt,...)
----— DEBUG ---------------------------------------— #define LOG_ALLOW(scope, level,...
Definition logging.h:274
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:44
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:45
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
Definition logging.h:207
LogLevel get_log_level()
Retrieves the current logging level from the environment variable LOG_LEVEL.
Definition logging.c:49
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:32
@ LOG_WARNING
Non-critical issues that warrant attention.
Definition logging.h:30
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:33
PetscReal Min_X
Definition variables.h:640
PetscReal Max_Y
Definition variables.h:640
PetscReal Min_Z
Definition variables.h:640
PetscReal Max_X
Definition variables.h:640
PetscReal Min_Y
Definition variables.h:640
PetscReal Max_Z
Definition variables.h:640
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitializeSwarm()

PetscErrorCode InitializeSwarm ( UserCtx user)

Initializes the DMSwarm object within the UserCtx structure.

This function creates the DMSwarm, sets its type and dimension, and configures basic swarm properties.

Parameters
[in,out]userPointer to the UserCtx structure containing simulation context.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 15 of file ParticleSwarm.c.

15 {
16 PetscErrorCode ierr; // Error code for PETSc functions
17
18 // Create the DMSwarm object for particle management
19 ierr = DMCreate(PETSC_COMM_WORLD, &user->swarm); CHKERRQ(ierr);
20 ierr = DMSetType(user->swarm, DMSWARM); CHKERRQ(ierr);
21 ierr = DMSetDimension(user->swarm, 3); CHKERRQ(ierr);
22 ierr = DMSwarmSetType(user->swarm, DMSWARM_BASIC); CHKERRQ(ierr);
23 LOG_ALLOW(LOCAL,LOG_INFO, "InitializeSwarm - DMSwarm created and configured.\n");
24
25 return 0;
26 }
Here is the caller graph for this function:

◆ RegisterSwarmField()

PetscErrorCode RegisterSwarmField ( DM  swarm,
const char *  fieldName,
PetscInt  fieldDim,
PetscDataType  dtype 
)

Registers a swarm field without finalizing registration.

This function calls DMSwarmRegisterPetscDatatypeField for the given field, but does not finalize the registration. The finalization is deferred until all fields have been registered.

Parameters
swarm[in] The DMSwarm object.
fieldName[in] Name of the field to register.
fieldDim[in] Dimension of the field (1 for scalar, 3 for vector, etc.).
dtype[in] The datatype of the swarm field being registered.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 41 of file ParticleSwarm.c.

42 {
43 PetscErrorCode ierr;
44 PetscFunctionBeginUser;
45
46 ierr = DMSwarmRegisterPetscDatatypeField(swarm, fieldName, fieldDim, dtype); CHKERRQ(ierr);
47 // PetscDataTypes is an extern char* [] defined in petscsystypes.h that gives string names for PetscDataType enums
48 LOG_ALLOW(LOCAL,LOG_DEBUG,"RegisterSwarmField - Registered field '%s' with dimension=%d, type=%s.\n",
49 fieldName, fieldDim, PetscDataTypes[dtype]);
50
51 PetscFunctionReturn(0);
52 }
Here is the caller graph for this function:

◆ RegisterParticleFields()

PetscErrorCode RegisterParticleFields ( DM  swarm)

Registers necessary particle fields within the DMSwarm.

This function registers fields such as position, velocity, CellID, and weight for each particle.

Parameters
[in,out]swarmThe DMSwarm object managing the particle swarm.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 64 of file ParticleSwarm.c.

65 {
66 PetscErrorCode ierr;
67 PetscFunctionBeginUser;
68
69 // Register each field using the helper function
70 ierr = RegisterSwarmField(swarm, "position", 3 ,PETSC_REAL); CHKERRQ(ierr);
71 LOG_ALLOW(LOCAL,LOG_DEBUG, "Registered field 'position'.\n");
72
73 ierr = RegisterSwarmField(swarm, "velocity", 3, PETSC_REAL); CHKERRQ(ierr);
74 LOG_ALLOW(LOCAL,LOG_DEBUG,"Registered field 'velocity'.\n");
75
76 ierr = RegisterSwarmField(swarm, "DMSwarm_CellID", 3, PETSC_INT); CHKERRQ(ierr);
77 LOG_ALLOW(LOCAL,LOG_DEBUG,"Registered field 'DMSwarm_CellID'.\n");
78
79 ierr = RegisterSwarmField(swarm, "weight", 3,PETSC_REAL); CHKERRQ(ierr);
80 LOG_ALLOW(LOCAL,LOG_DEBUG,"Registered field 'weight'.\n");
81
82 ierr = RegisterSwarmField(swarm,"Psi", 1,PETSC_REAL); CHKERRQ(ierr);
83 LOG_ALLOW(LOCAL,LOG_DEBUG,"Registered field 'Psi' - Scalar.\n");
84
85
86 ierr = RegisterSwarmField(swarm,"pos_phy", 3,PETSC_REAL); CHKERRQ(ierr);
87 LOG_ALLOW(LOCAL,LOG_DEBUG,"Registered field 'pos_phy' - Physical Position.\n");
88
89 ierr = RegisterSwarmField(swarm,"DMSwarm_location_status",1,PETSC_INT);CHKERRQ(ierr);
90 LOG_ALLOW(LOCAL,LOG_DEBUG,"Registered field 'DMSwarm_location_status' - Status of Location of Particle(located,lost etc).\n");
91
92 // Finalize the field registration after all fields have been added
93 ierr = DMSwarmFinalizeFieldRegister(swarm); CHKERRQ(ierr);
94 LOG_ALLOW(LOCAL,LOG_INFO,"RegisterParticleFields - Finalized field registration.\n");
95
96 PetscFunctionReturn(0);
97 }
PetscErrorCode RegisterSwarmField(DM swarm, const char *fieldName, PetscInt fieldDim, PetscDataType dtype)
Registers a swarm field without finalizing registration.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitializeRandomGenerators()

PetscErrorCode InitializeRandomGenerators ( UserCtx user,
PetscRandom *  randx,
PetscRandom *  randy,
PetscRandom *  randz 
)

Initializes random number generators for assigning particle properties.

This function creates and configures separate PETSc random number generators for the x, y, and z coordinates.

Parameters
[in,out]userPointer to the UserCtx structure containing simulation context.
[out]randxPointer to store the RNG for the x-coordinate.
[out]randyPointer to store the RNG for the y-coordinate.
[out]randzPointer to store the RNG for the z-coordinate.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 112 of file ParticleSwarm.c.

112 {
113 PetscErrorCode ierr; // Error code for PETSc functions
114 PetscMPIInt rank;
115 MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
116
117 // Initialize RNG for x-coordinate
118 ierr = PetscRandomCreate(PETSC_COMM_SELF, randx); CHKERRQ(ierr);
119 ierr = PetscRandomSetType((*randx), PETSCRAND48); CHKERRQ(ierr);
120 ierr = PetscRandomSetInterval(*randx, user->bbox.min_coords.x, user->bbox.max_coords.x); CHKERRQ(ierr);
121 ierr = PetscRandomSetSeed(*randx, rank + 12345); CHKERRQ(ierr); // Unique seed per rank
122 ierr = PetscRandomSeed(*randx); CHKERRQ(ierr);
123 LOG_ALLOW_SYNC(LOCAL,LOG_DEBUG, "InitializeRandomGenerators - Initialized RNG for X-axis.\n");
124
125 // Initialize RNG for y-coordinate
126 ierr = PetscRandomCreate(PETSC_COMM_SELF, randy); CHKERRQ(ierr);
127 ierr = PetscRandomSetType((*randy), PETSCRAND48); CHKERRQ(ierr);
128 ierr = PetscRandomSetInterval(*randy, user->bbox.min_coords.y, user->bbox.max_coords.y); CHKERRQ(ierr);
129 ierr = PetscRandomSetSeed(*randy, rank + 67890); CHKERRQ(ierr); // Unique seed per rank
130 ierr = PetscRandomSeed(*randy); CHKERRQ(ierr);
131 LOG_ALLOW_SYNC(LOCAL,LOG_DEBUG, "InitializeRandomGenerators - Initialized RNG for Y-axis.\n");
132
133 // Initialize RNG for z-coordinate
134 ierr = PetscRandomCreate(PETSC_COMM_SELF, randz); CHKERRQ(ierr);
135 ierr = PetscRandomSetType((*randz), PETSCRAND48); CHKERRQ(ierr);
136 ierr = PetscRandomSetInterval(*randz, user->bbox.min_coords.z, user->bbox.max_coords.z); CHKERRQ(ierr);
137 ierr = PetscRandomSetSeed(*randz, rank + 54321); CHKERRQ(ierr); // Unique seed per rank
138 ierr = PetscRandomSeed(*randz); CHKERRQ(ierr);
139 LOG_ALLOW_SYNC(LOCAL,LOG_DEBUG, "InitializeRandomGenerators - Initialized RNG for Z-axis.\n");
140
141 return 0;
142 }
Cmpnts max_coords
Maximum x, y, z coordinates of the bounding box.
Definition variables.h:155
Cmpnts min_coords
Minimum x, y, z coordinates of the bounding box.
Definition variables.h:154
PetscScalar x
Definition variables.h:100
PetscScalar z
Definition variables.h:100
PetscScalar y
Definition variables.h:100
BoundingBox bbox
Definition variables.h:641
Here is the caller graph for this function:

◆ InitializeLogicalSpaceRNGs()

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).

This function creates and configures three separate PETSc random number generators, one for each logical dimension (i, j, k or xi, eta, zeta equivalent). Each RNG is configured to produce uniformly distributed real numbers in the interval [0.0, 1.0). These are typically used for selecting owned cells or generating intra-cell logical coordinates.

Parameters
[out]rand_logic_iPointer to store the RNG for the i-logical dimension.
[out]rand_logic_jPointer to store the RNG for the j-logical dimension.
[out]rand_logic_kPointer to store the RNG for the k-logical dimension.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 158 of file ParticleSwarm.c.

158 {
159 PetscErrorCode ierr;
160 PetscMPIInt rank;
161 PetscFunctionBeginUser;
162
163 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
164
165 // --- RNG for i-logical dimension ---
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); // Key change: [0,1)
169 ierr = PetscRandomSetSeed(*rand_logic_i, rank + 202401); CHKERRQ(ierr); // Unique seed
170 ierr = PetscRandomSeed(*rand_logic_i); CHKERRQ(ierr);
171 LOG_ALLOW(LOCAL,LOG_DEBUG, "InitializeLogicalSpaceRNGs - Initialized RNG for i-logical dimension [0,1).\n");
172
173 // --- RNG for j-logical dimension ---
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); // Key change: [0,1)
177 ierr = PetscRandomSetSeed(*rand_logic_j, rank + 202402); CHKERRQ(ierr);
178 ierr = PetscRandomSeed(*rand_logic_j); CHKERRQ(ierr);
179 LOG_ALLOW(LOCAL,LOG_DEBUG, "InitializeLogicalSpaceRNGs - Initialized RNG for j-logical dimension [0,1).\n");
180
181 // --- RNG for k-logical dimension ---
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); // Key change: [0,1)
185 ierr = PetscRandomSetSeed(*rand_logic_k, rank + 202403); CHKERRQ(ierr);
186 ierr = PetscRandomSeed(*rand_logic_k); CHKERRQ(ierr);
187 LOG_ALLOW(LOCAL,LOG_DEBUG, "InitializeLogicalSpaceRNGs - Initialized RNG for k-logical dimension [0,1).\n");
188
189 PetscFunctionReturn(0);
190 }
Here is the caller graph for this function:

◆ AssignInitialPropertiesToSwarm()

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.

This function orchestrates the initialization of particle properties. It first determines the inlet face if surface initialization (Mode 0) is selected by parsing "bcs.dat". Then, it initializes basic particle properties (physical position, Particle ID, and placeholder Cell IDs) by calling InitializeParticleBasicProperties. This call uses the provided rand_logic_i/j/k RNGs, which must be pre-initialized for [0,1). The rand_phys_x/y/z RNGs (physically bounded) are passed but may not be used by InitializeParticleBasicProperties for position setting if all initialization paths use logical-to-physical mapping. Finally, it calls helper functions to initialize other registered swarm fields like "velocity", "weight", and "P" (pressure) to default values.

Parameters
[in,out]userPointer to the UserCtx structure.
[in]particlesPerProcessNumber of particles assigned to this MPI process.
[in]rand_phys_xRNG for physical x-coordinates (from InitializeRandomGenerators).
[in]rand_phys_yRNG for physical y-coordinates (from InitializeRandomGenerators).
[in]rand_phys_zRNG for physical z-coordinates (from InitializeRandomGenerators).
[in]rand_logic_iRNG for i-logical dimension tasks [0,1) (from InitializeLogicalSpaceRNGs).
[in]rand_logic_jRNG for j-logical dimension tasks [0,1) (from InitializeLogicalSpaceRNGs).
[in]rand_logic_kRNG for k-logical dimension tasks [0,1) (from InitializeLogicalSpaceRNGs).
[in]bboxlistArray of BoundingBox structures (potentially unused by IPBP).
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

This function orchestrates the initialization of particle properties. It first determines the inlet face if surface initialization (Mode 0) is selected by parsing "bcs.dat". Then, it initializes basic particle properties (physical position, Particle ID, and placeholder Cell IDs) by calling InitializeParticleBasicProperties. This call uses the provided rand_logic_i/j/k RNGs, which must be pre-initialized for [0,1). The rand_phys_x/y/z RNGs (physically bounded) are passed but may not be used by InitializeParticleBasicProperties for position setting if all initialization paths use logical-to-physical mapping. Finally, it calls helper functions to initialize other registered swarm fields like "velocity", "weight", and "Psi" (scalar) to default values.

Parameters
[in,out]userPointer to the UserCtx structure.
[in]particlesPerProcessNumber of particles assigned to this MPI process.
[in]rand_phys_xRNG for physical x-coordinates (from InitializeRandomGenerators).
[in]rand_phys_yRNG for physical y-coordinates (from InitializeRandomGenerators).
[in]rand_phys_zRNG for physical z-coordinates (from InitializeRandomGenerators).
[in]rand_logic_iRNG for i-logical dimension tasks [0,1) (from InitializeLogicalSpaceRNGs).
[in]rand_logic_jRNG for j-logical dimension tasks [0,1) (from InitializeLogicalSpaceRNGs).
[in]rand_logic_kRNG for k-logical dimension tasks [0,1) (from InitializeLogicalSpaceRNGs).
[in]bboxlistArray of BoundingBox structures (potentially unused by IPBP).
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 606 of file ParticleSwarm.c.

615 {
616 PetscErrorCode ierr;
617 PetscFunctionBeginUser;
618
619 SimCtx *simCtx = user->simCtx;
620
621 // --- 0. Input Validation ---
622 if (!user || !bboxlist || !rand_logic_i || !rand_logic_j || !rand_logic_k || !rand_phys_x || !rand_phys_y || !rand_phys_z) {
623 // Check all RNGs now as they are passed in
624 LOG_ALLOW(GLOBAL, LOG_ERROR, "AssignInitialPropertiesToSwarm - Null user, bboxlist, or RNG pointer.\n");
625 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "AssignInitialPropertiesToSwarm - Null input detected.");
626 }
627
628 LOG_ALLOW(GLOBAL, LOG_INFO, "AssignInitialPropertiesToSwarm - Initializing swarm with %d particles per process. Mode: %d.\n",
629 particlesPerProcess, simCtx->ParticleInitialization);
630
631 // --- 1. Parse BCS File for Inlet Information (if Mode 0) ---
632 if (simCtx->ParticleInitialization == 0) {
633 if(user->inletFaceDefined == PETSC_FALSE){
634 LOG_ALLOW(GLOBAL, LOG_ERROR, "AssignInitialPropertiesToSwarm - ParticleInitialization Mode 0 (Surface Init) selected, but no INLET face was identified from bcs.dat. Cannot proceed.\n");
635 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "ParticleInitialization Mode 0 requires an INLET face to be defined in bcs.dat.");
636 }else{
637 LOG_ALLOW(GLOBAL, LOG_INFO, "AssignInitialPropertiesToSwarm - After ParseBCSFileForInlet, identifiedInletBCFace = %d\n", user->identifiedInletBCFace);
638 }
639 }
640
641 // --- 2. Initialize Basic Particle Properties (Position, PID, Cell IDs placeholder) ---
642 // The rand_logic_i/j/k are now passed directly.
643 // The rand_phys_x/y/z are passed but InitializeParticleBasicProperties (refactored version)
644 // will not use them for setting positions if all its paths use logical-to-physical mapping.
645 LOG_ALLOW(LOCAL, LOG_DEBUG, "AssignInitialPropertiesToSwarm - Calling InitializeParticleBasicProperties.\n");
646 ierr = InitializeParticleBasicProperties(user, particlesPerProcess,
647 rand_logic_i, rand_logic_j, rand_logic_k,
648 bboxlist); // bboxlist passed along
649 CHKERRQ(ierr);
650 LOG_ALLOW(LOCAL, LOG_INFO, "AssignInitialPropertiesToSwarm - Successfully initialized basic particle properties.\n");
651
652 // Note: The logical RNGs (rand_logic_i/j/k) are NOT destroyed here.
653 // They were created externally (e.g., by InitializeLogicalSpaceRNGs) and
654 // should be destroyed externally (e.g., in FinalizeSwarmSetup).
655 // Same for rand_phys_x/y/z.
656
657 // --- 3. Initialize Other Swarm Fields (Velocity, Weight, Pressure, etc.) ---
658 LOG_ALLOW(LOCAL, LOG_DEBUG, "AssignInitialPropertiesToSwarm - Initializing 'velocity' field.\n");
659 ierr = AssignInitialFieldToSwarm(user, "velocity", 3); CHKERRQ(ierr);
660 LOG_ALLOW(LOCAL, LOG_INFO, "AssignInitialPropertiesToSwarm - 'velocity' field initialization complete.\n");
661
662 LOG_ALLOW(LOCAL, LOG_DEBUG, "AssignInitialPropertiesToSwarm - Initializing 'weight' field.\n");
663 ierr = AssignInitialFieldToSwarm(user, "weight", 3); CHKERRQ(ierr); // Assuming weight is vec3
664 LOG_ALLOW(LOCAL, LOG_INFO, "AssignInitialPropertiesToSwarm - 'weight' field initialization complete.\n");
665
666 LOG_ALLOW(LOCAL, LOG_DEBUG, "AssignInitialPropertiesToSwarm - Initializing 'P' (Pressure) field.\n");
667 ierr = AssignInitialFieldToSwarm(user, "Psi", 1); CHKERRQ(ierr);
668 LOG_ALLOW(LOCAL, LOG_INFO, "AssignInitialPropertiesToSwarm - 'P' field initialization complete.\n");
669
670 LOG_ALLOW(GLOBAL, LOG_INFO, "AssignInitialPropertiesToSwarm - Successfully completed all swarm property initialization.\n");
671
672 PetscFunctionReturn(0);
673 }
static PetscErrorCode AssignInitialFieldToSwarm(UserCtx *user, const char *fieldName, PetscInt fieldDim)
Initializes a generic swarm field with point-level updates.
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.
@ LOG_ERROR
Critical errors that may halt the program.
Definition logging.h:29
PetscBool inletFaceDefined
Definition variables.h:649
BCFace identifiedInletBCFace
Definition variables.h:650
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:633
PetscInt ParticleInitialization
Definition variables.h:589
The master context for the entire simulation.
Definition variables.h:513
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DistributeParticles()

PetscErrorCode DistributeParticles ( PetscInt  numParticles,
PetscMPIInt  rank,
PetscMPIInt  size,
PetscInt *  particlesPerProcess,
PetscInt *  remainder 
)

Distributes particles evenly across MPI processes, handling any remainders.

This function calculates the number of particles each MPI process should handle, distributing the remainder particles to the first few ranks if necessary.

Parameters
[in]numParticlesTotal number of particles to create across all MPI processes.
[in]rankMPI rank of the current process.
[in]sizeTotal number of MPI processes.
[out]particlesPerProcessNumber of particles assigned to the current MPI process.
[out]remainderRemainder particles when dividing numParticles by size.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 689 of file ParticleSwarm.c.

689 {
690
691 // Calculate the base number of particles per process
692 *particlesPerProcess = numParticles / size;
693 *remainder = numParticles % size;
694
695 // Distribute the remainder particles to the first 'remainder' ranks
696 if (rank < *remainder) {
697 *particlesPerProcess += 1;
698 LOG_ALLOW_SYNC(GLOBAL,LOG_INFO,"DistributeParticles - Rank %d receives an extra particle. Total: %d\n", rank, *particlesPerProcess);
699 } else {
700 LOG_ALLOW_SYNC(GLOBAL,LOG_INFO, "DistributeParticles - Rank %d receives %d particles.\n", rank, *particlesPerProcess);
701 }
702
703 return 0;
704 }
Here is the caller graph for this function:

◆ FinalizeSwarmSetup()

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.

This function cleans up resources by destroying random number generators and LOG_ALLOWs the completion of swarm setup.

Parameters
[in]randxRandom number generator for the x-coordinate.
[in]randyRandom number generator for the y-coordinate.
[in]randzRandom number generator for the z-coordinate.
[in]rand_logic_iRandom number generator for the xi-coordinate.
[in]rand_logic_jRandom number generator for the eta-coordinate.
[in]rand_logic_kRandom number generator for the zeta-coordinate.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 720 of file ParticleSwarm.c.

720 {
721 PetscErrorCode ierr; // Error code for PETSc functions
722 PetscInt ParticleInitialization;
723
724 ierr = PetscOptionsGetInt(NULL, NULL, "-pinit", &ParticleInitialization, NULL); CHKERRQ(ierr);
725
726 // Destroy random number generators to free resources
727 // Physical space
728 ierr = PetscRandomDestroy(randx); CHKERRQ(ierr);
729 ierr = PetscRandomDestroy(randy); CHKERRQ(ierr);
730 ierr = PetscRandomDestroy(randz); CHKERRQ(ierr);
731
732 // Logical space
733 ierr = PetscRandomDestroy(rand_logic_i); CHKERRQ(ierr);
734 ierr = PetscRandomDestroy(rand_logic_j); CHKERRQ(ierr);
735 ierr = PetscRandomDestroy(rand_logic_k); CHKERRQ(ierr);
736
737 LOG_ALLOW(LOCAL,LOG_DEBUG,"FinalizeSwarmSetup - Destroyed all random number generators.\n");
738
739 return 0;
740 }
Here is the caller graph for this function:

◆ UnpackSwarmFields()

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.

This helper function populates a Particle structure using data retrieved from DMSwarm fields.

Parameters
[in]iIndex of the particle in the DMSwarm.
[in]PIDsPointer to the array of particle IDs.
[in]weightsPointer to the array of particle weights.
[in]positionsPointer to the array of particle positions.
[in]cellIndicesPointer to the array of particle cell indices.
[in]velocitiesPointer to the array of particle velocities.
[in]LocStatusPointer to the array of cell location status indicators.
[out]particlePointer to the Particle struct to initialize.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 837 of file ParticleSwarm.c.

839 {
840 PetscFunctionBeginUser;
841 PetscMPIInt rank;
842 PetscErrorCode ierr;
843
844 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
845
846 if (particle == NULL) {
847 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Output Particle pointer is NULL. \n");
848 }
849
850 // logging the start of particle initialization
851 LOG_ALLOW(LOCAL,LOG_INFO, "[Rank %d]Unpacking Particle [%d] with PID: %ld.\n",rank, i, PIDs[i]);
852
853 // Initialize PID
854 particle->PID = PIDs[i];
855 LOG_ALLOW(LOCAL,LOG_DEBUG, "[Rank %d]Particle [%d] PID set to: %ld.\n", rank,i, particle->PID);
856
857 // Initialize weights
858 particle->weights.x = weights[3 * i];
859 particle->weights.y = weights[3 * i + 1];
860 particle->weights.z = weights[3 * i + 2];
861 LOG_ALLOW(LOCAL,LOG_DEBUG, "[Rank %d]Particle [%d] weights set to: (%.6f, %.6f, %.6f).\n",
862 rank,i, particle->weights.x, particle->weights.y, particle->weights.z);
863
864 // Initialize locations
865 particle->loc.x = positions[3 * i];
866 particle->loc.y = positions[3 * i + 1];
867 particle->loc.z = positions[3 * i + 2];
868 LOG_ALLOW(LOCAL,LOG_DEBUG, "[Rank %d]Particle [%d] location set to: (%.6f, %.6f, %.6f).\n",
869 rank,i, particle->loc.x, particle->loc.y, particle->loc.z);
870
871 // Initialize velocities (assuming default zero; modify if necessary)
872 particle->vel.x = velocities[3 * i];
873 particle->vel.y = velocities[3 * i + 1];
874 particle->vel.z = velocities[3 * i + 2];
875 LOG_ALLOW(LOCAL,LOG_DEBUG,"[Rank %d]Particle [%d] velocities unpacked to: [%.6f,%.6f,%.6f].\n",rank, i,particle->vel.x,particle->vel.y,particle->vel.z);
876
877 // Initialize cell indices
878 particle->cell[0] = cellIndices[3 * i];
879 particle->cell[1] = cellIndices[3 * i + 1];
880 particle->cell[2] = cellIndices[3 * i + 2];
881 LOG_ALLOW(LOCAL,LOG_DEBUG,"[Rank %d]Particle [%d] cell indices set to: [%d, %d, %d].\n",rank,i, particle->cell[0], particle->cell[1], particle->cell[2]);
882
883 particle->location_status = (ParticleLocationStatus)LocStatus[i];
884 LOG_ALLOW(LOCAL,LOG_DEBUG, "[Rank %d]Particle [%d] Status set to: %d.\n",rank, i, particle->location_status);
885
886 // The destination_rank is only set by the location search, not read from the swarm,
887 // so we initialize it to a known invalid state.
888 particle->destination_rank = MPI_PROC_NULL;
889
890 // logging the completion of particle initialization
891 LOG_ALLOW(LOCAL,LOG_INFO,"[Rank %d]Completed initialization of Particle [%d]. \n", rank,i);
892
893 PetscFunctionReturn(0);
894 }
Cmpnts vel
Definition variables.h:168
PetscInt cell[3]
Definition variables.h:166
ParticleLocationStatus
Defines the state of a particle with respect to its location and migration status during the iterativ...
Definition variables.h:134
Cmpnts loc
Definition variables.h:167
PetscMPIInt destination_rank
Definition variables.h:171
ParticleLocationStatus location_status
Definition variables.h:170
Cmpnts weights
Definition variables.h:169
PetscInt64 PID
Definition variables.h:165
Here is the caller graph for this function:

◆ UpdateSwarmFields()

PetscErrorCode UpdateSwarmFields ( PetscInt  i,
const Particle particle,
PetscReal *  weights,
PetscInt *  cellIndices,
PetscInt *  status_field 
)

Updates DMSwarm fields with data from a Particle struct.

This helper function writes back the modified Particle data to the corresponding DMSwarm fields.

Parameters
[in]iIndex of the particle in the DMSwarm.
[in]particlePointer to the Particle struct containing updated data.
[in,out]weightsPointer to the array of particle weights.
[in,out]cellIndicesPointer to the array of particle cell indices.
[in,out]LocStatusPointer to the array of cell location status indicators.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.

Definition at line 909 of file ParticleSwarm.c.

910 {
911 PetscFunctionBeginUser;
912
913 if (particle == NULL) {
914 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Input Particle pointer is NULL.\n");
915 }
916
917 // logging the start of swarm fields update
918 LOG_ALLOW(LOCAL,LOG_INFO,"Updating DMSwarm fields for Particle [%d].\n", i);
919
920 // Update weights
921 weights[3 * i] = particle->weights.x;
922 weights[3 * i + 1] = particle->weights.y;
923 weights[3 * i + 2] = particle->weights.z;
924 LOG_ALLOW(LOCAL,LOG_DEBUG,"Updated weights for Particle [%d]: (%.6f, %.6f, %.6f).\n",
925 i, weights[3 * i], weights[3 * i + 1], weights[3 * i + 2]);
926
927 // Update cell indices
928 cellIndices[3 * i] = particle->cell[0];
929 cellIndices[3 * i + 1] = particle->cell[1];
930 cellIndices[3 * i + 2] = particle->cell[2];
931 LOG_ALLOW(LOCAL,LOG_DEBUG, "Updated cell indices for Particle [%d]: [%d, %d, %d].\n",
932 i, cellIndices[3 * i], cellIndices[3 * i + 1], cellIndices[3 * i + 2]);
933
934 status_field[i] = particle->location_status;
935 LOG_ALLOW(LOCAL,LOG_DEBUG, "Updated location status for Particle [%d]: [%d].\n",
936 i, status_field[i]);
937
938 // logging the completion of swarm fields update
939 LOG_ALLOW(LOCAL,LOG_INFO,"Completed updating DMSwarm fields for Particle [%d].\n", i);
940
941 PetscFunctionReturn(0);
942 }
Here is the caller graph for this function:

◆ IsParticleInsideBoundingBox()

PetscBool IsParticleInsideBoundingBox ( const BoundingBox bbox,
const Particle particle 
)

Checks if a particle's location is within a specified bounding box.

This function determines whether the given particle's location lies inside the provided bounding box. It performs an axis-aligned bounding box (AABB) check by comparing the particle's coordinates to the minimum and maximum coordinates of the bounding box in each dimension (x, y, z).

Logging statements are included to provide detailed information about the function's execution.

Parameters
[in]bboxPointer to the BoundingBox structure containing minimum and maximum coordinates.
[in]particlePointer to the Particle structure containing the particle's location and identifier.
Returns
PetscBool Returns PETSC_TRUE if the particle is inside the bounding box, PETSC_FALSE otherwise.
Note
  • The function assumes that the bbox and particle pointers are valid and non-NULL.
  • The function includes logging statements that start with the function name.
  • Be cautious when logging in performance-critical code sections, especially if the function is called frequently.

This function determines whether the given particle's location lies inside the provided bounding box. It performs an axis-aligned bounding box (AABB) check by comparing the particle's coordinates to the minimum and maximum coordinates of the bounding box in each dimension (x, y, z).

logging statements are included to provide detailed information about the function's execution.

Parameters
[in]bboxPointer to the BoundingBox structure containing minimum and maximum coordinates.
[in]particlePointer to the Particle structure containing the particle's location and identifier.
Returns
PetscBool Returns PETSC_TRUE if the particle is inside the bounding box, PETSC_FALSE otherwise.
Note
  • The function assumes that the bbox and particle pointers are valid and non-NULL.
  • The function includes logging statements that start with the function name.
  • The LOG_ALLOW_SCOPE variable is used to distinguish between GLOBAL and LOCAL LOG_ALLOW outputs.
  • Be cautious when logging in performance-critical code sections, especially if the function is called frequently.

Definition at line 964 of file ParticleSwarm.c.

965 {
966 // Function name for logging purposes
967 const char *funcName = "IsParticleInsideBoundingBox";
968
969 // Validate input pointers
970 if (!bbox) {
971 // LOG_ALLOW error message and return PETSC_FALSE
972 LOG_ALLOW(LOCAL,LOG_ERROR, "%s: Error - 'bbox' pointer is NULL.", funcName);
973 return PETSC_FALSE;
974 }
975 if (!particle) {
976 LOG_ALLOW(LOCAL,LOG_ERROR,"%s: Error - 'particle' pointer is NULL.", funcName);
977 return PETSC_FALSE;
978 }
979
980 // Extract particle location and bounding box coordinates
981 const Cmpnts loc = particle->loc;
982 const Cmpnts min_coords = bbox->min_coords;
983 const Cmpnts max_coords = bbox->max_coords;
984
985 // LOG_ALLOW the particle location and bounding box coordinates for debugging
986 LOG_ALLOW_SYNC(LOCAL, LOG_DEBUG, "%s: Particle PID %ld location: (%.6f, %.6f, %.6f).\n", funcName, particle->PID, loc.x, loc.y, loc.z);
987 LOG_ALLOW_SYNC(LOCAL, LOG_DEBUG, "%s: BoundingBox min_coords: (%.6f, %.6f, %.6f), max_coords: (%.6f, %.6f, %.6f).\n",
988 funcName, min_coords.x, min_coords.y, min_coords.z, max_coords.x, max_coords.y, max_coords.z);
989
990 // Check if the particle's location is within the bounding box
991 if ((loc.x >= min_coords.x && loc.x <= max_coords.x) &&
992 (loc.y >= min_coords.y && loc.y <= max_coords.y) &&
993 (loc.z >= min_coords.z && loc.z <= max_coords.z)) {
994 // Particle is inside the bounding box
995 LOG_ALLOW_SYNC(LOCAL,LOG_DEBUG, "%s: Particle PID %ld is inside the bounding box.\n", funcName, particle->PID);
996 return PETSC_TRUE;
997 }
998
999 // Particle is outside the bounding box
1000 LOG_ALLOW_SYNC(LOCAL, LOG_DEBUG,"%s: Particle PID %ld is outside the bounding box.\n", funcName, particle->PID);
1001 return PETSC_FALSE;
1002 }
A 3D point or vector with PetscScalar components.
Definition variables.h:99

◆ UpdateParticleWeights()

PetscErrorCode UpdateParticleWeights ( PetscReal *  d,
Particle particle 
)

Updates a particle's interpolation weights based on distances to cell faces.

This function computes interpolation weights using distances to the six cell faces (d) and updates the weight field of the provided particle.

Parameters
[in]dPointer to an array of distances to the six cell faces.
[out]particlePointer to the Particle structure whose weights are to be updated.
Returns
PetscErrorCode Returns 0 on success, or a non-zero error code on failure.

Definition at line 1015 of file ParticleSwarm.c.

1015 {
1016
1017 // Validate input pointers
1018 if (!d || !particle) {
1019 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
1020 "UpdateParticleWeights - Null pointer argument (d or particle).");
1021 }
1022
1023
1024 // Validate distances
1025 for (PetscInt i = LEFT; i < NUM_FACES; i++) {
1028 "UpdateParticleWeights - face distance d[%d] = %f <= %f; "
1029 "clamping to 1e-14 to avoid zero/negative.\n",
1030 i, (double)d[i], INTERPOLATION_DISTANCE_TOLERANCE);
1032 }
1033 }
1034
1035 // LOG_ALLOW the input distances
1037 "UpdateParticleWeights - Calculating weights with distances: "
1038 "[LEFT=%f, RIGHT=%f, BOTTOM=%f, TOP=%f, FRONT=%f, BACK=%f].\n",
1039 d[LEFT], d[RIGHT], d[BOTTOM], d[TOP], d[FRONT], d[BACK]);
1040
1041 // Compute and update the particle's weights
1042 particle->weights.x = d[LEFT] / (d[LEFT] + d[RIGHT]);
1043 particle->weights.y = d[BOTTOM] / (d[BOTTOM] + d[TOP]);
1044 particle->weights.z = d[BACK] / (d[FRONT] + d[BACK]);
1045
1046 // LOG_ALLOW the updated weights
1048 "UpdateParticleWeights - Updated particle weights: x=%f, y=%f, z=%f.\n",
1049 particle->weights.x, particle->weights.y, particle->weights.z);
1050
1051 return 0;
1052 }
#define INTERPOLATION_DISTANCE_TOLERANCE
@ TOP
Definition variables.h:144
@ FRONT
Definition variables.h:144
@ BOTTOM
Definition variables.h:144
@ BACK
Definition variables.h:144
@ LEFT
Definition variables.h:144
@ NUM_FACES
Definition variables.h:144
@ RIGHT
Definition variables.h:144
Here is the caller graph for this function:

◆ PrepareLoadedSwarmForRelocation()

PetscErrorCode PrepareLoadedSwarmForRelocation ( UserCtx user)

Resets the location-dependent state of a loaded swarm to force relocation.

This function is a critical part of the simulation restart procedure. It must be called immediately after ReadAllSwarmFields has populated a swarm from restart files. Its purpose is to invalidate the "location" state of the loaded particles, ensuring that the LocateAllParticlesInGrid_TEST orchestrator performs a fresh, comprehensive search for every particle based on its loaded position.

It does this by performing two actions on every locally-owned particle:

  1. It resets the DMSwarm_CellID field to a sentinel value of (-1, -1, -1). This invalidates any cell index that might have been loaded or defaulted to 0.
  2. It sets the DMSwarm_location_status field to NEEDS_LOCATION.

This guarantees that the location logic will not mistakenly use a stale cell index from a previous run and will instead use the robust "Guess -> Verify" strategy appropriate for particles with unknown locations.

Parameters
[in,out]userPointer to the UserCtx structure which contains the DMSwarm object that has just been loaded with data from restart files.
Returns
PetscErrorCode 0 on success, or a non-zero PETSc error code if field access fails.

Definition at line 1078 of file ParticleSwarm.c.

1079 {
1080 PetscErrorCode ierr;
1081 DM swarm;
1082 PetscInt n_local;
1083 PetscInt *cell_p; // Pointer to the raw data for the CellID field
1084 PetscInt *status_p; // Pointer to the raw data for the location_status field
1085 PetscInt64 *PIDs; // Pointer to the raw data for the Particle ID field.
1086 PetscMPIInt rank,size;
1087
1088 PetscFunctionBeginUser;
1089
1090 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
1091 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); CHKERRQ(ierr);
1092
1093 SimCtx *simCtx = user->simCtx;
1094
1095 // --- 1. Input Validation and Setup ---
1096 if (!user || !user->swarm) {
1097 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx or its DMSwarm is NULL in PrepareLoadedSwarmForRelocation.");
1098 }
1099 swarm = user->swarm;
1100
1101 // Get the number of particles on this MPI rank.
1102 ierr = DMSwarmGetLocalSize(swarm, &n_local); CHKERRQ(ierr);
1103
1104 // If there are no local particles, there is nothing to do.
1105 if (n_local == 0) {
1106 PetscFunctionReturn(0);
1107 }
1108
1109
1110 LOG_ALLOW(GLOBAL, LOG_INFO, "Preparing %d loaded particles for relocation by resetting their CellID and Status.\n", n_local);
1111
1112 // --- 2. Get Writable Access to Swarm Fields ---
1113 // This provides direct pointers to the underlying data arrays for the fields.
1114 ierr = DMSwarmGetField(swarm, "DMSwarm_CellID", NULL, NULL, (void**)&cell_p); CHKERRQ(ierr);
1115 ierr = DMSwarmGetField(swarm, "DMSwarm_location_status", NULL, NULL, (void**)&status_p); CHKERRQ(ierr);
1116 ierr = DMSwarmGetField(swarm, "DMSwarm_pid", NULL, NULL, (void**)&PIDs); CHKERRQ(ierr); CHKERRQ(ierr);
1117
1118 // --- 3. Determine Starting Global PID for this Rank ---
1119 PetscInt particles_per_rank_ideal = simCtx->np / size; // Assumes user->size is PETSC_COMM_WORLD size
1120 PetscInt remainder_particles = simCtx->np % size;
1121 PetscInt base_pid_for_rank = rank * particles_per_rank_ideal + PetscMin(rank, remainder_particles);
1122 // This calculation must match how particlesPerProcess was determined (e.g., in DistributeParticles).
1123
1124 // --- 4. Loop Through All Local Particles and Reset State ---
1125 for (PetscInt p = 0; p < n_local; ++p) {
1126
1127
1128 // Reset the 3 components of the cell index vector.
1129 cell_p[3*p + 0] = -1;
1130 cell_p[3*p + 1] = -1;
1131 cell_p[3*p + 2] = -1;
1132
1133 // Reset the status to ensure it will be processed by the location algorithm.
1135
1136 //set the PID for each particle
1137 PIDs[p] = (PetscInt64)base_pid_for_rank + p;
1138 }
1139
1140 // --- 4. Restore Fields ---
1141 // This returns control of the data arrays back to the DMSwarm. It is a mandatory
1142 // step to ensure data consistency and prevent memory issues.
1143 ierr = DMSwarmRestoreField(swarm, "DMSwarm_CellID", NULL, NULL, (void**)&cell_p); CHKERRQ(ierr);
1144 ierr = DMSwarmRestoreField(swarm, "DMSwarm_location_status", NULL, NULL, (void**)&status_p); CHKERRQ(ierr);
1145 ierr = DMSwarmRestoreField(swarm, "DMSwarm_pid", NULL, NULL, (void**)&PIDs); CHKERRQ(ierr); CHKERRQ(ierr);
1146
1147 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Successfully reset location state for all loaded particles.\n");
1148
1149 PetscFunctionReturn(0);
1150 }
@ UNINITIALIZED
Definition variables.h:139
PetscInt np
Definition variables.h:585
Here is the caller graph for this function:

◆ InitializeParticleSwarm()

PetscErrorCode InitializeParticleSwarm ( SimCtx simCtx)

Perform particle swarm initialization, particle-grid interaction, and related operations.

This function handles the following tasks:

  1. Initializes the particle swarm using the provided bounding box list (bboxlist) to determine initial placement if ParticleInitialization is 0.
  2. Locates particles within the computational grid.
  3. Updates particle positions based on grid interactions (if such logic exists elsewhere in the code).
  4. Interpolates particle velocities from grid points using trilinear interpolation.
Parameters
[in,out]userPointer to the UserCtx structure containing grid and particle swarm information.
[in]npNumber of particles to initialize in the swarm.
[in]bboxlistPointer to an array of BoundingBox structures, one per MPI rank.
Returns
PetscErrorCode Returns 0 on success, non-zero on failure.
Note
  • Ensure that np (number of particles) is positive.
  • The bboxlist array must be correctly computed and passed in before calling this function.
  • If ParticleInitialization == 0, particles will be placed at the midpoint of the local bounding box.

Definition at line 1174 of file ParticleSwarm.c.

1175 {
1176
1177 PetscErrorCode ierr;
1178 PetscInt particlesPerProcess = 0; // Number of particles assigned to the local MPI process.
1179 PetscRandom randx,randy,randz; // Random number generators[x,y,z]. (used if ParticleInitialization==1).
1180 PetscRandom rand_logic_i, rand_logic_j,rand_logic_k; // RNGs for Logical space.
1181 PetscInt start_step = simCtx->StartStep;
1182 PetscInt np = simCtx->np;
1183 BoundingBox *bboxlist = simCtx->bboxlist;
1184 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
1185
1186 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting particle swarm Initialization with %d particles.\n", np);
1187
1188 // Step 1: Create and initialize the particle swarm
1189 // Here we pass in the bboxlist, which will be used by CreateParticleSwarm() and subsequently
1190 // by AssignInitialProperties() to position particles if ParticleInitialization == 0.
1191 LOG_ALLOW(GLOBAL, LOG_INFO, "Creating particle swarm.\n");
1192 ierr = CreateParticleSwarm(user, np, &particlesPerProcess,bboxlist); CHKERRQ(ierr);
1193 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle swarm created successfully.\n");
1194
1195 ierr = PetscOptionsGetInt(NULL, NULL, "-rstart", &start_step, NULL); CHKERRQ(ierr);
1196
1197 if(start_step == 0){
1198
1199 // Create the RNGs
1200 LOG_ALLOW(LOCAL, LOG_DEBUG, "Initializing physical space RNGs.\n");
1201 ierr = InitializeRandomGenerators(user, &randx, &randy, &randz); CHKERRQ(ierr);
1202
1203 LOG_ALLOW(LOCAL, LOG_DEBUG, "Initializing logical space RNGs [0,1).\n");
1204 ierr = InitializeLogicalSpaceRNGs(&rand_logic_i, &rand_logic_j, &rand_logic_k); CHKERRQ(ierr);
1205 // Assign initial properties to particles
1206 // The bboxlist array is passed here so that if ParticleInitialization == 0,
1207 // particles can be placed at the midpoint of the local bounding box corresponding to this rank.
1208 ierr = AssignInitialPropertiesToSwarm(user, particlesPerProcess, &randx, &randy, &randz, &rand_logic_i,&rand_logic_j,&rand_logic_k,bboxlist); CHKERRQ(ierr);
1209 // Finalize swarm setup by destroying RNGs if ParticleInitialization == 1
1210 ierr = FinalizeSwarmSetup(&randx, &randy, &randz, &rand_logic_i, &rand_logic_j, &rand_logic_k); CHKERRQ(ierr);
1211
1212 // Ensure all ranks complete before proceeding
1213 LOG_ALLOW_SYNC(GLOBAL, LOG_INFO, " Particles generated & initialized.\n");
1214 }
1215
1216 else if (start_step > 0){
1217
1218 LOG_ALLOW(LOCAL,LOG_DEBUG," Particle Swarm status being set at restart [Step %d].\n",start_step);
1219
1220 ierr = PreCheckAndResizeSwarm(user,start_step,"dat");
1221
1222 // --- Read Particle Data (EVERY timestep) ---
1223 // ReadAllSwarmFields should read position and velocity for timestep 'ti'
1224
1225 ierr = ReadAllSwarmFields(user, start_step);
1226 if (ierr) {
1227 // Check if the error was specifically a file open error (missing file)
1228 if (ierr == PETSC_ERR_FILE_OPEN) {
1229 LOG_ALLOW(GLOBAL, LOG_WARNING, "Missing particle data file(s) for timestep %d. Skipping VTK output for this step.\n",(PetscInt)user->simCtx->step );
1230 } else {
1231 LOG_ALLOW(GLOBAL, LOG_ERROR, "Failed to read swarm fields for timestep %d (Error code: %d). Skipping VTK output for this step.\n",(PetscInt)user->simCtx->step , ierr);
1232 }
1233 }
1234
1235 // Ensure all the swarm fields not read from file are initialized.
1237
1238 // Ensure all ranks complete before proceeding
1239 LOG_ALLOW_SYNC(GLOBAL, LOG_INFO, " Particles generated & initialized.\n");
1240
1241
1242 }
1243 return 0;
1244 }
PetscErrorCode PreCheckAndResizeSwarm(UserCtx *user, PetscInt ti, const char *ext)
Checks particle count in the reference file and resizes the swarm if needed.
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 InitializeRandomGenerators(UserCtx *user, PetscRandom *randx, PetscRandom *randy, PetscRandom *randz)
Initializes random number generators for assigning particle properties.
PetscErrorCode PrepareLoadedSwarmForRelocation(UserCtx *user)
Resets the location-dependent state of a loaded swarm to force relocation.
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 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.
PetscErrorCode ReadAllSwarmFields(UserCtx *user, PetscInt ti)
Reads multiple fields (positions, velocity, CellID, and weight) into a DMSwarm.
Definition io.c:1100
UserCtx * user
Definition variables.h:418
UserMG usermg
Definition variables.h:599
PetscInt StartStep
Definition variables.h:523
BoundingBox * bboxlist
Definition variables.h:588
PetscInt mglevels
Definition variables.h:425
PetscInt step
Definition variables.h:521
MGCtx * mgctx
Definition variables.h:428
Defines a 3D axis-aligned bounding box.
Definition variables.h:153
User-defined context containing data specific to a single computational grid level.
Definition variables.h:630
Here is the call graph for this function:
Here is the caller graph for this function: