20 double values[3][3][3];
21 double weights[3][3][3];
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;
34 "Simpson-rule filter should preserve a constant field"));
37 "box filter should preserve a constant field"));
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;
47 "box filter should return zero when all weights are zero"));
48 PetscFunctionReturn(0);
58 PetscErrorCode ierr_grid = 0;
59 PetscErrorCode ierr_non_square = 0;
61 PetscFunctionBeginUser;
64 "TGV3D should require custom geometry"));
66 "ZERO_FLOW should not require custom geometry"));
69 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
71 PetscCall(PetscPopErrorHandler());
73 "SetAnalyticalGridInfo should reject analytical types without custom geometry"));
77 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
79 PetscCall(PetscPopErrorHandler());
81 "TGV3D multi-block setup should reject non-square block counts"));
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"));
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"));
99 PetscFunctionReturn(0);
110 PetscReal value = 0.0;
111 PetscReal ***target_arr = NULL;
112 PetscReal *positions = NULL;
113 PetscReal *psi = NULL;
115 PetscFunctionBeginUser;
129 "constant scalar profile should evaluate to the configured value"));
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));
137 PetscCall(DMSwarmGetField(user->
swarm,
"Psi", NULL, NULL, (
void **)&psi));
139 "SetAnalyticalScalarFieldOnParticles should overwrite the first particle scalar"));
141 "SetAnalyticalScalarFieldOnParticles should overwrite the second particle scalar"));
142 PetscCall(DMSwarmRestoreField(user->
swarm,
"Psi", NULL, NULL, (
void **)&psi));
151 "linear-x scalar profile should evaluate phi0 + slope_x * x"));
153 PetscCall(VecDuplicate(user->
Psi, &target));
155 PetscCall(DMDAVecGetArrayRead(user->
da, target, &target_arr));
157 "cell-center scalar fill should use the physical x center coordinate"));
158 PetscCall(DMDAVecRestoreArrayRead(user->
da, target, &target_arr));
159 PetscCall(VecDestroy(&target));
170 "sin-product scalar profile should peak at pi/2 in each coordinate"));
173 PetscFunctionReturn(0);
183 PetscErrorCode ierr_unknown = 0;
187 PetscFunctionBeginUser;
189 PetscCall(VecSet(user->
Ucat, 3.0));
190 PetscCall(VecSet(user->
P, 5.0));
191 PetscCall(VecSet(user->
Bcs.
Ubcs, 7.0));
203 Cmpnts ***l_csi, ***l_eta, ***l_zet;
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};
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));
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));
246 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
248 PetscCall(PetscPopErrorHandler());
250 "AnalyticalSolutionEngine should reject unknown analytical type strings"));
253 PetscFunctionReturn(0);
268 PetscReal ***p = NULL;
269 const PetscReal vel_decay = PetscExpReal(-0.5);
271 PetscFunctionBeginUser;
277 PetscCall(DMDAVecGetArray(user->
fda, user->
Cent, ¢));
278 PetscCall(DMDAVecGetArray(user->
fda, user->
lCentx, ¢_x));
279 PetscCall(DMDAVecGetArray(user->
fda, user->
lCenty, ¢_y));
280 PetscCall(DMDAVecGetArray(user->
fda, user->
lCentz, ¢_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];
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, ¢_z));
303 PetscCall(DMDAVecRestoreArray(user->
fda, user->
lCenty, ¢_y));
304 PetscCall(DMDAVecRestoreArray(user->
fda, user->
lCentx, ¢_x));
305 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Cent, ¢));
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));
323 PetscFunctionReturn(0);
333 PetscReal *data = NULL;
334 const PetscReal vel_decay = PetscExpReal(-0.5);
336 PetscFunctionBeginUser;
337 PetscCall(PetscMemzero(&simCtx,
sizeof(simCtx)));
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));
349 PetscCall(VecGetArray(tempVec, &data));
351 "TGV3D particle dispatch should populate the x velocity at x=pi/2"));
353 "TGV3D particle dispatch should leave the first particle y velocity at zero"));
355 "TGV3D particle dispatch should leave the first particle z velocity at zero"));
357 "TGV3D particle dispatch should leave the second particle x velocity at zero"));
359 "TGV3D particle dispatch should populate the y velocity at y=pi/2"));
361 "TGV3D particle dispatch should leave the second particle z velocity at zero"));
362 PetscCall(VecRestoreArray(tempVec, &data));
365 PetscCall(VecGetArray(tempVec, &data));
369 PetscCall(VecRestoreArray(tempVec, &data));
371 PetscCall(VecGetArray(tempVec, &data));
373 "Non-TGV particle dispatch should leave the vector untouched"));
375 "Non-TGV particle dispatch should preserve the y component"));
377 "Non-TGV particle dispatch should preserve the z component"));
378 PetscCall(VecRestoreArray(tempVec, &data));
385 PetscCall(VecGetArray(tempVec, &data));
387 "UNIFORM_FLOW particle dispatch should populate the x velocity"));
389 "UNIFORM_FLOW particle dispatch should populate the y velocity"));
391 "UNIFORM_FLOW particle dispatch should populate the z velocity"));
393 "UNIFORM_FLOW particle dispatch should use the same x velocity for each particle"));
395 "UNIFORM_FLOW particle dispatch should use the same y velocity for each particle"));
397 "UNIFORM_FLOW particle dispatch should use the same z velocity for each particle"));
398 PetscCall(VecRestoreArray(tempVec, &data));
400 PetscCall(VecDestroy(&tempVec));
401 PetscFunctionReturn(0);
412 PetscReal ***
nu_t = NULL;
416 const PetscReal coefficient = 0.25;
417 const PetscReal expected_nu_t = 0.25 * PetscSqrtReal(2.0);
419 PetscFunctionBeginUser;
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));
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;
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));
449 PetscCall(DMDAVecGetArrayRead(user->
da, user->
Nu_t, &
nu_t));
451 "linear velocity field should yield deterministic LES eddy viscosity"));
453 "boundary cells should remain untouched by the interior LES loop"));
454 PetscCall(DMDAVecRestoreArrayRead(user->
da, user->
Nu_t, &
nu_t));
456 PetscCall(VecDestroy(&user->
CS));
457 PetscCall(VecDestroy(&user->
lCs));
459 PetscFunctionReturn(0);
469 PetscErrorCode ierr_flow = 0;
471 PetscFunctionBeginUser;
475 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
477 PetscCall(PetscPopErrorHandler());
479 "FlowSolver should reject unsupported momentum solver selectors"));
482 PetscFunctionReturn(0);
498 PetscFunctionBeginUser;
500 PetscCall(VecDuplicate(user->
Ucont, &rct));
501 PetscCall(VecZeroEntries(rct));
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));
527 PetscCall(DMDAVecGetArrayRead(user->
fda, rct, &rct_arr));
529 "driven flow source should update the controller magnitude"));
531 "driven flow source should leave the y component unchanged"));
533 "driven flow source should leave the z component unchanged"));
534 PetscCall(DMDAVecRestoreArrayRead(user->
fda, rct, &rct_arr));
536 PetscCall(VecDestroy(&rct));
538 PetscFunctionReturn(0);
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);
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);
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));
620 if (ci >= gxs && ci < gxs+gxm && cj >= gys && cj < gys+gym && ck >= gzs && ck < gzs+gzm)
622 PetscCall(DMDAVecRestoreArray(da, lvec, &a));
623 PetscFunctionReturn(0);
631 PetscFunctionBeginUser;
648 "restored history enables BDF2 at restart setup"));
651 "restored history enables BDF2 on first restart solve"));
653 PetscFunctionReturn(0);
660 PetscBool px, PetscBool py, PetscBool pz,
BCType bc)
662 PetscFunctionBeginUser;
670 (*simCtx)->dt = 0.1; (*simCtx)->step = 1; (*simCtx)->StartStep = 0;
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;
676 if (!(*user)->lNu_t) PetscCall(DMCreateLocalVector((*user)->da, &(*user)->lNu_t));
681 PetscFunctionReturn(0);
687 const PetscBool p = (PetscBool)(bc ==
PERIODIC);
688 PetscFunctionBeginUser;
690 PetscFunctionReturn(0);
697 PetscFunctionBeginUser;
708 PetscFunctionReturn(0);
715 PetscFunctionBeginUser;
723 PetscFunctionReturn(0);
730 PetscFunctionBeginUser;
738 PetscFunctionReturn(0);
745 PetscFunctionBeginUser;
753 PetscFunctionReturn(0);
760 PetscFunctionBeginUser;
766 PetscFunctionReturn(0);
773 PetscFunctionBeginUser;
780 PetscFunctionReturn(0);
787 PetscFunctionBeginUser;
797 PetscFunctionReturn(0);
804 PetscReal n_ucont_0, n_ucat_0, n_nvert_0, n_ucont_1, n_ucat_1, n_nvert_1;
805 PetscFunctionBeginUser;
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));
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));
822 PetscFunctionReturn(0);
833 const PetscReal sx = dy*dz, sy = dx*dz, sz = dx*dy, aj = 1.0/(dx*dy*dz);
838 PetscFunctionBeginUser;
839 for (
int t = 0; t < 4; ++t) {
845 PetscFunctionReturn(0);
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);
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);
895 PetscFunctionBeginUser;
902 PetscFunctionReturn(0);
909 PetscFunctionBeginUser;
917 PetscFunctionReturn(0);
924 const PetscInt offs[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
925 PetscFunctionBeginUser;
926 for (
int d = 0; d < 3; ++d) {
930 4+offs[d][0], 4+offs[d][1], 4+offs[d][2], 1.0));
944 PetscFunctionReturn(0);
952 PetscFunctionBeginUser;
969 PetscFunctionReturn(0);
976 PetscErrorCode e1 = 0, e2 = 0;
977 PetscFunctionBeginUser;
981 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
983 PetscCall(PetscPopErrorHandler());
984 PetscCall(
PicurvAssertBool((PetscBool)(e1 != 0),
"block_number<=0 rejected"));
987 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
989 PetscCall(PetscPopErrorHandler());
990 PetscCall(
PicurvAssertBool((PetscBool)(e2 != 0),
"non-finite inverse-Jacobian rejected"));
993 PetscFunctionReturn(0);
1000 PetscFunctionBeginUser;
1008 PetscFunctionReturn(0);
1015 PetscFunctionBeginUser;
1029 PetscFunctionReturn(0);
1036 PetscFunctionBeginUser;
1046 PetscFunctionReturn(0);
1053 Vec ucont0, ucat0, nvert0, nut0, aj0;
1055 PetscFunctionBeginUser;
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));
1068 PetscCall(VecEqual(user->
lUcat, ucat0, &eq)); PetscCall(
PicurvAssertBool(eq,
"lUcat 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));
1075 PetscFunctionReturn(0);
1084 const PetscInt mx = 9, my = 9, mz = 9;
1085 PetscFunctionBeginUser;
1087 PetscCall(DMDAVecGetArray(user->
da, user->
lNvert, &nvert));
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"));
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"));
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));
1102 PetscFunctionReturn(0);
1109 PetscErrorCode e_bad = 0; PetscBool eq;
1111 PetscFunctionBeginUser;
1114 PetscCall(VecDuplicate(user->
lAj, &aj_good)); PetscCall(VecCopy(user->
lAj, aj_good));
1117 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
1119 PetscCall(PetscPopErrorHandler());
1120 PetscCall(
PicurvAssertBool((PetscBool)(e_bad != 0),
"bad metric triggers error"));
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)"));
1130 PetscCall(VecDestroy(&aj_good));
1132 PetscFunctionReturn(0);
1140 Vec Rhs, ref; PetscReal dt, nrm;
1141 PetscFunctionBeginUser;
1144 PetscCall(VecSet(user->
Ucont, 2.0));
1145 PetscCall(VecSet(user->
Ucont_o, 1.0));
1146 PetscCall(VecSet(user->
Ucont_rm1, 0.5));
1147 PetscCall(VecDuplicate(user->
Ucont, &Rhs));
1148 PetscCall(VecDuplicate(user->
Ucont, &ref));
1155 PetscCall(VecSet(Rhs, 3.0));
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));
1160 PetscCall(VecSet(ref, -9.5));
1161 PetscCall(VecAXPY(ref, -1.0, Rhs)); PetscCall(VecNorm(ref, NORM_INFINITY, &nrm));
1169 PetscCall(VecSet(Rhs, 3.0));
1170 PetscCall(VecAXPY(Rhs, -a0/dt, user->
Ucont));
1171 PetscCall(VecAXPY(Rhs, +1.0/dt, user->
Ucont_o));
1173 PetscCall(VecSet(ref, -7.0));
1174 PetscCall(VecAXPY(ref, -1.0, Rhs)); PetscCall(VecNorm(ref, NORM_INFINITY, &nrm));
1177 PetscCall(VecDestroy(&Rhs)); PetscCall(VecDestroy(&ref));
1179 PetscFunctionReturn(0);
1188 PetscErrorCode ierr;
1222 ierr = PetscInitialize(&argc, &argv, NULL,
"PICurv solver utility tests");
1227 ierr =
PicurvRunTests(
"unit-solver", cases,
sizeof(cases) /
sizeof(cases[0]));
1233 ierr = PetscFinalize();
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.
PetscErrorCode AnalyticalSolutionEngine(SimCtx *simCtx)
Dispatches to the appropriate analytical solution function based on simulation settings.
PetscBool AnalyticalTypeRequiresCustomGeometry(const char *analytical_type)
Reports whether an analytical type requires custom geometry/decomposition logic.
PetscErrorCode SetAnalyticalSolutionForParticles(Vec tempVec, SimCtx *simCtx)
Applies the analytical solution to particle velocity vector.
PetscErrorCode SetAnalyticalGridInfo(UserCtx *user)
Sets the grid domain and resolution for analytical solution cases.
Momentum source terms added to the contravariant RHS.
PetscErrorCode ComputeDrivenChannelFlowSource(UserCtx *user, Vec Rct)
Applies a momentum source term to drive flow in a periodic channel or pipe.
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.
PetscErrorCode ComputeEddyViscosityLES(UserCtx *user)
Computes the turbulent eddy viscosity for one block.
@ MOM_STAB_LIMITER_VISCOSITY
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 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).
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().
PetscErrorCode FlowSolver(SimCtx *simCtx)
Orchestrates a single time step of the Eulerian fluid solver.
static PetscErrorCode TestAnalyticalSolutionEngineTaylorGreenSamples(void)
Tests exact Taylor-Green samples on selected Eulerian interior and boundary points.
static PetscErrorCode TestMomentumStabilityWallSuppression(void)
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 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)
int main(int argc, char **argv)
Runs the unit-solver PETSc test binary.
static PetscErrorCode TestMomentumStabilityReadOnly(void)
static PetscErrorCode TestMomentumStabilityOneSidedViscous(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 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 MomMakeUnitGrid(SimCtx **simCtx, UserCtx **user, PetscInt n, BCType bc)
static PetscErrorCode TestMomentumStabilityCandidateBCDivergence(void)
static PetscErrorCode TestDrivenChannelFlowSource(void)
Tests driven-channel flow source-term evaluation.
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 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 MomMakeUnitGridP(SimCtx **simCtx, UserCtx **user, PetscInt n, PetscBool px, PetscBool py, PetscBool pz, BCType bc)
static PetscErrorCode TestMomentumBDFResidualCombination(void)
static void MomSetAllBC(UserCtx *user, BCType t)
Sets the mathematical BC type on all six faces of a test UserCtx.
static PetscErrorCode MomFillLocalScalar(DM da, Vec lvec, PetscReal v)
Fills a local scalar vector (ghosts included) with a uniform value.
static PetscErrorCode TestLESTestFilterPaths(void)
Tests LES test-filter helper paths for representative cases.
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 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 MomFillUcontXRamp(DM fda, Vec lvec, PetscReal slope)
Fills lUcont.x as a linear ramp slope*i (nonzero discrete contravariant divergence).
static PetscErrorCode TestMomentumStabilityValidation(void)
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 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.
PetscErrorCode PicurvCreateSwarmPair(UserCtx *user, PetscInt nlocal, const char *post_field_name)
Creates matched solver and post-processing swarms for tests.
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.
BCType
Defines the general mathematical/physical Category of a boundary.
BoundaryFaceConfig boundary_faces[6]
PetscReal forceScalingFactor
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
BCHandlerType handler_type
PetscReal bulkVelocityCorrection
@ LES_TEST_FILTER_SIMPSON_IK
@ LES_TEST_FILTER_VOLUME_WEIGHTED_BOX
Vec Ubcs
Physical Cartesian velocity at boundary faces. Full 3D array but only boundary-face entries are meani...
MomentumSolverType
Enumerator to identify the implemented momentum solver strategies.
VerificationScalarConfig verificationScalar
Cmpnts AnalyticalUniformVelocity
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
PetscInt les
Active LES closure; an LESModelType value.
PetscBool restartHistoryAvailable
MomentumSolverType mom_solver_type
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.
double nu_t(double yplus)
Computes turbulent eddy viscosity ratio (ν_t / ν)