PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Code Architecture

This page is the developer-oriented map of the current PICurv C codebase.

1. Executable Entry Points

Both rely on shared setup/context infrastructure from setup.c, io.c, and variables.h. Persistent Eulerian field identity/runtime DM-Vec binding and separate solver-particle DMSwarm identity are shared through field_catalog.c, particle_field_catalog.c, and their headers; see Field Identity and Layout Catalog.

2. Solver Runtime Flow (simulator.c)

High-level stages:

  1. PetscInitialize
  2. CreateSimulationContext (setup.c) parses control/options and initializes defaults
  3. SetupSimulationEnvironment configures run directories and environment-dependent logging setup
  4. Setup stack:
    • SetupGridAndSolvers
    • SetupBoundaryConditions
    • SetupDomainRankInfo
    • InitializeEulerianState
    • InitializeParticleSwarm (if particles enabled)
  5. Time integration via AdvanceSimulation
  6. Finalization via profiling teardown + FinalizeSimulation + PetscFinalize

3. Postprocessor Runtime Flow (postprocessor.c)

  • Parse post recipe (post.run) into PostProcessParams
  • Load requested Eulerian/particle fields by timestep
  • Execute configured Eulerian/Lagrangian/statistics pipelines
  • Write VTK outputs (.vts, .vtp) and statistics CSV outputs

After successful field processing, the conductor's finalize_post_paraview_series can write .pvd indexes using committed checkpoint times and manifest ancestry. This serial presentation stage belongs to post.pipeline; it does not alter the C field kernels. Caught-up post invocations can refresh collections under the same post writer lock. See Physical-Time ParaView Collections (post.pipeline) for the tested scope.

4. Core Context Objects

4.1 SimCtx

  • Declared in include/variables.h
  • Holds global run configuration and top-level handles
  • Populated mainly in CreateSimulationContext

4.2 UserCtx

  • Block/grid-level state container (DM, vectors, metrics, block-local geometry)
  • Used throughout grid, solver, BC, and post kernels
  • Finest-level block arrays are central runtime work objects

5. Module Responsibilities

Observability sits apart from the list above rather than inside one of its rows, because every other module reports through it. logging.c owns the console tier system, the runtime metric emitters, and the lifecycle of the per-run diagnostic files in <run.runtime_logs>. Its dependency direction is one-way and deliberate: it reads SimCtx for the step, physical time, log directory, rank, and continuation state, and it depends on PETSc for collectives and formatted output, but no solver module depends on logging for a numerical result. That is what lets any module report without acquiring a dependency on any other, and it is why a change here can alter what a user sees without altering what the solver computes.

5.1 File-Level API Entry Points

For contributor orientation, the table below lists high-value public entry points per subsystem. Function names come from include/*.h and represent the safest integration seams.

5.2 Source-to-Test Coverage Lens

Current tests cover all src/*.c files at least at module level (unit suites and/or smoke). Coverage depth is intentionally uneven:

When adding docs, prioritize:

  1. explicit call-sequence narratives for orchestration modules
  2. contract/units/assumptions for numerical kernels
  3. failure signals and diagnostics for runtime-heavy paths

6. Configuration Ingestion Boundaries

Primary ingestion sites:

  • setup.c: PETSc option parsing for solver/post shared runtime controls
  • io.c: grid read/generation inputs, restart/data IO, post recipe parsing
  • logging path includes environment variable ingress (LOG_LEVEL)

Not all option consumption is explicit PetscOptionsGet*; PETSc dynamic ingestion also occurs through calls like KSPSetFromOptions in poisson.c.

7. Where to Extend

8. Next Steps