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

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 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: