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 double values[3][3][3];
21 double weights[3][3][3];
22
23 PetscFunctionBeginUser;
24 for (PetscInt k = 0; k < 3; ++k) {
25 for (PetscInt j = 0; j < 3; ++j) {
26 for (PetscInt i = 0; i < 3; ++i) {
27 values[k][j][i] = 2.0;
28 weights[k][j][i] = 1.0;
29 }
30 }
31 }
32
33 PetscCall(PicurvAssertRealNear(2.0, ApplyLESTestFilter(LES_TEST_FILTER_SIMPSON_IK, values, weights), 1.0e-12,
34 "Simpson-rule filter should preserve a constant field"));
35
36 PetscCall(PicurvAssertRealNear(2.0, ApplyLESTestFilter(LES_TEST_FILTER_VOLUME_WEIGHTED_BOX, values, weights), 1.0e-12,
37 "box filter should preserve a constant field"));
38
39 for (PetscInt k = 0; k < 3; ++k) {
40 for (PetscInt j = 0; j < 3; ++j) {
41 for (PetscInt i = 0; i < 3; ++i) {
42 weights[k][j][i] = 0.0;
43 }
44 }
45 }
46 PetscCall(PicurvAssertRealNear(0.0, ApplyLESTestFilter(LES_TEST_FILTER_VOLUME_WEIGHTED_BOX, values, weights), 1.0e-12,
47 "box filter should return zero when all weights are zero"));
48 PetscFunctionReturn(0);
49}
double ApplyLESTestFilter(LESTestFilterKernel kernel, 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.
@ LES_TEST_FILTER_SIMPSON_IK
Definition variables.h:593
@ LES_TEST_FILTER_VOLUME_WEIGHTED_BOX
Definition variables.h:592
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 54 of file test_solver_kernels.c.

55{
56 SimCtx *simCtx = NULL;
57 UserCtx *user = NULL;
58 PetscErrorCode ierr_grid = 0;
59 PetscErrorCode ierr_non_square = 0;
60
61 PetscFunctionBeginUser;
62 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 8, 8, 8));
64 "TGV3D should require custom geometry"));
65 PetscCall(PicurvAssertBool((PetscBool)!AnalyticalTypeRequiresCustomGeometry("ZERO_FLOW"),
66 "ZERO_FLOW should not require custom geometry"));
67
68 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "ZERO_FLOW", sizeof(simCtx->AnalyticalSolutionType)));
69 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
70 ierr_grid = SetAnalyticalGridInfo(user);
71 PetscCall(PetscPopErrorHandler());
72 PetscCall(PicurvAssertBool((PetscBool)(ierr_grid != 0),
73 "SetAnalyticalGridInfo should reject analytical types without custom geometry"));
74
75 PetscCall(PetscStrncpy(simCtx->AnalyticalSolutionType, "TGV3D", sizeof(simCtx->AnalyticalSolutionType)));
76 simCtx->block_number = 2;
77 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
78 ierr_non_square = SetAnalyticalGridInfo(user);
79 PetscCall(PetscPopErrorHandler());
80 PetscCall(PicurvAssertBool((PetscBool)(ierr_non_square != 0),
81 "TGV3D multi-block setup should reject non-square block counts"));
82
83 simCtx->block_number = 1;
84 PetscCall(SetAnalyticalGridInfo(user));
85 PetscCall(PicurvAssertRealNear(0.0, user->Min_X, 1.0e-12, "TGV3D single-block xmin"));
86 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_X, 1.0e-12, "TGV3D single-block xmax"));
87
88 simCtx->block_number = 4;
89 user->_this = 3;
90 PetscCall(SetAnalyticalGridInfo(user));
91 PetscCall(PicurvAssertRealNear(PETSC_PI, user->Min_X, 1.0e-12, "TGV3D multi-block xmin should reflect the block column"));
92 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_X, 1.0e-12, "TGV3D multi-block xmax should reflect the block column"));
93 PetscCall(PicurvAssertRealNear(PETSC_PI, user->Min_Y, 1.0e-12, "TGV3D multi-block ymin should reflect the block row"));
94 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_Y, 1.0e-12, "TGV3D multi-block ymax should reflect the block row"));
95 PetscCall(PicurvAssertRealNear(2.0 * PETSC_PI, user->Max_Z, 1.0e-12, "TGV3D multi-block zmax should span the full domain"));
96
97 simCtx->block_number = 1;
98 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
99 PetscFunctionReturn(0);
100}
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:952
PetscReal Min_X
Definition variables.h:1089
PetscInt _this
Definition variables.h:1092
PetscReal Max_Y
Definition variables.h:1089
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:893
PetscReal Max_X
Definition variables.h:1089
PetscReal Min_Y
Definition variables.h:1089
PetscReal Max_Z
Definition variables.h:1089
The master context for the entire simulation.
Definition variables.h:859
User-defined context containing data specific to a single computational grid level.
Definition variables.h:1074
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 105 of file test_solver_kernels.c.

106{
107 SimCtx *simCtx = NULL;
108 UserCtx *user = NULL;
109 Vec target = NULL;
110 PetscReal value = 0.0;
111 PetscReal ***target_arr = NULL;
112 PetscReal *positions = NULL;
113 PetscReal *psi = NULL;
114
115 PetscFunctionBeginUser;
116 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
117 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
118 simCtx->verificationScalar.enabled = PETSC_TRUE;
119 PetscCall(PetscStrncpy(simCtx->verificationScalar.mode,
120 "analytical",
121 sizeof(simCtx->verificationScalar.mode)));
122
123 PetscCall(PetscStrncpy(simCtx->verificationScalar.profile,
124 "CONSTANT",
125 sizeof(simCtx->verificationScalar.profile)));
126 simCtx->verificationScalar.value = 2.5;
127 PetscCall(EvaluateAnalyticalScalarProfile(simCtx, 0.2, 0.3, 0.4, 0.0, &value));
128 PetscCall(PicurvAssertRealNear(2.5, value, 1.0e-12,
129 "constant scalar profile should evaluate to the configured value"));
130
131 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
132 positions[0] = 0.1; positions[1] = 0.2; positions[2] = 0.3;
133 positions[3] = 0.8; positions[4] = 0.6; positions[5] = 0.4;
134 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
135
137 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
138 PetscCall(PicurvAssertRealNear(2.5, psi[0], 1.0e-12,
139 "SetAnalyticalScalarFieldOnParticles should overwrite the first particle scalar"));
140 PetscCall(PicurvAssertRealNear(2.5, psi[1], 1.0e-12,
141 "SetAnalyticalScalarFieldOnParticles should overwrite the second particle scalar"));
142 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
143
144 PetscCall(PetscStrncpy(simCtx->verificationScalar.profile,
145 "LINEAR_X",
146 sizeof(simCtx->verificationScalar.profile)));
147 simCtx->verificationScalar.phi0 = 1.0;
148 simCtx->verificationScalar.slope_x = 2.0;
149 PetscCall(EvaluateAnalyticalScalarProfile(simCtx, 0.25, 0.0, 0.0, 0.0, &value));
150 PetscCall(PicurvAssertRealNear(1.5, value, 1.0e-12,
151 "linear-x scalar profile should evaluate phi0 + slope_x * x"));
152
153 PetscCall(VecDuplicate(user->Psi, &target));
154 PetscCall(SetAnalyticalScalarFieldAtCellCenters(user, target));
155 PetscCall(DMDAVecGetArrayRead(user->da, target, &target_arr));
156 PetscCall(PicurvAssertRealNear(1.25, target_arr[1][1][1], 1.0e-12,
157 "cell-center scalar fill should use the physical x center coordinate"));
158 PetscCall(DMDAVecRestoreArrayRead(user->da, target, &target_arr));
159 PetscCall(VecDestroy(&target));
160
161 PetscCall(PetscStrncpy(simCtx->verificationScalar.profile,
162 "SIN_PRODUCT",
163 sizeof(simCtx->verificationScalar.profile)));
164 simCtx->verificationScalar.amplitude = 3.0;
165 simCtx->verificationScalar.kx = PETSC_PI;
166 simCtx->verificationScalar.ky = PETSC_PI;
167 simCtx->verificationScalar.kz = PETSC_PI;
168 PetscCall(EvaluateAnalyticalScalarProfile(simCtx, 0.5, 0.5, 0.5, 0.0, &value));
169 PetscCall(PicurvAssertRealNear(3.0, value, 1.0e-12,
170 "sin-product scalar profile should peak at pi/2 in each coordinate"));
171
172 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
173 PetscFunctionReturn(0);
174}
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:940
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 179 of file test_solver_kernels.c.

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

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

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

408{
409 SimCtx *simCtx = NULL;
410 UserCtx *user = NULL;
411 Cmpnts ***ucat = NULL;
412 PetscReal ***nu_t = NULL;
413 /* CS stores the coefficient C that multiplies Delta^2 |S|, so C = 0.25 is the
414 Cs = 0.5 of the classical form. With Aj = 1 the filter width is 1, and the
415 linear field below gives |S| = sqrt(2). */
416 const PetscReal coefficient = 0.25;
417 const PetscReal expected_nu_t = 0.25 * PetscSqrtReal(2.0);
418
419 PetscFunctionBeginUser;
420 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
421 simCtx->les = DYNAMIC_SMAGORINSKY;
422 PetscCall(DMCreateGlobalVector(user->da, &user->Nu_t));
423 PetscCall(DMCreateLocalVector(user->da, &user->lNu_t));
424 PetscCall(DMCreateGlobalVector(user->da, &user->CS));
425 PetscCall(DMCreateLocalVector(user->da, &user->lCs));
426
427 PetscCall(VecSet(user->Aj, 1.0));
428 PetscCall(VecSet(user->Nu_t, 0.0));
429 PetscCall(VecSet(user->CS, coefficient));
430 PetscCall(DMDAVecGetArray(user->fda, user->Ucat, &ucat));
431 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
432 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
433 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
434 ucat[k][j][i].x = (PetscReal)i;
435 ucat[k][j][i].y = 0.0;
436 ucat[k][j][i].z = 0.0;
437 }
438 }
439 }
440 PetscCall(DMDAVecRestoreArray(user->fda, user->Ucat, &ucat));
441 PetscCall(DMGlobalToLocalBegin(user->fda, user->Ucat, INSERT_VALUES, user->lUcat));
442 PetscCall(DMGlobalToLocalEnd(user->fda, user->Ucat, INSERT_VALUES, user->lUcat));
443 PetscCall(DMGlobalToLocalBegin(user->da, user->Aj, INSERT_VALUES, user->lAj));
444 PetscCall(DMGlobalToLocalEnd(user->da, user->Aj, INSERT_VALUES, user->lAj));
445 PetscCall(DMGlobalToLocalBegin(user->da, user->CS, INSERT_VALUES, user->lCs));
446 PetscCall(DMGlobalToLocalEnd(user->da, user->CS, INSERT_VALUES, user->lCs));
447
448 PetscCall(ComputeEddyViscosityLES(user));
449 PetscCall(DMDAVecGetArrayRead(user->da, user->Nu_t, &nu_t));
450 PetscCall(PicurvAssertRealNear(expected_nu_t, nu_t[2][2][2], 1.0e-6,
451 "linear velocity field should yield deterministic LES eddy viscosity"));
452 PetscCall(PicurvAssertRealNear(0.0, nu_t[0][2][2], 1.0e-12,
453 "boundary cells should remain untouched by the interior LES loop"));
454 PetscCall(DMDAVecRestoreArrayRead(user->da, user->Nu_t, &nu_t));
455
456 PetscCall(VecDestroy(&user->CS));
457 PetscCall(VecDestroy(&user->lCs));
458 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
459 PetscFunctionReturn(0);
460}
PetscErrorCode ComputeEddyViscosityLES(UserCtx *user)
Computes the turbulent eddy viscosity for one block.
Definition les.c:952
@ DYNAMIC_SMAGORINSKY
Definition variables.h:551
Vec lNu_t
Definition variables.h:1156
Vec lUcat
Definition variables.h:1113
PetscInt les
Active LES closure; an LESModelType value.
Definition variables.h:984
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 465 of file test_solver_kernels.c.

466{
467 SimCtx *simCtx = NULL;
468 UserCtx *user = NULL;
469 PetscErrorCode ierr_flow = 0;
470
471 PetscFunctionBeginUser;
472 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
473 simCtx->mom_solver_type = (MomentumSolverType)999;
474
475 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
476 ierr_flow = FlowSolver(simCtx);
477 PetscCall(PetscPopErrorHandler());
478 PetscCall(PicurvAssertBool((PetscBool)(ierr_flow != 0),
479 "FlowSolver should reject unsupported momentum solver selectors"));
480
481 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
482 PetscFunctionReturn(0);
483}
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:692
MomentumSolverType mom_solver_type
Definition variables.h:899
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 488 of file test_solver_kernels.c.

