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:123
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:792
The master context for the entire simulation.
Definition variables.h:684
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:768
PetscReal Min_X
Definition variables.h:886
PetscInt _this
Definition variables.h:889
PetscReal Max_Y
Definition variables.h:886
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:717
PetscReal Max_X
Definition variables.h:886
PetscReal Min_Y
Definition variables.h:886
PetscReal Max_Z
Definition variables.h:886
User-defined context containing data specific to a single computational grid level.
Definition variables.h:876
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
140 PetscCall(SetAnalyticalScalarFieldOnParticles(user, "Psi"));
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 SetAnalyticalScalarFieldOnParticles(UserCtx *user, const char *swarm_field_name)
Writes the configured verification scalar profile onto a particle swarm scalar field.
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 PicurvCreateSwarmPair(UserCtx *user, PetscInt nlocal, const char *post_field_name)
Creates matched solver and post-processing swarms for tests.
VerificationScalarConfig verificationScalar
Definition variables.h:756
Vec Psi
Definition variables.h:953
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:927
Vec Ucont
Definition variables.h:904
Vec Ubcs
Physical Cartesian velocity at boundary faces. Full 3D array but only boundary-face entries are meani...
Definition variables.h:121
PetscScalar x
Definition variables.h:101
BCS Bcs
Definition variables.h:899
Vec lCsi
Definition variables.h:927
Cmpnts AnalyticalUniformVelocity
Definition variables.h:748
PetscScalar z
Definition variables.h:101
Vec Ucat
Definition variables.h:904
PetscScalar y
Definition variables.h:101
Vec lEta
Definition variables.h:927
A 3D point or vector with PetscScalar components.
Definition variables.h:100
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:732
Vec lCenty
Definition variables.h:929
Vec lCentx
Definition variables.h:929
DMDALocalInfo info
Definition variables.h:883
Vec Cent
Definition variables.h:927
Vec lCentz
Definition variables.h:929
PetscReal ti
Definition variables.h:693
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:935
Vec lNu_t
Definition variables.h:935
Vec Nu_t
Definition variables.h:935
Vec lAj
Definition variables.h:927
Vec lUcat
Definition variables.h:904
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:532
MomentumSolverType mom_solver_type
Definition variables.h:724
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:290
BoundaryFaceConfig boundary_faces[6]
Definition variables.h:896
Vec lNvert
Definition variables.h:904
PetscReal forceScalingFactor
Definition variables.h:779
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
Definition variables.h:316
BCHandlerType handler_type
Definition variables.h:367
PetscReal dt
Definition variables.h:699
PetscReal bulkVelocityCorrection
Definition variables.h:781
Vec Nvert
Definition variables.h:904
BCType mathematical_type
Definition variables.h:366
PetscReal drivingForceMagnitude
Definition variables.h:779
@ BC_FACE_NEG_X
Definition variables.h:260
@ BC_FACE_POS_X
Definition variables.h:260
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 626 of file test_solver_kernels.c.

627{
628 SimCtx *simCtx = NULL; UserCtx *user = NULL;
629 PetscFunctionBeginUser;
630 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 6, 6, 6));
631 simCtx->StartStep = 0; simCtx->step = 1;
632 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 on cold-start step 1"));
633 PetscCall(PicurvAssertBool((PetscBool)(!MomentumUsesBDF2(simCtx)), "step 1 is BDF1"));
634 simCtx->step = 5;
635 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF2 on interior step"));
636 PetscCall(PicurvAssertBool(MomentumUsesBDF2(simCtx), "step 5 (StartStep 0) is BDF2"));
637 simCtx->StartStep = 5; simCtx->step = 5;
638 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 on restart step (ti==tistart)"));
639 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
640 PetscFunctionReturn(0);
641}
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:694
PetscInt step
Definition variables.h:692
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 646 of file test_solver_kernels.c.

648{
649 PetscFunctionBeginUser;
650 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(simCtx, user, n, n, n, px, py, pz));
651 (*user)->boundary_faces[BC_FACE_NEG_X].mathematical_type = px ? PERIODIC : bc;
652 (*user)->boundary_faces[BC_FACE_POS_X].mathematical_type = px ? PERIODIC : bc;
653 (*user)->boundary_faces[BC_FACE_NEG_Y].mathematical_type = py ? PERIODIC : bc;
654 (*user)->boundary_faces[BC_FACE_POS_Y].mathematical_type = py ? PERIODIC : bc;
655 (*user)->boundary_faces[BC_FACE_NEG_Z].mathematical_type = pz ? PERIODIC : bc;
656 (*user)->boundary_faces[BC_FACE_POS_Z].mathematical_type = pz ? PERIODIC : bc;
657 (*simCtx)->dt = 0.1; (*simCtx)->step = 1; (*simCtx)->StartStep = 0; /* a0=1 -> lambda_t=10 */
658 (*simCtx)->ren = 1.0; (*simCtx)->les = 0; (*simCtx)->rans = 0;
659 (*simCtx)->central = 0; (*simCtx)->invicid = 0; (*simCtx)->block_number = 1;
660 (*simCtx)->TwoD = 0; (*simCtx)->clark = 0;
661 /* The minimal fixture does not allocate lNu_t (LES off by default); create a
662 zeroed one so the estimator can read it when a test enables LES/RANS. */
663 if (!(*user)->lNu_t) PetscCall(DMCreateLocalVector((*user)->da, &(*user)->lNu_t));
664 PetscCall(MomFillLocalCmpnts((*user)->fda, (*user)->lUcont, 0.0, 0.0, 0.0));
665 PetscCall(MomFillLocalCmpnts((*user)->fda, (*user)->lUcat, 0.0, 0.0, 0.0));
666 PetscCall(MomFillLocalScalar((*user)->da, (*user)->lNvert, 0.0));
667 PetscCall(MomFillLocalScalar((*user)->da, (*user)->lNu_t, 0.0));
668 PetscFunctionReturn(0);
669}
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 672 of file test_solver_kernels.c.

673{
674 const PetscBool p = (PetscBool)(bc == PERIODIC);
675 PetscFunctionBeginUser;
676 PetscCall(MomMakeUnitGridP(simCtx, user, n, p, p, p, bc));
677 PetscFunctionReturn(0);
678}
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 681 of file test_solver_kernels.c.

682{
683 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
684 PetscFunctionBeginUser;
685 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
686 simCtx->central = 1; simCtx->invicid = 1;
687 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 2.0, 0.0, 0.0));
688 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
689 PetscCall(PicurvAssertRealNear(10.0, rep.lambda_t, 1e-9, "lambda_t = a0/dt"));
690 PetscCall(PicurvAssertRealNear(2.0, rep.lambda_c, 1e-9, "centered conv f_c=1 (Aj*U^xi scaling)"));
691 PetscCall(PicurvAssertRealNear(0.0, rep.lambda_v, 1e-9, "inviscid: no viscous term"));
692 PetscCall(PicurvAssertRealNear(12.0, rep.lambda, 1e-9, "total lambda"));
693 PetscCall(PicurvAssertIntEqual(0, (PetscInt)rep.cclass, "interior cell class"));
694 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
695 PetscFunctionReturn(0);
696}
@ 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:715
PetscInt central
Definition variables.h:730
Vec lUcont
Definition variables.h:904
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 699 of file test_solver_kernels.c.

700{
701 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
702 PetscFunctionBeginUser;
703 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
704 simCtx->central = 0; simCtx->invicid = 1; /* QUICK branch */
705 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 3.0, 0.0, 0.0));
706 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
707 PetscCall(PicurvAssertRealNear(4.0, rep.lambda_c, 1e-9, "QUICK interior f_c=4/3 (4/3*3=4)"));
708 PetscCall(PicurvAssertIntEqual(0, (PetscInt)rep.cclass, "interior cell class"));
709 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
710 PetscFunctionReturn(0);
711}
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 714 of file test_solver_kernels.c.

715{
716 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
717 PetscFunctionBeginUser;
718 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, INLET)); /* non-periodic -> boundary band active */
719 simCtx->central = 0; simCtx->invicid = 1;
720 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 8.0, 0.0, 0.0));
721 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
722 PetscCall(PicurvAssertRealNear(20.0, rep.lambda_c, 1e-9, "boundary QUICK f_c=2.5 (2.5*8=20)"));
723 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.cclass, "physical-boundary cell class"));
724 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
725 PetscFunctionReturn(0);
726}
@ INLET
Definition variables.h:288
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 729 of file test_solver_kernels.c.

