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,
223 const char *extra_options,
227 size_t control_path_len)
229 char bcs_path[PETSC_MAX_PATH_LEN];
230 char post_path[PETSC_MAX_PATH_LEN];
231 char output_dir[PETSC_MAX_PATH_LEN];
232 char log_dir[PETSC_MAX_PATH_LEN];
233 char analysis_dir[PETSC_MAX_PATH_LEN];
234 char control_buffer[8192];
235 const char *particle_block = NULL;
236 const char *default_bcs =
241 "-Zeta INLET constant_velocity vx=0.0 vy=0.0 vz=1.5\n"
242 "+Zeta OUTLET conservation\n";
244 PetscFunctionBeginUser;
246 PetscCall(PetscSNPrintf(bcs_path,
sizeof(bcs_path),
"%s/bcs.run", tmpdir));
247 PetscCall(PetscSNPrintf(post_path,
sizeof(post_path),
"%s/post.run", tmpdir));
248 PetscCall(PetscSNPrintf(output_dir,
sizeof(output_dir),
"%s/results", tmpdir));
249 PetscCall(PetscSNPrintf(log_dir,
sizeof(log_dir),
"%s/logs", tmpdir));
252 PetscCall(PetscSNPrintf(analysis_dir,
sizeof(analysis_dir),
"%s/results/analysis/metrics", tmpdir));
253 PetscCall(PetscSNPrintf(control_path, control_path_len,
"%s/test.control", tmpdir));
261 "output_particles = false\n"));
263 if (enable_particles) {
270 "-particle_restart_mode init\n";
277 PetscCall(PetscSNPrintf(
279 sizeof(control_buffer),
289 "-profiling_timestep_mode off\n"
290 "-profiling_final_summary true\n"
291 "-postprocessing_config_file %s\n"
307 "-euler_field_source solve\n"
308 "-mom_solver_type EXPLICIT_RK\n"
312 "-particle_console_output_freq 0\n"
319 "-allow_unsafe_log_dir true\n"
332 extra_options ? extra_options :
""));
334 PetscFunctionReturn(0);
344 PetscBool x_periodic,
345 PetscBool y_periodic,
346 PetscBool z_periodic)
351 PetscInt da_mx = mx + 1;
352 PetscInt da_my = my + 1;
353 PetscInt da_mz = mz + 1;
354 DMBoundaryType x_boundary = x_periodic ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
355 DMBoundaryType y_boundary = y_periodic ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
356 DMBoundaryType z_boundary = z_periodic ? DM_BOUNDARY_PERIODIC : DM_BOUNDARY_NONE;
357 PetscInt stencil_width = (x_periodic || y_periodic || z_periodic) ? 3 : 1;
359 PetscFunctionBeginUser;
360 if (!simCtx_out || !user_out) {
361 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Output pointers cannot be NULL.");
364 PetscCall(PetscCalloc1(1, &simCtx));
365 PetscCall(PetscCalloc1(1, &user));
367 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &simCtx->
rank));
368 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &simCtx->
size));
395 PetscCall(PetscStrncpy(simCtx->
log_dir,
"/tmp",
sizeof(simCtx->
log_dir)));
400 PetscCall(PetscCalloc1(simCtx->
size, &simCtx->
bboxlist));
430 for (PetscMPIInt rank_idx = 0; rank_idx < simCtx->
size; ++rank_idx) {
439 PetscCall(DMDACreate3d(PETSC_COMM_WORLD,
440 x_boundary, y_boundary, z_boundary,
443 PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,
447 PetscCall(DMSetUp(user->
da));
448 PetscCall(DMGetCoordinateDM(user->
da, &user->
fda));
456 PetscCall(DMCreateGlobalVector(user->
da, &user->
PostScalar));
458 PetscCall(DMCreateLocalVector(user->
da, &user->
lPostScalar));
462 PetscCall(DMCreateGlobalVector(user->
fda, &user->
PostVector));
468 PetscCall(PetscObjectReference((PetscObject)user->
fda));
469 PetscCall(DMDASetUniformCoordinates(user->
da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0));
470 PetscCall(DMDAGetLocalInfo(user->
da, &user->
info));
474 for (PetscMPIInt rank_idx = 0; rank_idx < simCtx->
size; ++rank_idx) {
475 simCtx->
bboxlist[rank_idx] = boxes[rank_idx];
572 *simCtx_out = simCtx;
574 PetscFunctionReturn(0);
582 PetscFunctionBeginUser;
584 PetscFunctionReturn(0);
596 PetscInt mx = user->
IM;
597 PetscInt my = user->
JM;
598 PetscInt mz = user->
KM;
600 PetscFunctionBeginUser;
601 PetscCall(DMDAVecGetArray(user->
fda, user->
Cent, ¢));
602 for (PetscInt k = user->
info.zs; k < user->
info.zs + user->
info.zm; k++) {
603 for (PetscInt j = user->
info.ys; j < user->
info.ys + user->
info.ym; j++) {
604 for (PetscInt i = user->
info.xs; i < user->
info.xs + user->
info.xm; i++) {
605 cent[k][j][i].
x = (i - 0.5) / (PetscReal)mx;
606 cent[k][j][i].
y = (j - 0.5) / (PetscReal)my;
607 cent[k][j][i].
z = (k - 0.5) / (PetscReal)mz;
611 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Cent, ¢));
612 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
613 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
614 PetscFunctionReturn(0);
635 PetscReal ***aj = NULL;
636 PetscReal ***iaj = NULL;
637 PetscReal ***jaj = NULL;
638 PetscReal ***kaj = NULL;
640 PetscFunctionBeginUser;
641 PetscCall(DMDAVecGetArray(user->
fda, user->
Csi, &csi));
642 PetscCall(DMDAVecGetArray(user->
fda, user->
Eta, &eta));
643 PetscCall(DMDAVecGetArray(user->
fda, user->
Zet, &zet));
644 PetscCall(DMDAVecGetArray(user->
fda, user->
ICsi, &icsi));
645 PetscCall(DMDAVecGetArray(user->
fda, user->
IEta, &ieta));
646 PetscCall(DMDAVecGetArray(user->
fda, user->
IZet, &izet));
647 PetscCall(DMDAVecGetArray(user->
fda, user->
JCsi, &jcsi));
648 PetscCall(DMDAVecGetArray(user->
fda, user->
JEta, &jeta));
649 PetscCall(DMDAVecGetArray(user->
fda, user->
JZet, &jzet));
650 PetscCall(DMDAVecGetArray(user->
fda, user->
KCsi, &kcsi));
651 PetscCall(DMDAVecGetArray(user->
fda, user->
KEta, &keta));
652 PetscCall(DMDAVecGetArray(user->
fda, user->
KZet, &kzet));
653 PetscCall(DMDAVecGetArray(user->
da, user->
Aj, &aj));
654 PetscCall(DMDAVecGetArray(user->
da, user->
IAj, &iaj));
655 PetscCall(DMDAVecGetArray(user->
da, user->
JAj, &jaj));
656 PetscCall(DMDAVecGetArray(user->
da, user->
KAj, &kaj));
658 for (PetscInt k = user->
info.zs; k < user->
info.zs + user->
info.zm; ++k) {
659 for (PetscInt j = user->
info.ys; j < user->
info.ys + user->
info.ym; ++j) {
660 for (PetscInt i = user->
info.xs; i < user->
info.xs + user->
info.xm; ++i) {
661 csi[k][j][i].
x = 1.0; csi[k][j][i].
y = 0.0; csi[k][j][i].
z = 0.0;
662 eta[k][j][i].
x = 0.0; eta[k][j][i].
y = 1.0; eta[k][j][i].
z = 0.0;
663 zet[k][j][i].
x = 0.0; zet[k][j][i].
y = 0.0; zet[k][j][i].
z = 1.0;
664 icsi[k][j][i] = csi[k][j][i];
665 ieta[k][j][i] = eta[k][j][i];
666 izet[k][j][i] = zet[k][j][i];
667 jcsi[k][j][i] = csi[k][j][i];
668 jeta[k][j][i] = eta[k][j][i];
669 jzet[k][j][i] = zet[k][j][i];
670 kcsi[k][j][i] = csi[k][j][i];
671 keta[k][j][i] = eta[k][j][i];
672 kzet[k][j][i] = zet[k][j][i];
681 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Csi, &csi));
682 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Eta, &eta));
683 PetscCall(DMDAVecRestoreArray(user->
fda, user->
Zet, &zet));
684 PetscCall(DMDAVecRestoreArray(user->
fda, user->
ICsi, &icsi));
685 PetscCall(DMDAVecRestoreArray(user->
fda, user->
IEta, &ieta));
686 PetscCall(DMDAVecRestoreArray(user->
fda, user->
IZet, &izet));
687 PetscCall(DMDAVecRestoreArray(user->
fda, user->
JCsi, &jcsi));
688 PetscCall(DMDAVecRestoreArray(user->
fda, user->
JEta, &jeta));
689 PetscCall(DMDAVecRestoreArray(user->
fda, user->
JZet, &jzet));
690 PetscCall(DMDAVecRestoreArray(user->
fda, user->
KCsi, &kcsi));
691 PetscCall(DMDAVecRestoreArray(user->
fda, user->
KEta, &keta));
692 PetscCall(DMDAVecRestoreArray(user->
fda, user->
KZet, &kzet));
693 PetscCall(DMDAVecRestoreArray(user->
da, user->
Aj, &aj));
694 PetscCall(DMDAVecRestoreArray(user->
da, user->
IAj, &iaj));
695 PetscCall(DMDAVecRestoreArray(user->
da, user->
JAj, &jaj));
696 PetscCall(DMDAVecRestoreArray(user->
da, user->
KAj, &kaj));
698 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Csi, INSERT_VALUES, user->
lCsi));
699 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Csi, INSERT_VALUES, user->
lCsi));
700 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Eta, INSERT_VALUES, user->
lEta));
701 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Eta, INSERT_VALUES, user->
lEta));
702 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Zet, INSERT_VALUES, user->
lZet));
703 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Zet, INSERT_VALUES, user->
lZet));
704 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
ICsi, INSERT_VALUES, user->
lICsi));
705 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
ICsi, INSERT_VALUES, user->
lICsi));
706 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
IEta, INSERT_VALUES, user->
lIEta));
707 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
IEta, INSERT_VALUES, user->
lIEta));
708 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
IZet, INSERT_VALUES, user->
lIZet));
709 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
IZet, INSERT_VALUES, user->
lIZet));
710 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
JCsi, INSERT_VALUES, user->
lJCsi));
711 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
JCsi, INSERT_VALUES, user->
lJCsi));
712 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
JEta, INSERT_VALUES, user->
lJEta));
713 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
JEta, INSERT_VALUES, user->
lJEta));
714 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
JZet, INSERT_VALUES, user->
lJZet));
715 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
JZet, INSERT_VALUES, user->
lJZet));
716 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
KCsi, INSERT_VALUES, user->
lKCsi));
717 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
KCsi, INSERT_VALUES, user->
lKCsi));
718 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
KEta, INSERT_VALUES, user->
lKEta));
719 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
KEta, INSERT_VALUES, user->
lKEta));
720 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
KZet, INSERT_VALUES, user->
lKZet));
721 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
KZet, INSERT_VALUES, user->
lKZet));
722 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
723 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Nvert, INSERT_VALUES, user->
lNvert));
724 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Aj, INSERT_VALUES, user->
lAj));
725 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Aj, INSERT_VALUES, user->
lAj));
726 PetscCall(DMGlobalToLocalBegin(user->
da, user->
IAj, INSERT_VALUES, user->
lIAj));
727 PetscCall(DMGlobalToLocalEnd(user->
da, user->
IAj, INSERT_VALUES, user->
lIAj));
728 PetscCall(DMGlobalToLocalBegin(user->
da, user->
JAj, INSERT_VALUES, user->
lJAj));
729 PetscCall(DMGlobalToLocalEnd(user->
da, user->
JAj, INSERT_VALUES, user->
lJAj));
730 PetscCall(DMGlobalToLocalBegin(user->
da, user->
KAj, INSERT_VALUES, user->
lKAj));
731 PetscCall(DMGlobalToLocalEnd(user->
da, user->
KAj, INSERT_VALUES, user->
lKAj));
732 PetscCall(DMGlobalToLocalBegin(user->
da, user->
P, INSERT_VALUES, user->
lP));
733 PetscCall(DMGlobalToLocalEnd(user->
da, user->
P, INSERT_VALUES, user->
lP));
734 PetscCall(DMGlobalToLocalBegin(user->
da, user->
Psi, INSERT_VALUES, user->
lPsi));
735 PetscCall(DMGlobalToLocalEnd(user->
da, user->
Psi, INSERT_VALUES, user->
lPsi));
736 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
737 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucat, INSERT_VALUES, user->
lUcat));
738 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
739 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Ucont, INSERT_VALUES, user->
lUcont));
740 PetscCall(DMGlobalToLocalBegin(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
741 PetscCall(DMGlobalToLocalEnd(user->
fda, user->
Cent, INSERT_VALUES, user->
lCent));
742 PetscFunctionReturn(0);
750 PetscFunctionBeginUser;
752 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx cannot be NULL.");
755 PetscCall(DMCreate(PETSC_COMM_WORLD, &user->
swarm));
756 PetscCall(DMSetType(user->
swarm, DMSWARM));
757 PetscCall(DMSetDimension(user->
swarm, 3));
758 PetscCall(DMSwarmSetType(user->
swarm, DMSWARM_BASIC));
759 PetscCall(DMSwarmSetCellDM(user->
swarm, user->
da));
768 PetscCall(DMSwarmFinalizeFieldRegister(user->
swarm));
769 PetscCall(DMSwarmSetLocalSizes(user->
swarm, nlocal, 0));
771 PetscCall(DMCreate(PETSC_COMM_WORLD, &user->
post_swarm));
772 PetscCall(DMSetType(user->
post_swarm, DMSWARM));
773 PetscCall(DMSetDimension(user->
post_swarm, 3));
774 PetscCall(DMSwarmSetType(user->
post_swarm, DMSWARM_BASIC));
775 PetscCall(DMSwarmSetCellDM(user->
post_swarm, user->
da));
777 PetscCall(DMSwarmFinalizeFieldRegister(user->
post_swarm));
778 PetscCall(DMSwarmSetLocalSizes(user->
post_swarm, nlocal, 0));
779 PetscFunctionReturn(0);
786 PetscBool enable_particles,
792 PetscFunctionBeginUser;
794 simCtx_out, user_out, tmpdir, tmpdir_len));
795 PetscFunctionReturn(0);
802 PetscBool enable_particles,
803 const char *extra_options,
809 char control_path[PETSC_MAX_PATH_LEN];
812 PetscFunctionBeginUser;
813 PetscCheck(simCtx_out != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx output cannot be NULL.");
815 PetscCall(PetscOptionsClear(NULL));
817 control_path,
sizeof(control_path)));
818 PetscCall(PetscOptionsSetValue(NULL,
"-control_file", control_path));
826 *simCtx_out = simCtx;
830 PetscFunctionReturn(0);
843 char bcs_path[PETSC_MAX_PATH_LEN];
844 char post_path[PETSC_MAX_PATH_LEN];
845 char output_dir[PETSC_MAX_PATH_LEN];
846 char log_dir[PETSC_MAX_PATH_LEN];
847 char analysis_dir[PETSC_MAX_PATH_LEN];
848 char control_path[PETSC_MAX_PATH_LEN];
849 char control_buffer[8192];
851 const char *default_bcs =
856 "-Zeta INLET constant_velocity vx=0.0 vy=0.0 vz=0.1\n"
857 "+Zeta OUTLET conservation\n";
859 PetscFunctionBeginUser;
860 PetscCheck(simCtx_out != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
861 "SimCtx output cannot be NULL.");
862 PetscCall(PetscOptionsClear(NULL));
864 PetscCall(PetscSNPrintf(bcs_path,
sizeof(bcs_path),
"%s/bcs.run", tmpdir));
865 PetscCall(PetscSNPrintf(post_path,
sizeof(post_path),
"%s/post.run", tmpdir));
866 PetscCall(PetscSNPrintf(output_dir,
sizeof(output_dir),
"%s/results", tmpdir));
867 PetscCall(PetscSNPrintf(log_dir,
sizeof(log_dir),
"%s/logs", tmpdir));
870 PetscCall(PetscSNPrintf(analysis_dir,
sizeof(analysis_dir),
"%s/results/analysis/metrics", tmpdir));
871 PetscCall(PetscSNPrintf(control_path,
sizeof(control_path),
"%s/test.control", tmpdir));
874 "startTime = 0\nendTime = 1\ntimeStep = 1\noutput_particles = false\n"));
875 PetscCall(PetscSNPrintf(control_buffer,
sizeof(control_buffer),
881 "-ucont_x 0.0\n-ucont_y 0.0\n-ucont_z 0.1\n"
883 "-profiling_timestep_mode off\n-profiling_final_summary true\n"
884 "-postprocessing_config_file %s\n"
887 "-grid\n-im 17\n-jm 17\n-km 65\n"
888 "-xMins 0.0\n-xMaxs 1.0\n-yMins 0.0\n-yMaxs 1.0\n-zMins 0.0\n-zMaxs 4.0\n"
889 "-rxs 1.0\n-rys 1.0\n-rzs 1.0\n-cgrids 0\n-nblk 1\n"
890 "-euler_field_source solve\n-mom_solver_type newton_krylov\n"
891 "-mg_level 1\n-poisson 0\n-tio 0\n-numParticles 0\n-pinit 2\n"
892 "-particle_console_output_freq 0\n-logfreq 1\n"
894 "-output_dir %s\n-restart_dir %s\n-allow_unsafe_log_dir true\n-log_dir %s\n"
895 "-analysis_dir %s\n",
896 bcs_path, post_path, output_dir, output_dir, log_dir, analysis_dir));
898 PetscCall(PetscOptionsSetValue(NULL,
"-control_file", control_path));
905 *simCtx_out = simCtx;
907 PetscFunctionReturn(0);
915 PetscFunctionBeginUser;
916 if (simCtx_ptr && *simCtx_ptr) {
920 PetscCall(PetscOptionsClear(NULL));
921 PetscFunctionReturn(0);
932 PetscFunctionBeginUser;
937 simCtx = *simCtx_ptr;
1040 PetscCall(PetscFree(user));
1048 PetscCall(PetscFree(simCtx->
bboxlist));
1050 PetscCall(PetscFree(simCtx->
pps));
1051 PetscCall(PetscFree(simCtx));
1057 PetscFunctionReturn(0);
1065 PetscFunctionBeginUser;
1068 if (!(PetscAbsReal(expected - actual) <= tol)) {
1069 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
1070 "[FAIL] %s | expected=%0.12e actual=%0.12e tol=%0.12e\n",
1071 context, (
double)expected, (
double)actual, (
double)tol));
1072 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Assertion failed.");
1074 PetscFunctionReturn(0);
1082 PetscFunctionBeginUser;
1083 if (expected != actual) {
1084 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
1085 "[FAIL] %s | expected=%" PetscInt_FMT
" actual=%" PetscInt_FMT
"\n",
1086 context, expected, actual));
1087 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Assertion failed.");
1089 PetscFunctionReturn(0);
1097 PetscFunctionBeginUser;
1099 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
"[FAIL] %s\n", context));
1100 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
"Assertion failed.");
1102 PetscFunctionReturn(0);
1110 PetscBool exists = PETSC_FALSE;
1112 PetscFunctionBeginUser;
1113 PetscCall(PetscTestFile(path,
'r', &exists));
1115 PetscCall(PetscPrintf(PETSC_COMM_WORLD,
"[FAIL] %s | missing file: %s\n", context, path));
1116 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Expected file is missing.");
1118 PetscFunctionReturn(0);
1126 PetscReal vmin = 0.0;
1127 PetscReal vmax = 0.0;
1129 PetscFunctionBeginUser;
1130 PetscCall(VecMin(vec, NULL, &vmin));
1131 PetscCall(VecMax(vec, NULL, &vmax));
1134 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 CreateCompatibleBlockDM(DM source, PetscInt dof, DM *result)
Creates a DMDA sharing a block's decomposition at a different degree of freedom.
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 LESConfigSetDefaults(LESConfig *config)
Installs the shipped defaults for every LES closure parameter.
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...
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.
static PetscErrorCode PrepareTinyRuntimeConfig(const char *bcs_contents, PetscBool enable_particles, const char *extra_options, 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 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.
PetscErrorCode PicurvBuildTinyRuntimeContextWithOptions(const char *bcs_contents, PetscBool enable_particles, const char *extra_options, SimCtx **simCtx_out, UserCtx **user_out, char *tmpdir, size_t tmpdir_len)
Builds the tiny runtime context with extra control-file options appended.
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
Vec Qcrit_nodal
Q-criterion averaged to grid nodes; the field a .vts can place correctly.
BoundaryFaceConfig boundary_faces[6]
LESConfig les_config
Parameters of the LES closure selected by les.
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]
PetscBool solutionConvergenceEnabled
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 log_dir[PETSC_MAX_PATH_LEN]
char initialConditionDirectory[PETSC_MAX_PATH_LEN]
PetscRandom BrownianMotionRNG
Vec lQcrit
Cell-centred Q-criterion and its ghosted copy for nodal averaging.
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.