489{
490 SimCtx *simCtx = NULL;
491 UserCtx *user = NULL;
492 Vec rct = NULL;
493 Cmpnts ***rct_arr = NULL;
494 Cmpnts ***l_csi = NULL;
495 Cmpnts ***l_eta = NULL;
496 Cmpnts ***l_zet = NULL;
497
498 PetscFunctionBeginUser;
499 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
500 PetscCall(VecDuplicate(user->Ucont, &rct));
501 PetscCall(VecZeroEntries(rct));
502
509 simCtx->bulkVelocityCorrection = 2.0;
510 simCtx->dt = 1.0;
511 simCtx->forceScalingFactor = 1.0;
512 simCtx->drivingForceMagnitude = 0.0;
513 PetscCall(VecSet(user->Nvert, 0.0));
514 PetscCall(DMGlobalToLocalBegin(user->da, user->Nvert, INSERT_VALUES, user->lNvert));
515 PetscCall(DMGlobalToLocalEnd(user->da, user->Nvert, INSERT_VALUES, user->lNvert));
516 PetscCall(DMDAVecGetArray(user->fda, user->lCsi, &l_csi));
517 PetscCall(DMDAVecGetArray(user->fda, user->lEta, &l_eta));
518 PetscCall(DMDAVecGetArray(user->fda, user->lZet, &l_zet));
519 l_csi[1][1][1].x = 1.0; l_csi[1][1][1].y = 0.0; l_csi[1][1][1].z = 0.0;
520 l_eta[1][1][1].x = 0.0; l_eta[1][1][1].y = 1.0; l_eta[1][1][1].z = 0.0;
521 l_zet[1][1][1].x = 0.0; l_zet[1][1][1].y = 0.0; l_zet[1][1][1].z = 1.0;
522 PetscCall(DMDAVecRestoreArray(user->fda, user->lZet, &l_zet));
523 PetscCall(DMDAVecRestoreArray(user->fda, user->lEta, &l_eta));
524 PetscCall(DMDAVecRestoreArray(user->fda, user->lCsi, &l_csi));
525
526 PetscCall(ComputeDrivenChannelFlowSource(user, rct));
527 PetscCall(DMDAVecGetArrayRead(user->fda, rct, &rct_arr));
528 PetscCall(PicurvAssertRealNear(1.5, simCtx->drivingForceMagnitude, 1.0e-12,
529 "driven flow source should update the controller magnitude"));
530 PetscCall(PicurvAssertRealNear(0.0, rct_arr[1][1][1].y, 1.0e-12,
531 "driven flow source should leave the y component unchanged"));
532 PetscCall(PicurvAssertRealNear(0.0, rct_arr[1][1][1].z, 1.0e-12,
533 "driven flow source should leave the z component unchanged"));
534 PetscCall(DMDAVecRestoreArrayRead(user->fda, rct, &rct_arr));
535
536 PetscCall(VecDestroy(&rct));
537 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
538 PetscFunctionReturn(0);
539}
PetscErrorCode ComputeDrivenChannelFlowSource(UserCtx *user, Vec Rct)
Applies a momentum source term to drive flow in a periodic channel or pipe.
Definition BodyForces.c:37
@ PERIODIC
Definition variables.h:318
BoundaryFaceConfig boundary_faces[6]
Definition variables.h:1099
Vec lNvert
Definition variables.h:1113
PetscReal forceScalingFactor
Definition variables.h:961
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
Definition variables.h:342
BCHandlerType handler_type
Definition variables.h:393
PetscReal dt
Definition variables.h:874
PetscReal bulkVelocityCorrection
Definition variables.h:973
Vec Nvert
Definition variables.h:1113
BCType mathematical_type
Definition variables.h:392
PetscReal drivingForceMagnitude
Definition variables.h:961
@ BC_FACE_NEG_X
Definition variables.h:288
@ BC_FACE_POS_X
Definition variables.h:288
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 552 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 569 of file test_solver_kernels.c.

570{
571 Cmpnts ***a;
572 PetscInt gxs, gys, gzs, gxm, gym, gzm;
573 PetscFunctionBeginUser;
574 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
575 PetscCall(DMDAVecGetArray(fda, lvec, &a));
576 for (PetscInt k = gzs; k < gzs+gzm; ++k)
577 for (PetscInt j = gys; j < gys+gym; ++j)
578 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; }
579 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
580 PetscFunctionReturn(0);
581}
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 590 of file test_solver_kernels.c.

591{
592 PetscReal ***a;
593 PetscInt gxs, gys, gzs, gxm, gym, gzm;
594 PetscFunctionBeginUser;
595 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
596 PetscCall(DMDAVecGetArray(da, lvec, &a));
597 for (PetscInt k = gzs; k < gzs+gzm; ++k)
598 for (PetscInt j = gys; j < gys+gym; ++j)
599 for (PetscInt i = gxs; i < gxs+gxm; ++i) a[k][j][i] = v;
600 PetscCall(DMDAVecRestoreArray(da, lvec, &a));
601 PetscFunctionReturn(0);
602}
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 612 of file test_solver_kernels.c.

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

◆ TestMomentumBDFCoefficient()

static PetscErrorCode TestMomentumBDFCoefficient ( void  )
static

Definition at line 628 of file test_solver_kernels.c.

629{
630 SimCtx *simCtx = NULL; UserCtx *user = NULL;
631 PetscFunctionBeginUser;
632 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 6, 6, 6));
633 simCtx->StartStep = 0; simCtx->step = 1;
634 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 on cold-start step 1"));
635 PetscCall(PicurvAssertBool((PetscBool)(!MomentumUsesBDF2(simCtx)), "step 1 is BDF1"));
636 simCtx->step = 5;
637 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF2 on interior step"));
638 PetscCall(PicurvAssertBool(MomentumUsesBDF2(simCtx), "step 5 (StartStep 0) is BDF2"));
639 simCtx->StartStep = 5; simCtx->step = 5;
640 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 at restart setup step"));
641 simCtx->step = 6;
642 PetscCall(PicurvAssertRealNear(1.0, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF1 on first restart solve (ti==StartStep+1)"));
643 simCtx->step = 7;
644 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12, "a0 BDF2 after first restart solve"));
645 simCtx->restartHistoryAvailable = PETSC_TRUE;
646 simCtx->step = 5;
647 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12,
648 "restored history enables BDF2 at restart setup"));
649 simCtx->step = 6;
650 PetscCall(PicurvAssertRealNear(1.5, MomentumBDFCoefficient(simCtx), 1e-12,
651 "restored history enables BDF2 on first restart solve"));
652 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
653 PetscFunctionReturn(0);
654}
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:869
PetscInt step
Definition variables.h:867
PetscBool restartHistoryAvailable
Definition variables.h:888
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 659 of file test_solver_kernels.c.

