Skip to content

Assemble the Navier-Stokes timestep and validate it against Ghia et al. (TASK-034) - #47

Merged
AdamClemens merged 1 commit into
mainfrom
feat/task-034-navier-stokes-timestep
Aug 29, 2026
Merged

Assemble the Navier-Stokes timestep and validate it against Ghia et al. (TASK-034)#47
AdamClemens merged 1 commit into
mainfrom
feat/task-034-navier-stokes-timestep

Conversation

@AdamClemens

Copy link
Copy Markdown
Owner

Summary

Stage 5's fifth and last task in build order — this defines the MVP.

  • pyflow.engine.simulation.navier_stokes_step assembles TASK-031/032/033 into one real incompressible Navier-Stokes timestep: momentum's own two components advance through the existing step path with no pressure term (the predictor), the result is reassembled and handed to whichever PressureCoupling was configured (the corrector), and the corrected components replace the predictor's own (the corrected state). NavierStokesStepResult exposes all three parts separately. stable_timestep derives a resolution-appropriate dt from the CFL/diffusive stability limits (safety factor measured via a disposable prototype sweep, not guessed).
  • Eleven scenarios in tests/features/navier_stokes_timestep.feature: the predictor/corrector/corrected sequence, both null tests (uniform periodic flow, fluid at rest), determinism, the ADR-003 substitution check, Couette flow at solver tolerance, the Ghia cavity comparison, the Taylor-Green matched/mismatched pair, and step-wise kinetic-energy conservation.
  • The Ghia cavity comparison — this project's most computationally expensive test, deliberately: three real runs (resolutions 9, 13, 17) to a measured steady state at Re = 100, RMS error against Ghia, Ghia & Shin (1982)'s own Table I (tests/fixtures/ghia_1982_re100.py, cross-checked against two independent public reproductions of the paper, a new committed-reference-data convention for this repo) decreasing strictly across all three resolutions, the finest resolution's primary vortex within 0.1 of Ghia's own reference point, and both downstream secondary corner vortices detected via opposite-sign discrete vorticity.
  • Two golden demos: Lid-Driven Cavity (the MVP's own golden demo — the first velocity field PyFlow has ever rendered that was solved, live, via a new bootstrap.py velocity-only rendering path) and Heat Diffusion (a single sinusoidal mode decaying at its exact analytic rate on a periodic domain).

Two real gaps found and closed along the way

  1. GreenGaussGradient/GreenGaussDivergence/PISO had no periodic-boundary support at all — found while building the periodic null test, which cannot reach PISO without it. Both operators gained a periodic_pairs constructor parameter (same shape CentralDifferenceDiffusion already had); PISO threads it through, including its own _rhie_chow_divergence correction loop. Verified directly: a uniform field measures exactly 0.0 divergence through this path; a non-uniform field gives a real nonzero value matching a hand-derivation. No ADR — registry-level widening, no interface change.
  2. PISO._poisson_matrix was rebuilt from scratch every single timestep — found while timing the cavity validation's own first real run. Caching it per instance (by mesh identity) cut measured per-timestep cost by 3.5–7.7x, which is what made the three-resolution comparison fit inside an 11-minute test.

A design finding, recorded rather than silently substituted

Stage 5's own design question two named velocity_tangential as its answer for the cavity's moving lid, but BoundaryFaceConfig.field_values/field_gradients (landed the next day) already supply the exact general mechanism needed — a per-field-name override at one wall. velocity_tangential was never built; this is documented explicitly in the roadmap and the test module's own docstring.

Test plan

  • make ci fully green locally: 672 tests passed, 99% coverage, all structural/scenario/status checks passing
  • mypy --strict clean, ruff clean
  • Ghia cavity scenario confirmed passing on a real run (11m24s)
  • Lid-Driven Cavity and Heat Diffusion demos run via the real CLI subprocess
  • Real CI run on both ubuntu-latest/windows-latest (Criterion 9 in the Stage 5 exit audit is marked pending this)

🤖 Generated with Claude Code

…l. (TASK-034)

Stage 5's fifth and last task, defining the MVP: pyflow.engine.simulation.
navier_stokes_step assembles TASK-031/032/033 into one real predictor/
corrector/corrected-state timestep, validated by eleven scenarios covering
the mechanism itself (both null tests, determinism, the ADR-003
substitution check, Couette flow), the Lid-Driven Cavity comparison
against Ghia, Ghia & Shin (1982) at three real mesh resolutions, the
Taylor-Green emergent-phenomenon pair, and kinetic-energy conservation.
Ships with the two golden demos Stage 5 owes (Lid-Driven Cavity, Heat
Diffusion) and closes two real gaps found along the way: PISO had no
periodic-boundary support at all, and its Poisson matrix was rebuilt from
scratch every timestep rather than cached.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@AdamClemens
AdamClemens merged commit a46a275 into main Aug 29, 2026
2 checks passed
@AdamClemens
AdamClemens deleted the feat/task-034-navier-stokes-timestep branch August 29, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant