|
PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
|
This page documents PICurv's local testing model. The suite is intentionally split by intent so users can choose the smallest command that answers the question they actually have.
PICurv exposes four validation layers plus aggregate gates:
Canonical commands:
make test-pythonmake coverage-pythonmake coverage-cmake coveragemake audit-buildmake doctormake unitmake unit-geometrymake unit-setupmake unit-solvermake unit-particlesmake unit-iomake unit-loggingmake unit-postmake unit-gridmake unit-metricmake unit-boundariesmake unit-poisson-rhsmake unit-runtimemake unit-simulationmake unit-mpimake unit-periodic-devmake smokemake smoke-mpimake smoke-mpi-matrixmake smoke-stressmake smoke-periodic-devmake checkmake check-mpimake check-mpi-matrixmake check-fullmake check-stressCompatibility aliases remain available:
make test -> make test-pythonmake install-check -> make doctormake ctest* -> make unit*Fast local checks:
Guidance:
python3 scripts/audit_function_docs.py when changing C/Python function signatures, docstrings, or test helpers.make test when working on scripts/picurv, schemas, or repository metadata.python3 scripts/check_markdown_links.py when changing docs/examples.make audit-build when you want a clean compilation audit with logs/build.log and logs/build.warnings.log captured under the repo logs/ directory.make doctor after provisioning PETSc on a new machine.make unit-setup when changing setup, teardown, initialization, or rank-info lifecycle code.make unit-simulation for the normal simulation-core debugging loop (unit-boundaries + unit-solver + unit-poisson-rhs + unit-runtime + unit-particles).make unit-<area> while changing a subsystem in isolation.make smoke after building binaries to execute tiny real solve/post/restart workflows.make smoke-mpi-matrix when you need a rank-sweep MPI runtime sanity check.make smoke-stress when you want the opt-in medium-budget runtime extension tier.make unit-periodic-dev and make smoke-periodic-dev only while working on the in-development periodic BC path; they are intentionally non-gating.make coverage to enforce line-coverage floors for core Python scripts and C sources.make check as the pre-merge gate at the end of a development cycle.make check-mpi when multi-rank MPI behavior is in scope.make check-full for comprehensive branch/CI/release validation that must cover all MPI layers.make check-stress when you want the full default gate plus the stress tier in one pass.Purpose:
scripts/picurvThis suite is implemented with pytest and does not require PETSc.
Current coverage includes:
For newly added or modified C test helpers, keep Doxygen blocks concise but descriptive: the @brief should state what the test or helper verifies rather than using a placeholder label.
Run locally:
CI note:
.github/workflows/quality.yml runs python scripts/audit_function_docs.py explicitly before pytest -q, then runs markdown link checks on pull requests and pushes to main.Current Python files and primary responsibilities:
tests/test_cli_smoke.pysubmit, cancel, and sweepsummarize JSON/text output and failure-path checkstests/test_case_maintenance.pybuild, sync-binaries, sync-config, status-source, and pull-sourceoverwrite, prune)tests/test_config_regressions.pytests/test_repo_consistency.pypicurv validatescripts/audit_function_docs.py)These files are intentionally role-specific to keep failures actionable.
Purpose:
PETSC_DIR is present and usableThe doctor target builds and runs a small C smoke binary under tests/c/test_install_check.c.
It validates:
environment-visible for PETSC_DIR visibilitybasic-petsc-objects for PetscInitialize, DMDA, Vec, DMSwarm, and PetscFinalizeThis target answers: "Is this machine set up correctly for PICurv development?"
Run locally:
Purpose:
Current suites:
make unit-geometrymake unit-setupmake unit-solvermake unit-particlesmake unit-iomake unit-postmake unit-gridmake unit-metricmake unit-boundariesmake unit-poisson-rhsmake unit-runtimemake unit-mpimake unit (all of the above)Suite focus areas:
These tests use real PETSc objects and run single-rank by default. unit-mpi is the dedicated multi-rank suite (default TEST_MPI_NPROCS=2).
Current C test files and their main purpose:
tests/c/test_install_check.c: PETSc installation viability (doctor: environment-visible, basic-petsc-objects)tests/c/test_geometry.c: interpolation/signed-distance helperstests/c/test_setup_lifecycle.c: setup/cleanup lifecycle, RNG, and initialized particle-settlement checkstests/c/test_solver_kernels.c: analytical geometry/particle dispatch, LES filter/eddy-viscosity, and FlowSolver guardrailstests/c/test_particle_kernels.c: walking-search helper kernelstests/c/test_io.c: I/O path, parser, scaling-ingestion, and startup-banner checkstests/c/test_logging.c: logging-contract checks (log level, allow-list, continuity/min-max/interpolation diagnostics, string conversion, profiling, snapshot cadence)tests/c/test_postprocessing.c: post kernel checks (specific KE, displacement, nodal averaging, normalization, dimensionalization, Q-criterion)tests/c/test_vtk_io.c: VTK prep/writer checks (Eulerian + particle data shaping)tests/c/test_postprocessor.c: postprocessor pipeline/orchestration checkstests/c/test_statistics.c: statistics-kernel checks (MSD CSV behavior)search_metrics.csv instrumentation complements Particle_Metrics.log for particle-enabled runs and is covered through logging/runtime test surfaces plus the examples/search_robustness/ bundletests/c/test_grid.c: bounding-box exchange checkstests/c/test_metric.c: metric and face-geometry checkstests/c/test_boundaries.c: boundary factory plus direct handler-behavior checkstests/c/test_poisson_rhs.c: pressure/rhs/projection/diffusivity helper checkstests/c/test_runtime_kernels.c: runtime orchestration, interpolation/scatter, particle lifecycle, wall, and walltime-guard checkstests/c/test_mpi_kernels.c: dedicated multi-rank consistency and restart-migration checkstests/c/test_support.{c,h}: shared PETSc fixture and assertion layerPurpose:
The current smoke runner verifies:
bin/simulator launches and responds to -helpbin/postprocessor launches and responds to -helpbin/picurv init creates a case directory with origin metadata (no binary copies)flat_channel, bent_channel, and brownian_motionpicurv run --dry-run --format json emits a valid solve/post execution plan--restart-from into the expected restart source directoryload and init)examples/search_robustness/ family provides a dedicated end-to-end runtime characterization path for search and migration observabilitymake smoke-mpi)load/init) runs (make smoke-mpi)make smoke-mpi-matrix)make smoke-stress)make smoke-periodic-dev, non-gating)These checks are intentionally tiny but execute real solver/postprocessor runtime paths. For the -help smoke checks, banner presence is authoritative: the local PETSc debug build may exit with code 62 (PETSC_ERR_ARG_WRONG) after printing help, and that still counts as a pass.
Run locally:
Environment controls used by the smoke layer:
KEEP_SMOKE_TMP=1:SMOKE_MPI_NPROCS=<n>:make smoke-mpi.SMOKE_MPI_MATRIX_NPROCS="<n1> <n2> ...":make smoke-mpi-matrix.Smoke orchestration lives in tests/smoke/run_smoke.sh; runtime profile mutation helpers there are part of the tested contract.
make check is the top-level local validation sweep.
It runs, in order:
make test-pythonmake doctormake unitmake smokeUse it when you want maximum local confidence before ending a development cycle.
make check-mpi extends this sweep by running make smoke-mpi and make unit-mpi afterward.
make check-mpi-matrix extends this sweep by running make smoke-mpi-matrix and make unit-mpi.
make check-full is the comprehensive MPI-inclusive gate. It runs make check, then make unit-mpi, make smoke-mpi, and make smoke-mpi-matrix.
make check-stress extends make check-full by running make smoke-stress afterward. make smoke-periodic-dev is intentionally outside the default gates and may fail honestly while periodic BC work is still in development.
Use check-full for release candidates or CI workflows where both focused multi-rank tests and rank-matrix runtime checks are required in a single pass.
Coverage gates are script-backed and checked in-repo:
make coverage-python:scripts/python_coverage_gate.pytrace and currently focuses on core runtime scripts (default: scripts/picurv)make coverage-c:unit + smoke, then executes scripts/c_coverage_gate.pysrc/*.cCoverage artifacts:
coverage/python/summary.txtcoverage/c/summary.txtThis dated snapshot records non-periodic C sources that still look thinly exercised after the 2026-03-20 local audit. Treat these numbers as test-readiness guidance for future work, not as evidence of confirmed product defects.
src/BodyForces.c: 11.69%src/AnalyticalSolutions.c: 23.93%src/les.c: 22.58%src/poisson.c: 45.66%src/rhs.c: 61.95%src/runloop.c: 64.76%src/Boundaries.c: 68.10%Next test work priorities from this snapshot:
Common issues:
PETSC_DIR is unset:make doctor, make unit*, make smoke*, and make check* will fail.PETSC_ARCH points to the wrong build:mpicc or MPI runtime wrappers are missing:/tmp/picurv-test-* for preserved intermediate artifacts.pytest is unavailable:gcov is unavailable:make coverage-c cannot produce C line-coverage reports.When adding new tests:
test-python, doctor, unit-*, or smoke)tests/c/test_support.* for PETSc-backed fixtures; it now provides both a fast minimal fixture and a richer tiny-runtime fixture while mirroring the production da/fda/swarm contract instead of a same-size synthetic DM/tmpFor detailed C test maintenance guidance, see C Test Suite Developer Guide.
The smoke suite uses these named runtime sequences:
S0: template matrix init/validate/dry-run across flat_channel, bent_channel, and brownian_motionS1: tiny flat-channel solve+post runS1b: tiny bent-channel solve+post runS2: tiny flat-channel solve+post with particles enabled (default Trilinear interpolation)S2b: tiny flat-channel particle solve+post with CornerAveraged interpolation (legacy path regression)S3: tiny restart runs from S2 with particle_restart_mode=load and particle_restart_mode=initS4: tiny Brownian analytical solve+post with particle outputs and MSD statisticsS5: multi-rank tiny solve+post runs for flat and bent channels, plus flat particle base/restart (load and init) branchesS6: restart-equivalence run for flat channel (continuous vs split restart continuity metric agreement)S7: periodic constant-flux validate + dry-run contract coverage in the opt-in stress tierS8: periodic constant-flux real runtime development harness (make smoke-periodic-dev, non-gating)Runtime file coverage map (unit targets + runtime sequences):
src/AnalyticalSolutions.c: unit-solver, S4src/BC_Handlers.c: unit-boundaries, unit-periodic-dev, unit-runtime, S1, S1b, S2, S3, S5, S6, S7, S8src/BodyForces.c: unit-solver, unit-poisson-rhs, S1, S2src/Boundaries.c: unit-boundaries, unit-periodic-dev, S1, S1b, S2, S3, S5, S6, S7, S8src/Filter.c: unit-solversrc/Metric.c: unit-metric, unit-grid, S1, S1b, S2, S5, S6src/ParticleMotion.c: unit-runtime, S2, S3, S4, S5src/ParticlePhysics.c: unit-runtime, S2, S3, S4, S5src/ParticleSwarm.c: unit-runtime, S2, S3, S4, S5src/grid.c: unit-grid, unit-setup, S1, S1b, S2, S4, S5, S6, S8src/initialcondition.c: unit-runtime, S1, S1b, S2, S4, S5, S6src/interpolation.c: unit-geometry, unit-runtime, unit-particles, S2, S2b, S3, S4, S5src/io.c: unit-io, S1, S1b, S2, S3, S4, S5, S6src/les.c: unit-solver, unit-runtimesrc/logging.c: unit-logging, S1, S1b, S2, S3, S4, S5, S6, S8src/momentumsolvers.c: S1, S1b, S2, S5, S6src/particle_statistics.c: unit-post, S4src/poisson.c: unit-poisson-rhs, S1, S1b, S2, S5, S6src/postprocessing_kernels.c: unit-post, S1, S1b, S2, S4, S5, S6src/postprocessor.c: unit-post, S1, S1b, S2, S3, S4, S5, S6src/rhs.c: unit-poisson-rhs, S1, S1b, S2, S5, S6src/runloop.c: unit-runtime, S1, S1b, S2, S3, S4, S5, S6src/setup.c: unit-setup, unit-runtime, S1, S1b, S2, S3, S4, S5, S6, S8src/simulator.c: S1, S1b, S2, S3, S4, S5, S6src/solvers.c: unit-solver, S1, S1b, S2, S5, S6src/vtk_io.c: S1, S1b, S2, S3, S4, S5, S6src/walkingsearch.c: unit-geometry, unit-particles, S2, S3, S4src/wallfunction.c: unit-runtimeP0 (implemented):
make coverage-python, make coverage-c, make coverageS6)make smoke-mpi-matrix)P1 (implemented):
unit-runtimeunit-boundariesP1 (next):
LocateParticleOrFindMigrationTarget:LOST and MIGRATING_OUT outcomesGuessParticleOwnerWithBBox heuristicMomentumSolver_Explicit_RungeKutta4MomentumSolver_DualTime_Picard_RK4PoissonSolver_MG and periodic/IBM stencil behavior checks beyond the current helper-level unit-poisson-rhs surfaceSMOKE_MPI_MATRIX_NPROCS="2 3 4 6") in CI/nightly profiles2026-03-20 audit:src/AnalyticalSolutions.c (23.93%) and src/BodyForces.c (11.69%)src/les.c (22.58%)src/poisson.c (45.66%) and src/rhs.c (61.95%)src/runloop.c (64.76%)src/Boundaries.c (68.10%)P2 (deeper hardening):
This page describes Testing and Validation Guide within the PICurv workflow. For CFD users, the most reliable reading strategy is to map the page content to a concrete run decision: what is configured, what runtime stage it influences, and which diagnostics should confirm expected behavior.
Treat this page as both a conceptual reference and a runbook. If you are debugging, pair the method/procedure described here with monitor output, generated runtime artifacts under runs/<run_id>/config, and the associated solver/post logs so numerical intent and implementation behavior stay aligned.