730{
731 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
732 PetscFunctionBeginUser;
733 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
734 simCtx->invicid = 0; simCtx->ren = 1.0; /* nu = 1, no convection */
735 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
736 PetscCall(PicurvAssertRealNear(24.0, rep.lambda_v, 1e-9, "viscous = 4*6*nu = 24nu (factor-8 longitudinal)"));
737 PetscCall(PicurvAssertRealNear(34.0, rep.lambda, 1e-9, "total lambda_t+lambda_v"));
738 PetscCall(PicurvAssertIntEqual((PetscInt)MOM_STAB_LIMITER_VISCOSITY, (PetscInt)rep.limiter, "viscosity-limited"));
739 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
740 PetscFunctionReturn(0);
741}
@ 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 744 of file test_solver_kernels.c.

745{
746 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
747 PetscFunctionBeginUser;
748 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
749 simCtx->invicid = 0; simCtx->ren = 4.0; /* nu = 0.25 -> 24*0.25 = 6 */
750 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
751 PetscCall(PicurvAssertRealNear(6.0, rep.lambda_v, 1e-9, "viscous scales with nu=1/Re"));
752 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
753 PetscFunctionReturn(0);
754}
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 757 of file test_solver_kernels.c.

758{
759 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
760 PetscFunctionBeginUser;
761 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
762 simCtx->invicid = 0; simCtx->ren = 1.0; simCtx->les = 1; /* nu_eff = 1 + nu_t */
763 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 1.0)); /* nu_t = 1 -> nu_eff = 2 -> 24*2 = 48 */
764 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
765 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "LES nu_t adds: 4*6*(1+1) = 48"));
766 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
767 PetscFunctionReturn(0);
768}
PetscInt les
Definition variables.h:789
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 771 of file test_solver_kernels.c.

772{
773 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
774 PetscFunctionBeginUser;
775 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
776 simCtx->invicid = 0; simCtx->ren = 1.0;
777 /* Mark one interior cell solid; its fluid cross-neighbours get the one-sided x2 (24 -> 48). */
778 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 5, 4, 1.0));
779 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
780 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "one-sided viscous x2 (24 -> 48)"));
781 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.one_sided, "one-sided multiplier flagged"));
782 PetscCall(PicurvAssertIntEqual(2, (PetscInt)rep.cclass, "IB-adjacent cell class"));
783 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
784 PetscFunctionReturn(0);
785}
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 788 of file test_solver_kernels.c.

789{
790 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
791 PetscReal n_ucont_0, n_ucat_0, n_nvert_0, n_ucont_1, n_ucat_1, n_nvert_1;
792 PetscFunctionBeginUser;
793 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
794 simCtx->invicid = 0; simCtx->ren = 2.0;
795 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 1.5, -0.7, 0.3));
796 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcat, 0.9, 0.4, -0.2));
797 PetscCall(VecNorm(user->lUcont, NORM_2, &n_ucont_0));
798 PetscCall(VecNorm(user->lUcat, NORM_2, &n_ucat_0));
799 PetscCall(VecNorm(user->lNvert, NORM_2, &n_nvert_0));
800 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
801 PetscCall(VecNorm(user->lUcont, NORM_2, &n_ucont_1));
802 PetscCall(VecNorm(user->lUcat, NORM_2, &n_ucat_1));
803 PetscCall(VecNorm(user->lNvert, NORM_2, &n_nvert_1));
804 PetscCall(PicurvAssertRealNear(n_ucont_0, n_ucont_1, 1e-14, "lUcont unchanged by estimator"));
805 PetscCall(PicurvAssertRealNear(n_ucat_0, n_ucat_1, 1e-14, "lUcat unchanged by estimator"));
806 PetscCall(PicurvAssertRealNear(n_nvert_0, n_nvert_1, 1e-14, "lNvert unchanged by estimator"));
807 PetscCall(PicurvAssertBool((PetscBool)(rep.lambda > 0.0), "estimate finite and positive"));
808 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
809 PetscFunctionReturn(0);
810}
@ 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 818 of file test_solver_kernels.c.

