25 PetscFunctionBeginUser;
27 PetscCall(VecDestroy(vec));
29 PetscFunctionReturn(0);
37 PetscFunctionBeginUser;
39 PetscCall(DMDestroy(dm));
41 PetscFunctionReturn(0);
49 PetscFunctionBeginUser;
51 PetscCall(MatDestroy(mat));
53 PetscFunctionReturn(0);
61 PetscFunctionBeginUser;
63 PetscCall(KSPDestroy(ksp));
65 PetscFunctionReturn(0);
73 PetscFunctionBeginUser;
74 if (nullsp && *nullsp) {
75 PetscCall(MatNullSpaceDestroy(nullsp));
77 PetscFunctionReturn(0);
85 PetscFunctionBeginUser;
86 if (rand_ctx && *rand_ctx) {
87 PetscCall(PetscRandomDestroy(rand_ctx));
89 PetscFunctionReturn(0);
97 PetscFunctionBeginUser;
98 PetscCall(DMSwarmRegisterPetscDatatypeField(swarm, field_name, field_dim, dtype));
99 PetscFunctionReturn(0);
107 PetscFunctionBeginUser;
108 PetscCall(DMCreateGlobalVector(dm, vec));
109 PetscCall(VecSet(*vec, 0.0));
110 PetscFunctionReturn(0);
118 PetscFunctionBeginUser;
119 PetscCall(DMCreateLocalVector(dm, vec));
120 PetscCall(VecSet(*vec, 0.0));
121 PetscFunctionReturn(0);
129 PetscFunctionBeginUser;
130 PetscCall(VecDuplicate(src, vec));
131 PetscCall(VecSet(*vec, 0.0));
132 PetscFunctionReturn(0);
140 PetscFunctionBeginUser;
142 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
"==> Running %s (%zu tests)\n", suite_name, case_count));
143 for (
size_t i = 0; i < case_count; ++i) {
144 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
" -> %s\n", cases[i].name));
145 PetscCall(cases[i].fn());
146 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
" [PASS] %s\n", cases[i].name));
149 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
"==> %s complete\n", suite_name));
150 PetscFunctionReturn(0);
158 PetscFunctionBeginUser;
159 if (mkdir(path, 0777) != 0 && errno != EEXIST) {
160 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to create directory '%s': %s", path, strerror(errno));
162 PetscFunctionReturn(0);
170 PetscFunctionBeginUser;
171 if (!path || path_len < 24) {
172 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Temp directory buffer is missing or too small.");
175 PetscCall(PetscSNPrintf(path, path_len,
"/tmp/picurv-test-XXXXXX"));
176 if (!mkdtemp(path)) {
177 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"mkdtemp failed for '%s': %s", path, strerror(errno));
179 PetscFunctionReturn(0);
189 PetscFunctionBeginUser;
190 if (!path || path[0] ==
'\0') PetscFunctionReturn(0);
192 if (strncmp(path,
"/tmp/picurv-test-", 17) != 0) {
193 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
194 "Refusing to remove path outside /tmp/picurv-test-*: '%s'", path);
196 PetscCall(PetscSNPrintf(cmd,
sizeof(cmd),
"rm -rf '%s'", path));
197 if (system(cmd) != 0) {
198 PetscCall(PetscPrintf(PETSC_COMM_SELF,
"Warning: failed to remove temp dir '%s'\n", path));
200 PetscFunctionReturn(0);
210 PetscFunctionBeginUser;
211 file = fopen(path,
"w");
212 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to open '%s' for writing.", path);
213 fputs(contents, file);
215 PetscFunctionReturn(0);
222 PetscBool enable_particles,
226 size_t control_path_len)
228 char bcs_path[PETSC_MAX_PATH_LEN];
229 char post_path[PETSC_MAX_PATH_LEN];
230 char output_dir[PETSC_MAX_PATH_LEN];
231 char log_dir[PETSC_MAX_PATH_LEN];
232 char control_buffer[8192];
233 const char *particle_block = NULL;
234 const char *default_bcs =
239 "-Zeta INLET constant_velocity vx=0.0 vy=0.0 vz=1.5\n"
240 "+Zeta OUTLET conservation\n";
242 PetscFunctionBeginUser;
244 PetscCall(PetscSNPrintf(bcs_path,
sizeof(bcs_path),
"%s/bcs.run", tmpdir));
245 PetscCall(PetscSNPrintf(post_path,
sizeof(post_path),
"%s/post.run", tmpdir));
246 PetscCall(PetscSNPrintf(output_dir,
sizeof(output_dir),
"%s/results", tmpdir));
247 PetscCall(PetscSNPrintf(log_dir,
sizeof(log_dir),
"%s/logs", tmpdir));
248 PetscCall(PetscSNPrintf(control_path, control_path_len,
"%s/test.control", tmpdir));
256 "output_particles = false\n"));
258 if (enable_particles) {
265 "-particle_restart_mode init\n";
272 PetscCall(PetscSNPrintf(
274 sizeof(control_buffer),
284 "-profiling_timestep_mode off\n"
285 "-profiling_final_summary true\n"
286 "-postprocessing_config_file %s\n"
302 "-euler_field_source solve\n"
303 "-mom_solver_type EXPLICIT_RK\n"
307 "-particle_console_output_freq 0\n"
320 PetscFunctionReturn(0);
330 PetscBool x_periodic,
331 PetscBool y_periodic,
332 PetscBool z_periodic)
337 PetscInt da_mx = mx + 1;
338 PetscInt da_my = my + 1;
339 PetscInt da_mz = mz + 1;
340 DMBoundaryType x_boundary = x_periodic ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
341 DMBoundaryType y_boundary = y_periodic ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
342 DMBoundaryType z_boundary = z_periodic ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
343 PetscInt stencil_width = (x_periodic || y_periodic || z_periodic) ? 3 : 1;
345 PetscFunctionBeginUser;
346 if (!simCtx_out || !user_out) {
347 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output pointers cannot be NULL.");
350 PetscCall(PetscCalloc1(1, &simCtx));
351 PetscCall(PetscCalloc1(1, &user));
353 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &simCtx->
rank));
354 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &simCtx->
size));
381 PetscCall(PetscStrncpy(simCtx->
log_dir,
"/tmp",
sizeof(simCtx->
log_dir)));
386 PetscCall(PetscCalloc1(simCtx->
size, &simCtx->
bboxlist));
416 for (PetscMPIInt rank_idx = 0; rank_idx < simCtx->
size; ++rank_idx) {
425 PetscCall(DMDACreate3d(PETSC_COMM_WORLD,
426 x_boundary, y_boundary, z_boundary,
429 PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,
433 PetscCall(DMSetUp(user->
da));
434 PetscCall(DMGetCoordinateDM(user->
da, &user->
fda));
435 PetscCall(PetscObjectReference((PetscObject)user->
fda));
436 PetscCall(DMDASetUniformCoordinates(user->
da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0));
437 PetscCall(DMDAGetLocalInfo(user->
da, &user->
info));
441 for (PetscMPIInt rank_idx = 0; rank_idx < simCtx->
size; ++rank_idx) {
442 simCtx->
bboxlist[rank_idx] = boxes[rank_idx];
531 *simCtx_out = simCtx;
533 PetscFunctionReturn(0);
541 PetscFunctionBeginUser;
543 PetscFunctionReturn(0);
555 PetscInt mx = user->
IM;
556 PetscInt my = user->
JM;
557 PetscInt mz = user->
KM;
559 PetscFunctionBeginUser;
560 PetscCall(DMDAVecGetArray(user->
fda, user->
Cent, ¢));
561 for (PetscInt k = user->
info.zs; k < user->
info.zs + user->
info.zm; k++) {
562 for (PetscInt j = user->
info.ys; j < user->
info.ys + user->
info.ym; j++) {
563 for (PetscInt i = user->
info.xs; i < user->
info.xs + user->
info.xm; i++) {
564 cent[k][j][i].
x = (i - 0.5) / (PetscReal)mx;
565 cent[k][j][i].
y = (j - 0.5) / (PetscReal)my;
566 cent[k][j][i].
z = (k - 0.5) / (PetscReal)mz;
570 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Cent, ¢));
571 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
572 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
573 PetscFunctionReturn(0);
594 PetscReal ***aj = NULL;
595 PetscReal ***iaj = NULL;
596 PetscReal ***jaj = NULL;
597 PetscReal ***kaj = NULL;
599 PetscFunctionBeginUser;
600 PetscCall(DMDAVecGetArray(user->
fda, user->
Csi, &csi));
601 PetscCall(DMDAVecGetArray(user->
fda, user->
Eta, &eta));
602 PetscCall(DMDAVecGetArray(user->
fda, user->
Zet, &zet));
603 PetscCall(DMDAVecGetArray(user->
fda, user->
ICsi, &icsi));
604 PetscCall(DMDAVecGetArray(user->
fda, user->
IEta, &ieta));
605 PetscCall(DMDAVecGetArray(user->
fda, user->
IZet, &izet));
606 PetscCall(DMDAVecGetArray(user->
fda, user->
JCsi, &jcsi));
607 PetscCall(DMDAVecGetArray(user->
fda, user->
JEta, &jeta));
608 PetscCall(DMDAVecGetArray(user->
fda, user->
JZet, &jzet));
609 PetscCall(DMDAVecGetArray(user->
fda, user->
KCsi, &kcsi));
610 PetscCall(DMDAVecGetArray(user->
fda, user->
KEta, &keta));
611 PetscCall(DMDAVecGetArray(user->
fda, user->
KZet, &kzet));
612 PetscCall(DMDAVecGetArray(user->
da, user->
Aj, &aj));
613 PetscCall(DMDAVecGetArray(user->
da, user->
IAj, &iaj));
614 PetscCall(DMDAVecGetArray(user->
da, user->
JAj, &jaj));
615 PetscCall(DMDAVecGetArray(user->
da, user->
KAj, &kaj));
617 for (PetscInt k = user->
info.zs; k < user->
info.zs + user->
info.zm; ++k) {
618 for (PetscInt j = user->
info.ys; j < user->
info.ys + user->
info.ym; ++j) {
619 for (PetscInt i = user->
info.xs; i < user->
info.xs + user->
info.xm; ++i) {
620 csi[k][j][i].
x = 1.0; csi[k][j][i].
y = 0.0; csi[k][j][i].
z = 0.0;
621 eta[k][j][i].
x = 0.0; eta[k][j][i].
y = 1.0; eta[k][j][i].
z = 0.0;
622 zet[k][j][i].
x = 0.0; zet[k][j][i].
y = 0.0; zet[k][j][i].
z = 1.0;
623 icsi[k][j][i] = csi[k][j][i];
624 ieta[k][j][i] = eta[k][j][i];
625 izet[k][j][i] = zet[k][j][i];
626 jcsi[k][j][i] = csi[k][j][i];
627 jeta[k][j][i] = eta[k][j][i];
628 jzet[k][j][i] = zet[k][j][i];
629 kcsi[k][j][i] = csi[k][j][i];
630 keta[k][j][i] = eta[k][j][i];
631 kzet[k][j][i] = zet[k][j][i];
640 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Csi, &csi));
641 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Eta, &eta));
642 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Zet, &zet));
643 PetscCall(DMDAVecRestoreArray(user->
fda, user->
ICsi, &icsi));
644 PetscCall(DMDAVecRestoreArray(user->
fda, user->
IEta, &ieta));
645 PetscCall(DMDAVecRestoreArray(user->
fda, user->
IZet, &izet));
646 PetscCall(DMDAVecRestoreArray(user->
fda, user->
JCsi, &jcsi));
647 PetscCall(DMDAVecRestoreArray(user->
fda, user->
JEta, &jeta));
648 PetscCall(DMDAVecRestoreArray(user->
fda, user->
JZet, &jzet));
649 PetscCall(DMDAVecRestoreArray(user->
fda, user->
KCsi, &kcsi));
650 PetscCall(DMDAVecRestoreArray(user->
fda, user->
KEta, &keta));
651 PetscCall(DMDAVecRestoreArray(user->
fda, user->
KZet, &kzet));
652 PetscCall(DMDAVecRestoreArray(user->
da, user->
Aj, &aj));
653 PetscCall(DMDAVecRestoreArray(user->
da, user->
IAj, &iaj));
654 PetscCall(DMDAVecRestoreArray(user->
da, user->
JAj, &jaj));
655 PetscCall(DMDAVecRestoreArray(user->
da, user->
KAj, &kaj));
657 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Csi, INSERT_VALUES, user->
lCsi));
658 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Csi, INSERT_VALUES, user->
lCsi));
659 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Eta, INSERT_VALUES, user->
lEta));
660 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Eta, INSERT_VALUES, user->
lEta));
661 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Zet, INSERT_VALUES, user->
lZet));
662 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Zet, INSERT_VALUES, user->
lZet));
663 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
ICsi, INSERT_VALUES, user->
lICsi));
664 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
ICsi, INSERT_VALUES, user->
lICsi));
665 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
IEta, INSERT_VALUES, user->
lIEta));
666 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
IEta, INSERT_VALUES, user->
lIEta));
667 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
IZet, INSERT_VALUES, user->
lIZet));
668 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
IZet, INSERT_VALUES, user->
lIZet));
669 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
JCsi, INSERT_VALUES, user->
lJCsi));
670 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
JCsi, INSERT_VALUES, user->
lJCsi));
671 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
JEta, INSERT_VALUES, user->
lJEta));
672 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
JEta, INSERT_VALUES, user->
lJEta));
673 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
JZet, INSERT_VALUES, user->
lJZet));
674 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
JZet, INSERT_VALUES, user->
lJZet));
675 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
KCsi, INSERT_VALUES, user->
lKCsi));
676 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
KCsi, INSERT_VALUES, user->
lKCsi));
677 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
KEta, INSERT_VALUES, user->
lKEta));
678 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
KEta, INSERT_VALUES, user->
lKEta));
679 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
KZet, INSERT_VALUES, user->
lKZet));
680 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
KZet, INSERT_VALUES, user->
lKZet));
681 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
682 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
683 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Aj, INSERT_VALUES, user->
lAj));
684 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Aj, INSERT_VALUES, user->
lAj));
685 PetscCall(DMGlobalToLocalBegin(user->
da, user->
IAj, INSERT_VALUES, user->
lIAj));
686 PetscCall(DMGlobalToLocalEnd(user->
da, user->
IAj, INSERT_VALUES, user->
lIAj));
687 PetscCall(DMGlobalToLocalBegin(user->
da, user->
JAj, INSERT_VALUES, user->
lJAj));
688 PetscCall(DMGlobalToLocalEnd(user->
da, user->
JAj, INSERT_VALUES, user->
lJAj));
689 PetscCall(DMGlobalToLocalBegin(user->
da, user->
KAj, INSERT_VALUES, user->
lKAj));
690 PetscCall(DMGlobalToLocalEnd(user->
da, user->
KAj, INSERT_VALUES, user->
lKAj));
691 PetscCall(DMGlobalToLocalBegin(user->
da, user->
P, INSERT_VALUES, user->
lP));
692 PetscCall(DMGlobalToLocalEnd(user->
da, user->
P, INSERT_VALUES, user->
lP));
693 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Psi, INSERT_VALUES, user->
lPsi));
694 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Psi, INSERT_VALUES, user->
lPsi));
695 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
696 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
697 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
698 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
699 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
700 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
701 PetscFunctionReturn(0);
709 PetscFunctionBeginUser;
711 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx cannot be NULL.");
714 PetscCall(DMCreate(PETSC_COMM_WORLD, &user->
swarm));
715 PetscCall(DMSetType(user->
swarm, DMSWARM));
716 PetscCall(DMSetDimension(user->
swarm, 3));
717 PetscCall(DMSwarmSetType(user->
swarm, DMSWARM_BASIC));
718 PetscCall(DMSwarmSetCellDM(user->
swarm, user->
da));
727 PetscCall(DMSwarmFinalizeFieldRegister(user->
swarm));
728 PetscCall(DMSwarmSetLocalSizes(user->
swarm, nlocal, 0));
730 PetscCall(DMCreate(PETSC_COMM_WORLD, &user->
post_swarm));
731 PetscCall(DMSetType(user->
post_swarm, DMSWARM));
732 PetscCall(DMSetDimension(user->
post_swarm, 3));
733 PetscCall(DMSwarmSetType(user->
post_swarm, DMSWARM_BASIC));
734 PetscCall(DMSwarmSetCellDM(user->
post_swarm, user->
da));
736 PetscCall(DMSwarmFinalizeFieldRegister(user->
post_swarm));
737 PetscCall(DMSwarmSetLocalSizes(user->
post_swarm, nlocal, 0));
738 PetscFunctionReturn(0);
745 PetscBool enable_particles,
751 char control_path[PETSC_MAX_PATH_LEN];
754 PetscFunctionBeginUser;
755 PetscCheck(simCtx_out != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx output cannot be NULL.");
757 PetscCall(PetscOptionsClear(NULL));
758 PetscCall(
PrepareTinyRuntimeConfig(bcs_contents, enable_particles, tmpdir, tmpdir_len, control_path,
sizeof(control_path)));
759 PetscCall(PetscOptionsSetValue(NULL,
"-control_file", control_path));
767 *simCtx_out = simCtx;
771 PetscFunctionReturn(0);
784 char bcs_path[PETSC_MAX_PATH_LEN];
785 char post_path[PETSC_MAX_PATH_LEN];
786 char output_dir[PETSC_MAX_PATH_LEN];
787 char log_dir[PETSC_MAX_PATH_LEN];
788 char control_path[PETSC_MAX_PATH_LEN];
789 char control_buffer[8192];
791 const char *default_bcs =
796 "-Zeta INLET constant_velocity vx=0.0 vy=0.0 vz=0.1\n"
797 "+Zeta OUTLET conservation\n";
799 PetscFunctionBeginUser;
800 PetscCheck(simCtx_out != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
801 "SimCtx output cannot be NULL.");
802 PetscCall(PetscOptionsClear(NULL));
804 PetscCall(PetscSNPrintf(bcs_path,
sizeof(bcs_path),
"%s/bcs.run", tmpdir));
805 PetscCall(PetscSNPrintf(post_path,
sizeof(post_path),
"%s/post.run", tmpdir));
806 PetscCall(PetscSNPrintf(output_dir,
sizeof(output_dir),
"%s/results", tmpdir));
807 PetscCall(PetscSNPrintf(log_dir,
sizeof(log_dir),
"%s/logs", tmpdir));
808 PetscCall(PetscSNPrintf(control_path,
sizeof(control_path),
"%s/test.control", tmpdir));
811 "startTime = 0\nendTime = 1\ntimeStep = 1\noutput_particles = false\n"));
812 PetscCall(PetscSNPrintf(control_buffer,
sizeof(control_buffer),
818 "-ucont_x 0.0\n-ucont_y 0.0\n-ucont_z 0.1\n"
820 "-profiling_timestep_mode off\n-profiling_final_summary true\n"
821 "-postprocessing_config_file %s\n"
824 "-grid\n-im 17\n-jm 17\n-km 65\n"
825 "-xMins 0.0\n-xMaxs 1.0\n-yMins 0.0\n-yMaxs 1.0\n-zMins 0.0\n-zMaxs 4.0\n"
826 "-rxs 1.0\n-rys 1.0\n-rzs 1.0\n-cgrids 0\n-nblk 1\n"
827 "-euler_field_source solve\n-mom_solver_type newton_krylov\n"
828 "-mg_level 1\n-poisson 0\n-tio 0\n-numParticles 0\n-pinit 2\n"
829 "-particle_console_output_freq 0\n-logfreq 1\n"
830 "-output_dir %s\n-restart_dir %s\n-log_dir %s\n",
831 bcs_path, post_path, output_dir, output_dir, log_dir));
833 PetscCall(PetscOptionsSetValue(NULL,
"-control_file", control_path));
840 *simCtx_out = simCtx;
842 PetscFunctionReturn(0);
850 PetscFunctionBeginUser;
851 if (simCtx_ptr && *simCtx_ptr) {
855 PetscCall(PetscOptionsClear(NULL));
856 PetscFunctionReturn(0);
867 PetscFunctionBeginUser;
872 simCtx = *simCtx_ptr;
965 PetscCall(PetscFree(user));
973 PetscCall(PetscFree(simCtx->
bboxlist));
975 PetscCall(PetscFree(simCtx->
pps));
976 PetscCall(PetscFree(simCtx));
982 PetscFunctionReturn(0);
990 PetscFunctionBeginUser;
991 if (PetscAbsReal(expected - actual) > tol) {
992 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
993 "[FAIL] %s | expected=%0.12e actual=%0.12e tol=%0.12e\n",
994 context, (
double)expected, (
double)actual, (
double)tol));
995 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Assertion failed.");
997 PetscFunctionReturn(0);
1005 PetscFunctionBeginUser;
1006 if (expected != actual) {
1007 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
1008 "[FAIL] %s | expected=%" PetscInt_FMT
" actual=%" PetscInt_FMT
"\n",
1009 context, expected, actual));
1010 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Assertion failed.");
1012 PetscFunctionReturn(0);
1020 PetscFunctionBeginUser;
1022 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
"[FAIL] %s\n", context));
1023 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Assertion failed.");
1025 PetscFunctionReturn(0);
1033 PetscBool exists = PETSC_FALSE;
1035 PetscFunctionBeginUser;
1036 PetscCall(PetscTestFile(path,
'r', &exists));
1038 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
"[FAIL] %s | missing file: %s\n", context, path));
1039 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Expected file is missing.");
1041 PetscFunctionReturn(0);
1049 PetscReal vmin = 0.0;
1050 PetscReal vmax = 0.0;
1052 PetscFunctionBeginUser;
1053 PetscCall(VecMin(vec, NULL, &vmin));
1054 PetscCall(VecMax(vec, NULL, &vmax));
1057 PetscFunctionReturn(0);
Public interface for grid, solver, and metric setup routines.
PetscErrorCode BroadcastAllBoundingBoxes(UserCtx *user, BoundingBox **bboxlist)
Broadcasts the bounding box information collected on rank 0 to all other ranks.
PetscErrorCode ComputeLocalBoundingBox(UserCtx *user, BoundingBox *localBBox)
Computes the local bounding box of the grid on the current process.
PetscErrorCode GatherAllBoundingBoxes(UserCtx *user, BoundingBox **allBBoxes)
Gathers local bounding boxes from all MPI processes to rank 0.
Public interface for data input/output routines.
void FreeBC_ParamList(BC_Param *head)
Frees an entire linked list of boundary-condition parameters.
PetscErrorCode SetupDomainRankInfo(SimCtx *simCtx)
Sets up the full rank communication infrastructure, including neighbor ranks and bounding box exchang...
PetscErrorCode SetupGridAndSolvers(SimCtx *simCtx)
The main orchestrator for setting up all grid-related components.
PetscErrorCode SetupSimulationEnvironment(SimCtx *simCtx)
Verifies and prepares the complete I/O environment for a simulation run.
PetscErrorCode DestroySolutionConvergenceState(SimCtx *simCtx)
Frees any runtime storage allocated for solution-convergence logging.
PetscErrorCode CreateSimulationContext(int argc, char **argv, SimCtx **p_simCtx)
Allocates and populates the master SimulationContext object.
PetscErrorCode SetupBoundaryConditions(SimCtx *simCtx)
(Orchestrator) Sets up all boundary conditions for the simulation.
PetscErrorCode FinalizeSimulation(SimCtx *simCtx)
Main cleanup function for the entire simulation context.
static PetscErrorCode DestroyKSPIfSet(KSP *ksp)
Destroys a PETSc KSP only when the handle is non-null.
PetscErrorCode PicurvMakeTempDir(char *path, size_t path_len)
Creates a unique temporary directory for one test case.
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 PicurvEnsureDir(const char *path)
Ensures a directory exists for test output.
PetscErrorCode PicurvAssertRealNear(PetscReal expected, PetscReal actual, PetscReal tol, const char *context)
Asserts that two real values agree within tolerance.
static PetscErrorCode DestroyDMIfSet(DM *dm)
Destroys a PETSc DM only when the handle is non-null.
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.
static PetscErrorCode DestroyNullSpaceIfSet(MatNullSpace *nullsp)
Destroys a PETSc nullspace only when the handle is non-null.
static PetscErrorCode CreateZeroedLocalVector(DM dm, Vec *vec)
Allocates and zeroes a local vector from the provided DM.
PetscErrorCode PicurvBuildMomentumPurityRuntimeContext(const char *bcs_contents, SimCtx **simCtx_out, UserCtx **user_out, char *tmpdir, size_t tmpdir_len)
Builds the production-sized straight-duct fixture used only by the opt-in Newton residual-purity diag...
static PetscErrorCode PrepareTinyRuntimeConfig(const char *bcs_contents, PetscBool enable_particles, char *tmpdir, size_t tmpdir_len, char *control_path, size_t control_path_len)
Creates a tiny control-file bundle used by richer runtime fixtures built through the setup path.
PetscErrorCode PicurvCreateSwarmPair(UserCtx *user, PetscInt nlocal, const char *post_field_name)
Creates matched solver and post-processing swarms for tests.
static PetscErrorCode WriteTextFileForTests(const char *path, const char *contents)
Writes one small temporary text file used by the richer runtime fixtures.
static PetscErrorCode DestroyRandomIfSet(PetscRandom *rand_ctx)
Destroys a PETSc random generator only when the handle is non-null.
PetscErrorCode PicurvDestroyRuntimeContext(SimCtx **simCtx_ptr)
Finalizes and frees a runtime context built by PicurvBuildTinyRuntimeContext.
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 PicurvBuildTinyRuntimeContext(const char *bcs_contents, PetscBool enable_particles, SimCtx **simCtx_out, UserCtx **user_out, char *tmpdir, size_t tmpdir_len)
Builds a tiny runtime context through the real setup path for behavior-level tests.
static PetscErrorCode CreateZeroedDuplicate(Vec src, Vec *vec)
Duplicates and zeroes a vector.
static PetscErrorCode DestroyVecIfSet(Vec *vec)
Destroys a PETSc vector only when the handle is non-null.
PetscErrorCode PicurvPopulateUniformCellCenters(UserCtx *user)
Populates cell center coordinates for a uniform grid on [0,1]^3.
PetscErrorCode PicurvAssertFileExists(const char *path, const char *context)
Asserts that a filesystem path exists as a readable file.
static PetscErrorCode RegisterSwarmFieldForTests(DM swarm, const char *field_name, PetscInt field_dim, PetscDataType dtype)
Registers one DMSwarm field used by the C test fixtures.
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.
static PetscErrorCode CreateZeroedGlobalVector(DM dm, Vec *vec)
Allocates and zeroes a global vector from the provided DM.
PetscErrorCode PicurvPopulateIdentityMetrics(UserCtx *user)
Populates identity metric vectors on the minimal grid fixture.
static PetscErrorCode DestroyMatIfSet(Mat *mat)
Destroys a PETSc matrix only when the handle is non-null.
PetscErrorCode PicurvAssertBool(PetscBool value, const char *context)
Asserts that one boolean condition is true.
PetscErrorCode PicurvRemoveTempDir(const char *path)
Recursively removes a temporary directory created by PicurvMakeTempDir.
Shared declarations for the PICurv C test fixture and assertion layer.
Named test case descriptor consumed by PicurvRunTests.
PetscReal icVelocityPhysical
BoundaryFaceConfig boundary_faces[6]
char euler_subdir[PETSC_MAX_PATH_LEN]
PetscReal forceScalingFactor
InitialConditionMode initialConditionMode
SimCtx * simCtx
Back-pointer to the master simulation context.
FlowDirection flowDirection
Cmpnts max_coords
Maximum x, y, z coordinates of the bounding box.
char output_dir[PETSC_MAX_PATH_LEN]
Cmpnts min_coords
Minimum x, y, z coordinates of the bounding box.
Vec Ubcs
Physical Cartesian velocity at boundary faces. Full 3D array but only boundary-face entries are meani...
@ MOMENTUM_SOLVER_EXPLICIT_RK
RankCellInfo * RankCellInfoMap
char particle_subdir[PETSC_MAX_PATH_LEN]
char log_dir[PETSC_MAX_PATH_LEN]
char initialConditionDirectory[PETSC_MAX_PATH_LEN]
PetscRandom BrownianMotionRNG
InitialConditionField initialConditionField
MomentumSolverType mom_solver_type
char restart_dir[PETSC_MAX_PATH_LEN]
PetscInt LoggingFrequency
Vec Uch
Characteristic velocity for boundary conditions.
Defines a 3D axis-aligned bounding box.
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.