PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Maintenance Backlog and Low-Priority Fixes

This page tracks non-blocking technical debt items (warnings cleanup, refactors, and quality-of-life fixes) that are safe to address incrementally.

1. Purpose

Use this page for:

  • compiler warning cleanup queues,
  • low-priority style/consistency fixes,
  • non-urgent tooling/docs polish tasks.

Do not use this page for urgent correctness/security issues.

2. Current Tracker Source

Primary warning tracker location:

  • <repo>/logs/doxygen.warnings (generated by make build-docs)

For compiler/runtime warning campaigns, track status directly in this page.

3. Warning Cleanup Categories

Current warning clusters include:

  • pointer/type mismatches,
  • potentially uninitialized variables,
  • format-string and buffer safety issues,
  • unused code/variables,
  • logical/style inconsistencies,
  • PETSc deprecations.

These categories should be fixed in small, reviewable batches.

4. Suggested Workflow

  1. Pick one warning category and one module area (for example, src/io.c).
  2. Fix warnings without behavior changes.
  3. Rebuild and confirm warning deltas.
  4. Update this page with resolved/remaining counts.
  5. Commit as maintenance-only patch.

5. Prioritization Policy

  • Correctness-affecting warnings (uninitialized, format overflows, type mismatches) first.
  • Pure style/unused warnings later.
  • Keep each patch narrowly scoped to reduce regression risk.

6. Sandbox Policy

  • sandbox/ is retained as optional developer scratch space.
  • Treat everything in sandbox as non-production unless promoted.
  • Stable outcomes should be moved into <repo>/config/, examples/, picurv_cli/, generators/, or docs/.

7. Runtime Observability Backlog

Potential low-priority observability improvements worth revisiting:

  • add golden-output fixtures for the option-aware CASE SUMMARY and command-status reports. The fixture matrix should cover initial-condition and boundary-condition families, restart/load paths, particle modes, solver families, monitor/profiling choices, and each solution-convergence mode.
  • evolve tests/tooling/user_facing_reporting_contract.json from its current structural command/reporting checks into a runtime-backed reporting matrix for representative submit, cancel, sweep, plot, deferred, and continuation outcomes.
  • consider presentation-only normalization for longstanding diagnostic renderers (consistent severity prefixes and stable identifiers) while preserving the documented exceptions: bootstrap warnings emitted before logging is initialized, and dedicated banner/progress output sinks.
  • move the local wrapper stream log out of <run.runtime_logs>/ so it is not affected by solver-side log-directory recreation; <run.scheduler>/ is the existing precedent for batch stdout/stderr.
  • add an optional compact per-step summary CSV that consolidates already-available signals such as momentum pseudo-iterations/final residual, Poisson iterations/final residual, continuity/divergence, and particle health counters.
  • add opt-in convergence-based runtime completion for solution_monitoring.convergence.mode: steady_deterministic; keep transient diagnostic-only and require configured tolerances, minimum samples, dwell windows, and safe-checkpoint final writes before stopping.
  • add an optional boundary-flux summary CSV for inlet/farfield/outlet totals and conservation error when boundary-condition debugging becomes a repeated workflow need.
  • add cadence-based field-extrema summaries (P, |Ucat|, Psi, diffusivity) only if users need compact trend logs instead of verbose anatomy/min-max output.
  • extend particle metrics only when current Particle_Metrics.log proves insufficient; prefer compact inventory/health summaries over larger particle state dumps.

Observability policy note:

  • current runtime coverage is already strong for most runs: momentum convergence, Poisson convergence, continuity metrics, particle metrics, console particle snapshots, and profiling summaries.
  • backlog items in this section are primarily convenience or subsystem-specific diagnostics, not missing core health signals.

8. Characterized: Restart Is Not Bit-Exact

Measured 2026-08-17 on flat_channel. This is characterized and accepted, not an open defect. It is recorded here so it is not rediscovered as a bug and so future restart/statistics tolerances are set from a measured floor.

What happens. SetInitialFluidState_Load calls ApplyBoundaryConditions immediately after ReadSimulationFields (src/initialcondition.c). That runs a three-pass boundary fixed-point loop whose Contra2Cart step rebuilds Ucat from Ucont, so a restarted run resumes from BC(x_N) rather than the checkpointed x_N. Apply_OutletConservation does not refine the outlet, it overwrites it: the outlet flux is regenerated from the adjacent interior Ucat plus a global mass correction. The stored end-of-step state is therefore not a fixed point of the boundary map, and re-applying it reveals the offset.

Measured behavior.

  • The perturbation is confined to the outlet plane. The interior is untouched.
  • P, Nvert, and Ucont_rm1 are bit-exact across the restart.
  • One step later it is domain-wide, which is expected: the elliptic pressure solve couples any boundary perturbation everywhere in a single step.
  • It then decays monotonically and does not amplify. On 24x24x48 with a restart at step 50, Ucont relative L2 peaks near 5e-8 at step 55 and decays to 4.5e-8 by step 100; P peaks near 1.5e-7 and decays to 1.3e-7.
  • Absolute magnitudes sit below the solver's own stopping tolerances (Ucont |d|inf ~4.6e-10 against momentum absolute_tol 1e-8).
  • The magnitude decreases on finer grids and more developed flow.

(Recorded before momentum convergence moved to the residual criterion: absolute_tol no longer participates while a residual tolerance is set. The finding is unaffected — it is about a structural floor, not about which tolerance is active.)

The perturbation is invariant to solver tolerance. Tightening momentum relative_tol 1e-3 to 1e-8, absolute_tol 1e-8 to 1e-12, and Poisson absolute_tolerance 1e-5 to 1e-10 changed the restart offset by under one percent (Ucont relative L2 9.061e-09 versus 9.153e-09), while changing the underlying trajectory by 1.67e-05, roughly 370 times larger than the offset itself. The floor is structural. It cannot be tightened away through solver settings.

Consequences.

  • 7. Checkpoints, Restart, and Continuation is correct that checkpointing Ucont_rm1 avoids an artificial first-order restart step. It must not be read as promising a bit-exact trajectory. One step after restart the BDF2 history pair is asymmetric: the n-1 slot carries BC(x_N) where an uninterrupted run carries x_N.
  • Statistics restart-equivalence acceptance tests must set tolerance from this measured floor, not from machine epsilon and not on the assumption that verification runs can tighten their way below it.
  • This floor was measured on a laminar, stable case. In turbulent runs trajectories separate exponentially and pointwise restart comparison stops being meaningful at any tolerance; statistics equivalence there must be tested on converged window means instead of field-by-field.

Open question, deliberately not pursued. Why the offset lands near 1e-7 rather than some other magnitude is not established. Two candidate mechanisms remain: a residual of the three-pass boundary loop, or the ordering of the pressure projection relative to the last boundary application within a step. Changing the pass count in src/Boundaries.c and re-measuring the offset would distinguish them. Geometric scaling with pass count implicates the loop; no change implicates checkpoint placement within the step.

9. Deferred: Field-Statistics Validation Gaps

Field statistics carry a validated acceptance suite covering moment accuracy, window scheduling and clipping, masks, layouts and periodicity, restart continuation, console monitoring, and equivalence across a changed MPI rank count. One item in that suite was deliberately left uncovered, and is recorded here so it is not mistaken for an oversight.

Graceful-shutdown ordering is guaranteed by construction, not by a test. The committed bundle at a given step carries that step's contribution, which the statistics smoke scenarios assert through the ordinary cadence, and the shutdown path writes through the same coordinator. What is untested is that the run loop offers the completed state to the windows before it reaches the shutdown writer. That ordering lives in src/runloop.c. A test that drove the sequence itself would re-assert the checkpoint round trip rather than the ordering, which is why one was not written; catching a reordering needs a test that runs the loop, or a signal delivered at a controlled step.