819{
820 const PetscReal sx = dy*dz, sy = dx*dz, sz = dx*dy, aj = 1.0/(dx*dy*dz);
821 Vec csiv[] = {user->lCsi, user->lICsi, user->lJCsi, user->lKCsi};
822 Vec etav[] = {user->lEta, user->lIEta, user->lJEta, user->lKEta};
823 Vec zetv[] = {user->lZet, user->lIZet, user->lJZet, user->lKZet};
824 Vec ajv[] = {user->lAj, user->lIAj, user->lJAj, user->lKAj};
825 PetscFunctionBeginUser;
826 for (int t = 0; t < 4; ++t) {
827 PetscCall(MomFillLocalCmpnts(user->fda, csiv[t], sx, 0, 0));
828 PetscCall(MomFillLocalCmpnts(user->fda, etav[t], 0, sy, 0));
829 PetscCall(MomFillLocalCmpnts(user->fda, zetv[t], 0, 0, sz));
830 PetscCall(MomFillLocalScalar(user->da, ajv[t], aj));
831 }
832 PetscFunctionReturn(0);
833}
Vec lIEta
Definition variables.h:930
Vec lIZet
Definition variables.h:930
Vec lIAj
Definition variables.h:930
Vec lKEta
Definition variables.h:932
Vec lJCsi
Definition variables.h:931
Vec lKZet
Definition variables.h:932
Vec lJEta
Definition variables.h:931
Vec lKCsi
Definition variables.h:932
Vec lJZet
Definition variables.h:931
Vec lICsi
Definition variables.h:930
Vec lJAj
Definition variables.h:931
Vec lKAj
Definition variables.h:932
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 842 of file test_solver_kernels.c.

843{
844 Cmpnts ***a;
845 PetscInt gxs, gys, gzs, gxm, gym, gzm;
846 PetscFunctionBeginUser;
847 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
848 PetscCall(DMDAVecGetArray(fda, lvec, &a));
849 for (PetscInt k = gzs; k < gzs+gzm; ++k)
850 for (PetscInt j = gys; j < gys+gym; ++j)
851 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; }
852 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
853 PetscFunctionReturn(0);
854}
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 863 of file test_solver_kernels.c.

864{
865 Cmpnts ***a;
866 PetscInt gxs, gys, gzs, gxm, gym, gzm;
867 PetscFunctionBeginUser;
868 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
869 PetscCall(DMDAVecGetArray(fda, lvec, &a));
870 for (PetscInt k = gzs; k < gzs+gzm; ++k)
871 for (PetscInt j = gys; j < gys+gym; ++j)
872 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; }
873 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
874 PetscFunctionReturn(0);
875}
Here is the caller graph for this function:

◆ TestMomentumStabilityAnisotropicViscous()

static PetscErrorCode TestMomentumStabilityAnisotropicViscous ( void  )
static

Definition at line 879 of file test_solver_kernels.c.

880{
881 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
882 PetscFunctionBeginUser;
883 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
884 simCtx->invicid = 0; simCtx->ren = 1.0;
885 PetscCall(MomSetCartesianMetrics(user, 1.0, 2.0, 4.0)); /* 8*(1 + 1/4 + 1/16) = 10.5 */
886 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
887 PetscCall(PicurvAssertRealNear(10.5, rep.lambda_v, 1e-9, "anisotropic viscous = 8nu*sum(1/d^2)"));
888 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
889 PetscFunctionReturn(0);
890}
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 893 of file test_solver_kernels.c.

894{
895 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
896 PetscFunctionBeginUser;
897 PetscCall(MomMakeUnitGridP(&simCtx, &user, 8, PETSC_FALSE, PETSC_TRUE, PETSC_TRUE, INLET)); /* x non-periodic */
898 simCtx->central = 0; simCtx->invicid = 1;
899 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 3.0, 3.0, 3.0));
900 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
901 /* boundary cell: 0.5*(2.5*6 + (4/3)*6 + (4/3)*6) = 15.5 ; NOT 22.5 (all-2.5). */
902 PetscCall(PicurvAssertRealNear(15.5, rep.lambda_c, 1e-9, "only x-direction modified to 2.5"));
903 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
904 PetscFunctionReturn(0);
905}
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 908 of file test_solver_kernels.c.

909{
910 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
911 const PetscInt offs[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; /* x,y,z neighbors of (4,4,4) */
912 PetscFunctionBeginUser;
913 for (int d = 0; d < 3; ++d) {
914 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
915 simCtx->invicid = 0; simCtx->ren = 1.0;
916 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert,
917 4+offs[d][0], 4+offs[d][1], 4+offs[d][2], 1.0));
918 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
919 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "single-direction one-sided x2"));
920 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.one_sided, "one-sided flagged"));
921 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
922 }
923 /* multiple solid neighbors still apply x2 only once (48, not 96). */
924 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
925 simCtx->invicid = 0; simCtx->ren = 1.0;
926 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 5, 4, 4, 1.0));
927 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 5, 4, 1.0));
928 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
929 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "multiple triggers -> x2 once (not 96)"));
930 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
931 PetscFunctionReturn(0);
932}
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 936 of file test_solver_kernels.c.

937{
938 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
939 PetscFunctionBeginUser;
940 /* Positive non-periodic x face (i=mx-2) disables the xi row only; cell stays active. */
941 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, INLET));
942 simCtx->central = 1; simCtx->invicid = 1;
943 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 2.0, 2.0, 2.0));
944 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
945 PetscCall(PicurvAssertBool((PetscBool)(rep.active_cells > 0), "boundary cells remain active"));
946 PetscCall(PicurvAssertBool((PetscBool)(rep.lambda > rep.lambda_t), "tangential rows retained"));
947 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
948 /* All cells solid -> zero active -> estimate falls back to lambda_t only. */
949 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
950 simCtx->invicid = 1;
951 PetscCall(MomFillLocalScalar(user->da, user->lNvert, 1.0)); /* every cell solid */
952 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
953 PetscCall(PicurvAssertIntEqual(0, rep.active_cells, "all solid -> zero active cells"));
954 PetscCall(PicurvAssertRealNear(rep.lambda_t, rep.lambda, 1e-12, "empty active set -> lambda_t only"));
955 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
956 PetscFunctionReturn(0);
957}
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 960 of file test_solver_kernels.c.

961{
962 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
963 PetscErrorCode e1 = 0, e2 = 0;
964 PetscFunctionBeginUser;
965 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
966 simCtx->invicid = 0; simCtx->ren = 1.0;
967
968 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
969 e1 = ComputeMomentumStabilityEstimate(user, 0, simCtx->dt, MOM_STAB_CAND_C, &rep); /* block_number=0 */
970 PetscCall(PetscPopErrorHandler());
971 PetscCall(PicurvAssertBool((PetscBool)(e1 != 0), "block_number<=0 rejected"));
972
973 PetscCall(MomSetLocalScalarCell(user->da, user->lAj, 4, 4, 4, PETSC_INFINITY)); /* bad metric */
974 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
975 e2 = ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep);
976 PetscCall(PetscPopErrorHandler());
977 PetscCall(PicurvAssertBool((PetscBool)(e2 != 0), "non-finite inverse-Jacobian rejected"));
978
979 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
980 PetscFunctionReturn(0);
981}
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 984 of file test_solver_kernels.c.

985{
986 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
987 PetscFunctionBeginUser;
988 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
989 simCtx->central = 1; simCtx->invicid = 1; /* f_c=1 isolates the div term */
990 PetscCall(MomFillUcontXRamp(user->fda, user->lUcont, 2.0)); /* div = slope = 2 */
991 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
992 /* C - B = 0.5*Aj*|div| = 0.5*2 = 1.0 at the (shared) controlling cell. */
993 PetscCall(PicurvAssertRealNear(1.0, rep.lambda_C - rep.lambda_B, 1e-9, "C-B = divergence term"));
994 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
995 PetscFunctionReturn(0);
996}
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 999 of file test_solver_kernels.c.

1000{
1001 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1002 PetscFunctionBeginUser;
1003 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1004 simCtx->central = 1; simCtx->invicid = 1;
1005 PetscCall(MomFillUcatShearY(user->fda, user->lUcat, 2.0)); /* |grad u|_inf = gamma = 2 */
1006 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1007 PetscCall(PicurvAssertRealNear(2.0, rep.lambda_D - rep.lambda_C, 1e-9, "D-C = |grad u| on shear"));
1008 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1009
1010 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1011 simCtx->central = 1; simCtx->invicid = 1;
1012 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcat, 0.7, -0.3, 0.5)); /* uniform velocity */
1013 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1014 PetscCall(PicurvAssertRealNear(rep.lambda_C, rep.lambda_D, 1e-12, "D == C for uniform velocity"));
1015 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1016 PetscFunctionReturn(0);
1017}
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 1020 of file test_solver_kernels.c.

1021{
1022 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1023 PetscFunctionBeginUser;
1024 /* n=3 -> DMDA mx=4 -> interior cells {1,2}; every interior cell touches 3 wall faces
1025 (no wall-free interior cell exists, so the global max reflects suppression). */
1026 PetscCall(MomMakeUnitGrid(&simCtx, &user, 3, WALL));
1027 simCtx->invicid = 0; simCtx->ren = 1.0; simCtx->les = 1;
1028 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 1.0));
1029 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
1030 /* 3 wall faces (nu_t suppressed, nu_eff=1) + 3 interior faces (nu_eff=2): 4*(3*1+3*2)=36. */
1031 PetscCall(PicurvAssertRealNear(36.0, rep.lambda_v, 1e-9, "wall-face eddy viscosity suppressed"));
1032 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1033 PetscFunctionReturn(0);
1034}
@ WALL
Definition variables.h:284
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 1037 of file test_solver_kernels.c.

1038{
1039 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1040 Vec ucont0, ucat0, nvert0, nut0, aj0;
1041 PetscBool eq;
1042 PetscFunctionBeginUser;
1043 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1044 simCtx->invicid = 0; simCtx->ren = 2.0; simCtx->les = 1;
1045 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 1.5, -0.7, 0.3));
1046 PetscCall(MomFillUcatShearY(user->fda, user->lUcat, 1.1));
1047 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 0.4));
1048 PetscCall(VecDuplicate(user->lUcont, &ucont0)); PetscCall(VecCopy(user->lUcont, ucont0));
1049 PetscCall(VecDuplicate(user->lUcat, &ucat0)); PetscCall(VecCopy(user->lUcat, ucat0));
1050 PetscCall(VecDuplicate(user->lNvert, &nvert0)); PetscCall(VecCopy(user->lNvert, nvert0));
1051 PetscCall(VecDuplicate(user->lNu_t, &nut0)); PetscCall(VecCopy(user->lNu_t, nut0));
1052 PetscCall(VecDuplicate(user->lAj, &aj0)); PetscCall(VecCopy(user->lAj, aj0));
1053 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1054 PetscCall(VecEqual(user->lUcont, ucont0, &eq)); PetscCall(PicurvAssertBool(eq, "lUcont bit-identical"));
1055 PetscCall(VecEqual(user->lUcat, ucat0, &eq)); PetscCall(PicurvAssertBool(eq, "lUcat bit-identical"));
1056 PetscCall(VecEqual(user->lNvert, nvert0, &eq)); PetscCall(PicurvAssertBool(eq, "lNvert bit-identical"));
1057 PetscCall(VecEqual(user->lNu_t, nut0, &eq)); PetscCall(PicurvAssertBool(eq, "lNu_t bit-identical"));
1058 PetscCall(VecEqual(user->lAj, aj0, &eq)); PetscCall(PicurvAssertBool(eq, "lAj bit-identical"));
1059 PetscCall(VecDestroy(&ucont0)); PetscCall(VecDestroy(&ucat0)); PetscCall(VecDestroy(&nvert0));
1060 PetscCall(VecDestroy(&nut0)); PetscCall(VecDestroy(&aj0));
1061 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1062 PetscFunctionReturn(0);
1063}
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 1067 of file test_solver_kernels.c.

1068{
1069 SimCtx *simCtx = NULL; UserCtx *user = NULL;
1070 PetscReal ***nvert;
1071 const PetscInt mx = 9, my = 9, mz = 9;
1072 PetscFunctionBeginUser;
1073 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC)); /* mx=9; all fluid */
1074 PetscCall(DMDAVecGetArray(user->da, user->lNvert, &nvert));
1075 /* fully periodic interior cell (4,4,4): all rows active regardless of TwoD value below. */
1076 PetscCall(PicurvAssertIntEqual(0x7, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,0), "all rows active (periodic interior)"));
1077 PetscCall(PicurvAssertIntEqual(0x6, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,1), "TwoD=1 clears xi row"));
1078 PetscCall(PicurvAssertIntEqual(0x5, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,2), "TwoD=2 clears eta row"));
1079 PetscCall(PicurvAssertIntEqual(0x3, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,3), "TwoD=3 clears zeta row"));
1080 /* positive non-periodic faces clear the corresponding normal rows. */
1081 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"));
1082 /* a location is skipped only when all three rows are inactive (here: solid cell). */
1083 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 4, 4, 1.0));
1084 PetscCall(DMDAVecRestoreArray(user->da, user->lNvert, &nvert));
1085 PetscCall(DMDAVecGetArray(user->da, user->lNvert, &nvert));
1086 PetscCall(PicurvAssertIntEqual(0, MomCellActiveRows(nvert,4,4,4,mx,my,mz,PETSC_FALSE,PETSC_FALSE,PETSC_FALSE,0), "solid cell -> all rows inactive"));
1087 PetscCall(DMDAVecRestoreArray(user->da, user->lNvert, &nvert));
1088 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1089 PetscFunctionReturn(0);
1090}
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 1093 of file test_solver_kernels.c.

