17 PetscFunctionBeginUser;
18 if (!user->
Phi) PetscCall(DMCreateGlobalVector(user->
da, &user->
Phi));
19 if (!user->
lPhi) PetscCall(DMCreateLocalVector(user->
da, &user->
lPhi));
20 if (!user->
Aj) PetscCall(DMCreateGlobalVector(user->
da, &user->
Aj));
21 if (!user->
lAj) PetscCall(DMCreateLocalVector(user->
da, &user->
lAj));
24 PetscFunctionReturn(0);
35 PetscFunctionBeginUser;
38 PetscCall(VecSet(user->
P, 1.0));
39 PetscCall(VecSet(user->
Phi, 0.25));
45 PetscFunctionReturn(0);
57 PetscFunctionBeginUser;
62 PetscCall(VecSet(user->
Ucont, 0.0));
63 PetscCall(VecSet(user->
Nvert, 0.0));
64 PetscCall(VecSet(user->
Aj, 1.0));
65 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
66 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
67 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
68 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
69 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Aj, INSERT_VALUES, user->
lAj));
70 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Aj, INSERT_VALUES, user->
lAj));
72 PetscCall(VecDuplicate(user->
P, &B));
74 PetscCall(
PicurvAssertVecConstant(B, 0.0, 1.0e-12,
"zero velocity divergence should produce zero Poisson RHS"));
77 PetscCall(VecDestroy(&B));
79 PetscFunctionReturn(0);
95 PetscFunctionBeginUser;
97 PetscCall(VecDuplicate(user->
Ucont, &rct));
98 PetscCall(VecZeroEntries(rct));
110 PetscCall(VecSet(user->
Nvert, 0.0));
111 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
112 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
113 PetscCall(DMDAVecGetArray(user->
fda, user->
lCsi, &l_csi));
114 PetscCall(DMDAVecGetArray(user->
fda, user->
lEta, &l_eta));
115 PetscCall(DMDAVecGetArray(user->
fda, user->
lZet, &l_zet));
116 l_csi[1][1][1].
x = 1.0; l_csi[1][1][1].
y = 0.0; l_csi[1][1][1].
z = 0.0;
117 l_eta[1][1][1].
x = 0.0; l_eta[1][1][1].
y = 1.0; l_eta[1][1][1].
z = 0.0;
118 l_zet[1][1][1].
x = 0.0; l_zet[1][1][1].
y = 0.0; l_zet[1][1][1].
z = 1.0;
119 PetscCall(DMDAVecRestoreArray(user->
fda, user->
lZet, &l_zet));
120 PetscCall(DMDAVecRestoreArray(user->
fda, user->
lEta, &l_eta));
121 PetscCall(DMDAVecRestoreArray(user->
fda, user->
lCsi, &l_csi));
124 PetscCall(DMDAVecGetArrayRead(user->
fda, rct, &rct_arr));
126 "ComputeBodyForces should update the driven-flow controller magnitude"));
127 PetscCall(
PicurvAssertRealNear(0.0, rct_arr[1][1][1].y, 1.0e-12,
"ComputeBodyForces should keep y unchanged"));
128 PetscCall(
PicurvAssertRealNear(0.0, rct_arr[1][1][1].z, 1.0e-12,
"ComputeBodyForces should keep z unchanged"));
129 PetscCall(DMDAVecRestoreArrayRead(user->
fda, rct, &rct_arr));
131 PetscCall(VecDestroy(&rct));
133 PetscFunctionReturn(0);
143 PetscReal ***diff_arr = NULL;
145 PetscFunctionBeginUser;
151 simCtx->
les = PETSC_FALSE;
152 simCtx->
rans = PETSC_FALSE;
156 PetscCall(DMDAVecGetArrayRead(user->
da, user->
Diffusivity, &diff_arr));
157 PetscCall(
PicurvAssertRealNear(0.125, diff_arr[1][1][1], 1.0e-12,
"molecular diffusivity interior value"));
158 PetscCall(DMDAVecRestoreArrayRead(user->
da, user->
Diffusivity, &diff_arr));
161 PetscFunctionReturn(0);
173 PetscFunctionBeginUser;
175 PetscCall(VecDuplicate(user->
lUcont, &conv));
176 PetscCall(VecSet(user->
Ucont, 0.0));
177 PetscCall(VecSet(user->
Ucat, 0.0));
178 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
179 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
180 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
181 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
186 PetscCall(VecDestroy(&conv));
188 PetscFunctionReturn(0);
200 PetscFunctionBeginUser;
202 PetscCall(VecDuplicate(user->
lUcont, &visc));
203 PetscCall(VecSet(user->
Ucont, 1.0));
204 PetscCall(VecSet(user->
Ucat, 1.0));
205 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
206 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
207 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
208 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
213 PetscCall(VecDestroy(&visc));
215 PetscFunctionReturn(0);
226 PetscFunctionBeginUser;
228 PetscCall(VecSet(user->
Ucont, 0.0));
229 PetscCall(VecSet(user->
Ucat, 0.0));
230 PetscCall(VecSet(user->
Nvert, 0.0));
231 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
232 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
233 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
234 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
235 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
236 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
239 PetscCall(
PicurvAssertVecConstant(user->
Rhs, 0.0, 1.0e-12,
"ComputeRHS should remain zero without forcing on a quiescent field"));
242 PetscFunctionReturn(0);
253 PetscFunctionBeginUser;
263 PetscFunctionReturn(0);
273 PetscReal ***diff_arr = NULL;
274 Cmpnts ***grad_arr = NULL;
276 const PetscReal gamma0 = 0.5;
277 const PetscReal slope_x = 0.25;
279 PetscFunctionBeginUser;
289 "verification diffusivity override should report as active"));
293 PetscCall(DMDAVecGetArrayRead(user->
da, user->
Diffusivity, &diff_arr));
294 PetscCall(DMDAVecGetArrayRead(user->
fda, user->
Cent, ¢));
296 "verification override should populate the linear diffusivity field"));
297 PetscCall(DMDAVecRestoreArrayRead(user->
fda, user->
Cent, ¢));
298 PetscCall(DMDAVecRestoreArrayRead(user->
da, user->
Diffusivity, &diff_arr));
302 "linear verification diffusivity should yield the current finite-difference x gradient"));
304 "linear verification diffusivity should keep y gradient zero"));
306 "linear verification diffusivity should keep z gradient zero"));
310 PetscFunctionReturn(0);
322 PetscReal ***x_arr = NULL;
324 PetscFunctionBeginUser;
326 PetscCall(VecDuplicate(user->
P, &x));
327 PetscCall(VecSet(x, 3.0));
328 PetscCall(VecSet(user->
Nvert, 0.0));
329 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
330 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
333 PetscCall(VecSum(x, &sum));
334 PetscCall(
PicurvAssertRealNear(0.0, sum, 1.0e-10,
"PoissonNullSpaceFunction should remove the global mean"));
335 PetscCall(DMDAVecGetArrayRead(user->
da, x, &x_arr));
336 PetscCall(
PicurvAssertRealNear(0.0, x_arr[1][1][1], 1.0e-10,
"PoissonNullSpaceFunction should zero a uniform interior field"));
337 PetscCall(DMDAVecRestoreArrayRead(user->
da, x, &x_arr));
339 PetscCall(VecDestroy(&x));
341 PetscFunctionReturn(0);
350 PetscInt rows = 0, cols = 0;
352 const PetscInt *col_idx = NULL;
353 const PetscScalar *values = NULL;
354 PetscInt interior_row = 0;
356 PetscFunctionBeginUser;
358 PetscCall(VecSet(user->
Nvert, 0.0));
359 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
360 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
363 PetscCall(
PicurvAssertBool((PetscBool)(user->
A != NULL),
"PoissonLHSNew should allocate the Poisson operator"));
365 PetscCall(MatGetSize(user->
A, &rows, &cols));
369 interior_row = (2 * user->
info.my + 2) * user->
info.mx + 2;
370 PetscCall(MatGetRow(user->
A, interior_row, &ncols, &col_idx, &values));
371 PetscCall(
PicurvAssertBool((PetscBool)(ncols > 1),
"Interior Poisson row should couple to neighboring nodes"));
372 PetscCall(
PicurvAssertBool((PetscBool)(values != NULL),
"Interior Poisson row should expose non-null coefficients"));
373 PetscCall(MatRestoreRow(user->
A, interior_row, &ncols, &col_idx, &values));
376 PetscFunctionReturn(0);
387 PetscFunctionBeginUser;
389 PetscCall(VecSet(user->
Ucont, 0.0));
390 PetscCall(VecSet(user->
Phi, 0.0));
391 PetscCall(VecSet(user->
Nvert, 0.0));
392 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
393 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
394 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Phi, INSERT_VALUES, user->
lPhi));
395 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Phi, INSERT_VALUES, user->
lPhi));
396 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
397 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
400 PetscCall(
PicurvAssertVecConstant(user->
Ucont, 0.0, 1.0e-12,
"Projection should leave a zero-velocity field unchanged when Phi is zero"));
403 PetscFunctionReturn(0);
412 PetscReal ***phi = NULL;
415 PetscFunctionBeginUser;
418 PetscCall(VecSet(user->
Ucont, 0.0));
419 PetscCall(VecSet(user->
Nvert, 0.0));
420 PetscCall(DMDAVecGetArray(user->
da, user->
Phi, &phi));
421 for (PetscInt k = user->
info.zs; k < user->
info.zs + user->
info.zm; ++k) {
422 for (PetscInt j = user->
info.ys; j < user->
info.ys + user->
info.ym; ++j) {
423 for (PetscInt i = user->
info.xs; i < user->
info.xs + user->
info.xm; ++i) {
424 phi[k][j][i] = (PetscReal)i;
428 PetscCall(DMDAVecRestoreArray(user->
da, user->
Phi, &phi));
429 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
430 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
431 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Phi, INSERT_VALUES, user->
lPhi));
432 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Phi, INSERT_VALUES, user->
lPhi));
433 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
434 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
438 PetscCall(DMDAVecGetArrayRead(user->
fda, user->
Ucont, &ucont));
439 PetscCall(
PicurvAssertRealNear(-1.0, ucont[2][2][2].x, 1.0e-10,
"Projection should subtract the x pressure gradient under identity metrics"));
440 PetscCall(
PicurvAssertRealNear(0.0, ucont[2][2][2].y, 1.0e-10,
"Projection should leave the y component unchanged for an x-only gradient"));
441 PetscCall(
PicurvAssertRealNear(0.0, ucont[2][2][2].z, 1.0e-10,
"Projection should leave the z component unchanged for an x-only gradient"));
442 PetscCall(DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, &ucont));
445 PetscFunctionReturn(0);
470 ierr = PetscInitialize(&argc, &argv, NULL,
"PICurv Poisson/RHS tests");
475 ierr =
PicurvRunTests(
"unit-poisson-rhs", cases,
sizeof(cases) /
sizeof(cases[0]));
481 ierr = PetscFinalize();
PetscErrorCode PoissonNullSpaceFunction(MatNullSpace nullsp, Vec X, void *ctx)
The callback function for PETSc's MatNullSpace object.
PetscErrorCode PoissonLHSNew(UserCtx *user)
Assembles the Left-Hand-Side (LHS) matrix (Laplacian operator) for the Poisson equation on a single g...
PetscErrorCode Projection(UserCtx *user)
Corrects the contravariant velocity field Ucont to be divergence-free using the gradient of the press...
PetscErrorCode UpdatePressure(UserCtx *user)
Updates the pressure field P with the pressure correction Phi computed by the Poisson solver.
PetscErrorCode PoissonRHS(UserCtx *user, Vec B)
Computes the Right-Hand-Side (RHS) of the Poisson equation, which is the divergence of the intermedia...
PetscErrorCode ComputeBodyForces(UserCtx *user, Vec Rct)
General dispatcher for applying all active body forces (momentum sources).
PetscErrorCode Viscous(UserCtx *user, Vec Ucont, Vec Ucat, Vec Visc)
Computes the viscous contribution to the contravariant momentum RHS.
PetscErrorCode ComputeEulerianDiffusivity(UserCtx *user)
Computes the effective diffusivity scalar field (Gamma_eff) on the Eulerian grid.
PetscErrorCode ComputeEulerianDiffusivityGradient(UserCtx *user)
Computes the Eulerian gradient of the effective diffusivity field.
PetscErrorCode Convection(UserCtx *user, Vec Ucont, Vec Ucat, Vec Conv)
Computes the convective contribution to the contravariant momentum RHS.
PetscErrorCode ComputeRHS(UserCtx *user, Vec Rhs)
Computes the Right-Hand Side (RHS) of the momentum equations.
static PetscErrorCode TestComputeEulerianDiffusivityMolecularOnly(void)
Tests Eulerian diffusivity for the molecular-only configuration.
static PetscErrorCode TestComputeRHSZeroFieldNoForcing(void)
Tests that the full RHS remains zero without forcing on a quiescent field.
static PetscErrorCode TestViscousUniformField(void)
Tests that viscous terms vanish for a uniform field.
int main(int argc, char **argv)
Runs the unit-poisson-rhs PETSc test binary.
static PetscErrorCode TestConvectionZeroField(void)
Tests that convection vanishes for a quiescent field.
static PetscErrorCode TestComputeBodyForcesDispatcher(void)
Tests the body-force dispatcher across supported source terms.
static PetscErrorCode TestPoissonLHSNewAssemblesOperator(void)
Tests that Poisson matrix assembly produces a populated operator on a tiny Cartesian grid.
static PetscErrorCode TestUpdatePressureAddsPhi(void)
Tests that pressure updates add the correction potential.
static PetscErrorCode TestProjectionZeroPhiLeavesVelocityUnchanged(void)
Tests that projection leaves a zero pressure-correction field unchanged.
static PetscErrorCode TestPoissonRHSZeroDivergence(void)
Tests that the Poisson RHS is zero for zero-divergence velocity.
static PetscErrorCode TestPoissonNullSpaceFunctionRemovesMean(void)
Tests that the Poisson null-space operator removes the mean from a constant field.
static PetscErrorCode TestComputeEulerianDiffusivityVerificationLinearX(void)
Tests verification-driven linear diffusivity override and its gradient.
static PetscErrorCode EnsurePoissonAndRhsVectors(UserCtx *user)
Allocates Poisson/RHS support vectors required by the tests.
static PetscErrorCode TestProjectionLinearPhiCorrectsVelocity(void)
Tests that projection applies the expected x-direction correction for a linear pressure field.
static PetscErrorCode TestComputeEulerianDiffusivityGradientConstantField(void)
Tests diffusivity-gradient computation on a constant field.
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 PicurvAssertRealNear(PetscReal expected, PetscReal actual, PetscReal tol, const char *context)
Asserts that two real values agree within tolerance.
PetscErrorCode PicurvDestroyMinimalContexts(SimCtx **simCtx_ptr, UserCtx **user_ptr)
Destroys minimal SimCtx/UserCtx fixtures and all owned PETSc objects.
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.
PetscErrorCode PicurvAssertVecConstant(Vec vec, PetscScalar expected, PetscReal tol, const char *context)
Asserts that a PETSc vector is spatially constant within tolerance.
PetscErrorCode PicurvAssertIntEqual(PetscInt expected, PetscInt actual, const char *context)
Asserts that two integer values are equal.
PetscErrorCode PicurvAssertBool(PetscBool value, const char *context)
Asserts that one boolean condition is true.
Shared declarations for the PICurv C test fixture and assertion layer.
Named test case descriptor consumed by PicurvRunTests.
BoundaryFaceConfig boundary_faces[6]
PetscReal forceScalingFactor
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
BCHandlerType handler_type
PetscReal bulkVelocityCorrection
char eulerianSource[PETSC_MAX_PATH_LEN]
#define COEF_TIME_ACCURACY
Coefficient controlling the temporal accuracy scheme (e.g., 1.5 for 2nd Order Backward Difference).
VerificationDiffusivityConfig verificationDiffusivity
PetscReal drivingForceMagnitude
A 3D point or vector with PetscScalar components.
The master context for the entire simulation.
User-defined context containing data specific to a single computational grid level.
PetscBool VerificationDiffusivityOverrideActive(const SimCtx *simCtx)
Reports whether a verification-only diffusivity override is active.