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

C unit tests for solver-side analytical and LES helper kernels. More...

#include "test_support.h"
#include "AnalyticalSolutions.h"
#include "BodyForces.h"
#include "Filter.h"
#include "les.h"
#include "solvers.h"
#include "momentumsolvers.h"
Include dependency graph for test_solver_kernels.c:

Go to the source code of this file.

Functions

static PetscErrorCode TestLESTestFilterPaths (void)
 Tests LES test-filter helper paths for representative cases.
 
static PetscErrorCode TestAnalyticalGeometrySelection (void)
 Tests analytical geometry selection for supported analytical solutions.
 
static PetscErrorCode TestAnalyticalScalarVerificationHelpers (void)
 Tests analytical scalar verification helper routines.
 
static PetscErrorCode TestAnalyticalSolutionEngineDispatch (void)
 Tests analytical solution engine ZERO_FLOW, UNIFORM_FLOW, and unknown-type dispatch.
 
static PetscErrorCode TestAnalyticalSolutionEngineTaylorGreenSamples (void)
 Tests exact Taylor-Green samples on selected Eulerian interior and boundary points.
 
static PetscErrorCode TestAnalyticalSolutionForParticlesDispatch (void)
 Tests particle analytical-solution dispatch for TGV3D, UNIFORM_FLOW, and non-analytical no-op paths.
 
static PetscErrorCode TestComputeEddyViscosityLESDeterministicField (void)
 Tests deterministic LES eddy-viscosity computation on a linear velocity field.
 
static PetscErrorCode TestFlowSolverRejectsUnsupportedMomentumSolverType (void)
 Tests FlowSolver guardrails for unsupported momentum solver selections.
 
static PetscErrorCode TestDrivenChannelFlowSource (void)
 Tests driven-channel flow source-term evaluation.
 
static void MomSetAllBC (UserCtx *user, BCType t)
 Sets the mathematical BC type on all six faces of a test UserCtx.
 
static PetscErrorCode MomFillLocalCmpnts (DM fda, Vec lvec, PetscReal x, PetscReal y, PetscReal z)
 Fills a local Cmpnts vector (ghosts included) with a uniform vector value.
 
static PetscErrorCode MomFillLocalScalar (DM da, Vec lvec, PetscReal v)
 Fills a local scalar vector (ghosts included) with a uniform value.
 
static PetscErrorCode MomSetLocalScalarCell (DM da, Vec lvec, PetscInt ci, PetscInt cj, PetscInt ck, PetscReal v)
 Sets a single local-scalar cell value (e.g.
 
static PetscErrorCode TestMomentumBDFCoefficient (void)
 
static PetscErrorCode MomMakeUnitGridP (SimCtx **simCtx, UserCtx **user, PetscInt n, PetscBool px, PetscBool py, PetscBool pz, BCType bc)
 
static PetscErrorCode MomMakeUnitGrid (SimCtx **simCtx, UserCtx **user, PetscInt n, BCType bc)
 
static PetscErrorCode TestMomentumStabilityCenteredConvection (void)
 
static PetscErrorCode TestMomentumStabilityQuickInterior (void)
 
static PetscErrorCode TestMomentumStabilityQuickBoundary (void)
 
static PetscErrorCode TestMomentumStabilityViscousLongitudinal (void)
 
static PetscErrorCode TestMomentumStabilityViscousScalesWithNu (void)
 
static PetscErrorCode TestMomentumStabilityLESEddyViscosity (void)
 
static PetscErrorCode TestMomentumStabilityOneSidedViscous (void)
 
static PetscErrorCode TestMomentumStabilityReadOnly (void)
 
static PetscErrorCode MomSetCartesianMetrics (UserCtx *user, PetscReal dx, PetscReal dy, PetscReal dz)
 Sets uniform Cartesian metrics for spacing (dx,dy,dz) on all cell and face arrays.
 
static PetscErrorCode MomFillUcontXRamp (DM fda, Vec lvec, PetscReal slope)
 Fills lUcont.x as a linear ramp slope*i (nonzero discrete contravariant divergence).
 
static PetscErrorCode MomFillUcatShearY (DM fda, Vec lvec, PetscReal gamma)
 Fills lUcat as a linear shear u=(gamma*j,0,0) so |grad u|_inf = gamma.
 
static PetscErrorCode TestMomentumStabilityAnisotropicViscous (void)
 
static PetscErrorCode TestMomentumStabilityDirectionalQuick (void)
 
static PetscErrorCode TestMomentumStabilityOneSidedDirections (void)
 
static PetscErrorCode TestMomentumStabilityActiveRowMask (void)
 
static PetscErrorCode TestMomentumStabilityValidation (void)
 
static PetscErrorCode TestMomentumStabilityCandidateBCDivergence (void)
 
static PetscErrorCode TestMomentumStabilityCandidateDShear (void)
 
static PetscErrorCode TestMomentumStabilityWallSuppression (void)
 
static PetscErrorCode TestMomentumStabilityReadOnlyExact (void)
 
static PetscErrorCode TestMomentumActiveRowsHelper (void)
 
static PetscErrorCode TestMomentumStabilityErrorReentry (void)
 
static PetscErrorCode TestMomentumBDFResidualCombination (void)
 
int main (int argc, char **argv)
 Runs the unit-solver PETSc test binary.
 

Detailed Description

C unit tests for solver-side analytical and LES helper kernels.

Definition in file test_solver_kernels.c.

Function Documentation

◆ TestLESTestFilterPaths()

static PetscErrorCode TestLESTestFilterPaths ( void  )
static

Tests LES test-filter helper paths for representative cases.

Definition at line 18 of file test_solver_kernels.c.

19{
20 SimCtx simCtx;
21 double values[3][3][3];
22 double weights[3][3][3];
23
24 PetscFunctionBeginUser;
25 PetscCall(PetscMemzero(&simCtx, sizeof(simCtx)));
26 for (PetscInt k = 0; k < 3; ++k) {
27 for (PetscInt j = 0; j < 3; ++j) {
28 for (PetscInt i = 0; i < 3; ++i) {
29 values[k][j][i] = 2.0;
30 weights[k][j][i] = 1.0;
31 }
32 }
33 }
34
35 simCtx.testfilter_ik = 1;
36 PetscCall(PicurvAssertRealNear(2.0, ApplyLESTestFilter(&simCtx, values, weights), 1.0e-12,
37 "Simpson-rule filter should preserve a constant field"));
38
39 simCtx.testfilter_ik = 0;
40 PetscCall(PicurvAssertRealNear(2.0, ApplyLESTestFilter(&simCtx, values, weights), 1.0e-12,
41 "box filter should preserve a constant field"));
42
43 for (PetscInt k = 0; k < 3; ++k) {
44 for (PetscInt j = 0; j < 3; ++j) {
45 for (PetscInt i = 0; i < 3; ++i) {
46 weights[k][j][i] = 0.0;
47 }
48 }
49 }
50 PetscCall(PicurvAssertRealNear(0.0, ApplyLESTestFilter(&simCtx, values, weights), 1.0e-12,
51 "box filter should return zero when all weights are zero"));
52 PetscFunctionReturn(0);
53}
double ApplyLESTestFilter(const SimCtx *simCtx, double values[3][3][3], double weights[3][3][3])
Applies a numerical "test filter" to a 3x3x3 stencil of data points.
Definition Filter.c:121
PetscErrorCode PicurvAssertRealNear(PetscReal expected, PetscReal actual, PetscReal tol, const char *context)
Asserts that two real values agree within tolerance.
PetscInt testfilter_ik
Definition variables.h:824
The master context for the entire simulation.
Definition variables.h:695
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestAnalyticalGeometrySelection()

static PetscErrorCode TestAnalyticalGeometrySelection ( void  )
static

Tests analytical geometry selection for supported analytical solutions.

Definition at line 58 of file test_solver_kernels.c.

59{
60 SimCtx *simCtx = NULL;
61 UserCtx *user = NULL;
62 PetscErrorCode ierr_grid = 0;
63 PetscErrorCode ierr_non_square = 0;
64
65 PetscFunctionBeginUser;
66 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 8, 8, 8));
68 "TGV3D should require custom geometry"));
69 PetscCall(PicurvAssertBool((PetscBool)!AnalyticalTypeRequiresCustomGeometry("ZERO_FLOW"),
70 "ZERO_FLOW should not require custom geometry"));
71
72 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "ZERO_FLOW", sizeof(simCtx->AnalyticalSolutionType)));
73 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
74 ierr_grid = SetAnalyticalGridInfo(user);
75 PetscCall(PetscPopErrorHandler());
76 PetscCall(PicurvAssertBool((PetscBool)(ierr_grid != 0),
77 "SetAnalyticalGridInfo should reject analytical types without custom geometry"));
78
79 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "TGV3D", sizeof(simCtx->AnalyticalSolutionType)));
80 simCtx->block_number = 2;
81 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
82 ierr_non_square = SetAnalyticalGridInfo(user);
83 PetscCall(PetscPopErrorHandler());
84 PetscCall(PicurvAssertBool((PetscBool)(ierr_non_square != 0),
85 "TGV3D multi-block setup should reject non-square block counts"));
86
87 simCtx->block_number = 1;
88 PetscCall(SetAnalyticalGridInfo(user));
89 PetscCall(PicurvAssertRealNear(0.0, user->Min_X, 1.0e-12, "TGV3D single-block xmin"));
90 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_X, 1.0e-12, "TGV3D single-block xmax"));
91
92 simCtx->block_number = 4;
93 user->_this = 3;
94 PetscCall(SetAnalyticalGridInfo(user));
95 PetscCall(PicurvAssertRealNear(PETSC_PI, user->Min_X, 1.0e-12, "TGV3D multi-block xmin should reflect the block column"));
96 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_X, 1.0e-12, "TGV3D multi-block xmax should reflect the block column"));
97 PetscCall(PicurvAssertRealNear(PETSC_PI, user->Min_Y, 1.0e-12, "TGV3D multi-block ymin should reflect the block row"));
98 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_Y, 1.0e-12, "TGV3D multi-block ymax should reflect the block row"));
99 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_Z, 1.0e-12, "TGV3D multi-block zmax should span the full domain"));
100
101 simCtx->block_number = 1;
102 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
103 PetscFunctionReturn(0);
104}
PetscBool AnalyticalTypeRequiresCustomGeometry(const char *analytical_type)
Reports whether an analytical type requires custom geometry/decomposition logic.
PetscErrorCode SetAnalyticalGridInfo(UserCtx *user)
Sets the grid domain and resolution for analytical solution cases.
PetscErrorCode PicurvCreateMinimalContexts(SimCtx **simCtx_out, UserCtx **user_out, PetscInt mx, PetscInt my, PetscInt mz)
Builds minimal SimCtx and UserCtx fixtures for C unit tests.
PetscErrorCode PicurvDestroyMinimalContexts(SimCtx **simCtx_ptr, UserCtx **user_ptr)
Destroys minimal SimCtx/UserCtx fixtures and all owned PETSc objects.
PetscErrorCode PicurvAssertBool(PetscBool value, const char *context)
Asserts that one boolean condition is true.
PetscInt block_number
Definition variables.h:790
PetscReal Min_X
Definition variables.h:921
PetscInt _this
Definition variables.h:924
PetscReal Max_Y
Definition variables.h:921
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:729
PetscReal Max_X
Definition variables.h:921
PetscReal Min_Y
Definition variables.h:921
PetscReal Max_Z
Definition variables.h:921
User-defined context containing data specific to a single computational grid level.
Definition variables.h:906
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestAnalyticalScalarVerificationHelpers()

static PetscErrorCode TestAnalyticalScalarVerificationHelpers ( void  )
static

Tests analytical scalar verification helper routines.

Definition at line 109 of file test_solver_kernels.c.

110{
111 SimCtx *simCtx = NULL;
112 UserCtx *user = NULL;
113 Vec target = NULL;
114 PetscReal value = 0.0;
115 PetscReal ***target_arr = NULL;
116 PetscReal *positions = NULL;
117 PetscReal *psi = NULL;
118
119 PetscFunctionBeginUser;
120 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
121 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
122 simCtx->verificationScalar.enabled = PETSC_TRUE;
123 PetscCall(PetscStrncpy(simCtx->verificationScalar.mode,
124 "analytical",
125 sizeof(simCtx->verificationScalar.mode)));
126
127 PetscCall(PetscStrncpy(simCtx->verificationScalar.profile,
128 "CONSTANT",
129 sizeof(simCtx->verificationScalar.profile)));
130 simCtx->verificationScalar.value = 2.5;
131 PetscCall(EvaluateAnalyticalScalarProfile(simCtx, 0.2, 0.3, 0.4, 0.0, &value));
132 PetscCall(PicurvAssertRealNear(2.5, value, 1.0e-12,
133 "constant scalar profile should evaluate to the configured value"));
134
135 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
136 positions[0] = 0.1; positions[1] = 0.2; positions[2] = 0.3;
137 positions[3] = 0.8; positions[4] = 0.6; positions[5] = 0.4;
138 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
139
141 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
142 PetscCall(PicurvAssertRealNear(2.5, psi[0], 1.0e-12,
143 "SetAnalyticalScalarFieldOnParticles should overwrite the first particle scalar"));
144 PetscCall(PicurvAssertRealNear(2.5, psi[1], 1.0e-12,
145 "SetAnalyticalScalarFieldOnParticles should overwrite the second particle scalar"));
146 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
147
148 PetscCall(PetscStrncpy(simCtx->verificationScalar.profile,
149 "LINEAR_X",
150 sizeof(simCtx->verificationScalar.profile)));
151 simCtx->verificationScalar.phi0 = 1.0;
152 simCtx->verificationScalar.slope_x = 2.0;
153 PetscCall(EvaluateAnalyticalScalarProfile(simCtx, 0.25, 0.0, 0.0, 0.0, &value));
154 PetscCall(PicurvAssertRealNear(1.5, value, 1.0e-12,
155 "linear-x scalar profile should evaluate phi0 + slope_x * x"));
156
157 PetscCall(VecDuplicate(user->Psi, &target));
158 PetscCall(SetAnalyticalScalarFieldAtCellCenters(user, target));
159 PetscCall(DMDAVecGetArrayRead(user->da, target, &target_arr));
160 PetscCall(PicurvAssertRealNear(1.25, target_arr[1][1][1], 1.0e-12,
161 "cell-center scalar fill should use the physical x center coordinate"));
162 PetscCall(DMDAVecRestoreArrayRead(user->da, target, &target_arr));
163 PetscCall(VecDestroy(&target));
164
165 PetscCall(PetscStrncpy(simCtx->verificationScalar.profile,
166 "SIN_PRODUCT",
167 sizeof(simCtx->verificationScalar.profile)));
168 simCtx->verificationScalar.amplitude = 3.0;
169 simCtx->verificationScalar.kx = PETSC_PI;
170 simCtx->verificationScalar.ky = PETSC_PI;
171 simCtx->verificationScalar.kz = PETSC_PI;
172 PetscCall(EvaluateAnalyticalScalarProfile(simCtx, 0.5, 0.5, 0.5, 0.0, &value));
173 PetscCall(PicurvAssertRealNear(3.0, value, 1.0e-12,
174 "sin-product scalar profile should peak at pi/2 in each coordinate"));
175
176 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
177 PetscFunctionReturn(0);
178}
PetscErrorCode EvaluateAnalyticalScalarProfile(const SimCtx *simCtx, PetscReal x, PetscReal y, PetscReal z, PetscReal t, PetscReal *value)
Evaluates the configured verification scalar profile at one physical point.
PetscErrorCode SetAnalyticalScalarFieldAtCellCenters(UserCtx *user, Vec targetVec)
Writes the configured verification scalar profile at physical cell centers into a scalar Vec.
PetscErrorCode SetAnalyticalScalarFieldOnParticles(UserCtx *user, ParticleFieldId particle_field_id)
Writes the configured verification scalar profile onto a particle swarm scalar field.
@ PARTICLE_FIELD_ID_PSI
PetscErrorCode PicurvCreateSwarmPair(UserCtx *user, PetscInt nlocal, const char *post_field_name)
Creates matched solver and post-processing swarms for tests.
VerificationScalarConfig verificationScalar
Definition variables.h:778
Vec Psi
Definition variables.h:997
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestAnalyticalSolutionEngineDispatch()

static PetscErrorCode TestAnalyticalSolutionEngineDispatch ( void  )
static

Tests analytical solution engine ZERO_FLOW, UNIFORM_FLOW, and unknown-type dispatch.

Definition at line 183 of file test_solver_kernels.c.

184{
185 SimCtx *simCtx = NULL;
186 UserCtx *user = NULL;
187 PetscErrorCode ierr_unknown = 0;
188 Cmpnts ***ucat = NULL;
189 Cmpnts ***ubcs = NULL;
190
191 PetscFunctionBeginUser;
192 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
193 PetscCall(VecSet(user->Ucat, 3.0));
194 PetscCall(VecSet(user->P, 5.0));
195 PetscCall(VecSet(user->Bcs.Ubcs, 7.0));
196
197 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "ZERO_FLOW", sizeof(simCtx->AnalyticalSolutionType)));
198 PetscCall(AnalyticalSolutionEngine(simCtx));
199 PetscCall(PicurvAssertVecConstant(user->Ucat, 0.0, 1.0e-12, "ZERO_FLOW should zero the Eulerian velocity field"));
200 PetscCall(PicurvAssertVecConstant(user->P, 0.0, 1.0e-12, "ZERO_FLOW should zero the pressure field"));
201 PetscCall(PicurvAssertVecConstant(user->Bcs.Ubcs, 0.0, 1.0e-12, "ZERO_FLOW should zero boundary-condition velocity data"));
202
203 /* UNIFORM_FLOW now works in curvilinear form (sets Ucont via metric dot products,
204 derives Ucat via Contra2Cart). The test grid needs identity metrics so the
205 transformation is invertible and Ucat recovers the physical velocity exactly. */
206 {
207 Cmpnts ***l_csi, ***l_eta, ***l_zet;
208 DMDALocalInfo linfo;
209 PetscCall(DMDAGetLocalInfo(user->fda, &linfo));
210 PetscCall(DMDAVecGetArray(user->fda, user->lCsi, &l_csi));
211 PetscCall(DMDAVecGetArray(user->fda, user->lEta, &l_eta));
212 PetscCall(DMDAVecGetArray(user->fda, user->lZet, &l_zet));
213 for (PetscInt k = linfo.zs; k < linfo.zs + linfo.zm; k++)
214 for (PetscInt j = linfo.ys; j < linfo.ys + linfo.ym; j++)
215 for (PetscInt i = linfo.xs; i < linfo.xs + linfo.xm; i++) {
216 l_csi[k][j][i] = (Cmpnts){1.0, 0.0, 0.0};
217 l_eta[k][j][i] = (Cmpnts){0.0, 1.0, 0.0};
218 l_zet[k][j][i] = (Cmpnts){0.0, 0.0, 1.0};
219 }
220 PetscCall(DMDAVecRestoreArray(user->fda, user->lZet, &l_zet));
221 PetscCall(DMDAVecRestoreArray(user->fda, user->lEta, &l_eta));
222 PetscCall(DMDAVecRestoreArray(user->fda, user->lCsi, &l_csi));
223 }
224
225 simCtx->AnalyticalUniformVelocity.x = 1.25;
226 simCtx->AnalyticalUniformVelocity.y = -0.5;
227 simCtx->AnalyticalUniformVelocity.z = 0.75;
228 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "UNIFORM_FLOW", sizeof(simCtx->AnalyticalSolutionType)));
229 PetscCall(AnalyticalSolutionEngine(simCtx));
230 PetscCall(PicurvAssertVecConstant(user->P, 0.0, 1.0e-12, "UNIFORM_FLOW should keep the pressure field zero"));
231
232 Cmpnts ***ucont = NULL;
233 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucat, &ucat));
234 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
235 PetscCall(DMDAVecGetArrayRead(user->fda, user->Bcs.Ubcs, &ubcs));
236 PetscCall(PicurvAssertRealNear(1.25, ucat[1][1][1].x, 1.0e-12, "UNIFORM_FLOW should impose the configured x velocity"));
237 PetscCall(PicurvAssertRealNear(-0.5, ucat[1][1][1].y, 1.0e-12, "UNIFORM_FLOW should impose the configured y velocity"));
238 PetscCall(PicurvAssertRealNear(0.75, ucat[1][1][1].z, 1.0e-12, "UNIFORM_FLOW should impose the configured z velocity"));
239 PetscCall(PicurvAssertRealNear(1.25, ucont[1][1][1].x, 1.0e-12, "UNIFORM_FLOW should set contravariant x flux (identity metric)"));
240 PetscCall(PicurvAssertRealNear(-0.5, ucont[1][1][1].y, 1.0e-12, "UNIFORM_FLOW should set contravariant y flux (identity metric)"));
241 PetscCall(PicurvAssertRealNear(0.75, ucont[1][1][1].z, 1.0e-12, "UNIFORM_FLOW should set contravariant z flux (identity metric)"));
242 PetscCall(PicurvAssertRealNear(1.25, ubcs[0][1][1].x, 1.0e-12, "UNIFORM_FLOW should populate boundary x velocity"));
243 PetscCall(PicurvAssertRealNear(-0.5, ubcs[0][1][1].y, 1.0e-12, "UNIFORM_FLOW should populate boundary y velocity"));
244 PetscCall(PicurvAssertRealNear(0.75, ubcs[0][1][1].z, 1.0e-12, "UNIFORM_FLOW should populate boundary z velocity"));
245 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Bcs.Ubcs, &ubcs));
246 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
247 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucat, &ucat));
248
249 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "NOT_A_REAL_ANALYTICAL_TYPE", sizeof(simCtx->AnalyticalSolutionType)));
250 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
251 ierr_unknown = AnalyticalSolutionEngine(simCtx);
252 PetscCall(PetscPopErrorHandler());
253 PetscCall(PicurvAssertBool((PetscBool)(ierr_unknown != 0),
254 "AnalyticalSolutionEngine should reject unknown analytical type strings"));
255
256 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
257 PetscFunctionReturn(0);
258}
PetscErrorCode AnalyticalSolutionEngine(SimCtx *simCtx)
Dispatches to the appropriate analytical solution function based on simulation settings.
PetscErrorCode PicurvAssertVecConstant(Vec vec, PetscScalar expected, PetscReal tol, const char *context)
Asserts that a PETSc vector is spatially constant within tolerance.
Vec lZet
Definition variables.h:974
Vec Ucont
Definition variables.h:939
Vec Ubcs
Physical Cartesian velocity at boundary faces. Full 3D array but only boundary-face entries are meani...
Definition variables.h:123
PetscScalar x
Definition variables.h:103
BCS Bcs
Definition variables.h:934
Vec lCsi
Definition variables.h:974
Cmpnts AnalyticalUniformVelocity
Definition variables.h:760
PetscScalar z
Definition variables.h:103
Vec Ucat
Definition variables.h:939
PetscScalar y
Definition variables.h:103
Vec lEta
Definition variables.h:974
A 3D point or vector with PetscScalar components.
Definition variables.h:102
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestAnalyticalSolutionEngineTaylorGreenSamples()

static PetscErrorCode TestAnalyticalSolutionEngineTaylorGreenSamples ( void  )
static

Tests exact Taylor-Green samples on selected Eulerian interior and boundary points.

Definition at line 262 of file test_solver_kernels.c.

263{
264 SimCtx *simCtx = NULL;
265 UserCtx *user = NULL;
266 Cmpnts ***cent = NULL;
267 Cmpnts ***cent_x = NULL;
268 Cmpnts ***cent_y = NULL;
269 Cmpnts ***cent_z = NULL;
270 Cmpnts ***ucat = NULL;
271 Cmpnts ***ubcs = NULL;
272 PetscReal ***p = NULL;
273 const PetscReal vel_decay = PetscExpReal(-0.5);
274
275 PetscFunctionBeginUser;
276 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
277 simCtx->ren = 2.0;
278 simCtx->ti = 0.5;
279 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "TGV3D", sizeof(simCtx->AnalyticalSolutionType)));
280
281 PetscCall(DMDAVecGetArray(user->fda, user->Cent, &cent));
282 PetscCall(DMDAVecGetArray(user->fda, user->lCentx, &cent_x));
283 PetscCall(DMDAVecGetArray(user->fda, user->lCenty, &cent_y));
284 PetscCall(DMDAVecGetArray(user->fda, user->lCentz, &cent_z));
285 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
286 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
287 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
288 cent[k][j][i].x = 0.0;
289 cent[k][j][i].y = 0.0;
290 cent[k][j][i].z = 0.0;
291 cent_x[k][j][i] = cent[k][j][i];
292 cent_y[k][j][i] = cent[k][j][i];
293 cent_z[k][j][i] = cent[k][j][i];
294 }
295 }
296 }
297 cent[1][1][1].x = 0.5 * PETSC_PI;
298 cent[1][1][1].y = 0.0;
299 cent[1][1][1].z = 0.0;
300 cent[1][2][1].x = 0.0;
301 cent[1][2][1].y = 0.5 * PETSC_PI;
302 cent[1][2][1].z = 0.0;
303 cent_z[0][1][1].x = 0.5 * PETSC_PI;
304 cent_z[0][1][1].y = 0.0;
305 cent_z[0][1][1].z = 0.0;
306 PetscCall(DMDAVecRestoreArray(user->fda, user->lCentz, &cent_z));
307 PetscCall(DMDAVecRestoreArray(user->fda, user->lCenty, &cent_y));
308 PetscCall(DMDAVecRestoreArray(user->fda, user->lCentx, &cent_x));
309 PetscCall(DMDAVecRestoreArray(user->fda, user->Cent, &cent));
310
311 PetscCall(AnalyticalSolutionEngine(simCtx));
312
313 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucat, &ucat));
314 PetscCall(DMDAVecGetArrayRead(user->fda, user->Bcs.Ubcs, &ubcs));
315 PetscCall(DMDAVecGetArrayRead(user->da, user->P, &p));
316 PetscCall(PicurvAssertRealNear(vel_decay, ucat[1][1][1].x, 1.0e-12, "TGV sample should set the expected interior x velocity"));
317 PetscCall(PicurvAssertRealNear(0.0, ucat[1][1][1].y, 1.0e-12, "TGV sample should keep the paired interior y velocity at zero"));
318 PetscCall(PicurvAssertRealNear(-vel_decay, ucat[1][2][1].y, 1.0e-12, "TGV sample should set the expected interior y velocity"));
319 PetscCall(PicurvAssertRealNear(0.0, p[1][1][1], 1.0e-12, "Chosen TGV sample should produce zero pressure"));
320 PetscCall(PicurvAssertRealNear(vel_decay, ubcs[0][1][1].x, 1.0e-12, "TGV sample should set the expected boundary x velocity"));
321 PetscCall(PicurvAssertRealNear(0.0, ubcs[0][1][1].y, 1.0e-12, "TGV boundary sample should keep the paired y velocity at zero"));
322 PetscCall(DMDAVecRestoreArrayRead(user->da, user->P, &p));
323 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Bcs.Ubcs, &ubcs));
324 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucat, &ucat));
325
326 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
327 PetscFunctionReturn(0);
328}
PetscReal ren
Definition variables.h:744
Vec lCenty
Definition variables.h:976
Vec lCentx
Definition variables.h:976
DMDALocalInfo info
Definition variables.h:918
Vec Cent
Definition variables.h:974
Vec lCentz
Definition variables.h:976
PetscReal ti
Definition variables.h:704
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestAnalyticalSolutionForParticlesDispatch()

static PetscErrorCode TestAnalyticalSolutionForParticlesDispatch ( void  )
static

Tests particle analytical-solution dispatch for TGV3D, UNIFORM_FLOW, and non-analytical no-op paths.

Definition at line 333 of file test_solver_kernels.c.

334{
335 SimCtx simCtx;
336 Vec tempVec = NULL;
337 PetscReal *data = NULL;
338 const PetscReal vel_decay = PetscExpReal(-0.5);
339
340 PetscFunctionBeginUser;
341 PetscCall(PetscMemzero(&simCtx, sizeof(simCtx)));
342 simCtx.ren = 2.0;
343 simCtx.ti = 0.5;
344 PetscCall(PetscStrncpy(simCtx.AnalyticalSolutionType, "TGV3D", sizeof(simCtx.AnalyticalSolutionType)));
345
346 PetscCall(VecCreateSeq(PETSC_COMM_SELF, 6, &tempVec));
347 PetscCall(VecGetArray(tempVec, &data));
348 data[0] = 0.5 * PETSC_PI; data[1] = 0.0; data[2] = 0.0;
349 data[3] = 0.0; data[4] = 0.5 * PETSC_PI; data[5] = 0.0;
350 PetscCall(VecRestoreArray(tempVec, &data));
351
352 PetscCall(SetAnalyticalSolutionForParticles(tempVec, &simCtx));
353 PetscCall(VecGetArray(tempVec, &data));
354 PetscCall(PicurvAssertRealNear(vel_decay, data[0], 1.0e-12,
355 "TGV3D particle dispatch should populate the x velocity at x=pi/2"));
356 PetscCall(PicurvAssertRealNear(0.0, data[1], 1.0e-12,
357 "TGV3D particle dispatch should leave the first particle y velocity at zero"));
358 PetscCall(PicurvAssertRealNear(0.0, data[2], 1.0e-12,
359 "TGV3D particle dispatch should leave the first particle z velocity at zero"));
360 PetscCall(PicurvAssertRealNear(0.0, data[3], 1.0e-12,
361 "TGV3D particle dispatch should leave the second particle x velocity at zero"));
362 PetscCall(PicurvAssertRealNear(-vel_decay, data[4], 1.0e-12,
363 "TGV3D particle dispatch should populate the y velocity at y=pi/2"));
364 PetscCall(PicurvAssertRealNear(0.0, data[5], 1.0e-12,
365 "TGV3D particle dispatch should leave the second particle z velocity at zero"));
366 PetscCall(VecRestoreArray(tempVec, &data));
367
368 PetscCall(PetscStrncpy(simCtx.AnalyticalSolutionType, "ZERO_FLOW", sizeof(simCtx.AnalyticalSolutionType)));
369 PetscCall(VecGetArray(tempVec, &data));
370 data[0] = 3.0;
371 data[1] = 4.0;
372 data[2] = 5.0;
373 PetscCall(VecRestoreArray(tempVec, &data));
374 PetscCall(SetAnalyticalSolutionForParticles(tempVec, &simCtx));
375 PetscCall(VecGetArray(tempVec, &data));
376 PetscCall(PicurvAssertRealNear(3.0, data[0], 1.0e-12,
377 "Non-TGV particle dispatch should leave the vector untouched"));
378 PetscCall(PicurvAssertRealNear(4.0, data[1], 1.0e-12,
379 "Non-TGV particle dispatch should preserve the y component"));
380 PetscCall(PicurvAssertRealNear(5.0, data[2], 1.0e-12,
381 "Non-TGV particle dispatch should preserve the z component"));
382 PetscCall(VecRestoreArray(tempVec, &data));
383
384 simCtx.AnalyticalUniformVelocity.x = 0.125;
385 simCtx.AnalyticalUniformVelocity.y = -0.25;
386 simCtx.AnalyticalUniformVelocity.z = 0.375;
387 PetscCall(PetscStrncpy(simCtx.AnalyticalSolutionType, "UNIFORM_FLOW", sizeof(simCtx.AnalyticalSolutionType)));
388 PetscCall(SetAnalyticalSolutionForParticles(tempVec, &simCtx));
389 PetscCall(VecGetArray(tempVec, &data));
390 PetscCall(PicurvAssertRealNear(0.125, data[0], 1.0e-12,
391 "UNIFORM_FLOW particle dispatch should populate the x velocity"));
392 PetscCall(PicurvAssertRealNear(-0.25, data[1], 1.0e-12,
393 "UNIFORM_FLOW particle dispatch should populate the y velocity"));
394 PetscCall(PicurvAssertRealNear(0.375, data[2], 1.0e-12,
395 "UNIFORM_FLOW particle dispatch should populate the z velocity"));
396 PetscCall(PicurvAssertRealNear(0.125, data[3], 1.0e-12,
397 "UNIFORM_FLOW particle dispatch should use the same x velocity for each particle"));
398 PetscCall(PicurvAssertRealNear(-0.25, data[4], 1.0e-12,
399 "UNIFORM_FLOW particle dispatch should use the same y velocity for each particle"));
400 PetscCall(PicurvAssertRealNear(0.375, data[5], 1.0e-12,
401 "UNIFORM_FLOW particle dispatch should use the same z velocity for each particle"));
402 PetscCall(VecRestoreArray(tempVec, &data));
403
404 PetscCall(VecDestroy(&tempVec));
405 PetscFunctionReturn(0);
406}
PetscErrorCode SetAnalyticalSolutionForParticles(Vec tempVec, SimCtx *simCtx)
Applies the analytical solution to particle velocity vector.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestComputeEddyViscosityLESDeterministicField()

static PetscErrorCode TestComputeEddyViscosityLESDeterministicField ( void  )
static

Tests deterministic LES eddy-viscosity computation on a linear velocity field.

Definition at line 411 of file test_solver_kernels.c.

412{
413 SimCtx *simCtx = NULL;
414 UserCtx *user = NULL;
415 Cmpnts ***ucat = NULL;
416 PetscReal ***nu_t = NULL;
417 const PetscReal expected_nu_t = 0.25 * PetscSqrtReal(2.0);
418
419 PetscFunctionBeginUser;
420 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
421 PetscCall(DMCreateGlobalVector(user->da, &user->Nu_t));
422 PetscCall(DMCreateLocalVector(user->da, &user->lNu_t));
423 PetscCall(DMCreateGlobalVector(user->da, &user->CS));
424 PetscCall(DMCreateLocalVector(user->da, &user->lCs));
425
426 PetscCall(VecSet(user->Aj, 1.0));
427 PetscCall(VecSet(user->Nu_t, 0.0));
428 PetscCall(VecSet(user->CS, 0.5));
429 PetscCall(DMDAVecGetArray(user->fda, user->Ucat, &ucat));
430 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
431 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
432 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
433 ucat[k][j][i].x = (PetscReal)i;
434 ucat[k][j][i].y = 0.0;
435 ucat[k][j][i].z = 0.0;
436 }
437 }
438 }
439 PetscCall(DMDAVecRestoreArray(user->fda, user->Ucat, &ucat));
440 PetscCall(DMGlobalToLocalBegin(user->fda, user->Ucat, INSERT_VALUES, user->lUcat));
441 PetscCall(DMGlobalToLocalEnd(user->fda, user->Ucat, INSERT_VALUES, user->lUcat));
442 PetscCall(DMGlobalToLocalBegin(user->da, user->Aj, INSERT_VALUES, user->lAj));
443 PetscCall(DMGlobalToLocalEnd(user->da, user->Aj, INSERT_VALUES, user->lAj));
444 PetscCall(DMGlobalToLocalBegin(user->da, user->CS, INSERT_VALUES, user->lCs));
445 PetscCall(DMGlobalToLocalEnd(user->da, user->CS, INSERT_VALUES, user->lCs));
446
447 PetscCall(ComputeEddyViscosityLES(user));
448 PetscCall(DMDAVecGetArrayRead(user->da, user->Nu_t, &nu_t));
449 PetscCall(PicurvAssertRealNear(expected_nu_t, nu_t[2][2][2], 1.0e-6,
450 "linear velocity field should yield deterministic LES eddy viscosity"));
451 PetscCall(PicurvAssertRealNear(0.0, nu_t[0][2][2], 1.0e-12,
452 "boundary cells should remain untouched by the interior LES loop"));
453 PetscCall(DMDAVecRestoreArrayRead(user->da, user->Nu_t, &nu_t));
454
455 PetscCall(VecDestroy(&user->CS));
456 PetscCall(VecDestroy(&user->lCs));
457 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
458 PetscFunctionReturn(0);
459}
PetscErrorCode ComputeEddyViscosityLES(UserCtx *user)
Computes the turbulent eddy viscosity (Nu_t) for the LES model.
Definition les.c:327
Vec lCs
Definition variables.h:982
Vec lNu_t
Definition variables.h:982
Vec Nu_t
Definition variables.h:982
Vec lAj
Definition variables.h:974
Vec lUcat
Definition variables.h:939
double nu_t(double yplus)
Computes turbulent eddy viscosity ratio (ν_t / ν)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestFlowSolverRejectsUnsupportedMomentumSolverType()

static PetscErrorCode TestFlowSolverRejectsUnsupportedMomentumSolverType ( void  )
static

Tests FlowSolver guardrails for unsupported momentum solver selections.

Definition at line 464 of file test_solver_kernels.c.

465{
466 SimCtx *simCtx = NULL;
467 UserCtx *user = NULL;
468 PetscErrorCode ierr_flow = 0;
469
470 PetscFunctionBeginUser;
471 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
472 simCtx->mom_solver_type = (MomentumSolverType)999;
473
474 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
475 ierr_flow = FlowSolver(simCtx);
476 PetscCall(PetscPopErrorHandler());
477 PetscCall(PicurvAssertBool((PetscBool)(ierr_flow != 0),
478 "FlowSolver should reject unsupported momentum solver selectors"));
479
480 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
481 PetscFunctionReturn(0);
482}
PetscErrorCode FlowSolver(SimCtx *simCtx)
Orchestrates a single time step of the Eulerian fluid solver.
Definition solvers.c:11
MomentumSolverType
Enumerator to identify the implemented momentum solver strategies.
Definition variables.h:534
MomentumSolverType mom_solver_type
Definition variables.h:736
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestDrivenChannelFlowSource()

static PetscErrorCode TestDrivenChannelFlowSource ( void  )
static

Tests driven-channel flow source-term evaluation.

Definition at line 487 of file test_solver_kernels.c.

488{
489 SimCtx *simCtx = NULL;
490 UserCtx *user = NULL;
491 Vec rct = NULL;
492 Cmpnts ***rct_arr = NULL;
493 Cmpnts ***l_csi = NULL;
494 Cmpnts ***l_eta = NULL;
495 Cmpnts ***l_zet = NULL;
496
497 PetscFunctionBeginUser;
498 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
499 PetscCall(VecDuplicate(user->Ucont, &rct));
500 PetscCall(VecZeroEntries(rct));
501
508 simCtx->bulkVelocityCorrection = 2.0;
509 simCtx->dt = 1.0;
510 simCtx->forceScalingFactor = 1.0;
511 simCtx->drivingForceMagnitude = 0.0;
512 PetscCall(VecSet(user->Nvert, 0.0));
513 PetscCall(DMGlobalToLocalBegin(user->da, user->Nvert, INSERT_VALUES, user->lNvert));
514 PetscCall(DMGlobalToLocalEnd(user->da, user->Nvert, INSERT_VALUES, user->lNvert));
515 PetscCall(DMDAVecGetArray(user->fda, user->lCsi, &l_csi));
516 PetscCall(DMDAVecGetArray(user->fda, user->lEta, &l_eta));
517 PetscCall(DMDAVecGetArray(user->fda, user->lZet, &l_zet));
518 l_csi[1][1][1].x = 1.0; l_csi[1][1][1].y = 0.0; l_csi[1][1][1].z = 0.0;
519 l_eta[1][1][1].x = 0.0; l_eta[1][1][1].y = 1.0; l_eta[1][1][1].z = 0.0;
520 l_zet[1][1][1].x = 0.0; l_zet[1][1][1].y = 0.0; l_zet[1][1][1].z = 1.0;
521 PetscCall(DMDAVecRestoreArray(user->fda, user->lZet, &l_zet));
522 PetscCall(DMDAVecRestoreArray(user->fda, user->lEta, &l_eta));
523 PetscCall(DMDAVecRestoreArray(user->fda, user->lCsi, &l_csi));
524
525 PetscCall(ComputeDrivenChannelFlowSource(user, rct));
526 PetscCall(DMDAVecGetArrayRead(user->fda, rct, &rct_arr));
527 PetscCall(PicurvAssertRealNear(1.5, simCtx->drivingForceMagnitude, 1.0e-12,
528 "driven flow source should update the controller magnitude"));
529 PetscCall(PicurvAssertRealNear(0.0, rct_arr[1][1][1].y, 1.0e-12,
530 "driven flow source should leave the y component unchanged"));
531 PetscCall(PicurvAssertRealNear(0.0, rct_arr[1][1][1].z, 1.0e-12,
532 "driven flow source should leave the z component unchanged"));
533 PetscCall(DMDAVecRestoreArrayRead(user->fda, rct, &rct_arr));
534
535 PetscCall(VecDestroy(&rct));
536 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
537 PetscFunctionReturn(0);
538}
PetscErrorCode ComputeDrivenChannelFlowSource(UserCtx *user, Vec Rct)
Applies a momentum source term to drive flow in a periodic channel or pipe.
Definition BodyForces.c:14
@ PERIODIC
Definition variables.h:292
BoundaryFaceConfig boundary_faces[6]
Definition variables.h:931
Vec lNvert
Definition variables.h:939
PetscReal forceScalingFactor
Definition variables.h:801
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
Definition variables.h:318
BCHandlerType handler_type
Definition variables.h:369
PetscReal dt
Definition variables.h:710
PetscReal bulkVelocityCorrection
Definition variables.h:813
Vec Nvert
Definition variables.h:939
BCType mathematical_type
Definition variables.h:368
PetscReal drivingForceMagnitude
Definition variables.h:801
@ BC_FACE_NEG_X
Definition variables.h:262
@ BC_FACE_POS_X
Definition variables.h:262
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomSetAllBC()

static void MomSetAllBC ( UserCtx user,
BCType  t 
)
static

Sets the mathematical BC type on all six faces of a test UserCtx.

Parameters
userTest user context.
tBCType to assign to every face (e.g. PERIODIC, INLET).

Definition at line 551 of file test_solver_kernels.c.

◆ MomFillLocalCmpnts()

static PetscErrorCode MomFillLocalCmpnts ( DM  fda,
Vec  lvec,
PetscReal  x,
PetscReal  y,
PetscReal  z 
)
static

Fills a local Cmpnts vector (ghosts included) with a uniform vector value.

Parameters
fdaVector DM owning lvec.
lvecLocal Cmpnts vector to fill.
x,y,zUniform component values.
Returns
PetscErrorCode 0 on success.

Definition at line 568 of file test_solver_kernels.c.

569{
570 Cmpnts ***a;
571 PetscInt gxs, gys, gzs, gxm, gym, gzm;
572 PetscFunctionBeginUser;
573 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
574 PetscCall(DMDAVecGetArray(fda, lvec, &a));
575 for (PetscInt k = gzs; k < gzs+gzm; ++k)
576 for (PetscInt j = gys; j < gys+gym; ++j)
577 for (PetscInt i = gxs; i < gxs+gxm; ++i) { a[k][j][i].x = x; a[k][j][i].y = y; a[k][j][i].z = z; }
578 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
579 PetscFunctionReturn(0);
580}
Here is the caller graph for this function:

◆ MomFillLocalScalar()

static PetscErrorCode MomFillLocalScalar ( DM  da,
Vec  lvec,
PetscReal  v 
)
static

Fills a local scalar vector (ghosts included) with a uniform value.

Parameters
daScalar DM owning lvec.
lvecLocal scalar vector to fill.
vUniform value.
Returns
PetscErrorCode 0 on success.

Definition at line 589 of file test_solver_kernels.c.

590{
591 PetscReal ***a;
592 PetscInt gxs, gys, gzs, gxm, gym, gzm;
593 PetscFunctionBeginUser;
594 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
595 PetscCall(DMDAVecGetArray(da, lvec, &a));
596 for (PetscInt k = gzs; k < gzs+gzm; ++k)
597 for (PetscInt j = gys; j < gys+gym; ++j)
598 for (PetscInt i = gxs; i < gxs+gxm; ++i) a[k][j][i] = v;
599 PetscCall(DMDAVecRestoreArray(da, lvec, &a));
600 PetscFunctionReturn(0);
601}
Here is the caller graph for this function:

◆ MomSetLocalScalarCell()

static PetscErrorCode MomSetLocalScalarCell ( DM  da,
Vec  lvec,
PetscInt  ci,
PetscInt  cj,
PetscInt  ck,
PetscReal  v 
)
static

Sets a single local-scalar cell value (e.g.

to mark one nvert solid).

Parameters
daScalar DM owning lvec.
lvecLocal scalar vector.
ci,cj,ckCell indices to set.
vValue to assign.
Returns
PetscErrorCode 0 on success.

Definition at line 611 of file test_solver_kernels.c.

612{
613 PetscReal ***a;
614 PetscInt gxs, gys, gzs, gxm, gym, gzm;
615 PetscFunctionBeginUser;
616 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
617 PetscCall(DMDAVecGetArray(da, lvec, &a));
618 /* MPI-safe: only write if (ci,cj,ck) is within this rank's ghost-inclusive range. */
619 if (ci >= gxs && ci < gxs+gxm && cj >= gys && cj < gys+gym && ck >= gzs && ck < gzs+gzm)
620 a[ck][cj][ci] = v;
621 PetscCall(DMDAVecRestoreArray(da, lvec, &a));
622 PetscFunctionReturn(0);
623}
Here is the caller graph for this function:

◆ TestMomentumBDFCoefficient()

static PetscErrorCode TestMomentumBDFCoefficient ( void  )
static

Definition at line 627 of file test_solver_kernels.c.

628{
629 SimCtx *simCtx = NULL; UserCtx *user = NULL;
630 PetscFunctionBeginUser;
631 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 6, 6, 6));
632 simCtx->StartStep = 0; simCtx->step = 1;
633 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 on cold-start step 1"));
634 PetscCall(PicurvAssertBool((PetscBool)(!MomentumUsesBDF2(simCtx)), "step 1 is BDF1"));
635 simCtx->step = 5;
636 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF2 on interior step"));
637 PetscCall(PicurvAssertBool(MomentumUsesBDF2(simCtx), "step 5 (StartStep 0) is BDF2"));
638 simCtx->StartStep = 5; simCtx->step = 5;
639 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 at restart setup step"));
640 simCtx->step = 6;
641 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 on first restart solve (ti==StartStep+1)"));
642 simCtx->step = 7;
643 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF2 after first restart solve"));
644 simCtx->restartHistoryAvailable = PETSC_TRUE;
645 simCtx->step = 5;
646 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12,
647 "restored history enables BDF2 at restart setup"));
648 simCtx->step = 6;
649 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12,
650 "restored history enables BDF2 on first restart solve"));
651 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
652 PetscFunctionReturn(0);
653}
PetscBool MomentumUsesBDF2(SimCtx *simCtx)
Returns whether the current physical step uses the BDF2 discretization.
PetscReal MomentumBDFCoefficient(SimCtx *simCtx)
Returns the BDF physical-time coefficient a0 for the current step.
PetscInt StartStep
Definition variables.h:705
PetscInt step
Definition variables.h:703
PetscBool restartHistoryAvailable
Definition variables.h:723
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomMakeUnitGridP()

static PetscErrorCode MomMakeUnitGridP ( SimCtx **  simCtx,
UserCtx **  user,
PetscInt  n,
PetscBool  px,
PetscBool  py,
PetscBool  pz,
BCType  bc 
)
static

Definition at line 658 of file test_solver_kernels.c.

660{
661 PetscFunctionBeginUser;
662 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(simCtx, user, n, n, n, px, py, pz));
663 (*user)->boundary_faces[BC_FACE_NEG_X].mathematical_type = px ? PERIODIC : bc;
664 (*user)->boundary_faces[BC_FACE_POS_X].mathematical_type = px ? PERIODIC : bc;
665 (*user)->boundary_faces[BC_FACE_NEG_Y].mathematical_type = py ? PERIODIC : bc;
666 (*user)->boundary_faces[BC_FACE_POS_Y].mathematical_type = py ? PERIODIC : bc;
667 (*user)->boundary_faces[BC_FACE_NEG_Z].mathematical_type = pz ? PERIODIC : bc;
668 (*user)->boundary_faces[BC_FACE_POS_Z].mathematical_type = pz ? PERIODIC : bc;
669 (*simCtx)->dt = 0.1; (*simCtx)->step = 1; (*simCtx)->StartStep = 0; /* a0=1 -> lambda_t=10 */
670 (*simCtx)->ren = 1.0; (*simCtx)->les = 0; (*simCtx)->rans = 0;
671 (*simCtx)->central = 0; (*simCtx)->invicid = 0; (*simCtx)->block_number = 1;
672 (*simCtx)->TwoD = 0; (*simCtx)->clark = 0;
673 /* The minimal fixture does not allocate lNu_t (LES off by default); create a
674 zeroed one so the estimator can read it when a test enables LES/RANS. */
675 if (!(*user)->lNu_t) PetscCall(DMCreateLocalVector((*user)->da, &(*user)->lNu_t));
676 PetscCall(MomFillLocalCmpnts((*user)->fda, (*user)->lUcont, 0.0, 0.0, 0.0));
677 PetscCall(MomFillLocalCmpnts((*user)->fda, (*user)->lUcat, 0.0, 0.0, 0.0));
678 PetscCall(MomFillLocalScalar((*user)->da, (*user)->lNvert, 0.0));
679 PetscCall(MomFillLocalScalar((*user)->da, (*user)->lNu_t, 0.0));
680 PetscFunctionReturn(0);
681}
static PetscErrorCode MomFillLocalCmpnts(DM fda, Vec lvec, PetscReal x, PetscReal y, PetscReal z)
Fills a local Cmpnts vector (ghosts included) with a uniform vector value.
static PetscErrorCode MomFillLocalScalar(DM da, Vec lvec, PetscReal v)
Fills a local scalar vector (ghosts included) with a uniform value.
PetscErrorCode PicurvCreateMinimalContextsWithPeriodicity(SimCtx **simCtx_out, UserCtx **user_out, PetscInt mx, PetscInt my, PetscInt mz, PetscBool x_periodic, PetscBool y_periodic, PetscBool z_periodic)
Builds minimal SimCtx and UserCtx fixtures for C unit tests with configurable periodicity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomMakeUnitGrid()

static PetscErrorCode MomMakeUnitGrid ( SimCtx **  simCtx,
UserCtx **  user,
PetscInt  n,
BCType  bc 
)
static

Definition at line 684 of file test_solver_kernels.c.

685{
686 const PetscBool p = (PetscBool)(bc == PERIODIC);
687 PetscFunctionBeginUser;
688 PetscCall(MomMakeUnitGridP(simCtx, user, n, p, p, p, bc));
689 PetscFunctionReturn(0);
690}
static PetscErrorCode MomMakeUnitGridP(SimCtx **simCtx, UserCtx **user, PetscInt n, PetscBool px, PetscBool py, PetscBool pz, BCType bc)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityCenteredConvection()

static PetscErrorCode TestMomentumStabilityCenteredConvection ( void  )
static

Definition at line 693 of file test_solver_kernels.c.

694{
695 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
696 PetscFunctionBeginUser;
697 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
698 simCtx->central = 1; simCtx->invicid = 1;
699 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 2.0, 0.0, 0.0));
700 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
701 PetscCall(PicurvAssertRealNear(10.0, rep.lambda_t, 1e-9, "lambda_t = a0/dt"));
702 PetscCall(PicurvAssertRealNear(2.0, rep.lambda_c, 1e-9, "centered conv f_c=1 (Aj*U^xi scaling)"));
703 PetscCall(PicurvAssertRealNear(0.0, rep.lambda_v, 1e-9, "inviscid: no viscous term"));
704 PetscCall(PicurvAssertRealNear(12.0, rep.lambda, 1e-9, "total lambda"));
705 PetscCall(PicurvAssertIntEqual(0, (PetscInt)rep.cclass, "interior cell class"));
706 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
707 PetscFunctionReturn(0);
708}
@ MOM_STAB_CAND_C
PetscErrorCode ComputeMomentumStabilityEstimate(UserCtx *user, PetscInt block_number, PetscReal dt, MomStabCandidate candidate, MomStabilityReport *rep)
Compute the momentum pseudo-time stability estimate (shadow/diagnostic).
Diagnostic report produced by ComputeMomentumStabilityEstimate().
static PetscErrorCode MomMakeUnitGrid(SimCtx **simCtx, UserCtx **user, PetscInt n, BCType bc)
PetscErrorCode PicurvAssertIntEqual(PetscInt expected, PetscInt actual, const char *context)
Asserts that two integer values are equal.
PetscInt invicid
Definition variables.h:727
PetscInt central
Definition variables.h:742
Vec lUcont
Definition variables.h:939
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityQuickInterior()

static PetscErrorCode TestMomentumStabilityQuickInterior ( void  )
static

Definition at line 711 of file test_solver_kernels.c.

712{
713 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
714 PetscFunctionBeginUser;
715 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
716 simCtx->central = 0; simCtx->invicid = 1; /* QUICK branch */
717 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 3.0, 0.0, 0.0));
718 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
719 PetscCall(PicurvAssertRealNear(4.0, rep.lambda_c, 1e-9, "QUICK interior f_c=4/3 (4/3*3=4)"));
720 PetscCall(PicurvAssertIntEqual(0, (PetscInt)rep.cclass, "interior cell class"));
721 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
722 PetscFunctionReturn(0);
723}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityQuickBoundary()

static PetscErrorCode TestMomentumStabilityQuickBoundary ( void  )
static

Definition at line 726 of file test_solver_kernels.c.

727{
728 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
729 PetscFunctionBeginUser;
730 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, INLET)); /* non-periodic -> boundary band active */
731 simCtx->central = 0; simCtx->invicid = 1;
732 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 8.0, 0.0, 0.0));
733 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
734 PetscCall(PicurvAssertRealNear(20.0, rep.lambda_c, 1e-9, "boundary QUICK f_c=2.5 (2.5*8=20)"));
735 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.cclass, "physical-boundary cell class"));
736 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
737 PetscFunctionReturn(0);
738}
@ INLET
Definition variables.h:290
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityViscousLongitudinal()

static PetscErrorCode TestMomentumStabilityViscousLongitudinal ( void  )
static

Definition at line 741 of file test_solver_kernels.c.

742{
743 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
744 PetscFunctionBeginUser;
745 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
746 simCtx->invicid = 0; simCtx->ren = 1.0; /* nu = 1, no convection */
747 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
748 PetscCall(PicurvAssertRealNear(24.0, rep.lambda_v, 1e-9, "viscous = 4*6*nu = 24nu (factor-8 longitudinal)"));
749 PetscCall(PicurvAssertRealNear(34.0, rep.lambda, 1e-9, "total lambda_t+lambda_v"));
750 PetscCall(PicurvAssertIntEqual((PetscInt)MOM_STAB_LIMITER_VISCOSITY, (PetscInt)rep.limiter, "viscosity-limited"));
751 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
752 PetscFunctionReturn(0);
753}
@ MOM_STAB_LIMITER_VISCOSITY
MomStabLimiter limiter
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityViscousScalesWithNu()

static PetscErrorCode TestMomentumStabilityViscousScalesWithNu ( void  )
static

Definition at line 756 of file test_solver_kernels.c.

757{
758 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
759 PetscFunctionBeginUser;
760 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
761 simCtx->invicid = 0; simCtx->ren = 4.0; /* nu = 0.25 -> 24*0.25 = 6 */
762 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
763 PetscCall(PicurvAssertRealNear(6.0, rep.lambda_v, 1e-9, "viscous scales with nu=1/Re"));
764 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
765 PetscFunctionReturn(0);
766}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityLESEddyViscosity()

static PetscErrorCode TestMomentumStabilityLESEddyViscosity ( void  )
static

Definition at line 769 of file test_solver_kernels.c.

770{
771 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
772 PetscFunctionBeginUser;
773 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
774 simCtx->invicid = 0; simCtx->ren = 1.0; simCtx->les = 1; /* nu_eff = 1 + nu_t */
775 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 1.0)); /* nu_t = 1 -> nu_eff = 2 -> 24*2 = 48 */
776 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
777 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "LES nu_t adds: 4*6*(1+1) = 48"));
778 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
779 PetscFunctionReturn(0);
780}
PetscInt les
Definition variables.h:821
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityOneSidedViscous()

static PetscErrorCode TestMomentumStabilityOneSidedViscous ( void  )
static

Definition at line 783 of file test_solver_kernels.c.

784{
785 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
786 PetscFunctionBeginUser;
787 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
788 simCtx->invicid = 0; simCtx->ren = 1.0;
789 /* Mark one interior cell solid; its fluid cross-neighbours get the one-sided x2 (24 -> 48). */
790 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 5, 4, 1.0));
791 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
792 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "one-sided viscous x2 (24 -> 48)"));
793 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.one_sided, "one-sided multiplier flagged"));
794 PetscCall(PicurvAssertIntEqual(2, (PetscInt)rep.cclass, "IB-adjacent cell class"));
795 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
796 PetscFunctionReturn(0);
797}
static PetscErrorCode MomSetLocalScalarCell(DM da, Vec lvec, PetscInt ci, PetscInt cj, PetscInt ck, PetscReal v)
Sets a single local-scalar cell value (e.g.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityReadOnly()

static PetscErrorCode TestMomentumStabilityReadOnly ( void  )
static

Definition at line 800 of file test_solver_kernels.c.

801{
802 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
803 PetscReal n_ucont_0, n_ucat_0, n_nvert_0, n_ucont_1, n_ucat_1, n_nvert_1;
804 PetscFunctionBeginUser;
805 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
806 simCtx->invicid = 0; simCtx->ren = 2.0;
807 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 1.5, -0.7, 0.3));
808 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcat, 0.9, 0.4, -0.2));
809 PetscCall(VecNorm(user->lUcont, NORM_2, &n_ucont_0));
810 PetscCall(VecNorm(user->lUcat, NORM_2, &n_ucat_0));
811 PetscCall(VecNorm(user->lNvert, NORM_2, &n_nvert_0));
812 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
813 PetscCall(VecNorm(user->lUcont, NORM_2, &n_ucont_1));
814 PetscCall(VecNorm(user->lUcat, NORM_2, &n_ucat_1));
815 PetscCall(VecNorm(user->lNvert, NORM_2, &n_nvert_1));
816 PetscCall(PicurvAssertRealNear(n_ucont_0, n_ucont_1, 1e-14, "lUcont unchanged by estimator"));
817 PetscCall(PicurvAssertRealNear(n_ucat_0, n_ucat_1, 1e-14, "lUcat unchanged by estimator"));
818 PetscCall(PicurvAssertRealNear(n_nvert_0, n_nvert_1, 1e-14, "lNvert unchanged by estimator"));
819 PetscCall(PicurvAssertBool((PetscBool)(rep.lambda > 0.0), "estimate finite and positive"));
820 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
821 PetscFunctionReturn(0);
822}
@ MOM_STAB_CAND_D
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomSetCartesianMetrics()

static PetscErrorCode MomSetCartesianMetrics ( UserCtx user,
PetscReal  dx,
PetscReal  dy,
PetscReal  dz 
)
static

Sets uniform Cartesian metrics for spacing (dx,dy,dz) on all cell and face arrays.

Parameters
userTest user context.
dx,dy,dzCartesian cell spacings.
Returns
PetscErrorCode 0 on success.

Definition at line 830 of file test_solver_kernels.c.

831{
832 const PetscReal sx = dy*dz, sy = dx*dz, sz = dx*dy, aj = 1.0/(dx*dy*dz);
833 Vec csiv[] = {user->lCsi, user->lICsi, user->lJCsi, user->lKCsi};
834 Vec etav[] = {user->lEta, user->lIEta, user->lJEta, user->lKEta};
835 Vec zetv[] = {user->lZet, user->lIZet, user->lJZet, user->lKZet};
836 Vec ajv[] = {user->lAj, user->lIAj, user->lJAj, user->lKAj};
837 PetscFunctionBeginUser;
838 for (int t = 0; t < 4; ++t) {
839 PetscCall(MomFillLocalCmpnts(user->fda, csiv[t], sx, 0, 0));
840 PetscCall(MomFillLocalCmpnts(user->fda, etav[t], 0, sy, 0));
841 PetscCall(MomFillLocalCmpnts(user->fda, zetv[t], 0, 0, sz));
842 PetscCall(MomFillLocalScalar(user->da, ajv[t], aj));
843 }
844 PetscFunctionReturn(0);
845}
Vec lIEta
Definition variables.h:977
Vec lIZet
Definition variables.h:977
Vec lIAj
Definition variables.h:977
Vec lKEta
Definition variables.h:979
Vec lJCsi
Definition variables.h:978
Vec lKZet
Definition variables.h:979
Vec lJEta
Definition variables.h:978
Vec lKCsi
Definition variables.h:979
Vec lJZet
Definition variables.h:978
Vec lICsi
Definition variables.h:977
Vec lJAj
Definition variables.h:978
Vec lKAj
Definition variables.h:979
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomFillUcontXRamp()

static PetscErrorCode MomFillUcontXRamp ( DM  fda,
Vec  lvec,
PetscReal  slope 
)
static

Fills lUcont.x as a linear ramp slope*i (nonzero discrete contravariant divergence).

Parameters
fdaVector DM.
lvecLocal Cmpnts vector.
slopeRamp slope.
Returns
PetscErrorCode 0 on success.

Definition at line 854 of file test_solver_kernels.c.

855{
856 Cmpnts ***a;
857 PetscInt gxs, gys, gzs, gxm, gym, gzm;
858 PetscFunctionBeginUser;
859 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
860 PetscCall(DMDAVecGetArray(fda, lvec, &a));
861 for (PetscInt k = gzs; k < gzs+gzm; ++k)
862 for (PetscInt j = gys; j < gys+gym; ++j)
863 for (PetscInt i = gxs; i < gxs+gxm; ++i) { a[k][j][i].x = slope*i; a[k][j][i].y = 0; a[k][j][i].z = 0; }
864 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
865 PetscFunctionReturn(0);
866}
Here is the caller graph for this function:

◆ MomFillUcatShearY()

static PetscErrorCode MomFillUcatShearY ( DM  fda,
Vec  lvec,
PetscReal  gamma 
)
static

Fills lUcat as a linear shear u=(gamma*j,0,0) so |grad u|_inf = gamma.

Parameters
fdaVector DM.
lvecLocal Cmpnts vector.
gammaShear rate.
Returns
PetscErrorCode 0 on success.

Definition at line 875 of file test_solver_kernels.c.

876{
877 Cmpnts ***a;
878 PetscInt gxs, gys, gzs, gxm, gym, gzm;
879 PetscFunctionBeginUser;
880 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
881 PetscCall(DMDAVecGetArray(fda, lvec, &a));
882 for (PetscInt k = gzs; k < gzs+gzm; ++k)
883 for (PetscInt j = gys; j < gys+gym; ++j)
884 for (PetscInt i = gxs; i < gxs+gxm; ++i) { a[k][j][i].x = gamma*j; a[k][j][i].y = 0; a[k][j][i].z = 0; }
885 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
886 PetscFunctionReturn(0);
887}
Here is the caller graph for this function:

◆ TestMomentumStabilityAnisotropicViscous()

static PetscErrorCode TestMomentumStabilityAnisotropicViscous ( void  )
static

Definition at line 891 of file test_solver_kernels.c.

892{
893 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
894 PetscFunctionBeginUser;
895 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
896 simCtx->invicid = 0; simCtx->ren = 1.0;
897 PetscCall(MomSetCartesianMetrics(user, 1.0, 2.0, 4.0)); /* 8*(1 + 1/4 + 1/16) = 10.5 */
898 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
899 PetscCall(PicurvAssertRealNear(10.5, rep.lambda_v, 1e-9, "anisotropic viscous = 8nu*sum(1/d^2)"));
900 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
901 PetscFunctionReturn(0);
902}
static PetscErrorCode MomSetCartesianMetrics(UserCtx *user, PetscReal dx, PetscReal dy, PetscReal dz)
Sets uniform Cartesian metrics for spacing (dx,dy,dz) on all cell and face arrays.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityDirectionalQuick()

static PetscErrorCode TestMomentumStabilityDirectionalQuick ( void  )
static

Definition at line 905 of file test_solver_kernels.c.

906{
907 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
908 PetscFunctionBeginUser;
909 PetscCall(MomMakeUnitGridP(&simCtx, &user, 8, PETSC_FALSE, PETSC_TRUE, PETSC_TRUE, INLET)); /* x non-periodic */
910 simCtx->central = 0; simCtx->invicid = 1;
911 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 3.0, 3.0, 3.0));
912 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
913 /* boundary cell: 0.5*(2.5*6 + (4/3)*6 + (4/3)*6) = 15.5 ; NOT 22.5 (all-2.5). */
914 PetscCall(PicurvAssertRealNear(15.5, rep.lambda_c, 1e-9, "only x-direction modified to 2.5"));
915 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
916 PetscFunctionReturn(0);
917}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityOneSidedDirections()

static PetscErrorCode TestMomentumStabilityOneSidedDirections ( void  )
static

Definition at line 920 of file test_solver_kernels.c.

921{
922 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
923 const PetscInt offs[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; /* x,y,z neighbors of (4,4,4) */
924 PetscFunctionBeginUser;
925 for (int d = 0; d < 3; ++d) {
926 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
927 simCtx->invicid = 0; simCtx->ren = 1.0;
928 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert,
929 4+offs[d][0], 4+offs[d][1], 4+offs[d][2], 1.0));
930 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
931 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "single-direction one-sided x2"));
932 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.one_sided, "one-sided flagged"));
933 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
934 }
935 /* multiple solid neighbors still apply x2 only once (48, not 96). */
936 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
937 simCtx->invicid = 0; simCtx->ren = 1.0;
938 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 5, 4, 4, 1.0));
939 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 5, 4, 1.0));
940 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
941 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "multiple triggers -> x2 once (not 96)"));
942 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
943 PetscFunctionReturn(0);
944}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityActiveRowMask()

static PetscErrorCode TestMomentumStabilityActiveRowMask ( void  )
static

Definition at line 948 of file test_solver_kernels.c.

949{
950 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
951 PetscFunctionBeginUser;
952 /* Positive non-periodic x face (i=mx-2) disables the xi row only; cell stays active. */
953 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, INLET));
954 simCtx->central = 1; simCtx->invicid = 1;
955 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 2.0, 2.0, 2.0));
956 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
957 PetscCall(PicurvAssertBool((PetscBool)(rep.active_cells > 0), "boundary cells remain active"));
958 PetscCall(PicurvAssertBool((PetscBool)(rep.lambda > rep.lambda_t), "tangential rows retained"));
959 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
960 /* All cells solid -> zero active -> estimate falls back to lambda_t only. */
961 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
962 simCtx->invicid = 1;
963 PetscCall(MomFillLocalScalar(user->da, user->lNvert, 1.0)); /* every cell solid */
964 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
965 PetscCall(PicurvAssertIntEqual(0, rep.active_cells, "all solid -> zero active cells"));
966 PetscCall(PicurvAssertRealNear(rep.lambda_t, rep.lambda, 1e-12, "empty active set -> lambda_t only"));
967 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
968 PetscFunctionReturn(0);
969}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityValidation()

static PetscErrorCode TestMomentumStabilityValidation ( void  )
static

Definition at line 972 of file test_solver_kernels.c.

973{
974 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
975 PetscErrorCode e1 = 0, e2 = 0;
976 PetscFunctionBeginUser;
977 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
978 simCtx->invicid = 0; simCtx->ren = 1.0;
979
980 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
981 e1 = ComputeMomentumStabilityEstimate(user, 0, simCtx->dt, MOM_STAB_CAND_C, &rep); /* block_number=0 */
982 PetscCall(PetscPopErrorHandler());
983 PetscCall(PicurvAssertBool((PetscBool)(e1 != 0), "block_number<=0 rejected"));
984
985 PetscCall(MomSetLocalScalarCell(user->da, user->lAj, 4, 4, 4, PETSC_INFINITY)); /* bad metric */
986 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
987 e2 = ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep);
988 PetscCall(PetscPopErrorHandler());
989 PetscCall(PicurvAssertBool((PetscBool)(e2 != 0), "non-finite inverse-Jacobian rejected"));
990
991 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
992 PetscFunctionReturn(0);
993}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityCandidateBCDivergence()

static PetscErrorCode TestMomentumStabilityCandidateBCDivergence ( void  )
static

Definition at line 996 of file test_solver_kernels.c.

997{
998 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
999 PetscFunctionBeginUser;
1000 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1001 simCtx->central = 1; simCtx->invicid = 1; /* f_c=1 isolates the div term */
1002 PetscCall(MomFillUcontXRamp(user->fda, user->lUcont, 2.0)); /* div = slope = 2 */
1003 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
1004 /* C - B = 0.5*Aj*|div| = 0.5*2 = 1.0 at the (shared) controlling cell. */
1005 PetscCall(PicurvAssertRealNear(1.0, rep.lambda_C - rep.lambda_B, 1e-9, "C-B = divergence term"));
1006 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1007 PetscFunctionReturn(0);
1008}
static PetscErrorCode MomFillUcontXRamp(DM fda, Vec lvec, PetscReal slope)
Fills lUcont.x as a linear ramp slope*i (nonzero discrete contravariant divergence).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityCandidateDShear()

static PetscErrorCode TestMomentumStabilityCandidateDShear ( void  )
static

Definition at line 1011 of file test_solver_kernels.c.

1012{
1013 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1014 PetscFunctionBeginUser;
1015 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1016 simCtx->central = 1; simCtx->invicid = 1;
1017 PetscCall(MomFillUcatShearY(user->fda, user->lUcat, 2.0)); /* |grad u|_inf = gamma = 2 */
1018 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1019 PetscCall(PicurvAssertRealNear(2.0, rep.lambda_D - rep.lambda_C, 1e-9, "D-C = |grad u| on shear"));
1020 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1021
1022 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1023 simCtx->central = 1; simCtx->invicid = 1;
1024 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcat, 0.7, -0.3, 0.5)); /* uniform velocity */
1025 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1026 PetscCall(PicurvAssertRealNear(rep.lambda_C, rep.lambda_D, 1e-12, "D == C for uniform velocity"));
1027 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1028 PetscFunctionReturn(0);
1029}
static PetscErrorCode MomFillUcatShearY(DM fda, Vec lvec, PetscReal gamma)
Fills lUcat as a linear shear u=(gamma*j,0,0) so |grad u|_inf = gamma.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityWallSuppression()

static PetscErrorCode TestMomentumStabilityWallSuppression ( void  )
static

Definition at line 1032 of file test_solver_kernels.c.

1033{
1034 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1035 PetscFunctionBeginUser;
1036 /* n=3 -> DMDA mx=4 -> interior cells {1,2}; every interior cell touches 3 wall faces
1037 (no wall-free interior cell exists, so the global max reflects suppression). */
1038 PetscCall(MomMakeUnitGrid(&simCtx, &user, 3, WALL));
1039 simCtx->invicid = 0; simCtx->ren = 1.0; simCtx->les = 1;
1040 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 1.0));
1041 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
1042 /* 3 wall faces (nu_t suppressed, nu_eff=1) + 3 interior faces (nu_eff=2): 4*(3*1+3*2)=36. */
1043 PetscCall(PicurvAssertRealNear(36.0, rep.lambda_v, 1e-9, "wall-face eddy viscosity suppressed"));
1044 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1045 PetscFunctionReturn(0);
1046}
@ WALL
Definition variables.h:286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityReadOnlyExact()

static PetscErrorCode TestMomentumStabilityReadOnlyExact ( void  )
static

Definition at line 1049 of file test_solver_kernels.c.

1050{
1051 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1052 Vec ucont0, ucat0, nvert0, nut0, aj0;
1053 PetscBool eq;
1054 PetscFunctionBeginUser;
1055 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1056 simCtx->invicid = 0; simCtx->ren = 2.0; simCtx->les = 1;
1057 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 1.5, -0.7, 0.3));
1058 PetscCall(MomFillUcatShearY(user->fda, user->lUcat, 1.1));
1059 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 0.4));
1060 PetscCall(VecDuplicate(user->lUcont, &ucont0)); PetscCall(VecCopy(user->lUcont, ucont0));
1061 PetscCall(VecDuplicate(user->lUcat, &ucat0)); PetscCall(VecCopy(user->lUcat, ucat0));
1062 PetscCall(VecDuplicate(user->lNvert, &nvert0)); PetscCall(VecCopy(user->lNvert, nvert0));
1063 PetscCall(VecDuplicate(user->lNu_t, &nut0)); PetscCall(VecCopy(user->lNu_t, nut0));
1064 PetscCall(VecDuplicate(user->lAj, &aj0)); PetscCall(VecCopy(user->lAj, aj0));
1065 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1066 PetscCall(VecEqual(user->lUcont, ucont0, &eq)); PetscCall(PicurvAssertBool(eq, "lUcont bit-identical"));
1067 PetscCall(VecEqual(user->lUcat, ucat0, &eq)); PetscCall(PicurvAssertBool(eq, "lUcat bit-identical"));
1068 PetscCall(VecEqual(user->lNvert, nvert0, &eq)); PetscCall(PicurvAssertBool(eq, "lNvert bit-identical"));
1069 PetscCall(VecEqual(user->lNu_t, nut0, &eq)); PetscCall(PicurvAssertBool(eq, "lNu_t bit-identical"));
1070 PetscCall(VecEqual(user->lAj, aj0, &eq)); PetscCall(PicurvAssertBool(eq, "lAj bit-identical"));
1071 PetscCall(VecDestroy(&ucont0)); PetscCall(VecDestroy(&ucat0)); PetscCall(VecDestroy(&nvert0));
1072 PetscCall(VecDestroy(&nut0)); PetscCall(VecDestroy(&aj0));
1073 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1074 PetscFunctionReturn(0);
1075}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumActiveRowsHelper()

static PetscErrorCode TestMomentumActiveRowsHelper ( void  )
static

Definition at line 1079 of file test_solver_kernels.c.

1080{
1081 SimCtx *simCtx = NULL; UserCtx *user = NULL;
1082 PetscReal ***nvert;
1083 const PetscInt mx = 9, my = 9, mz = 9;
1084 PetscFunctionBeginUser;
1085 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC)); /* mx=9; all fluid */
1086 PetscCall(DMDAVecGetArray(user->da, user->lNvert, &nvert));
1087 /* fully periodic interior cell (4,4,4): all rows active regardless of TwoD value below. */
1088 PetscCall(PicurvAssertIntEqual(0x7, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,0), "all rows active (periodic interior)"));
1089 PetscCall(PicurvAssertIntEqual(0x6, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,1), "TwoD=1 clears xi row"));
1090 PetscCall(PicurvAssertIntEqual(0x5, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,2), "TwoD=2 clears eta row"));
1091 PetscCall(PicurvAssertIntEqual(0x3, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,3), "TwoD=3 clears zeta row"));
1092 /* positive non-periodic faces clear the corresponding normal rows. */
1093 PetscCall(PicurvAssertIntEqual(0x6, MomCellActiveRows(nvert,4,4,mx-2,mx,my,mz,PETSC_TRUE,PETSC_FALSE,PETSC_FALSE,0), "pos non-periodic xi face clears xi row"));
1094 /* a location is skipped only when all three rows are inactive (here: solid cell). */
1095 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 4, 4, 1.0));
1096 PetscCall(DMDAVecRestoreArray(user->da, user->lNvert, &nvert));
1097 PetscCall(DMDAVecGetArray(user->da, user->lNvert, &nvert));
1098 PetscCall(PicurvAssertIntEqual(0, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,0), "solid cell -> all rows inactive"));
1099 PetscCall(DMDAVecRestoreArray(user->da, user->lNvert, &nvert));
1100 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1101 PetscFunctionReturn(0);
1102}
PetscInt MomCellActiveRows(PetscReal ***nvert, PetscInt k, PetscInt j, PetscInt i, PetscInt mx, PetscInt my, PetscInt mz, PetscBool np_x1, PetscBool np_y1, PetscBool np_z1, PetscInt twoD)
Active staggered-momentum row mask for a cell (exposed for unit testing).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumStabilityErrorReentry()

static PetscErrorCode TestMomentumStabilityErrorReentry ( void  )
static

Definition at line 1105 of file test_solver_kernels.c.

1106{
1107 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1108 PetscErrorCode e_bad = 0; PetscBool eq;
1109 Vec aj_good;
1110 PetscFunctionBeginUser;
1111 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1112 simCtx->invicid = 0; simCtx->ren = 1.0;
1113 PetscCall(VecDuplicate(user->lAj, &aj_good)); PetscCall(VecCopy(user->lAj, aj_good));
1114
1115 PetscCall(MomSetLocalScalarCell(user->da, user->lAj, 4, 4, 4, PETSC_INFINITY));
1116 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
1117 e_bad = ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep);
1118 PetscCall(PetscPopErrorHandler());
1119 PetscCall(PicurvAssertBool((PetscBool)(e_bad != 0), "bad metric triggers error"));
1120
1121 /* Arrays must have been restored: lAj is still writable/usable -> repair it. */
1122 PetscCall(VecCopy(aj_good, user->lAj));
1123 PetscCall(VecEqual(user->lAj, aj_good, &eq));
1124 PetscCall(PicurvAssertBool(eq, "lAj usable after error (arrays were restored)"));
1125
1126 /* Re-entry must now succeed on the repaired state. */
1127 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
1128 PetscCall(PicurvAssertRealNear(24.0, rep.lambda_v, 1e-9, "estimator reusable after repair"));
1129 PetscCall(VecDestroy(&aj_good));
1130 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1131 PetscFunctionReturn(0);
1132}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMomentumBDFResidualCombination()

static PetscErrorCode TestMomentumBDFResidualCombination ( void  )
static

Definition at line 1136 of file test_solver_kernels.c.

1137{
1138 SimCtx *simCtx = NULL; UserCtx *user = NULL;
1139 Vec Rhs, ref; PetscReal dt, nrm;
1140 PetscFunctionBeginUser;
1141 PetscCall(MomMakeUnitGrid(&simCtx, &user, 6, PERIODIC));
1142 dt = simCtx->dt;
1143 PetscCall(VecSet(user->Ucont, 2.0)); /* U^{n} */
1144 PetscCall(VecSet(user->Ucont_o, 1.0)); /* U^{n-1} */
1145 PetscCall(VecSet(user->Ucont_rm1, 0.5)); /* U^{n-2} */
1146 PetscCall(VecDuplicate(user->Ucont, &Rhs));
1147 PetscCall(VecDuplicate(user->Ucont, &ref));
1148
1149 /* ---- BDF2 (step != 1, step != StartStep) ---- */
1150 simCtx->StartStep = 0; simCtx->step = 5;
1151 PetscCall(PicurvAssertBool(MomentumUsesBDF2(simCtx), "step5 uses BDF2"));
1152 {
1153 const PetscReal a0 = MomentumBDFCoefficient(simCtx); /* == 1.5 */
1154 PetscCall(VecSet(Rhs, 3.0)); /* mock R_spatial */
1155 PetscCall(VecAXPY(Rhs, -a0/dt, user->Ucont));
1156 PetscCall(VecAXPY(Rhs, +2.0/dt, user->Ucont_o));
1157 PetscCall(VecAXPY(Rhs, -0.5/dt, user->Ucont_rm1));
1158 /* independent reference: 3 + (-1.5*2 + 2*1 - 0.5*0.5)/dt = 3 + (-3+2-0.25)/0.1 = 3 - 12.5 = -9.5 */
1159 PetscCall(VecSet(ref, -9.5));
1160 PetscCall(VecAXPY(ref, -1.0, Rhs)); PetscCall(VecNorm(ref, NORM_INFINITY, &nrm));
1161 PetscCall(PicurvAssertRealNear(0.0, nrm, 1e-9, "BDF2 temporal vector combination"));
1162 }
1163 /* ---- BDF1 (step == 1) ---- */
1164 simCtx->StartStep = 0; simCtx->step = 1;
1165 PetscCall(PicurvAssertBool((PetscBool)(!MomentumUsesBDF2(simCtx)), "step1 uses BDF1"));
1166 {
1167 const PetscReal a0 = MomentumBDFCoefficient(simCtx); /* == 1.0 */
1168 PetscCall(VecSet(Rhs, 3.0));
1169 PetscCall(VecAXPY(Rhs, -a0/dt, user->Ucont));
1170 PetscCall(VecAXPY(Rhs, +1.0/dt, user->Ucont_o));
1171 /* reference: 3 + (-1*2 + 1*1)/0.1 = 3 + (-1)/0.1 = 3 - 10 = -7.0 */
1172 PetscCall(VecSet(ref, -7.0));
1173 PetscCall(VecAXPY(ref, -1.0, Rhs)); PetscCall(VecNorm(ref, NORM_INFINITY, &nrm));
1174 PetscCall(PicurvAssertRealNear(0.0, nrm, 1e-9, "BDF1 temporal vector combination"));
1175 }
1176 PetscCall(VecDestroy(&Rhs)); PetscCall(VecDestroy(&ref));
1177 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1178 PetscFunctionReturn(0);
1179}
Vec Ucont_o
Definition variables.h:946
Vec Ucont_rm1
Definition variables.h:947
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Runs the unit-solver PETSc test binary.

Definition at line 1185 of file test_solver_kernels.c.

1186{
1187 PetscErrorCode ierr;
1188 const PicurvTestCase cases[] = {
1189 {"les-filter-paths", TestLESTestFilterPaths},
1190 {"analytical-geometry-selection", TestAnalyticalGeometrySelection},
1191 {"analytical-scalar-verification-helpers", TestAnalyticalScalarVerificationHelpers},
1192 {"analytical-solution-engine-dispatch", TestAnalyticalSolutionEngineDispatch},
1193 {"analytical-solution-engine-taylor-green-samples", TestAnalyticalSolutionEngineTaylorGreenSamples},
1194 {"analytical-solution-for-particles-dispatch", TestAnalyticalSolutionForParticlesDispatch},
1195 {"compute-eddy-viscosity-les-deterministic-field", TestComputeEddyViscosityLESDeterministicField},
1196 {"flow-solver-rejects-unsupported-momentum-solver-type", TestFlowSolverRejectsUnsupportedMomentumSolverType},
1197 {"driven-channel-flow-source", TestDrivenChannelFlowSource},
1198 {"momentum-bdf-coefficient", TestMomentumBDFCoefficient},
1199 {"momentum-stability-centered-convection", TestMomentumStabilityCenteredConvection},
1200 {"momentum-stability-quick-interior", TestMomentumStabilityQuickInterior},
1201 {"momentum-stability-quick-boundary", TestMomentumStabilityQuickBoundary},
1202 {"momentum-stability-viscous-cartesian-factor8-estimate", TestMomentumStabilityViscousLongitudinal},
1203 {"momentum-stability-viscous-scales-with-nu", TestMomentumStabilityViscousScalesWithNu},
1204 {"momentum-stability-les-eddy-viscosity", TestMomentumStabilityLESEddyViscosity},
1205 {"momentum-stability-one-sided-viscous", TestMomentumStabilityOneSidedViscous},
1206 {"momentum-stability-read-only", TestMomentumStabilityReadOnly},
1207 {"momentum-stability-anisotropic-viscous", TestMomentumStabilityAnisotropicViscous},
1208 {"momentum-stability-directional-quick", TestMomentumStabilityDirectionalQuick},
1209 {"momentum-stability-one-sided-directions", TestMomentumStabilityOneSidedDirections},
1210 {"momentum-stability-active-row-mask", TestMomentumStabilityActiveRowMask},
1211 {"momentum-stability-validation", TestMomentumStabilityValidation},
1212 {"momentum-stability-candidate-bc-divergence", TestMomentumStabilityCandidateBCDivergence},
1213 {"momentum-stability-candidate-d-shear", TestMomentumStabilityCandidateDShear},
1214 {"momentum-stability-wall-suppression", TestMomentumStabilityWallSuppression},
1215 {"momentum-stability-read-only-exact", TestMomentumStabilityReadOnlyExact},
1216 {"momentum-active-rows-helper", TestMomentumActiveRowsHelper},
1217 {"momentum-stability-error-reentry", TestMomentumStabilityErrorReentry},
1218 {"momentum-bdf-residual-combination", TestMomentumBDFResidualCombination},
1219 };
1220
1221 ierr = PetscInitialize(&argc, &argv, NULL, "PICurv solver utility tests");
1222 if (ierr) {
1223 return (int)ierr;
1224 }
1225
1226 ierr = PicurvRunTests("unit-solver", cases, sizeof(cases) / sizeof(cases[0]));
1227 if (ierr) {
1228 PetscFinalize();
1229 return (int)ierr;
1230 }
1231
1232 ierr = PetscFinalize();
1233 return (int)ierr;
1234}
static PetscErrorCode TestAnalyticalSolutionEngineTaylorGreenSamples(void)
Tests exact Taylor-Green samples on selected Eulerian interior and boundary points.
static PetscErrorCode TestMomentumStabilityWallSuppression(void)
static PetscErrorCode TestMomentumActiveRowsHelper(void)
static PetscErrorCode TestComputeEddyViscosityLESDeterministicField(void)
Tests deterministic LES eddy-viscosity computation on a linear velocity field.
static PetscErrorCode TestFlowSolverRejectsUnsupportedMomentumSolverType(void)
Tests FlowSolver guardrails for unsupported momentum solver selections.
static PetscErrorCode TestMomentumStabilityOneSidedDirections(void)
static PetscErrorCode TestMomentumStabilityReadOnly(void)
static PetscErrorCode TestMomentumStabilityOneSidedViscous(void)
static PetscErrorCode TestAnalyticalScalarVerificationHelpers(void)
Tests analytical scalar verification helper routines.
static PetscErrorCode TestMomentumStabilityReadOnlyExact(void)
static PetscErrorCode TestMomentumStabilityErrorReentry(void)
static PetscErrorCode TestMomentumStabilityActiveRowMask(void)
static PetscErrorCode TestMomentumStabilityCandidateDShear(void)
static PetscErrorCode TestMomentumStabilityViscousLongitudinal(void)
static PetscErrorCode TestMomentumStabilityCandidateBCDivergence(void)
static PetscErrorCode TestDrivenChannelFlowSource(void)
Tests driven-channel flow source-term evaluation.
static PetscErrorCode TestMomentumStabilityViscousScalesWithNu(void)
static PetscErrorCode TestMomentumStabilityAnisotropicViscous(void)
static PetscErrorCode TestAnalyticalGeometrySelection(void)
Tests analytical geometry selection for supported analytical solutions.
static PetscErrorCode TestMomentumBDFCoefficient(void)
static PetscErrorCode TestMomentumStabilityCenteredConvection(void)
static PetscErrorCode TestMomentumStabilityDirectionalQuick(void)
static PetscErrorCode TestAnalyticalSolutionForParticlesDispatch(void)
Tests particle analytical-solution dispatch for TGV3D, UNIFORM_FLOW, and non-analytical no-op paths.
static PetscErrorCode TestMomentumBDFResidualCombination(void)
static PetscErrorCode TestLESTestFilterPaths(void)
Tests LES test-filter helper paths for representative cases.
static PetscErrorCode TestMomentumStabilityQuickBoundary(void)
static PetscErrorCode TestMomentumStabilityLESEddyViscosity(void)
static PetscErrorCode TestMomentumStabilityQuickInterior(void)
static PetscErrorCode TestAnalyticalSolutionEngineDispatch(void)
Tests analytical solution engine ZERO_FLOW, UNIFORM_FLOW, and unknown-type dispatch.
static PetscErrorCode TestMomentumStabilityValidation(void)
PetscErrorCode PicurvRunTests(const char *suite_name, const PicurvTestCase *cases, size_t case_count)
Runs a named C test suite and prints pass/fail progress markers.
Named test case descriptor consumed by PicurvRunTests.
Here is the call graph for this function: