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

Header file for Particle related physics modules. More...

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

Go to the source code of this file.

Functions

PetscErrorCode UpdateParticleField (ParticleFieldId field_id, PetscReal dt, PetscReal *psi_io, PetscReal diffusivity, PetscReal mean_val, PetscReal cell_vol, PetscReal C_model)
 Updates a single particle's field based on its state and physics model.
 
PetscErrorCode UpdateFieldForAllParticles (UserCtx *user, ParticleFieldId field_id)
 Loops over all local particles and updates a specified field.
 
PetscErrorCode UpdateAllParticleFields (UserCtx *user)
 Orchestrates the update of all physical properties for particles.
 

Detailed Description

Header file for Particle related physics modules.

This file contains declarations of functions responsible for solving for fields in the particle swarms within a simulation using PETSc's DMSwarm.

Definition in file ParticlePhysics.h.

Function Documentation

◆ UpdateParticleField()

PetscErrorCode UpdateParticleField ( ParticleFieldId  field_id,
PetscReal  dt,
PetscReal *  psi_io,
PetscReal  diffusivity,
PetscReal  mean_val,
PetscReal  cell_vol,
PetscReal  C_model 
)

Updates a single particle's field based on its state and physics model.

Implements the IEM (Interaction by Exchange with the Mean) model for scalar mixing. Physics: dPsi/dt = -Omega * (Psi - Psi_mean) Solution: Psi_new = Psi_mean + (Psi_old - Psi_mean) * exp(-Omega * dt)

Parameters
field_idTyped particle-field identity.
dtTime
psi_ioPointer
diffusivityParticle
mean_valLocal
cell_volVolume
C_modelModel
Returns
PetscErrorCode 0 on success.

Updates a single particle's field based on its state and physics model.

Local to this translation unit.

Definition at line 14 of file ParticlePhysics.c.

21{
22 PetscFunctionBeginUser;
23
24 if (field_id == PARTICLE_FIELD_ID_PSI) {
25 // Guard the LES mixing time scale against degenerate or cut-cell volumes.
26 if (cell_vol < 1.0e-14) cell_vol = 1.0e-14;
27
28 // The IEM model relaxes Psi exponentially toward the cell mean over dt.
29 PetscReal delta2 = PetscPowReal(cell_vol, 0.6666667);
30 PetscReal omega = C_model * diffusivity / delta2;
31 PetscReal decay = PetscExpReal(-omega * dt);
32
33 PetscReal psi_old = *psi_io;
34 *psi_io = mean_val + (psi_old - mean_val) * decay;
35 }
36
37 PetscFunctionReturn(0);
38}
@ PARTICLE_FIELD_ID_PSI
Here is the caller graph for this function:

◆ UpdateFieldForAllParticles()

PetscErrorCode UpdateFieldForAllParticles ( UserCtx user,
ParticleFieldId  field_id 
)

Loops over all local particles and updates a specified field.

This function orchestrates the update of a single particle field across the entire local swarm. It gets access to the necessary particle data arrays and calls the UpdateParticleField kernel for each particle.

Parameters
[in,out]userPointer to the UserCtx containing the swarm and simulation context.
[in]field_idTyped identity of the field to update.
Returns
PetscErrorCode 0 on success.

Loops over all local particles and updates a specified field.

Local to this translation unit.

Definition at line 46 of file ParticlePhysics.c.

47{
48 PetscErrorCode ierr;
49 DM swarm = user->swarm;
50 DM da = user->da;
51 PetscInt n_local;
52 PetscReal dt = user->simCtx->dt;
53 PetscReal C_IEM = 2.0;
54
55 PetscReal *psi_arr = NULL;
56 PetscReal *diff_arr = NULL;
57 PetscInt *cell_arr = NULL;
58
59 PetscReal ***grid_mean = NULL;
60 PetscReal ***grid_aj = NULL;
61
62 PetscBool accessed_eulerian = PETSC_FALSE;
63 const ParticleFieldDescriptor *descriptor = NULL;
64 const char *fieldName = NULL;
65
66 PetscFunctionBeginUser;
68
69 ierr = ParticleFieldGetDescriptor(field_id, &descriptor); CHKERRQ(ierr);
70 PetscCheck((descriptor->capabilities & PARTICLE_FIELD_CAPABILITY_MODEL_UPDATE) != 0,
71 PETSC_COMM_SELF, PETSC_ERR_SUP,
72 "Particle field '%s' has no registered model-update kernel.",
73 descriptor->canonical_name);
74 fieldName = descriptor->canonical_name;
75
76 ierr = DMSwarmGetLocalSize(swarm, &n_local); CHKERRQ(ierr);
77 if (n_local == 0) {
79 PetscFunctionReturn(0);
80 }
81
82 ierr = DMSwarmGetField(swarm, fieldName, NULL, NULL, (void**)&psi_arr); CHKERRQ(ierr);
83
84 if (field_id == PARTICLE_FIELD_ID_PSI) {
85 ierr = DMSwarmGetField(swarm, ParticleFieldName(PARTICLE_FIELD_ID_DIFFUSIVITY), NULL, NULL, (void**)&diff_arr); CHKERRQ(ierr);
86 ierr = DMSwarmGetField(swarm, ParticleFieldName(PARTICLE_FIELD_ID_CELL_ID), NULL, NULL, (void**)&cell_arr); CHKERRQ(ierr);
87
88 // Psi relaxation requires ghosted Eulerian mean and Jacobian fields.
89 if (!user->lPsi || !user->lAj) {
90 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "UserCtx lPsi or lAj not initialized.");
91 }
92
93 ierr = DMDAVecGetArrayRead(da, user->lPsi, &grid_mean); CHKERRQ(ierr);
94 ierr = DMDAVecGetArrayRead(da, user->lAj, &grid_aj); CHKERRQ(ierr);
95 accessed_eulerian = PETSC_TRUE;
96 }
97
98 for (PetscInt p = 0; p < n_local; ++p) {
99 PetscReal p_diff = 0.0;
100 PetscReal p_mean = 0.0;
101 PetscReal p_vol = 1.0;
102
103 if (field_id == PARTICLE_FIELD_ID_PSI) {
104 PetscInt i = cell_arr[3*p + 0];
105 PetscInt j = cell_arr[3*p + 1];
106 PetscInt k = cell_arr[3*p + 2];
107
108 p_diff = diff_arr[p];
109 p_mean = grid_mean[k][j][i];
110
111 // Aj is the reciprocal cell volume in the curvilinear-grid representation.
112 PetscReal jac = grid_aj[k][j][i];
113 p_vol = (jac > 1.0e-14) ? (1.0 / jac) : 1.0e-14;
114 }
115
116 ierr = UpdateParticleField(field_id, dt, &psi_arr[p], p_diff, p_mean, p_vol, C_IEM);
117 CHKERRQ(ierr);
118 }
119
120 ierr = DMSwarmRestoreField(swarm, fieldName, NULL, NULL, (void**)&psi_arr); CHKERRQ(ierr);
121
122 if (field_id == PARTICLE_FIELD_ID_PSI) {
123 ierr = DMSwarmRestoreField(swarm, ParticleFieldName(PARTICLE_FIELD_ID_DIFFUSIVITY), NULL, NULL, (void**)&diff_arr); CHKERRQ(ierr);
124 ierr = DMSwarmRestoreField(swarm, ParticleFieldName(PARTICLE_FIELD_ID_CELL_ID), NULL, NULL, (void**)&cell_arr); CHKERRQ(ierr);
125 }
126
127 if (accessed_eulerian) {
128 ierr = DMDAVecRestoreArrayRead(da, user->lPsi, &grid_mean); CHKERRQ(ierr);
129 ierr = DMDAVecRestoreArrayRead(da, user->lAj, &grid_aj); CHKERRQ(ierr);
130 }
131
132 LOG_ALLOW(GLOBAL, LOG_INFO, "Updated particle physics for field '%s'.\n", fieldName);
133
135 PetscFunctionReturn(0);
136}
PetscErrorCode UpdateParticleField(ParticleFieldId field_id, PetscReal dt, PetscReal *psi_io, PetscReal diffusivity, PetscReal mean_val, PetscReal cell_vol, PetscReal C_model)
Internal helper implementation: UpdateParticleField().
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:46
#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:200
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:859
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:31
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:850
const char * ParticleFieldName(ParticleFieldId field_id)
Return the canonical PETSc DMSwarm name for an ID.
@ PARTICLE_FIELD_ID_CELL_ID
@ PARTICLE_FIELD_ID_DIFFUSIVITY
@ PARTICLE_FIELD_CAPABILITY_MODEL_UPDATE
PetscErrorCode ParticleFieldGetDescriptor(ParticleFieldId field_id, const ParticleFieldDescriptor **descriptor)
Return immutable metadata for a valid particle field ID.
Immutable metadata for one persistent particle field.
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:909
PetscReal dt
Definition variables.h:710
Vec lPsi
Definition variables.h:997
Vec lAj
Definition variables.h:974
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateAllParticleFields()

PetscErrorCode UpdateAllParticleFields ( UserCtx user)

Orchestrates the update of all physical properties for particles.

This function serves as the top-level entry point for updating particle-specific physical quantities after their position and the surrounding fluid velocity are known. It calls a sequence of more specific update routines for each property.

For example, it can be configured to update:

Parameters
[in,out]userPointer to the UserCtx containing the swarm and simulation context.
Returns
PetscErrorCode 0 on success.

Orchestrates the update of all physical properties for particles.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/ParticlePhysics.h.

See also
UpdateAllParticleFields()

Definition at line 146 of file ParticlePhysics.c.

147{
148 PetscErrorCode ierr;
149 PetscFunctionBeginUser;
151
152 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating all particle physical properties...\n");
153
155 // Verification profiles define Psi exactly, so bypass the model-driven update.
156 ierr = ApplyVerificationScalarOverrideToParticles(user); CHKERRQ(ierr);
157 LOG_ALLOW(GLOBAL, LOG_INFO, "Verification scalar override active; skipped model-driven Psi update.\n");
159 PetscFunctionReturn(0);
160 }
161
162 ierr = UpdateFieldForAllParticles(user, PARTICLE_FIELD_ID_PSI); CHKERRQ(ierr);
163
164 LOG_ALLOW(GLOBAL, LOG_INFO, "All particle physical properties updated.\n");
165
167 PetscFunctionReturn(0);
168}
PetscErrorCode UpdateFieldForAllParticles(UserCtx *user, ParticleFieldId field_id)
Internal helper implementation: UpdateFieldForAllParticles().
PetscErrorCode ApplyVerificationScalarOverrideToParticles(UserCtx *user)
Populates the particle Psi field from a verification-only source override.
PetscBool VerificationScalarOverrideActive(const SimCtx *simCtx)
Reports whether a verification-only scalar override is active.
Here is the call graph for this function:
Here is the caller graph for this function: