PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Macros | Functions
ParticlePhysics.c File Reference
#include "ParticlePhysics.h"
#include "verification_sources.h"
Include dependency graph for ParticlePhysics.c:

Go to the source code of this file.

Macros

#define ERROR_MSG_BUFFER_SIZE   256
 
#define __FUNCT__   "UpdateParticleField"
 
#define __FUNCT__   "UpdateFieldForAllParticles"
 
#define __FUNCT__   "UpdateAllParticleFields"
 

Functions

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().
 
PetscErrorCode UpdateFieldForAllParticles (UserCtx *user, ParticleFieldId field_id)
 Internal helper implementation: UpdateFieldForAllParticles().
 
PetscErrorCode UpdateAllParticleFields (UserCtx *user)
 Implementation of UpdateAllParticleFields().
 

Macro Definition Documentation

◆ ERROR_MSG_BUFFER_SIZE

#define ERROR_MSG_BUFFER_SIZE   256

Definition at line 5 of file ParticlePhysics.c.

◆ __FUNCT__ [1/3]

#define __FUNCT__   "UpdateParticleField"

Definition at line 9 of file ParticlePhysics.c.

◆ __FUNCT__ [2/3]

#define __FUNCT__   "UpdateFieldForAllParticles"

Definition at line 9 of file ParticlePhysics.c.

◆ __FUNCT__ [3/3]

#define __FUNCT__   "UpdateAllParticleFields"

Definition at line 9 of file ParticlePhysics.c.

Function Documentation

◆ UpdateParticleField()

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

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 
)

Internal helper implementation: UpdateFieldForAllParticles().

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 = user->simCtx->iem_constant;
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 // Cell IDs are 0-based geometric indices; cell-centred storage starts at index 1
105 // (index 0 is the boundary slot), the shift the scatter applies when it writes lPsi.
106 PetscInt i = cell_arr[3*p + 0] + 1;
107 PetscInt j = cell_arr[3*p + 1] + 1;
108 PetscInt k = cell_arr[3*p + 2] + 1;
109
110 p_diff = diff_arr[p];
111 p_mean = grid_mean[k][j][i];
112
113 // Aj is the reciprocal cell volume in the curvilinear-grid representation.
114 PetscReal jac = grid_aj[k][j][i];
115 p_vol = (jac > 1.0e-14) ? (1.0 / jac) : 1.0e-14;
116 }
117
118 ierr = UpdateParticleField(field_id, dt, &psi_arr[p], p_diff, p_mean, p_vol, C_IEM);
119 CHKERRQ(ierr);
120 }
121
122 ierr = DMSwarmRestoreField(swarm, fieldName, NULL, NULL, (void**)&psi_arr); CHKERRQ(ierr);
123
124 if (field_id == PARTICLE_FIELD_ID_PSI) {
125 ierr = DMSwarmRestoreField(swarm, ParticleFieldName(PARTICLE_FIELD_ID_DIFFUSIVITY), NULL, NULL, (void**)&diff_arr); CHKERRQ(ierr);
126 ierr = DMSwarmRestoreField(swarm, ParticleFieldName(PARTICLE_FIELD_ID_CELL_ID), NULL, NULL, (void**)&cell_arr); CHKERRQ(ierr);
127 }
128
129 if (accessed_eulerian) {
130 ierr = DMDAVecRestoreArrayRead(da, user->lPsi, &grid_mean); CHKERRQ(ierr);
131 ierr = DMDAVecRestoreArrayRead(da, user->lAj, &grid_aj); CHKERRQ(ierr);
132 }
133
134 LOG_ALLOW(GLOBAL, LOG_INFO, "Updated particle physics for field '%s'.\n", fieldName);
135
137 PetscFunctionReturn(0);
138}
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:894
@ 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:885
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:1077
PetscReal iem_constant
IEM mixing constant C_IEM in Omega = C_IEM Gamma / Delta^2 (default 2.0).
Definition variables.h:949
PetscReal dt
Definition variables.h:874
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateAllParticleFields()

PetscErrorCode UpdateAllParticleFields ( UserCtx *  user)

Implementation of UpdateAllParticleFields().

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 148 of file ParticlePhysics.c.

149{
150 PetscErrorCode ierr;
151 PetscFunctionBeginUser;
153
154 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating all particle physical properties...\n");
155
157 // Verification profiles define Psi exactly, so bypass the model-driven update.
158 ierr = ApplyVerificationScalarOverrideToParticles(user); CHKERRQ(ierr);
159 LOG_ALLOW(GLOBAL, LOG_INFO, "Verification scalar override active; skipped model-driven Psi update.\n");
161 PetscFunctionReturn(0);
162 }
163
164 /* C_IEM = 0 switches micromixing off. The update is skipped rather than run with a
165 * zero rate: mean + (psi - mean) * 1 need not round-trip to psi exactly, and a passive
166 * label must stay bit-identical. */
167 if (user->simCtx->iem_constant == 0.0) {
168 LOG_ALLOW(GLOBAL, LOG_INFO, "IEM constant is zero; Psi is carried unchanged.\n");
169 } else {
170 ierr = UpdateFieldForAllParticles(user, PARTICLE_FIELD_ID_PSI); CHKERRQ(ierr);
171 }
172
173 LOG_ALLOW(GLOBAL, LOG_INFO, "All particle physical properties updated.\n");
174
176 PetscFunctionReturn(0);
177}
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: