22 PetscFunctionBeginUser;
23 PetscCall(PetscMemzero(&simCtx,
sizeof(simCtx)));
29 PetscFunctionReturn(0);
37 char tmpdir[PETSC_MAX_PATH_LEN];
38 char filepath[PETSC_MAX_PATH_LEN];
40 PetscBool exists = PETSC_FALSE;
42 PetscFunctionBeginUser;
44 PetscCall(PetscSNPrintf(filepath,
sizeof(filepath),
"%s/sample.txt", tmpdir));
46 file = fopen(filepath,
"w");
47 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to create temp file '%s'.", filepath);
48 fputs(
"picurv\n", file);
52 PetscCall(
PicurvAssertBool(exists,
"VerifyPathExistence should find the temp directory"));
55 PetscCall(
PicurvAssertBool(exists,
"VerifyPathExistence should find the temp file"));
57 PetscFunctionReturn(0);
67 char tmpdir[PETSC_MAX_PATH_LEN];
68 char euler_dir[PETSC_MAX_PATH_LEN];
70 PetscFunctionBeginUser;
73 PetscCall(PetscSNPrintf(euler_dir,
sizeof(euler_dir),
"%s/%s", tmpdir, simCtx->
euler_subdir));
78 PetscCall(VecSet(user->
P, 4.5));
79 PetscCall(VecSet(user->
Nvert, 0.0));
80 PetscCall(VecSet(user->
Ucat, 2.0));
81 PetscCall(VecSet(user->
Ucont, 3.0));
85 PetscCall(VecZeroEntries(user->
P));
86 PetscCall(VecZeroEntries(user->
Ucat));
87 PetscCall(VecZeroEntries(user->
Ucont));
96 PetscFunctionReturn(0);
106 char tmpdir[PETSC_MAX_PATH_LEN];
107 char cfg_path[PETSC_MAX_PATH_LEN];
110 PetscFunctionBeginUser;
112 PetscCall(PetscCalloc1(1, &simCtx->
pps));
114 PetscCall(PetscSNPrintf(cfg_path,
sizeof(cfg_path),
"%s/post.run", tmpdir));
117 file = fopen(cfg_path,
"w");
118 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to create temp config file '%s'.", cfg_path);
119 fputs(
"startTime = 2\n", file);
120 fputs(
"endTime = 6\n", file);
121 fputs(
"timeStep = 2\n", file);
122 fputs(
"output_particles = true\n", file);
123 fputs(
"output_prefix = SmokeField\n", file);
132 "ParsePostProcessingSettings should parse output_prefix"));
136 PetscFunctionReturn(0);
144 char value_a[] =
" inlet_value ";
145 char value_b[] =
" ";
147 PetscFunctionBeginUser;
149 PetscCall(
PicurvAssertBool((PetscBool)(strcmp(value_a,
"inlet_value") == 0),
150 "TrimWhitespace should remove leading and trailing whitespace"));
154 "TrimWhitespace should reduce all-whitespace strings to empty"));
155 PetscFunctionReturn(0);
167 PetscFunctionBeginUser;
176 "StringToBCHandlerType should parse constant_flux"));
177 PetscFunctionReturn(0);
185 PetscFunctionBeginUser;
187 "WALL + noslip should be a valid combination"));
189 "PERIODIC + geometric should be a valid combination"));
191 "INLET + noslip should be rejected"));
192 PetscFunctionReturn(0);
202 PetscFunctionBeginUser;
203 PetscCall(PetscMemzero(&simCtx,
sizeof(simCtx)));
205 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_L_ref"));
206 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_U_ref"));
207 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_rho_ref"));
215 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_L_ref",
"2.5"));
216 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_U_ref",
"4.0"));
217 PetscCall(PetscOptionsSetValue(NULL,
"-scaling_rho_ref",
"1.2"));
225 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_L_ref"));
226 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_U_ref"));
227 PetscCall(PetscOptionsClearValue(NULL,
"-scaling_rho_ref"));
228 PetscFunctionReturn(0);
235 char tmpdir[PETSC_MAX_PATH_LEN];
236 char capture_path[PETSC_MAX_PATH_LEN];
237 FILE *capture_file = NULL;
238 int saved_stdout = -1;
240 size_t bytes_read = 0;
243 PetscFunctionBeginUser;
244 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx cannot be NULL.");
245 PetscCheck(captured != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Capture buffer cannot be NULL.");
246 PetscCheck(captured_len > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
"Capture buffer must be non-empty.");
249 PetscCall(PetscSNPrintf(capture_path,
sizeof(capture_path),
"%s/banner.log", tmpdir));
252 saved_stdout = dup(STDOUT_FILENO);
253 PetscCheck(saved_stdout >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup(STDOUT_FILENO) failed.");
254 capture_fd = open(capture_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
255 PetscCheck(capture_fd >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to open capture file '%s'.", capture_path);
256 PetscCheck(dup2(capture_fd, STDOUT_FILENO) >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup2() failed while redirecting stdout.");
262 PetscCheck(dup2(saved_stdout, STDOUT_FILENO) >= 0, PETSC_COMM_SELF, PETSC_ERR_SYS,
"dup2() failed while restoring stdout.");
267 capture_file = fopen(capture_path,
"r");
268 PetscCheck(capture_file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Failed to read capture file '%s'.", capture_path);
269 bytes_read = fread(captured, 1, captured_len - 1, capture_file);
270 captured[bytes_read] =
'\0';
271 fclose(capture_file);
273 PetscFunctionReturn(0);
280 PetscFunctionBeginUser;
281 PetscCall(
PicurvAssertBool((PetscBool)(strstr(captured, needle) != NULL), message));
282 PetscFunctionReturn(0);
289 PetscFunctionBeginUser;
290 PetscCall(
PicurvAssertBool((PetscBool)(strstr(captured, needle) == NULL), message));
291 PetscFunctionReturn(0);
301 char captured[16384];
303 PetscFunctionBeginUser;
315 "DisplayBanner should include the run mode"));
317 "DisplayBanner should include field/restart cadence"));
319 "DisplayBanner should include immersed-boundary state"));
321 "DisplayBanner should include the total particle count"));
323 "DisplayBanner should omit particle console cadence when no particles are configured"));
325 "DisplayBanner should omit particle row sampling when no particles are configured"));
327 "DisplayBanner should omit particle restart mode when no particles are configured"));
329 "DisplayBanner should omit particle initialization mode when no particles are configured"));
331 "DisplayBanner should omit interpolation method when no particles are configured"));
340 "DisplayBanner should include the active particle count"));
342 "DisplayBanner should show disabled particle console cadence when particles are configured"));
344 "DisplayBanner should include particle row sampling when particles are configured"));
346 "DisplayBanner should include particle restart mode for restarted particle runs"));
348 "DisplayBanner should include particle initialization mode when particles are configured"));
350 "DisplayBanner should include default interpolation method when particles are configured"));
352 "DisplayBanner should omit inlet-face placement details for point-source particle initialization"));
363 "DisplayBanner should include the analytical solution type for analytical runs"));
365 "DisplayBanner should include active particle console cadence when particles are configured"));
367 "DisplayBanner should include particle initialization mode for analytical particle runs"));
369 "DisplayBanner should include inlet-face placement details for surface particle initialization"));
372 PetscFunctionReturn(0);
393 ierr = PetscInitialize(&argc, &argv, NULL,
"PICurv I/O tests");
398 ierr =
PicurvRunTests(
"unit-io", cases,
sizeof(cases) /
sizeof(cases[0]));
404 ierr = PetscFinalize();
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)
Helper function to trim leading/trailing whitespace from a string.
PetscErrorCode WriteSimulationFields(UserCtx *user)
Writes simulation fields to files.
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.
static PetscErrorCode TestParseScalingInformation(void)
Tests scaling-reference parsing and derived pressure scaling.
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 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 PetscErrorCode TestDisplayBannerTracksConditionalStartupFields(void)
Tests conditional startup-banner fields across particle and analytical cases.
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 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.
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.
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.
BCType
Defines the general mathematical/physical Category of a boundary.
PetscBool inletFaceDefined
BCFace identifiedInletBCFace
char euler_subdir[PETSC_MAX_PATH_LEN]
@ 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
char output_dir[PETSC_MAX_PATH_LEN]
char particleRestartMode[16]
char eulerianSource[PETSC_MAX_PATH_LEN]
ParticleInitializationType ParticleInitialization
PetscBool outputParticles
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
PetscInt particleConsoleOutputFreq
char PostprocessingControlFile[PETSC_MAX_PATH_LEN]
char restart_dir[PETSC_MAX_PATH_LEN]
PetscInt LoggingFrequency
BCFace
Identifies the six logical faces of a structured computational block.
The master context for the entire simulation.
User-defined context containing data specific to a single computational grid level.