661{
662 PetscFunctionBeginUser;
663 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(simCtx, user, n, n, n, px, py, pz));
664 (*user)->boundary_faces[BC_FACE_NEG_X].mathematical_type = px ? PERIODIC : bc;
665 (*user)->boundary_faces[BC_FACE_POS_X].mathematical_type = px ? PERIODIC : bc;
666 (*user)->boundary_faces[BC_FACE_NEG_Y].mathematical_type = py ? PERIODIC : bc;
667 (*user)->boundary_faces[BC_FACE_POS_Y].mathematical_type = py ? PERIODIC : bc;
668 (*user)->boundary_faces[BC_FACE_NEG_Z].mathematical_type = pz ? PERIODIC : bc;
669 (*user)->boundary_faces[BC_FACE_POS_Z].mathematical_type = pz ? PERIODIC : bc;
670 (*simCtx)->dt = 0.1; (*simCtx)->step = 1; (*simCtx)->StartStep = 0; /* a0=1 -> lambda_t=10 */
671 (*simCtx)->ren = 1.0; (*simCtx)->les = 0;
672 (*simCtx)->central = 0; (*simCtx)->invicid = 0; (*simCtx)->block_number = 1;
673 (*simCtx)->TwoD = 0; (*simCtx)->les_gradient_model = 0;
674 /* The minimal fixture does not allocate lNu_t (LES off by default); create a
675 zeroed one so the estimator can read it when a test enables LES. */
676 if (!(*user)->lNu_t) PetscCall(DMCreateLocalVector((*user)->da, &(*user)->lNu_t));
677 PetscCall(MomFillLocalCmpnts((*user)->fda, (*user)->lUcont, 0.0, 0.0, 0.0));
678 PetscCall(MomFillLocalCmpnts((*user)->fda, (*user)->lUcat, 0.0, 0.0, 0.0));
679 PetscCall(MomFillLocalScalar((*user)->da, (*user)->lNvert, 0.0));
680 PetscCall(MomFillLocalScalar((*user)->da, (*user)->lNu_t, 0.0));
681 PetscFunctionReturn(0);
682}
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 685 of file test_solver_kernels.c.

686{
687 const PetscBool p = (PetscBool)(bc == PERIODIC);
688 PetscFunctionBeginUser;
689 PetscCall(MomMakeUnitGridP(simCtx, user, n, p, p, p, bc));
690 PetscFunctionReturn(0);
691}
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 694 of file test_solver_kernels.c.

695{
696 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
697 PetscFunctionBeginUser;
698 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
699 simCtx->central = 1; simCtx->invicid = 1;
700 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 2.0, 0.0, 0.0));
701 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
702 PetscCall(PicurvAssertRealNear(10.0, rep.lambda_t, 1e-9, "lambda_t = a0/dt"));
703 PetscCall(PicurvAssertRealNear(2.0, rep.lambda_c, 1e-9, "centered conv f_c=1 (Aj*U^xi scaling)"));
704 PetscCall(PicurvAssertRealNear(0.0, rep.lambda_v, 1e-9, "inviscid: no viscous term"));
705 PetscCall(PicurvAssertRealNear(12.0, rep.lambda, 1e-9, "total lambda"));
706 PetscCall(PicurvAssertIntEqual(0, (PetscInt)rep.cclass, "interior cell class"));
707 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
708 PetscFunctionReturn(0);
709}
@ 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:892
PetscInt central
Definition variables.h:904
Vec lUcont
Definition variables.h:1113
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 712 of file test_solver_kernels.c.

713{
714 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
715 PetscFunctionBeginUser;
716 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
717 simCtx->central = 0; simCtx->invicid = 1; /* QUICK branch */
718 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 3.0, 0.0, 0.0));
719 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
720 PetscCall(PicurvAssertRealNear(4.0, rep.lambda_c, 1e-9, "QUICK interior f_c=4/3 (4/3*3=4)"));
721 PetscCall(PicurvAssertIntEqual(0, (PetscInt)rep.cclass, "interior cell class"));
722 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
723 PetscFunctionReturn(0);
724}
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 727 of file test_solver_kernels.c.

728{
729 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
730 PetscFunctionBeginUser;
731 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, INLET)); /* non-periodic -> boundary band active */
732 simCtx->central = 0; simCtx->invicid = 1;
733 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 8.0, 0.0, 0.0));
734 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
735 PetscCall(PicurvAssertRealNear(20.0, rep.lambda_c, 1e-9, "boundary QUICK f_c=2.5 (2.5*8=20)"));
736 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.cclass, "physical-boundary cell class"));
737 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
738 PetscFunctionReturn(0);
739}
@ INLET
Definition variables.h:316
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 742 of file test_solver_kernels.c.

743{
744 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
745 PetscFunctionBeginUser;
746 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
747 simCtx->invicid = 0; simCtx->ren = 1.0; /* nu = 1, no convection */
748 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
749 PetscCall(PicurvAssertRealNear(24.0, rep.lambda_v, 1e-9, "viscous = 4*6*nu = 24nu (factor-8 longitudinal)"));
750 PetscCall(PicurvAssertRealNear(34.0, rep.lambda, 1e-9, "total lambda_t+lambda_v"));
751 PetscCall(PicurvAssertIntEqual((PetscInt)MOM_STAB_LIMITER_VISCOSITY, (PetscInt)rep.limiter, "viscosity-limited"));
752 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
753 PetscFunctionReturn(0);
754}
@ 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 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 = 4.0; /* nu = 0.25 -> 24*0.25 = 6 */
763 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
764 PetscCall(PicurvAssertRealNear(6.0, rep.lambda_v, 1e-9, "viscous scales with nu=1/Re"));
765 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
766 PetscFunctionReturn(0);
767}
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 770 of file test_solver_kernels.c.

771{
772 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
773 PetscFunctionBeginUser;
774 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
775 simCtx->invicid = 0; simCtx->ren = 1.0; simCtx->les = 1; /* nu_eff = 1 + nu_t */
776 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 1.0)); /* nu_t = 1 -> nu_eff = 2 -> 24*2 = 48 */
777 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
778 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "LES nu_t adds: 4*6*(1+1) = 48"));
779 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
780 PetscFunctionReturn(0);
781}
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 784 of file test_solver_kernels.c.

785{
786 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
787 PetscFunctionBeginUser;
788 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
789 simCtx->invicid = 0; simCtx->ren = 1.0;
790 /* Mark one interior cell solid; its fluid cross-neighbours get the one-sided x2 (24 -> 48). */
791 PetscCall(MomSetLocalScalarCell(user->da, user->lNvert, 4, 5, 4, 1.0));
792 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
793 PetscCall(PicurvAssertRealNear(48.0, rep.lambda_v, 1e-9, "one-sided viscous x2 (24 -> 48)"));
794 PetscCall(PicurvAssertIntEqual(1, (PetscInt)rep.one_sided, "one-sided multiplier flagged"));
795 PetscCall(PicurvAssertIntEqual(2, (PetscInt)rep.cclass, "IB-adjacent cell class"));
796 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
797 PetscFunctionReturn(0);
798}
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 801 of file test_solver_kernels.c.

802{
803 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
804 PetscReal n_ucont_0, n_ucat_0, n_nvert_0, n_ucont_1, n_ucat_1, n_nvert_1;
805 PetscFunctionBeginUser;
806 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
807 simCtx->invicid = 0; simCtx->ren = 2.0;
808 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 1.5, -0.7, 0.3));
809 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcat, 0.9, 0.4, -0.2));
810 PetscCall(VecNorm(user->lUcont, NORM_2, &n_ucont_0));
811 PetscCall(VecNorm(user->lUcat, NORM_2, &n_ucat_0));
812 PetscCall(VecNorm(user->lNvert, NORM_2, &n_nvert_0));
813 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
814 PetscCall(VecNorm(user->lUcont, NORM_2, &n_ucont_1));
815 PetscCall(VecNorm(user->lUcat, NORM_2, &n_ucat_1));
816 PetscCall(VecNorm(user->lNvert, NORM_2, &n_nvert_1));
817 PetscCall(PicurvAssertRealNear(n_ucont_0, n_ucont_1, 1e-14, "lUcont unchanged by estimator"));
818 PetscCall(PicurvAssertRealNear(n_ucat_0, n_ucat_1, 1e-14, "lUcat unchanged by estimator"));
819 PetscCall(PicurvAssertRealNear(n_nvert_0, n_nvert_1, 1e-14, "lNvert unchanged by estimator"));
820 PetscCall(PicurvAssertBool((PetscBool)(rep.lambda > 0.0), "estimate finite and positive"));
821 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
822 PetscFunctionReturn(0);
823}
@ 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 831 of file test_solver_kernels.c.