1094{
1095 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1096 PetscErrorCode e_bad = 0; PetscBool eq;
1097 Vec aj_good;
1098 PetscFunctionBeginUser;
1099 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1100 simCtx->invicid = 0; simCtx->ren = 1.0;
1101 PetscCall(VecDuplicate(user->lAj, &aj_good)); PetscCall(VecCopy(user->lAj, aj_good));
1102
1103 PetscCall(MomSetLocalScalarCell(user->da, user->lAj, 4, 4, 4, PETSC_INFINITY));
1104 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
1105 e_bad = ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep);
1106 PetscCall(PetscPopErrorHandler());
1107 PetscCall(PicurvAssertBool((PetscBool)(e_bad != 0), "bad metric triggers error"));
1108
1109 /* Arrays must have been restored: lAj is still writable/usable -> repair it. */
1110 PetscCall(VecCopy(aj_good, user->lAj));
1111 PetscCall(VecEqual(user->lAj, aj_good, &eq));
1112 PetscCall(PicurvAssertBool(eq, "lAj usable after error (arrays were restored)"));
1113
1114 /* Re-entry must now succeed on the repaired state. */
1115 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
1116 PetscCall(PicurvAssertRealNear(24.0, rep.lambda_v, 1e-9, "estimator reusable after repair"));
1117 PetscCall(VecDestroy(&aj_good));
1118 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1119 PetscFunctionReturn(0);
1120}
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 1124 of file test_solver_kernels.c.

1125{
1126 SimCtx *simCtx = NULL; UserCtx *user = NULL;
1127 Vec Rhs, ref; PetscReal dt, nrm;
1128 PetscFunctionBeginUser;
1129 PetscCall(MomMakeUnitGrid(&simCtx, &user, 6, PERIODIC));
1130 dt = simCtx->dt;
1131 PetscCall(VecSet(user->Ucont, 2.0)); /* U^{n} */
1132 PetscCall(VecSet(user->Ucont_o, 1.0)); /* U^{n-1} */
1133 PetscCall(VecSet(user->Ucont_rm1, 0.5)); /* U^{n-2} */
1134 PetscCall(VecDuplicate(user->Ucont, &Rhs));
1135 PetscCall(VecDuplicate(user->Ucont, &ref));
1136
1137 /* ---- BDF2 (step != 1, step != StartStep) ---- */
1138 simCtx->StartStep = 0; simCtx->step = 5;
1139 PetscCall(PicurvAssertBool(MomentumUsesBDF2(simCtx), "step5 uses BDF2"));
1140 {
1141 const PetscReal a0 = MomentumBDFCoefficient(simCtx); /* == 1.5 */
1142 PetscCall(VecSet(Rhs, 3.0)); /* mock R_spatial */
1143 PetscCall(VecAXPY(Rhs, -a0/dt, user->Ucont));
1144 PetscCall(VecAXPY(Rhs, +2.0/dt, user->Ucont_o));
1145 PetscCall(VecAXPY(Rhs, -0.5/dt, user->Ucont_rm1));
1146 /* 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 */
1147 PetscCall(VecSet(ref, -9.5));
1148 PetscCall(VecAXPY(ref, -1.0, Rhs)); PetscCall(VecNorm(ref, NORM_INFINITY, &nrm));
1149 PetscCall(PicurvAssertRealNear(0.0, nrm, 1e-9, "BDF2 temporal vector combination"));
1150 }
1151 /* ---- BDF1 (step == 1) ---- */
1152 simCtx->StartStep = 0; simCtx->step = 1;
1153 PetscCall(PicurvAssertBool((PetscBool)(!MomentumUsesBDF2(simCtx)), "step1 uses BDF1"));
1154 {
1155 const PetscReal a0 = MomentumBDFCoefficient(simCtx); /* == 1.0 */
1156 PetscCall(VecSet(Rhs, 3.0));
1157 PetscCall(VecAXPY(Rhs, -a0/dt, user->Ucont));
1158 PetscCall(VecAXPY(Rhs, +1.0/dt, user->Ucont_o));
1159 /* reference: 3 + (-1*2 + 1*1)/0.1 = 3 + (-1)/0.1 = 3 - 10 = -7.0 */
1160 PetscCall(VecSet(ref, -7.0));
1161 PetscCall(VecAXPY(ref, -1.0, Rhs)); PetscCall(VecNorm(ref, NORM_INFINITY, &nrm));
1162 PetscCall(PicurvAssertRealNear(0.0, nrm, 1e-9, "BDF1 temporal vector combination"));
1163 }
1164 PetscCall(VecDestroy(&Rhs)); PetscCall(VecDestroy(&ref));
1165 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1166 PetscFunctionReturn(0);
1167}
Vec Ucont_o
Definition variables.h:911
Vec Ucont_rm1
Definition variables.h:912
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 1173 of file test_solver_kernels.c.

1174{
1175 PetscErrorCode ierr;
1176 const PicurvTestCase cases[] = {
1177 {"les-filter-paths", TestLESTestFilterPaths},
1178 {"analytical-geometry-selection", TestAnalyticalGeometrySelection},
1179 {"analytical-scalar-verification-helpers", TestAnalyticalScalarVerificationHelpers},
1180 {"analytical-solution-engine-dispatch", TestAnalyticalSolutionEngineDispatch},
1181 {"analytical-solution-engine-taylor-green-samples", TestAnalyticalSolutionEngineTaylorGreenSamples},
1182 {"analytical-solution-for-particles-dispatch", TestAnalyticalSolutionForParticlesDispatch},
1183 {"compute-eddy-viscosity-les-deterministic-field", TestComputeEddyViscosityLESDeterministicField},
1184 {"flow-solver-rejects-unsupported-momentum-solver-type", TestFlowSolverRejectsUnsupportedMomentumSolverType},
1185 {"driven-channel-flow-source", TestDrivenChannelFlowSource},
1186 {"momentum-bdf-coefficient", TestMomentumBDFCoefficient},
1187 {"momentum-stability-centered-convection", TestMomentumStabilityCenteredConvection},
1188 {"momentum-stability-quick-interior", TestMomentumStabilityQuickInterior},
1189 {"momentum-stability-quick-boundary", TestMomentumStabilityQuickBoundary},
1190 {"momentum-stability-viscous-cartesian-factor8-estimate", TestMomentumStabilityViscousLongitudinal},
1191 {"momentum-stability-viscous-scales-with-nu", TestMomentumStabilityViscousScalesWithNu},
1192 {"momentum-stability-les-eddy-viscosity", TestMomentumStabilityLESEddyViscosity},
1193 {"momentum-stability-one-sided-viscous", TestMomentumStabilityOneSidedViscous},
1194 {"momentum-stability-read-only", TestMomentumStabilityReadOnly},
1195 {"momentum-stability-anisotropic-viscous", TestMomentumStabilityAnisotropicViscous},
1196 {"momentum-stability-directional-quick", TestMomentumStabilityDirectionalQuick},
1197 {"momentum-stability-one-sided-directions", TestMomentumStabilityOneSidedDirections},
1198 {"momentum-stability-active-row-mask", TestMomentumStabilityActiveRowMask},
1199 {"momentum-stability-validation", TestMomentumStabilityValidation},
1200 {"momentum-stability-candidate-bc-divergence", TestMomentumStabilityCandidateBCDivergence},
1201 {"momentum-stability-candidate-d-shear", TestMomentumStabilityCandidateDShear},
1202 {"momentum-stability-wall-suppression", TestMomentumStabilityWallSuppression},
1203 {"momentum-stability-read-only-exact", TestMomentumStabilityReadOnlyExact},
1204 {"momentum-active-rows-helper", TestMomentumActiveRowsHelper},
1205 {"momentum-stability-error-reentry", TestMomentumStabilityErrorReentry},
1206 {"momentum-bdf-residual-combination", TestMomentumBDFResidualCombination},
1207 };
1208
1209 ierr = PetscInitialize(&argc, &argv, NULL, "PICurv solver utility tests");
1210 if (ierr) {
1211 return (int)ierr;
1212 }
1213
1214 ierr = PicurvRunTests("unit-solver", cases, sizeof(cases) / sizeof(cases[0]));
1215 if (ierr) {
1216 PetscFinalize();
1217 return (int)ierr;
1218 }
1219
1220 ierr = PetscFinalize();
1221 return (int)ierr;
1222}
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: