27 PetscFunctionBeginUser;
28 PetscCall(PetscMemzero(&simCtx,
sizeof(simCtx)));
34 PetscFunctionReturn(0);
42 char tmpdir[PETSC_MAX_PATH_LEN];
43 char filepath[PETSC_MAX_PATH_LEN];
45 PetscBool exists = PETSC_FALSE;
47 PetscFunctionBeginUser;
49 PetscCall(PetscSNPrintf(filepath,
sizeof(filepath),
"%s/sample.txt", tmpdir));
51 file = fopen(filepath,
"w");
52 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to create temp file '%s'.", filepath);
53 fputs(
"picurv\n", file);
57 PetscCall(
PicurvAssertBool(exists,
"VerifyPathExistence should find the temp directory"));
60 PetscCall(
PicurvAssertBool(exists,
"VerifyPathExistence should find the temp file"));
62 PetscFunctionReturn(0);
72 char tmpdir[PETSC_MAX_PATH_LEN];
73 char path[PETSC_MAX_PATH_LEN];
74 PetscBool exists = PETSC_FALSE;
76 PetscFunctionBeginUser;
80 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
84 PetscCall(VecSet(user->
P, 4.5));
85 PetscCall(VecSet(user->
Nvert, 0.0));
86 PetscCall(VecSet(user->
Ucat, 2.0));
87 PetscCall(VecSet(user->
Ucont, 3.0));
93 PetscCall(PetscSNPrintf(path,
sizeof(path),
94 "%s/checkpoints/step_000000000001/checkpoint.meta", tmpdir));
95 PetscCall(PetscTestFile(path,
'r', &exists));
96 PetscCall(
PicurvAssertBool(exists,
"checkpoint coordinator should write checkpoint.meta"));
97 PetscCall(PetscSNPrintf(path,
sizeof(path),
98 "%s/checkpoints/step_000000000001/COMMITTED", tmpdir));
99 PetscCall(PetscTestFile(path,
'r', &exists));
100 PetscCall(
PicurvAssertBool(exists,
"checkpoint coordinator should write COMMITTED last"));
101 PetscCall(PetscSNPrintf(path,
sizeof(path),
102 "%s/checkpoints/step_000000000001/eulerian/block_0000/Ucat.dat", tmpdir));
103 PetscCall(PetscTestFile(path,
'r', &exists));
104 PetscCall(
PicurvAssertBool(exists,
"checkpoint should use catalogued canonical field names"));
105 PetscCall(VecZeroEntries(user->
P));
106 PetscCall(VecZeroEntries(user->
Ucat));
107 PetscCall(VecZeroEntries(user->
Ucont));
108 PetscCall(VecZeroEntries(user->
Ucont_rm1));
116 "ReadSimulationFields should restore BDF2 history"));
118 "checkpoint physical time should be authoritative"));
120 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
122 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
124 PetscFunctionReturn(0);
138 char tmpdir[PETSC_MAX_PATH_LEN];
140 PetscFunctionBeginUser;
144 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
148 PetscCall(VecSet(user->
P, 2.0));
149 PetscCall(VecSet(user->
Nvert, 0.0));
150 PetscCall(VecSet(user->
Ucat, 1.0));
151 PetscCall(VecSet(user->
Ucont, 1.0));
156 PetscCall(PetscCalloc1(1, &simCtx->
pps));
165 for (PetscInt pass = 0; pass < 2; ++pass) {
173 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
175 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
177 PetscFunctionReturn(0);
185 memset(&d, 0,
sizeof(d));
201 PetscFunctionBeginUser;
208 PetscFunctionReturn(0);
215 PetscFunctionBeginUser;
221 PetscFunctionReturn(0);
237 PetscBool accepted = PETSC_FALSE;
238 PetscReal weight = 0.0;
239 char step_directory[PETSC_MAX_PATH_LEN];
241 PetscFunctionBeginUser;
249 "the fixture window reaches its bounded end"));
253 PetscCall(PetscSNPrintf(step_directory,
sizeof(step_directory),
254 "%s/checkpoints/step_000000000001", simCtx->
output_dir));
255 if (simCtx->
rank == 0) PetscCall(PetscRMTree(step_directory));
256 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
258 PetscFunctionReturn(0);
276 char tmpdir[PETSC_MAX_PATH_LEN];
277 char path[PETSC_MAX_PATH_LEN];
278 PetscBool exists = PETSC_FALSE;
279 PetscInt payload_count = 0;
280 Vec *reference = NULL;
282 PetscFunctionBeginUser;
286 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
290 PetscCall(VecSet(user->
Nvert, 0.0));
296 const PetscReal scalars[3] = {1.0, 2.0, 6.0};
298 for (PetscInt s = 0; s < 3; ++s) {
299 PetscBool accepted = PETSC_FALSE;
300 PetscReal weight = 0.0;
302 PetscCall(VecSet(user->
P, scalars[s]));
303 PetscCall(VecSet(user->
Ucat, scalars[s]));
311 PetscCall(PetscSNPrintf(path,
sizeof(path),
312 "%s/checkpoints/step_000000000001/statistics/window_0000/block_0000/P_mean.dat",
314 PetscCall(PetscTestFile(path,
'r', &exists));
315 PetscCall(
PicurvAssertBool(exists,
"statistics payloads use their enumerated names"));
316 PetscCall(PetscSNPrintf(path,
sizeof(path),
317 "%s/checkpoints/step_000000000001/statistics/window_0000/block_0000/Ucat_m2.dat",
319 PetscCall(PetscTestFile(path,
'r', &exists));
320 PetscCall(
PicurvAssertBool(exists,
"the symmetric product is one payload, not six"));
325 PetscCall(PetscCalloc1((
size_t)payload_count, &reference));
326 for (PetscInt index = 0; index < payload_count; ++index) {
330 PetscCall(VecDuplicate(payload.
vec, &reference[index]));
331 PetscCall(VecCopy(payload.
vec, reference[index]));
332 PetscCall(VecZeroEntries(payload.
vec));
343 "the represented time is restored"));
345 "the quadrature origin is restored"));
348 "the duplicate-event guard survives the restart"));
351 "an open window resumes active"));
356 for (PetscInt index = 0; index < payload_count; ++index) {
358 PetscReal difference = 0.0;
362 PetscCall(VecAXPY(reference[index], -1.0, payload.
vec));
363 PetscCall(VecNorm(reference[index], NORM_INFINITY, &difference));
364 PetscCall(PetscSNPrintf(context,
sizeof(context),
365 "payload '%s' is restored bit for bit", payload.
name));
367 PetscCall(VecDestroy(&reference[index]));
369 PetscCall(PetscFree(reference));
374 PetscReal ***mean = NULL;
376 PetscCall(DMDAVecGetArrayRead(user->
da, storage.
mean[1], &mean));
377 if (user->
info.xs <= 2 && 2 < user->
info.xs + user->
info.xm &&
378 user->
info.ys <= 2 && 2 < user->
info.ys + user->
info.ym &&
379 user->
info.zs <= 2 && 2 < user->
info.zs + user->
info.zm) {
381 "the restored scalar mean holds the accumulated value"));
383 PetscCall(DMDAVecRestoreArrayRead(user->
da, storage.
mean[1], &mean));
386 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
388 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
391 PetscFunctionReturn(0);
409 char tmpdir[PETSC_MAX_PATH_LEN];
410 PetscErrorCode bad = 0;
412 PetscFunctionBeginUser;
416 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
420 PetscCall(VecSet(user->
Nvert, 0.0));
423 PetscBool accepted = PETSC_FALSE;
424 PetscReal weight = 0.0;
433 changed = definition;
437 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
439 PetscCall(PetscPopErrorHandler());
441 "a changed definition is refused rather than merged"));
444 changed = definition;
447 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
449 PetscCall(PetscPopErrorHandler());
453 changed = definition;
457 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
459 PetscCall(PetscPopErrorHandler());
465 changed = definition;
472 "an extended window resumes active"));
478 changed = definition;
482 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
484 PetscCall(PetscPopErrorHandler());
486 "reopening a closed window across an unsampled gap is refused"));
493 "statistics start fresh when continuation is not requested"));
495 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
497 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
500 PetscFunctionReturn(0);
517 char tmpdir[PETSC_MAX_PATH_LEN];
518 char payload_path[PETSC_MAX_PATH_LEN];
519 PetscErrorCode bad = 0;
521 PetscFunctionBeginUser;
525 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
529 PetscCall(VecSet(user->
Nvert, 0.0));
532 PetscBool accepted = PETSC_FALSE;
533 PetscReal weight = 0.0;
543 PetscCall(PetscSNPrintf(payload_path,
sizeof(payload_path),
544 "%s/checkpoints/step_000000000001/statistics/window_0000/block_0000/P_mean.dat",
546 if (simCtx->
rank == 0) {
547 FILE *damaged = fopen(payload_path,
"w");
549 PetscCheck(damaged != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
550 "Unable to truncate '%s'.", payload_path);
551 PetscCheck(fclose(damaged) == 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE,
552 "Unable to close '%s'.", payload_path);
554 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
557 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
559 PetscCall(PetscPopErrorHandler());
561 "a truncated statistics payload fails bundle validation"));
563 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
565 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
568 PetscFunctionReturn(0);
579 char tmpdir[PETSC_MAX_PATH_LEN];
580 char path[PETSC_MAX_PATH_LEN];
581 PetscBool exists = PETSC_TRUE;
582 PetscErrorCode bad = 0;
584 PetscFunctionBeginUser;
588 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
594 PetscCall(PetscSNPrintf(path,
sizeof(path),
"%s/checkpoints/step_000000000001/statistics", tmpdir));
595 PetscCall(PetscTestDirectory(path,
'r', &exists));
597 "a run without statistics writes no statistics subtree"));
602 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
604 PetscCall(PetscPopErrorHandler());
606 "missing statistics state is fatal, never silently zeroed"));
608 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
610 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
613 PetscFunctionReturn(0);
629 char tmpdir[PETSC_MAX_PATH_LEN];
630 char payload_path[PETSC_MAX_PATH_LEN];
631 struct stat first_stat;
632 struct stat second_stat;
633 PetscErrorCode mismatch_ierr = 0;
635 PetscFunctionBeginUser;
639 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
643 PetscCall(VecSet(user->
P, 4.5));
644 PetscCall(VecSet(user->
Nvert, 0.0));
645 PetscCall(VecSet(user->
Ucat, 2.0));
646 PetscCall(VecSet(user->
Ucont, 3.0));
647 PetscCall(VecSet(user->
Ucont_rm1, 1.25));
652 PetscCall(PetscSNPrintf(payload_path,
sizeof(payload_path),
653 "%s/checkpoints/step_000000000001/eulerian/block_0000/Ucat.dat", tmpdir));
654 PetscCall(
PicurvAssertBool((PetscBool)(stat(payload_path, &first_stat) == 0),
655 "first checkpoint write should produce a Ucat payload"));
658 PetscCall(VecSet(user->
Ucat, 99.0));
661 PetscCall(
PicurvAssertBool((PetscBool)(stat(payload_path, &second_stat) == 0),
662 "repeated checkpoint write should leave the Ucat payload in place"));
664 PetscCall(
PicurvAssertBool((PetscBool)(first_stat.st_mtim.tv_sec == second_stat.st_mtim.tv_sec &&
665 first_stat.st_mtim.tv_nsec == second_stat.st_mtim.tv_nsec),
666 "repeated checkpoint write at a committed step should not touch payload mtime"));
667 PetscCall(
PicurvAssertBool((PetscBool)(first_stat.st_size == second_stat.st_size),
668 "repeated checkpoint write at a committed step should not resize payloads"));
670 PetscCall(VecZeroEntries(user->
Ucat));
673 "repeated checkpoint write must not overwrite committed payload contents"));
677 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
679 PetscCall(PetscPopErrorHandler());
681 "same-step checkpoint write with a different physical time should fail"));
683 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
685 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
687 PetscFunctionReturn(0);
696 PetscFunctionBeginUser;
701 (PetscBool)!strcmp(digest,
"ba7816bf8f01cfea414140de5dae2223"
702 "b00361a396177a9cb410ff61f20015ad"),
703 "SHA-256 implementation should match the standard abc test vector"));
704 PetscFunctionReturn(0);
714 char tmpdir[PETSC_MAX_PATH_LEN];
715 char cfg_path[PETSC_MAX_PATH_LEN];
718 PetscFunctionBeginUser;
720 PetscCall(PetscCalloc1(1, &simCtx->
pps));
722 PetscCall(PetscSNPrintf(cfg_path,
sizeof(cfg_path),
"%s/post.run", tmpdir));
725 file = fopen(cfg_path,
"w");
726 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to create temp config file '%s'.", cfg_path);
727 fputs(
"startTime = 2\n", file);
728 fputs(
"endTime = 6\n", file);
729 fputs(
"timeStep = 2\n", file);
730 fputs(
"output_particles = true\n", file);
731 fputs(
"output_prefix = SmokeField\n", file);
740 "ParsePostProcessingSettings should parse output_prefix"));
743 const PetscInt intervals[] = {1, 0, -1, 1, 1, 0};
744 const char *overrides[] = {NULL, NULL, NULL,
"0",
"-1",
"1"};
745 for (
size_t n = 0; n <
sizeof(intervals) /
sizeof(intervals[0]); ++n) {
746 PetscErrorCode parse_ierr;
747 file = fopen(cfg_path,
"w");
748 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to reopen post config.");
749 fprintf(file,
"startTime = 100\nendTime = 100\ntimeStep = %d\n", (
int)intervals[n]);
751 if (overrides[n]) PetscCall(PetscOptionsSetValue(NULL,
"-timeStep", overrides[n]));
752 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
754 PetscCall(PetscPopErrorHandler());
755 PetscCall(PetscOptionsClearValue(NULL,
"-timeStep"));
757 parse_ierr,
"post interval must be positive after command-line overrides"));
762 PetscFunctionReturn(0);
771 char value_a[] =
" inlet_value ";
772 char value_b[] =
" ";
774 PetscFunctionBeginUser;
776 PetscCall(
PicurvAssertBool((PetscBool)(strcmp(value_a,
"inlet_value") == 0),
777 "TrimWhitespace should remove leading and trailing whitespace"));
781 "TrimWhitespace should reduce all-whitespace strings to empty"));
782 PetscFunctionReturn(0);
794 PetscFunctionBeginUser;
803 "StringToBCHandlerType should parse constant_flux"));
806 "StringToBCHandlerType should parse prescribed_flow"));
807 PetscFunctionReturn(0);
815 PetscFunctionBeginUser;
817 "WALL + noslip should be a valid combination"));
819 "PERIODIC + geometric should be a valid combination"));
821 "INLET + prescribed_flow should be a valid combination"));
823 "INLET + noslip should be rejected"));
824 PetscFunctionReturn(0);
834 PetscFunctionBeginUser;
835 PetscCall(PetscMemzero(&simCtx,
sizeof(simCtx)));
837 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_L_ref"));
838 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_U_ref"));
839 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_rho_ref"));
847 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_L_ref",
"2.5"));
848 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_U_ref",
"4.0"));
849 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_rho_ref",
"1.2"));
857 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_L_ref"));
858 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_U_ref"));
859 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_rho_ref"));
860 PetscFunctionReturn(0);
867 char tmpdir[PETSC_MAX_PATH_LEN];
868 char capture_path[PETSC_MAX_PATH_LEN];
869 FILE *capture_file = NULL;
870 int saved_stdout = -1;
872 size_t bytes_read = 0;
875 PetscFunctionBeginUser;
876 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx cannot be NULL.");
877 PetscCheck(captured != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Capture buffer cannot be NULL.");
878 PetscCheck(captured_len > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
"Capture buffer must be non-empty.");
881 PetscCall(PetscSNPrintf(capture_path,
sizeof(capture_path),
"%s/banner.log", tmpdir));
884 saved_stdout = dup(STDOUT_FILENO);
885 PetscCheck(saved_stdout >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup(STDOUT_FILENO) failed.");
886 capture_fd = open(capture_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
887 PetscCheck(capture_fd >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to open capture file '%s'.", capture_path);
888 PetscCheck(dup2(capture_fd, STDOUT_FILENO) >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup2() failed while redirecting stdout.");
894 PetscCheck(dup2(saved_stdout, STDOUT_FILENO) >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup2() failed while restoring stdout.");
899 capture_file = fopen(capture_path,
"r");
900 PetscCheck(capture_file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to read capture file '%s'.", capture_path);
901 bytes_read = fread(captured, 1, captured_len - 1, capture_file);
902 captured[bytes_read] =
'\0';
903 fclose(capture_file);
905 PetscCallMPI(MPI_Bcast(captured, (PetscMPIInt)captured_len, MPI_CHAR, 0, PETSC_COMM_WORLD));
906 PetscFunctionReturn(0);
913 PetscFunctionBeginUser;
914 PetscCall(
PicurvAssertBool((PetscBool)(strstr(captured, needle) != NULL), message));
915 PetscFunctionReturn(0);
922 PetscFunctionBeginUser;
923 PetscCall(
PicurvAssertBool((PetscBool)(strstr(captured, needle) == NULL), message));
924 PetscFunctionReturn(0);
942 char captured[16384];
944 PetscFunctionBeginUser;
958 "DisplayBanner should report the live statistics console cadence"));
963 PetscCall(
AssertCapturedContains(captured,
"Statistics Console Cadence : DISABLED (1 window(s) accumulating)",
964 "DisplayBanner should distinguish a silenced console from an inactive subsystem"));
971 PetscCall(
AssertCapturedContains(captured,
"Statistics Console Cadence : DISABLED (no window configured)",
972 "DisplayBanner should record that no statistics window was configured"));
975 PetscFunctionReturn(0);
985 char captured[16384];
987 PetscFunctionBeginUser;
1000 "DisplayBanner should include the run mode"));
1002 "DisplayBanner should include field/restart cadence"));
1004 "DisplayBanner should include immersed-boundary state"));
1006 "DisplayBanner should include BC-derived periodic axes"));
1008 "DisplayBanner should include the total particle count"));
1010 "DisplayBanner should identify a fresh solve IC as the Eulerian source"));
1012 "DisplayBanner should omit particle console cadence when no particles are configured"));
1014 "DisplayBanner should omit particle row sampling when no particles are configured"));
1016 "DisplayBanner should omit particle restart mode when no particles are configured"));
1018 "DisplayBanner should omit particle initialization mode when no particles are configured"));
1020 "DisplayBanner should omit interpolation method when no particles are configured"));
1022 "DisplayBanner should report pseudo-CFL for the dual-time momentum solver"));
1024 "DisplayBanner should report the active dual-time controller"));
1026 "DisplayBanner should report the effective console log level"));
1028 "DisplayBanner should report profiling mode"));
1030 "DisplayBanner should report runtime-memory logging state"));
1035 "DisplayBanner should identify the selected Newton-Krylov solver"));
1037 "DisplayBanner must not report pseudo-CFL for Newton-Krylov"));
1039 "DisplayBanner should report the active Newton-Krylov control family"));
1046 "DisplayBanner should identify the active periodic convergence mode"));
1048 "DisplayBanner should report the active periodic convergence period"));
1052 "DisplayBanner should omit periodic-only convergence fields when inactive"));
1064 "DisplayBanner should identify restart authority"));
1066 "DisplayBanner should not present an IC as active during restart"));
1068 "DisplayBanner should include the active particle count"));
1070 "DisplayBanner should include validated periodic translation"));
1072 "DisplayBanner should distinguish Eulerian periodicity from particle wrapping"));
1074 "DisplayBanner should show disabled particle console cadence when particles are configured"));
1076 "DisplayBanner should include particle row sampling when particles are configured"));
1078 "DisplayBanner should include particle restart mode for restarted particle runs"));
1080 "DisplayBanner should include particle initialization mode when particles are configured"));
1082 "DisplayBanner should include default interpolation method when particles are configured"));
1084 "DisplayBanner should omit inlet-face placement details for point-source particle initialization"));
1090 "DisplayBanner should identify load authority"));
1092 "DisplayBanner should not present an IC as active in load mode"));
1103 "DisplayBanner should include the analytical solution type for analytical runs"));
1105 "DisplayBanner should include active particle console cadence when particles are configured"));
1107 "DisplayBanner should include particle initialization mode for analytical particle runs"));
1109 "DisplayBanner should include inlet-face placement details for surface particle initialization"));
1112 PetscFunctionReturn(0);
1120 PetscErrorCode ierr;
1141 ierr = PetscInitialize(&argc, &argv, NULL,
"PICurv I/O tests");
1146 ierr =
PicurvRunTests(
"unit-io", cases,
sizeof(cases) /
sizeof(cases[0]));
1152 ierr = PetscFinalize();
Small dependency-free SHA-256 utility for persistent metadata identity.
void PicurvSHA256Init(PicurvSHA256Context *context)
Initialize an incremental SHA-256 calculation.
void PicurvSHA256Update(PicurvSHA256Context *context, const void *data, size_t length)
Add bytes to an incremental SHA-256 calculation.
void PicurvSHA256FinalHex(PicurvSHA256Context *context, char digest_hex[65])
Finish a SHA-256 calculation and return a lowercase hexadecimal digest.
Incremental SHA-256 state.
Authoritative identities and storage metadata for persistent Eulerian fields.
Public interface for data input/output routines.
PetscErrorCode ParsePostProcessingSettings(SimCtx *simCtx)
Initializes post-processing settings from a config file and command-line overrides.
PetscErrorCode ParseScalingInformation(SimCtx *simCtx)
Parses physical scaling parameters from command-line options.
PetscErrorCode StringToBCHandlerType(const char *str, BCHandlerType *handler_out)
Converts a BC handler token (implementation strategy) to BCHandlerType.
PetscErrorCode ReadSimulationFields(UserCtx *user, PetscInt ti)
Reads binary field data for velocity, pressure, and other required vectors.
PetscBool ShouldWriteDataOutput(const SimCtx *simCtx, PetscInt completed_step)
Returns whether full field/restart output should be written for the.
PetscErrorCode ValidateBCHandlerForBCType(BCType type, BCHandlerType handler)
Validates that a selected handler is compatible with a mathematical BC type.
void TrimWhitespace(char *str)
Removes leading and trailing ASCII whitespace from a mutable string.
PetscErrorCode RestoreFieldStatisticsState(SimCtx *simCtx, PetscInt ti)
Restores field-statistics window state and accumulators from a checkpoint.
PetscErrorCode StringToBCFace(const char *str, BCFace *face_out)
Converts a face-token string (e.g., "-Xi", "+Eta") to the internal BCFace enum.
PetscErrorCode VerifyPathExistence(const char *path, PetscBool is_dir, PetscBool is_optional, const char *description, PetscBool *exists)
A parallel-safe helper to verify the existence of a generic file or directory path.
PetscErrorCode StringToBCType(const char *str, BCType *type_out)
Converts a mathematical BC type string (e.g., "PERIODIC", "WALL") to BCType.
PetscErrorCode DisplayBanner(SimCtx *simCtx)
Displays a structured banner summarizing the simulation configuration.
PetscErrorCode WriteCheckpointBundle(SimCtx *simCtx, const char *reason)
Write and atomically publish one complete checkpoint bundle.
Per-window PETSc accumulator storage and pointwise application.
Vec * mean
One per field, matching that field's layout.
Vec vec
Borrowed accumulator vector; never owned by the caller.
PetscErrorCode PicurvWindowStorageCreate(UserCtx *user, const PicurvWindowDefinition *definition, PicurvWindowStorage *storage)
Allocates the accumulator state one window owns on one block.
PetscErrorCode PicurvWindowStoragePayload(UserCtx *user, const PicurvWindowDefinition *definition, const PicurvWindowStorage *storage, PetscInt index, PicurvStatisticsPayload *payload)
Resolves one enumerated payload of a window's storage.
char name[96]
File basename, no extension.
PetscErrorCode PicurvWindowAccumulate(UserCtx *user, const PicurvWindowDefinition *definition, PicurvWindowStorage *storage, PetscReal weight)
Applies one accepted completed state to a window's accumulators.
PetscErrorCode PicurvWindowStorageDestroy(PicurvWindowStorage *storage)
Releases accumulator state previously created for one window.
PetscErrorCode PicurvWindowStoragePayloadCount(const PicurvWindowStorage *storage, PetscInt *count)
Reports how many checkpointable vectors one window's storage holds.
One checkpointable accumulator vector, resolved by enumeration index.
Independent accumulator state for one window on one block.
Window lifecycle, scheduling, and weighting for the field-statistics pipeline.
PetscInt last_event_step
Guards against a step being offered twice.
PetscReal last_accepted_time
Right edge of the last represented interval.
PicurvWindowFieldRequest fields[16]
PetscInt restart_count
Restart segments this state descends from.
PetscReal end_time
Requested end; ignored when bounded is false.
PicurvCadenceKind cadence_kind
PetscInt step_cadence
Used when cadence_kind is step; must be positive.
#define PICURV_WINDOW_NAME_LENGTH
Maximum stored length of a window name, including the terminator.
@ PICURV_WINDOW_COMPLETE
Bounded end reached; accepts nothing further.
@ PICURV_WINDOW_ACTIVE
Accepting due states.
PetscErrorCode PicurvWindowInit(PicurvWindow *window, const PicurvWindowDefinition *definition)
Validates a definition and initializes a window to the pending state.
PetscErrorCode PicurvWindowOfferState(PicurvWindow *window, PetscInt step, PetscReal time, PetscBool *accepted, PetscReal *weight)
Offers one completed state to a window and reports the decision.
PetscBool want_second
Also keep the centered second moment.
PetscBool bounded
False for an open-ended window.
PetscInt activation_step
Step at which the window became active.
PetscInt field_id
Catalogued Eulerian field identity.
@ PICURV_WEIGHTING_PHYSICAL_TIME
Weight is the represented interval.
@ PICURV_WEIGHTING_SAMPLE
Equal weight per accepted state.
@ PICURV_CADENCE_STEP
Every n completed steps from activation.
PetscReal represented_time
Physical time the window covers.
PicurvWeighting weighting
Runtime state of one window.
The scientifically immutable definition of one window.
static PetscErrorCode TestCheckpointSameStepRewriteIsRejected(void)
Verifies a committed checkpoint step is rewritten neither silently nor inconsistently.
static PetscErrorCode TestParseScalingInformation(void)
Tests scaling-reference parsing and derived pressure scaling.
static PetscErrorCode DetachStatisticsFixture(SimCtx *simCtx, UserCtx *user, PicurvWindowStorage *storage)
Detaches the statistics fixture without disturbing the shared teardown.
int main(int argc, char **argv)
Runs the unit-io PETSc test binary.
static PetscErrorCode TestValidateBCHandlerForBCType(void)
Tests validation of boundary-type and handler compatibility.
static PetscErrorCode TestCheckpointStatisticsContinuationGuards(void)
Verifies continuation refuses every state that would corrupt an average.
static PetscErrorCode AssertCapturedOmits(const char *captured, const char *needle, const char *message)
Asserts that captured banner output omits one forbidden substring.
static PetscErrorCode TestPostprocessorReadScalesEachLoadOnce(void)
Tests that a dimensionalizing post-processor scales each loaded field once per load.
static PetscErrorCode TestParsePostProcessingSettings(void)
Tests parsing of post-processing control settings from a file.
static PicurvWindowDefinition StatisticsFixtureDefinition(void)
Builds the statistics fixture: one Ucat/P window with a second moment.
static PetscErrorCode TestCheckpointStatisticsPayloadIsValidated(void)
A damaged statistics payload must fail bundle validation, not load silently.
static PetscErrorCode TestCheckpointStatisticsAbsentWhenDisabled(void)
A run without statistics writes no statistics subtree and refuses to fake one.
static PetscErrorCode TestCheckpointSHA256KnownVector(void)
Verifies the dependency-free SHA-256 implementation against a standard vector.
static PetscErrorCode TestDisplayBannerTracksConditionalStartupFields(void)
Tests conditional startup-banner fields across particle and analytical cases.
static PetscErrorCode TestDisplayBannerReportsStatisticsCadence(void)
Tests that the startup banner reports statistics monitoring in every state.
static PetscErrorCode TestVerifyPathExistence(void)
Tests filesystem existence checks for files and directories.
static PetscErrorCode AssertCapturedContains(const char *captured, const char *needle, const char *message)
Asserts that captured banner output contains one expected substring.
static PetscErrorCode TestTrimWhitespace(void)
Tests trimming of leading and trailing whitespace.
static PetscErrorCode TestShouldWriteDataOutput(void)
Tests cadence-based Eulerian output triggering.
static PetscErrorCode WriteCompletedStatisticsWindow(SimCtx *simCtx, UserCtx *user, PicurvWindow *window, PicurvWindowStorage *storage, const PicurvWindowDefinition *definition)
Rewrites the bundle holding a window that closed well before the checkpoint time.
static PetscErrorCode TestCheckpointStatisticsRoundTrip(void)
Verifies accumulated statistics survive a checkpoint round trip unchanged.
static PetscErrorCode TestBoundaryConditionStringParsers(void)
Tests boundary-condition string parsers for face, type, and handler names.
static PetscErrorCode CaptureBannerOutput(SimCtx *simCtx, char *captured, size_t captured_len)
Captures the startup banner into a temporary file-backed buffer.
static PetscErrorCode TestWriteAndReadSimulationFields(void)
Tests writing and reloading core Eulerian field vectors.
static PetscErrorCode AttachStatisticsFixture(SimCtx *simCtx, UserCtx *user, PicurvWindow *window, PicurvWindowStorage *storage, const PicurvWindowDefinition *definition)
Attaches one accumulating window to a fixture context and primes it with samples.
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 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 PicurvPopulateIdentityMetrics(UserCtx *user)
Populates identity metric vectors on the minimal grid fixture.
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.
PetscInt fieldStatisticsWindowCount
BCType
Defines the general mathematical/physical Category of a boundary.
PetscBool inletFaceDefined
PetscInt statisticsConsoleOutputFreq
BCFace identifiedInletBCFace
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
@ PARTICLE_INIT_POINT_SOURCE
All particles at a fixed (psrc_x,psrc_y,psrc_z) — for validation.
PetscBool dimensionalize
Whether derived output leaves non-dimensional form, from global_operations.dimensionalize.
BCHandlerType
Defines the specific computational "strategy" for a boundary handler.
@ BC_HANDLER_PERIODIC_GEOMETRIC
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
@ BC_HANDLER_INLET_PROFILE_FROM_FILE
char output_dir[PETSC_MAX_PATH_LEN]
PetscBool fieldStatisticsEnabled
@ MOMENTUM_SOLVER_DUALTIME_PICARD_JAMESON_RK
@ MOMENTUM_SOLVER_NEWTON_KRYLOV
PetscInt solutionConvergencePeriodSteps
char particleRestartMode[16]
struct PicurvWindow * fieldStatisticsWindows
char source_dir[PETSC_MAX_PATH_LEN]
char eulerianSource[PETSC_MAX_PATH_LEN]
ParticleInitializationType ParticleInitialization
PetscBool outputParticles
struct PicurvWindowStorage * fieldStatisticsStorage
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
PetscInt particleConsoleOutputFreq
@ EXEC_MODE_POSTPROCESSOR
Cmpnts periodic_translation[3]
@ SOLUTION_CONVERGENCE_PERIODIC_DETERMINISTIC
@ SOLUTION_CONVERGENCE_STEADY_DETERMINISTIC
PetscBool periodic_translation_valid[3]
SolutionConvergenceMode solutionConvergenceMode
MomentumSolverType mom_solver_type
char PostprocessingControlFile[PETSC_MAX_PATH_LEN]
char restart_dir[PETSC_MAX_PATH_LEN]
PetscInt LoggingFrequency
PetscBool fieldStatisticsContinue
BCFace
Identifies the six logical faces of a structured computational block.
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.