832{
833 const PetscReal sx = dy*dz, sy = dx*dz, sz = dx*dy, aj = 1.0/(dx*dy*dz);
834 Vec csiv[] = {user->lCsi, user->lICsi, user->lJCsi, user->lKCsi};
835 Vec etav[] = {user->lEta, user->lIEta, user->lJEta, user->lKEta};
836 Vec zetv[] = {user->lZet, user->lIZet, user->lJZet, user->lKZet};
837 Vec ajv[] = {user->lAj, user->lIAj, user->lJAj, user->lKAj};
838 PetscFunctionBeginUser;
839 for (int t = 0; t < 4; ++t) {
840 PetscCall(MomFillLocalCmpnts(user->fda, csiv[t], sx, 0, 0));
841 PetscCall(MomFillLocalCmpnts(user->fda, etav[t], 0, sy, 0));
842 PetscCall(MomFillLocalCmpnts(user->fda, zetv[t], 0, 0, sz));
843 PetscCall(MomFillLocalScalar(user->da, ajv[t], aj));
844 }
845 PetscFunctionReturn(0);
846}
Vec lIEta
Definition variables.h:1151
Vec lIZet
Definition variables.h:1151
Vec lKEta
Definition variables.h:1153
Vec lJCsi
Definition variables.h:1152
Vec lKZet
Definition variables.h:1153
Vec lJEta
Definition variables.h:1152
Vec lKCsi
Definition variables.h:1153
Vec lJZet
Definition variables.h:1152
Vec lICsi
Definition variables.h:1151
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 855 of file test_solver_kernels.c.

856{
857 Cmpnts ***a;
858 PetscInt gxs, gys, gzs, gxm, gym, gzm;
859 PetscFunctionBeginUser;
860 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
861 PetscCall(DMDAVecGetArray(fda, lvec, &a));
862 for (PetscInt k = gzs; k < gzs+gzm; ++k)
863 for (PetscInt j = gys; j < gys+gym; ++j)
864 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; }
865 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
866 PetscFunctionReturn(0);
867}
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 876 of file test_solver_kernels.c.

877{
878 Cmpnts ***a;
879 PetscInt gxs, gys, gzs, gxm, gym, gzm;
880 PetscFunctionBeginUser;
881 PetscCall(DMDAGetGhostCorners(fda, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
882 PetscCall(DMDAVecGetArray(fda, lvec, &a));
883 for (PetscInt k = gzs; k < gzs+gzm; ++k)
884 for (PetscInt j = gys; j < gys+gym; ++j)
885 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; }
886 PetscCall(DMDAVecRestoreArray(fda, lvec, &a));
887 PetscFunctionReturn(0);
888}
Here is the caller graph for this function:

◆ TestMomentumStabilityAnisotropicViscous()

static PetscErrorCode TestMomentumStabilityAnisotropicViscous ( void  )
static

Definition at line 892 of file test_solver_kernels.c.

893{
894 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
895 PetscFunctionBeginUser;
896 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
897 simCtx->invicid = 0; simCtx->ren = 1.0;
898 PetscCall(MomSetCartesianMetrics(user, 1.0, 2.0, 4.0)); /* 8*(1 + 1/4 + 1/16) = 10.5 */
899 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
900 PetscCall(PicurvAssertRealNear(10.5, rep.lambda_v, 1e-9, "anisotropic viscous = 8nu*sum(1/d^2)"));
901 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
902 PetscFunctionReturn(0);
903}
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 906 of file test_solver_kernels.c.

907{
908 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
909 PetscFunctionBeginUser;
910 PetscCall(MomMakeUnitGridP(&simCtx, &user, 8, PETSC_FALSE, PETSC_TRUE, PETSC_TRUE, INLET)); /* x non-periodic */
911 simCtx->central = 0; simCtx->invicid = 1;
912 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 3.0, 3.0, 3.0));
913 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
914 /* boundary cell: 0.5*(2.5*6 + (4/3)*6 + (4/3)*6) = 15.5 ; NOT 22.5 (all-2.5). */
915 PetscCall(PicurvAssertRealNear(15.5, rep.lambda_c, 1e-9, "only x-direction modified to 2.5"));
916 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
917 PetscFunctionReturn(0);
918}
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 921 of file test_solver_kernels.c.

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

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

974{
975 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
976 PetscErrorCode e1 = 0, e2 = 0;
977 PetscFunctionBeginUser;
978 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
979 simCtx->invicid = 0; simCtx->ren = 1.0;
980
981 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
982 e1 = ComputeMomentumStabilityEstimate(user, 0, simCtx->dt, MOM_STAB_CAND_C, &rep); /* block_number=0 */
983 PetscCall(PetscPopErrorHandler());
984 PetscCall(PicurvAssertBool((PetscBool)(e1 != 0), "block_number<=0 rejected"));
985
986 PetscCall(MomSetLocalScalarCell(user->da, user->lAj, 4, 4, 4, PETSC_INFINITY)); /* bad metric */
987 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
988 e2 = ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep);
989 PetscCall(PetscPopErrorHandler());
990 PetscCall(PicurvAssertBool((PetscBool)(e2 != 0), "non-finite inverse-Jacobian rejected"));
991
992 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
993 PetscFunctionReturn(0);
994}
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 997 of file test_solver_kernels.c.

998{
999 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1000 PetscFunctionBeginUser;
1001 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1002 simCtx->central = 1; simCtx->invicid = 1; /* f_c=1 isolates the div term */
1003 PetscCall(MomFillUcontXRamp(user->fda, user->lUcont, 2.0)); /* div = slope = 2 */
1004 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_C, &rep));
1005 /* C - B = 0.5*Aj*|div| = 0.5*2 = 1.0 at the (shared) controlling cell. */
1006 PetscCall(PicurvAssertRealNear(1.0, rep.lambda_C - rep.lambda_B, 1e-9, "C-B = divergence term"));
1007 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1008 PetscFunctionReturn(0);
1009}
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 1012 of file test_solver_kernels.c.

1013{
1014 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1015 PetscFunctionBeginUser;
1016 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1017 simCtx->central = 1; simCtx->invicid = 1;
1018 PetscCall(MomFillUcatShearY(user->fda, user->lUcat, 2.0)); /* |grad u|_inf = gamma = 2 */
1019 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1020 PetscCall(PicurvAssertRealNear(2.0, rep.lambda_D - rep.lambda_C, 1e-9, "D-C = |grad u| on shear"));
1021 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1022
1023 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1024 simCtx->central = 1; simCtx->invicid = 1;
1025 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcat, 0.7, -0.3, 0.5)); /* uniform velocity */
1026 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1027 PetscCall(PicurvAssertRealNear(rep.lambda_C, rep.lambda_D, 1e-12, "D == C for uniform velocity"));
1028 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1029 PetscFunctionReturn(0);
1030}
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 1033 of file test_solver_kernels.c.

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

1051{
1052 SimCtx *simCtx = NULL; UserCtx *user = NULL; MomStabilityReport rep;
1053 Vec ucont0, ucat0, nvert0, nut0, aj0;
1054 PetscBool eq;
1055 PetscFunctionBeginUser;
1056 PetscCall(MomMakeUnitGrid(&simCtx, &user, 8, PERIODIC));
1057 simCtx->invicid = 0; simCtx->ren = 2.0; simCtx->les = 1;
1058 PetscCall(MomFillLocalCmpnts(user->fda, user->lUcont, 1.5, -0.7, 0.3));
1059 PetscCall(MomFillUcatShearY(user->fda, user->lUcat, 1.1));
1060 PetscCall(MomFillLocalScalar(user->da, user->lNu_t, 0.4));
1061 PetscCall(VecDuplicate(user->lUcont, &ucont0)); PetscCall(VecCopy(user->lUcont, ucont0));
1062 PetscCall(VecDuplicate(user->lUcat, &ucat0)); PetscCall(VecCopy(user->lUcat, ucat0));
1063 PetscCall(VecDuplicate(user->lNvert, &nvert0)); PetscCall(VecCopy(user->lNvert, nvert0));
1064 PetscCall(VecDuplicate(user->lNu_t, &nut0)); PetscCall(VecCopy(user->lNu_t, nut0));
1065 PetscCall(VecDuplicate(user->lAj, &aj0)); PetscCall(VecCopy(user->lAj, aj0));
1066 PetscCall(ComputeMomentumStabilityEstimate(user, 1, simCtx->dt, MOM_STAB_CAND_D, &rep));
1067 PetscCall(VecEqual(user->lUcont, ucont0, &eq)); PetscCall(PicurvAssertBool(eq, "lUcont bit-identical"));
1068 PetscCall(VecEqual(user->lUcat, ucat0, &eq)); PetscCall(PicurvAssertBool(eq, "lUcat bit-identical"));
1069 PetscCall(VecEqual(user->lNvert, nvert0, &eq)); PetscCall(PicurvAssertBool(eq, "lNvert bit-identical"));
1070 PetscCall(VecEqual(user->lNu_t, nut0, &eq)); PetscCall(PicurvAssertBool(eq, "lNu_t bit-identical"));
1071 PetscCall(VecEqual(user->lAj, aj0, &eq)); PetscCall(PicurvAssertBool(eq, "lAj bit-identical"));
1072 PetscCall(VecDestroy(&ucont0)); PetscCall(VecDestroy(&ucat0)); PetscCall(VecDestroy(&nvert0));
1073 PetscCall(VecDestroy(&nut0)); PetscCall(VecDestroy(&aj0));
1074 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1075 PetscFunctionReturn(0);
1076}
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 1080 of file test_solver_kernels.c.

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

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

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

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