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);
132 memset(&d, 0,
sizeof(d));
148 PetscFunctionBeginUser;
155 PetscFunctionReturn(0);
162 PetscFunctionBeginUser;
168 PetscFunctionReturn(0);
184 PetscBool accepted = PETSC_FALSE;
185 PetscReal weight = 0.0;
186 char step_directory[PETSC_MAX_PATH_LEN];
188 PetscFunctionBeginUser;
196 "the fixture window reaches its bounded end"));
200 PetscCall(PetscSNPrintf(step_directory,
sizeof(step_directory),
201 "%s/checkpoints/step_000000000001", simCtx->
output_dir));
202 if (simCtx->
rank == 0) PetscCall(PetscRMTree(step_directory));
203 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
205 PetscFunctionReturn(0);
223 char tmpdir[PETSC_MAX_PATH_LEN];
224 char path[PETSC_MAX_PATH_LEN];
225 PetscBool exists = PETSC_FALSE;
226 PetscInt payload_count = 0;
227 Vec *reference = NULL;
229 PetscFunctionBeginUser;
233 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
237 PetscCall(VecSet(user->
Nvert, 0.0));
243 const PetscReal scalars[3] = {1.0, 2.0, 6.0};
245 for (PetscInt s = 0; s < 3; ++s) {
246 PetscBool accepted = PETSC_FALSE;
247 PetscReal weight = 0.0;
249 PetscCall(VecSet(user->
P, scalars[s]));
250 PetscCall(VecSet(user->
Ucat, scalars[s]));
258 PetscCall(PetscSNPrintf(path,
sizeof(path),
259 "%s/checkpoints/step_000000000001/statistics/window_0000/block_0000/P_mean.dat",
261 PetscCall(PetscTestFile(path,
'r', &exists));
262 PetscCall(
PicurvAssertBool(exists,
"statistics payloads use their enumerated names"));
263 PetscCall(PetscSNPrintf(path,
sizeof(path),
264 "%s/checkpoints/step_000000000001/statistics/window_0000/block_0000/Ucat_m2.dat",
266 PetscCall(PetscTestFile(path,
'r', &exists));
267 PetscCall(
PicurvAssertBool(exists,
"the symmetric product is one payload, not six"));
272 PetscCall(PetscCalloc1((
size_t)payload_count, &reference));
273 for (PetscInt index = 0; index < payload_count; ++index) {
277 PetscCall(VecDuplicate(payload.
vec, &reference[index]));
278 PetscCall(VecCopy(payload.
vec, reference[index]));
279 PetscCall(VecZeroEntries(payload.
vec));
290 "the represented time is restored"));
292 "the quadrature origin is restored"));
295 "the duplicate-event guard survives the restart"));
298 "an open window resumes active"));
303 for (PetscInt index = 0; index < payload_count; ++index) {
305 PetscReal difference = 0.0;
309 PetscCall(VecAXPY(reference[index], -1.0, payload.
vec));
310 PetscCall(VecNorm(reference[index], NORM_INFINITY, &difference));
311 PetscCall(PetscSNPrintf(context,
sizeof(context),
312 "payload '%s' is restored bit for bit", payload.
name));
314 PetscCall(VecDestroy(&reference[index]));
316 PetscCall(PetscFree(reference));
321 PetscReal ***mean = NULL;
323 PetscCall(DMDAVecGetArrayRead(user->
da, storage.
mean[1], &mean));
324 if (user->
info.xs <= 2 && 2 < user->
info.xs + user->
info.xm &&
325 user->
info.ys <= 2 && 2 < user->
info.ys + user->
info.ym &&
326 user->
info.zs <= 2 && 2 < user->
info.zs + user->
info.zm) {
328 "the restored scalar mean holds the accumulated value"));
330 PetscCall(DMDAVecRestoreArrayRead(user->
da, storage.
mean[1], &mean));
333 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
335 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
338 PetscFunctionReturn(0);
356 char tmpdir[PETSC_MAX_PATH_LEN];
357 PetscErrorCode bad = 0;
359 PetscFunctionBeginUser;
363 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
367 PetscCall(VecSet(user->
Nvert, 0.0));
370 PetscBool accepted = PETSC_FALSE;
371 PetscReal weight = 0.0;
380 changed = definition;
384 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
386 PetscCall(PetscPopErrorHandler());
388 "a changed definition is refused rather than merged"));
391 changed = definition;
394 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
396 PetscCall(PetscPopErrorHandler());
400 changed = definition;
404 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
406 PetscCall(PetscPopErrorHandler());
412 changed = definition;
419 "an extended window resumes active"));
425 changed = definition;
429 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
431 PetscCall(PetscPopErrorHandler());
433 "reopening a closed window across an unsampled gap is refused"));
440 "statistics start fresh when continuation is not requested"));
442 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
444 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
447 PetscFunctionReturn(0);
464 char tmpdir[PETSC_MAX_PATH_LEN];
465 char payload_path[PETSC_MAX_PATH_LEN];
466 PetscErrorCode bad = 0;
468 PetscFunctionBeginUser;
472 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
476 PetscCall(VecSet(user->
Nvert, 0.0));
479 PetscBool accepted = PETSC_FALSE;
480 PetscReal weight = 0.0;
490 PetscCall(PetscSNPrintf(payload_path,
sizeof(payload_path),
491 "%s/checkpoints/step_000000000001/statistics/window_0000/block_0000/P_mean.dat",
493 if (simCtx->
rank == 0) {
494 FILE *damaged = fopen(payload_path,
"w");
496 PetscCheck(damaged != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
497 "Unable to truncate '%s'.", payload_path);
498 PetscCheck(fclose(damaged) == 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE,
499 "Unable to close '%s'.", payload_path);
501 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
504 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
506 PetscCall(PetscPopErrorHandler());
508 "a truncated statistics payload fails bundle validation"));
510 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
512 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
515 PetscFunctionReturn(0);
526 char tmpdir[PETSC_MAX_PATH_LEN];
527 char path[PETSC_MAX_PATH_LEN];
528 PetscBool exists = PETSC_TRUE;
529 PetscErrorCode bad = 0;
531 PetscFunctionBeginUser;
535 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
541 PetscCall(PetscSNPrintf(path,
sizeof(path),
"%s/checkpoints/step_000000000001/statistics", tmpdir));
542 PetscCall(PetscTestDirectory(path,
'r', &exists));
544 "a run without statistics writes no statistics subtree"));
549 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
551 PetscCall(PetscPopErrorHandler());
553 "missing statistics state is fatal, never silently zeroed"));
555 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
557 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
560 PetscFunctionReturn(0);
576 char tmpdir[PETSC_MAX_PATH_LEN];
577 char payload_path[PETSC_MAX_PATH_LEN];
578 struct stat first_stat;
579 struct stat second_stat;
580 PetscErrorCode mismatch_ierr = 0;
582 PetscFunctionBeginUser;
586 PetscCallMPI(MPI_Bcast(tmpdir,
sizeof(tmpdir), MPI_CHAR, 0, PETSC_COMM_WORLD));
590 PetscCall(VecSet(user->
P, 4.5));
591 PetscCall(VecSet(user->
Nvert, 0.0));
592 PetscCall(VecSet(user->
Ucat, 2.0));
593 PetscCall(VecSet(user->
Ucont, 3.0));
594 PetscCall(VecSet(user->
Ucont_rm1, 1.25));
599 PetscCall(PetscSNPrintf(payload_path,
sizeof(payload_path),
600 "%s/checkpoints/step_000000000001/eulerian/block_0000/Ucat.dat", tmpdir));
601 PetscCall(
PicurvAssertBool((PetscBool)(stat(payload_path, &first_stat) == 0),
602 "first checkpoint write should produce a Ucat payload"));
605 PetscCall(VecSet(user->
Ucat, 99.0));
608 PetscCall(
PicurvAssertBool((PetscBool)(stat(payload_path, &second_stat) == 0),
609 "repeated checkpoint write should leave the Ucat payload in place"));
611 PetscCall(
PicurvAssertBool((PetscBool)(first_stat.st_mtim.tv_sec == second_stat.st_mtim.tv_sec &&
612 first_stat.st_mtim.tv_nsec == second_stat.st_mtim.tv_nsec),
613 "repeated checkpoint write at a committed step should not touch payload mtime"));
614 PetscCall(
PicurvAssertBool((PetscBool)(first_stat.st_size == second_stat.st_size),
615 "repeated checkpoint write at a committed step should not resize payloads"));
617 PetscCall(VecZeroEntries(user->
Ucat));
620 "repeated checkpoint write must not overwrite committed payload contents"));
624 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
626 PetscCall(PetscPopErrorHandler());
628 "same-step checkpoint write with a different physical time should fail"));
630 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
632 PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
634 PetscFunctionReturn(0);
643 PetscFunctionBeginUser;
648 (PetscBool)!strcmp(digest,
"ba7816bf8f01cfea414140de5dae2223"
649 "b00361a396177a9cb410ff61f20015ad"),
650 "SHA-256 implementation should match the standard abc test vector"));
651 PetscFunctionReturn(0);
661 char tmpdir[PETSC_MAX_PATH_LEN];
662 char cfg_path[PETSC_MAX_PATH_LEN];
665 PetscFunctionBeginUser;
667 PetscCall(PetscCalloc1(1, &simCtx->
pps));
669 PetscCall(PetscSNPrintf(cfg_path,
sizeof(cfg_path),
"%s/post.run", tmpdir));
672 file = fopen(cfg_path,
"w");
673 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to create temp config file '%s'.", cfg_path);
674 fputs(
"startTime = 2\n", file);
675 fputs(
"endTime = 6\n", file);
676 fputs(
"timeStep = 2\n", file);
677 fputs(
"output_particles = true\n", file);
678 fputs(
"output_prefix = SmokeField\n", file);
687 "ParsePostProcessingSettings should parse output_prefix"));
691 PetscFunctionReturn(0);
700 char value_a[] =
" inlet_value ";
701 char value_b[] =
" ";
703 PetscFunctionBeginUser;
705 PetscCall(
PicurvAssertBool((PetscBool)(strcmp(value_a,
"inlet_value") == 0),
706 "TrimWhitespace should remove leading and trailing whitespace"));
710 "TrimWhitespace should reduce all-whitespace strings to empty"));
711 PetscFunctionReturn(0);
723 PetscFunctionBeginUser;
732 "StringToBCHandlerType should parse constant_flux"));
735 "StringToBCHandlerType should parse prescribed_flow"));
736 PetscFunctionReturn(0);
744 PetscFunctionBeginUser;
746 "WALL + noslip should be a valid combination"));
748 "PERIODIC + geometric should be a valid combination"));
750 "INLET + prescribed_flow should be a valid combination"));
752 "INLET + noslip should be rejected"));
753 PetscFunctionReturn(0);
763 PetscFunctionBeginUser;
764 PetscCall(PetscMemzero(&simCtx,
sizeof(simCtx)));
766 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_L_ref"));
767 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_U_ref"));
768 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_rho_ref"));
776 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_L_ref",
"2.5"));
777 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_U_ref",
"4.0"));
778 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_rho_ref",
"1.2"));
786 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_L_ref"));
787 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_U_ref"));
788 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_rho_ref"));
789 PetscFunctionReturn(0);
796 char tmpdir[PETSC_MAX_PATH_LEN];
797 char capture_path[PETSC_MAX_PATH_LEN];
798 FILE *capture_file = NULL;
799 int saved_stdout = -1;
801 size_t bytes_read = 0;
804 PetscFunctionBeginUser;
805 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx cannot be NULL.");
806 PetscCheck(captured != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Capture buffer cannot be NULL.");
807 PetscCheck(captured_len > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
"Capture buffer must be non-empty.");
810 PetscCall(PetscSNPrintf(capture_path,
sizeof(capture_path),
"%s/banner.log", tmpdir));
813 saved_stdout = dup(STDOUT_FILENO);
814 PetscCheck(saved_stdout >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup(STDOUT_FILENO) failed.");
815 capture_fd = open(capture_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
816 PetscCheck(capture_fd >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to open capture file '%s'.", capture_path);
817 PetscCheck(dup2(capture_fd, STDOUT_FILENO) >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup2() failed while redirecting stdout.");
823 PetscCheck(dup2(saved_stdout, STDOUT_FILENO) >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup2() failed while restoring stdout.");
828 capture_file = fopen(capture_path,
"r");
829 PetscCheck(capture_file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to read capture file '%s'.", capture_path);
830 bytes_read = fread(captured, 1, captured_len - 1, capture_file);
831 captured[bytes_read] =
'\0';
832 fclose(capture_file);
834 PetscCallMPI(MPI_Bcast(captured, (PetscMPIInt)captured_len, MPI_CHAR, 0, PETSC_COMM_WORLD));
835 PetscFunctionReturn(0);
842 PetscFunctionBeginUser;
843 PetscCall(
PicurvAssertBool((PetscBool)(strstr(captured, needle) != NULL), message));
844 PetscFunctionReturn(0);
851 PetscFunctionBeginUser;
852 PetscCall(
PicurvAssertBool((PetscBool)(strstr(captured, needle) == NULL), message));
853 PetscFunctionReturn(0);
871 char captured[16384];
873 PetscFunctionBeginUser;
887 "DisplayBanner should report the live statistics console cadence"));
892 PetscCall(
AssertCapturedContains(captured,
"Statistics Console Cadence : DISABLED (1 window(s) accumulating)",
893 "DisplayBanner should distinguish a silenced console from an inactive subsystem"));
900 PetscCall(
AssertCapturedContains(captured,
"Statistics Console Cadence : DISABLED (no window configured)",
901 "DisplayBanner should record that no statistics window was configured"));
904 PetscFunctionReturn(0);
914 char captured[16384];
916 PetscFunctionBeginUser;
929 "DisplayBanner should include the run mode"));
931 "DisplayBanner should include field/restart cadence"));
933 "DisplayBanner should include immersed-boundary state"));
935 "DisplayBanner should include BC-derived periodic axes"));
937 "DisplayBanner should include the total particle count"));
939 "DisplayBanner should identify a fresh solve IC as the Eulerian source"));
941 "DisplayBanner should omit particle console cadence when no particles are configured"));
943 "DisplayBanner should omit particle row sampling when no particles are configured"));
945 "DisplayBanner should omit particle restart mode when no particles are configured"));
947 "DisplayBanner should omit particle initialization mode when no particles are configured"));
949 "DisplayBanner should omit interpolation method when no particles are configured"));
951 "DisplayBanner should report pseudo-CFL for the dual-time momentum solver"));
953 "DisplayBanner should report the active dual-time controller"));
955 "DisplayBanner should report the effective console log level"));
957 "DisplayBanner should report profiling mode"));
959 "DisplayBanner should report runtime-memory logging state"));
964 "DisplayBanner should identify the selected Newton-Krylov solver"));
966 "DisplayBanner must not report pseudo-CFL for Newton-Krylov"));
968 "DisplayBanner should report the active Newton-Krylov control family"));
975 "DisplayBanner should identify the active periodic convergence mode"));
977 "DisplayBanner should report the active periodic convergence period"));
981 "DisplayBanner should omit periodic-only convergence fields when inactive"));
993 "DisplayBanner should identify restart authority"));
995 "DisplayBanner should not present an IC as active during restart"));
997 "DisplayBanner should include the active particle count"));
999 "DisplayBanner should include validated periodic translation"));
1001 "DisplayBanner should distinguish Eulerian periodicity from particle wrapping"));
1003 "DisplayBanner should show disabled particle console cadence when particles are configured"));
1005 "DisplayBanner should include particle row sampling when particles are configured"));
1007 "DisplayBanner should include particle restart mode for restarted particle runs"));
1009 "DisplayBanner should include particle initialization mode when particles are configured"));
1011 "DisplayBanner should include default interpolation method when particles are configured"));
1013 "DisplayBanner should omit inlet-face placement details for point-source particle initialization"));
1019 "DisplayBanner should identify load authority"));
1021 "DisplayBanner should not present an IC as active in load mode"));
1032 "DisplayBanner should include the analytical solution type for analytical runs"));
1034 "DisplayBanner should include active particle console cadence when particles are configured"));
1036 "DisplayBanner should include particle initialization mode for analytical particle runs"));
1038 "DisplayBanner should include inlet-face placement details for surface particle initialization"));
1041 PetscFunctionReturn(0);
1049 PetscErrorCode ierr;
1069 ierr = PetscInitialize(&argc, &argv, NULL,
"PICurv I/O tests");
1074 ierr =
PicurvRunTests(
"unit-io", cases,
sizeof(cases) /
sizeof(cases[0]));
1080 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 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.
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 eulerianSource[PETSC_MAX_PATH_LEN]
ParticleInitializationType ParticleInitialization
PetscBool outputParticles
struct PicurvWindowStorage * fieldStatisticsStorage
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
PetscInt particleConsoleOutputFreq
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.