PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
verification_sources.c
Go to the documentation of this file.
2
3#include "expression.h"
4#include "logging.h"
5#include "setup.h"
6
7/** @brief Names a verification field's expression reads, in the order of its values. */
8static const char *const kVerificationVariableNames[4] = {"x", "y", "z", "t"};
9
10/**
11 * @brief Compiles a verification field's expression and enables the field.
12 * @details See `include/verification_sources.h` for the public parameter and return contract.
13 */
14PetscErrorCode VerificationFieldCompile(const char *text, VerificationFieldConfig *field)
15{
16 PetscFunctionBeginUser;
18 PetscCall(PicurvExpressionDestroy(&field->expression));
19 PetscCall(PicurvExpressionCompile(text, kVerificationVariableNames, 4, PETSC_FALSE, &field->expression));
21 PetscFunctionReturn(0);
22}
23
24/**
25 * @brief Reads and compiles the configured verification fields.
26 * @details See `include/verification_sources.h` for the public parameter and return contract.
27 */
28PetscErrorCode VerificationFieldsCreate(SimCtx *simCtx)
29{
30 char text[4096];
31 PetscBool found = PETSC_FALSE;
32
33 PetscFunctionBeginUser;
35 PetscCall(PetscOptionsGetString(NULL, NULL, "-verification_diffusivity_expr", text, sizeof(text), &found));
36 if (found) PetscCall(VerificationFieldCompile(text, &simCtx->verificationDiffusivity));
37 PetscCall(PetscOptionsGetString(NULL, NULL, "-verification_scalar_expr", text, sizeof(text), &found));
38 if (found) PetscCall(VerificationFieldCompile(text, &simCtx->verificationScalar));
39 PetscCheck(!simCtx->verificationDiffusivity.expression || strcmp(simCtx->eulerianSource, "analytical") == 0,
40 PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
41 "verification diffusivity overrides require -euler_field_source \"analytical\".");
42 PetscCheck(!simCtx->verificationScalar.expression || strcmp(simCtx->eulerianSource, "analytical") == 0,
43 PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
44 "verification scalar overrides require -euler_field_source \"analytical\".");
46 PetscFunctionReturn(0);
47}
48
49/**
50 * @brief Releases the compiled verification fields.
51 * @details See `include/verification_sources.h` for the public parameter and return contract.
52 */
53PetscErrorCode VerificationFieldsDestroy(SimCtx *simCtx)
54{
55 PetscFunctionBeginUser;
60 PetscFunctionReturn(0);
61}
62
63/**
64 * @brief Evaluates a verification field at a solver-unit point and time.
65 * @details See `include/verification_sources.h` for the public parameter and return contract.
66 */
67PetscErrorCode VerificationFieldEvaluate(const SimCtx *simCtx, const VerificationFieldConfig *field, Cmpnts point,
68 PetscReal solver_time, PetscReal *value)
69{
70 const PetscReal L_ref = simCtx->scaling.L_ref;
71 PetscReal values[4] = {point.x * L_ref, point.y * L_ref, point.z * L_ref, 0.0};
72
73 PetscFunctionBeginUser;
75 PetscCall(PicurvPhysicalTime(simCtx, solver_time, &values[3]));
76 PetscCall(PicurvExpressionEvaluate(field->expression, values, NULL, value));
78 PetscFunctionReturn(0);
79}
80
81/**
82 * @brief Reports whether the verification-only diffusivity override is enabled.
83 * @details See `include/verification_sources.h` for the public parameter and return contract.
84 */
86{
88 const PetscBool active = (PetscBool)(simCtx && simCtx->verificationDiffusivity.expression);
90 return active;
91}
92
93/**
94 * @brief Reports whether the verification-only scalar override is enabled.
95 * @details See `include/verification_sources.h` for the public parameter and return contract.
96 */
98{
100 const PetscBool active = (PetscBool)(simCtx && simCtx->verificationScalar.expression);
102 return active;
103}
104
105/**
106 * @brief Fills the Eulerian diffusivity field from the configured verification profile.
107 * @details See `include/verification_sources.h` for the public parameter and return contract.
108 */
110{
111 PetscErrorCode ierr;
112 SimCtx *simCtx = user->simCtx;
113 PetscReal ***diff_arr = NULL;
114 const Cmpnts ***cent = NULL;
115 DMDALocalInfo info = user->info;
116 PetscReal min_gamma = PETSC_MAX_REAL;
117
118 PetscFunctionBeginUser;
120
121 // Leave the production diffusivity untouched unless this verification mode is selected.
122 if (!VerificationDiffusivityOverrideActive(simCtx)) { PROFILE_HELPER_END; PetscFunctionReturn(0); }
123
124 ierr = DMDAVecGetArray(user->da, user->Diffusivity, &diff_arr); CHKERRQ(ierr);
125 ierr = DMDAVecGetArrayRead(user->fda, user->Cent, &cent); CHKERRQ(ierr);
126
127 for (PetscInt k = info.zs; k < info.zs + info.zm; ++k) {
128 for (PetscInt j = info.ys; j < info.ys + info.ym; ++j) {
129 for (PetscInt i = info.xs; i < info.xs + info.xm; ++i) {
130 PetscReal gamma;
131 ierr = VerificationFieldEvaluate(simCtx, &simCtx->verificationDiffusivity, cent[k][j][i], simCtx->ti, &gamma); CHKERRQ(ierr);
132 gamma /= simCtx->scaling.U_ref * simCtx->scaling.L_ref;
133 diff_arr[k][j][i] = gamma;
134 min_gamma = PetscMin(min_gamma, gamma);
135 }
136 }
137 }
138
139 ierr = DMDAVecRestoreArrayRead(user->fda, user->Cent, &cent); CHKERRQ(ierr);
140 ierr = DMDAVecRestoreArray(user->da, user->Diffusivity, &diff_arr); CHKERRQ(ierr);
141
142 {
143 PetscReal global_min_gamma = 0.0;
144 ierr = MPI_Allreduce(&min_gamma, &global_min_gamma, 1, MPIU_REAL, MPI_MIN, PETSC_COMM_WORLD); CHKERRMPI(ierr);
145 // Diffusivity must remain positive on every rank for the PDE operator to be valid.
146 if (global_min_gamma <= 0.0) {
147 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
148 "verification diffusivity override produced non-positive Gamma values (min=%g).",
149 (double)global_min_gamma);
150 }
151 }
152
153 {
154 const FieldId periodic_fields[] = {FIELD_ID_DIFFUSIVITY};
155 // Make the analytic field coherent across periodic seams before ghost updates.
156 ierr = SynchronizePeriodicCellFields(user, 1, periodic_fields); CHKERRQ(ierr);
157 ierr = UpdateLocalGhosts(user, FIELD_ID_DIFFUSIVITY); CHKERRQ(ierr);
158 }
159 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Applied the verification diffusivity.\n");
160
162 PetscFunctionReturn(0);
163}
164
165/**
166 * @brief Fills the particle `Psi` field from the configured verification scalar profile.
167 * @details See `include/verification_sources.h` for the public parameter and return contract.
168 */
170{
171 PetscFunctionBeginUser;
173 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx cannot be NULL.");
174 // The normal particle model owns Psi unless the verification override is enabled.
175 if (!VerificationScalarOverrideActive(user->simCtx)) { PROFILE_HELPER_END; PetscFunctionReturn(0); }
176
178 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Applied the verification scalar to particle field Psi.\n");
180 PetscFunctionReturn(0);
181}
182
183/**
184 * @brief Implementation of \ref SetVerificationScalarOnParticles().
185 * @details Full API contract (arguments, ownership, side effects) is documented with
186 * the header declaration in `include/verification_sources.h`.
187 * @see SetVerificationScalarOnParticles()
188 */
189PetscErrorCode SetVerificationScalarOnParticles(UserCtx *user, ParticleFieldId particle_field_id)
190{
191 PetscErrorCode ierr;
192 PetscInt nlocal = 0;
193 PetscReal *positions = NULL;
194 PetscReal *scalar_values = NULL;
195 const ParticleFieldDescriptor *descriptor = NULL;
196 const char *swarm_field_name = NULL;
197
198 PetscFunctionBeginUser;
200 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx cannot be NULL.");
201 if (!user->swarm) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "UserCtx->swarm is NULL.");
202
203 ierr = ParticleFieldGetDescriptor(particle_field_id, &descriptor); CHKERRQ(ierr);
204 PetscCheck(descriptor->components == 1 && descriptor->data_type == PETSC_REAL,
205 PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP,
206 "Verification scalar assignment requires a one-component PETSC_REAL particle field; '%s' has %" PetscInt_FMT " components and type %s.",
207 descriptor->canonical_name, descriptor->components, PetscDataTypes[descriptor->data_type]);
208 swarm_field_name = descriptor->canonical_name;
209
210 ierr = DMSwarmGetLocalSize(user->swarm, &nlocal); CHKERRQ(ierr);
211 if (nlocal == 0) { PROFILE_HELPER_END; PetscFunctionReturn(0); }
212
213 ierr = DMSwarmGetField(user->swarm, ParticleFieldName(PARTICLE_FIELD_ID_POSITION), NULL, NULL, (void **)&positions); CHKERRQ(ierr);
214 ierr = DMSwarmGetField(user->swarm, swarm_field_name, NULL, NULL, (void **)&scalar_values); CHKERRQ(ierr);
215
216 for (PetscInt p = 0; p < nlocal; ++p) {
217 PetscReal value = 0.0;
218 const Cmpnts point = {positions[3 * p + 0], positions[3 * p + 1], positions[3 * p + 2]};
219 ierr = VerificationFieldEvaluate(user->simCtx, &user->simCtx->verificationScalar, point, user->simCtx->ti, &value); CHKERRQ(ierr);
220 scalar_values[p] = value;
221 }
222
223 ierr = DMSwarmRestoreField(user->swarm, swarm_field_name, NULL, NULL, (void **)&scalar_values); CHKERRQ(ierr);
224 ierr = DMSwarmRestoreField(user->swarm, ParticleFieldName(PARTICLE_FIELD_ID_POSITION), NULL, NULL, (void **)&positions); CHKERRQ(ierr);
226 PetscFunctionReturn(0);
227}
228
229/**
230 * @brief Implementation of \ref SetVerificationScalarAtCellCenters().
231 * @details Full API contract (arguments, ownership, side effects) is documented with
232 * the header declaration in `include/verification_sources.h`.
233 * @see SetVerificationScalarAtCellCenters()
234 */
235PetscErrorCode SetVerificationScalarAtCellCenters(UserCtx *user, Vec targetVec)
236{
237 PetscErrorCode ierr;
238 PetscReal ***target = NULL;
239 const Cmpnts ***cent = NULL;
240 DMDALocalInfo info;
241 PetscInt xs, xe, ys, ye, zs, ze, mx, my, mz;
242 PetscInt lxs, lxe, lys, lye, lzs, lze;
243
244 PetscFunctionBeginUser;
246 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx cannot be NULL.");
247 if (!targetVec) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "targetVec cannot be NULL.");
248
249 info = user->info;
250 xs = info.xs; xe = info.xs + info.xm;
251 ys = info.ys; ye = info.ys + info.ym;
252 zs = info.zs; ze = info.zs + info.zm;
253 mx = info.mx; my = info.my; mz = info.mz;
254 lxs = (xs == 0) ? xs + 1 : xs; lxe = (xe == mx) ? xe - 1 : xe;
255 lys = (ys == 0) ? ys + 1 : ys; lye = (ye == my) ? ye - 1 : ye;
256 lzs = (zs == 0) ? zs + 1 : zs; lze = (ze == mz) ? ze - 1 : ze;
257
258 ierr = VecSet(targetVec, 0.0); CHKERRQ(ierr);
259 ierr = DMDAVecGetArray(user->da, targetVec, &target); CHKERRQ(ierr);
260 ierr = DMDAVecGetArrayRead(user->fda, user->Cent, &cent); CHKERRQ(ierr);
261
262 for (PetscInt k = lzs; k < lze; ++k) {
263 for (PetscInt j = lys; j < lye; ++j) {
264 for (PetscInt i = lxs; i < lxe; ++i) {
265 PetscReal value = 0.0;
266 ierr = VerificationFieldEvaluate(user->simCtx, &user->simCtx->verificationScalar, cent[k][j][i], user->simCtx->ti, &value); CHKERRQ(ierr);
267 target[k][j][i] = value;
268 }
269 }
270 }
271
272 ierr = DMDAVecRestoreArrayRead(user->fda, user->Cent, &cent); CHKERRQ(ierr);
273 ierr = DMDAVecRestoreArray(user->da, targetVec, &target); CHKERRQ(ierr);
275 PetscFunctionReturn(0);
276}
PetscErrorCode SynchronizePeriodicCellFields(UserCtx *user, PetscInt num_fields, const FieldId field_ids[])
Synchronizes periodic endpoint cells for a list of cell-centered fields.
The expression language shared by every configured field, the keyed hashes its random draws and other...
PetscErrorCode PicurvExpressionEvaluate(const PicurvExpression *expression, const PetscReal *values, const PicurvExpressionDrawKey *key, PetscReal *result)
Evaluate a compiled expression.
Definition expression.c:724
PetscErrorCode PicurvExpressionDestroy(PicurvExpression **expression)
Free a compiled expression.
Definition expression.c:818
PetscErrorCode PicurvExpressionCompile(const char *text, const char *const *names, PetscInt name_count, PetscBool allow_random, PicurvExpression **expression)
Compile one expression against a list of variable names.
Definition expression.c:551
FieldId
Compile-time identity for a catalogued Eulerian field.
@ FIELD_ID_DIFFUSIVITY
PetscErrorCode PicurvPhysicalTime(const SimCtx *simCtx, PetscReal solver_time, PetscReal *physical)
Convert a solver time to physical seconds, t * L_ref / U_ref.
Definition io.c:2986
Logging utilities and macros for PETSc-based applications.
#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:214
#define PROFILE_HELPER_BEGIN
Marks the beginning of a profiled helper: timed only when enabled by name.
Definition logging.h:1014
#define PROFILE_HELPER_END
Alias of PROFILE_FUNCTION_END for a function that began with PROFILE_HELPER_BEGIN.
Definition logging.h:1033
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:1029
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:32
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled function: an always-on aggregate timer.
Definition logging.h:1000
const char * ParticleFieldName(ParticleFieldId field_id)
Return the canonical PETSc DMSwarm name for an ID.
ParticleFieldId
Compile-time identity for a persistent solver-particle field.
@ PARTICLE_FIELD_ID_POSITION
@ PARTICLE_FIELD_ID_PSI
PetscErrorCode ParticleFieldGetDescriptor(ParticleFieldId field_id, const ParticleFieldDescriptor **descriptor)
Return immutable metadata for a valid particle field ID.
Immutable metadata for one persistent particle field.
PetscErrorCode UpdateLocalGhosts(UserCtx *user, FieldId field_id)
Updates the local vector (including ghost points) from its corresponding global vector.
Definition setup.c:2587
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:1138
PetscReal L_ref
Definition variables.h:878
PetscScalar x
Definition variables.h:145
struct PicurvExpression * expression
Compiled expression, or NULL when the field is not configured.
Definition variables.h:276
VerificationFieldConfig verificationDiffusivity
Definition variables.h:974
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:918
PetscScalar z
Definition variables.h:145
ScalingCtx scaling
Definition variables.h:981
Vec Diffusivity
Definition variables.h:1178
DMDALocalInfo info
Definition variables.h:1147
PetscScalar y
Definition variables.h:145
PetscReal ti
Definition variables.h:905
PetscReal U_ref
Definition variables.h:879
VerificationFieldConfig verificationScalar
Definition variables.h:975
A 3D point or vector with PetscScalar components.
Definition variables.h:144
The master context for the entire simulation.
Definition variables.h:896
User-defined context containing data specific to a single computational grid level.
Definition variables.h:1135
A verification-only prescribed field: an expression in physical x, y, z and t, enabled when set.
Definition variables.h:275
PetscErrorCode VerificationFieldCompile(const char *text, VerificationFieldConfig *field)
Compiles a verification field's expression and enables the field.
PetscErrorCode ApplyVerificationDiffusivityOverride(UserCtx *user)
Fills the Eulerian diffusivity field from the configured verification profile.
PetscErrorCode SetVerificationScalarOnParticles(UserCtx *user, ParticleFieldId particle_field_id)
Implementation of SetVerificationScalarOnParticles().
static const char *const kVerificationVariableNames[4]
Names a verification field's expression reads, in the order of its values.
PetscBool VerificationDiffusivityOverrideActive(const SimCtx *simCtx)
Reports whether the verification-only diffusivity override is enabled.
PetscErrorCode VerificationFieldsCreate(SimCtx *simCtx)
Reads and compiles the configured verification fields.
PetscErrorCode ApplyVerificationScalarOverrideToParticles(UserCtx *user)
Fills the particle Psi field from the configured verification scalar profile.
PetscBool VerificationScalarOverrideActive(const SimCtx *simCtx)
Reports whether the verification-only scalar override is enabled.
PetscErrorCode VerificationFieldEvaluate(const SimCtx *simCtx, const VerificationFieldConfig *field, Cmpnts point, PetscReal solver_time, PetscReal *value)
Evaluates a verification field at a solver-unit point and time.
PetscErrorCode VerificationFieldsDestroy(SimCtx *simCtx)
Releases the compiled verification fields.
PetscErrorCode SetVerificationScalarAtCellCenters(UserCtx *user, Vec targetVec)
Implementation of SetVerificationScalarAtCellCenters().