# Fluid physics audit — 23 October 2026 This pass repairs conservation and boundary coupling, establishes repeatable physical tests, and measures kernel and threading performance. It is not a certification that every engine or acoustic subsystem is physically validated. ## Findings and changes 1. **Pipe–volume mass/energy mismatch.** Previously, the volume used an orifice's requested discharge while the pipe used a different Rusanov ghost-cell flux. Each boundary now supplies one integrated mass, energy and fresh-air flux; the volume receives the exact opposite exchange. Stationary walls transfer momentum but no mass or energy. Open-end audio reports the mass flux actually applied by the finite-volume update. 2. **Substep integration.** Components previously received only the final boundary flow after several pipe substeps. Every component now updates after every pipe substep. CFL is recalculated as the solution evolves. 3. **Profiled pipes.** Geometry was stored but absent from the conservation update. Shared face fluxes now include face area and divide by cell volume; momentum includes the quasi-1D pressure source `p dA/dx`. Constant-pressure rest remains stationary while closed profiled pipes conserve mass/energy. 4. **Orifice choking.** The old formula used the upstream sound speed with throat Mach number, overestimating discharge. The nozzle calculation now uses the isentropic throat temperature and satisfies the sonic-flow test. 5. **Unstable small-signal boundary.** Evaluating `sqrt(dp)` using only the adjacent cell-centre pressure destabilized a small Helmholtz excitation. The nozzle discharge is now matched to the outgoing duct characteristic using a safeguarded analytic Newton solve of a squared-flow residual. Bisection remains the fallback. Subsonic, isentropic characteristic and quasi-steady nozzle assumptions still limit this model. 6. **Inertance units.** For mass flow, `d(mdot)/dt = A dp/L`, not `A dp/(rho L)`. Dimensionless quadratic resistance is integrated with a dissipative semi-implicit term. Removed the additional lumped inertance in the Helmholtz scenario: its resolved neck already carries inertance. 7. **Moving volumes.** Volume0D previously applied work without changing its geometric volume. Closed adiabatic work now follows `E V^(gamma-1)=constant` and updates volume. Crankcase geometry work is applied once per geometry change rather than again for each solver substep. Removed its five-bar cap, which silently deleted gas during high compression. 8. **Invalid configurations.** Reject invalid geometry, timesteps, duplicate or missing endpoints and incompatible gas constants. A pressure-only boundary cannot specify a supersonic inlet; that case now fails explicitly. Direct pipe joints support equal endpoint areas and all orientation combinations; unequal-area direct joints are rejected. Use a profiled transition instead. 9. **Performance.** Cache primitive states/wave speeds, evaluate each shared interior face once, and hoist uniform relaxation outside the cell loop. Compiler SIMD is enabled without fast-math. No per-step allocations were introduced into the pipe/boundary kernels. ## Validation `fluidsim_fluid_validation` contains 29 named cases, in addition to the existing physics/audio/ECU regression executable. Coverage includes: - Closed pipes, variable-area equilibrium/conservation, stationary hot contacts. - Sealed volume–pipe exchange, several volumes and a shared tiny donor. - Direct joints in four orientations and split/unsplit equivalence. - Fresh-air species conservation, actual open-end mass accounting on both ends. - Sonic choking against the analytic ideal-gas formula; inertance units and steady quadratic resistance. - Adiabatic moving volumes, thermal exponential relaxation and sealed crankcase compression beyond five bar without mass deletion. - Closed/open acoustic reflection signs, closed-duct mode frequencies at 50/100/200 cells, and small-signal cavity resonance. - Sod shock-tube density error at 100/200/400 cells, strong pressure pulses, expanding-flow near-vacuum states, positivity-repair checks. - Invalid geometry/configuration, incompatible gas coupling, unsupported supersonic inlet and missing/duplicate endpoint rejection. Representative measured results: | Check | Result | | --- | --- | | Sod density L1, 100 / 200 / 400 cells | 0.02332 / 0.01595 / 0.01052 | | Closed-duct fundamental | approximately 171.9 Hz; analytic 171.91 Hz | | Cavity fundamental | approximately 136.2 Hz; lumped estimate 138.51 Hz | | Closed mass/energy relative tolerances | 2e-5 to 5e-5, depending on case | | Cavity frequency tolerance | 5%, with growth and positivity checks | | Closed-duct frequency tolerance | 1% across three resolutions | The cavity estimate assumes a compact, lossless neck without radiation end correction; the discretized model includes neck compressibility and numerical losses. These comparisons are verification of stated assumptions, not a comparison with measured engine hardware. ## Benchmarks and SIMD Machine: Intel Core i5-12600K, GCC 16.2.1, Linux x86-64, Release. These are local wall-clock microbenchmarks; CPU frequency and background load affect timings. The pipe benchmark advances an equilibrium lossless duct with reflected ends; the twin benchmark runs one simulated second including its nonlinear boundaries. Before this audit, isolated kernels measured about 49–52 million cell updates/s and the twin about 3.84 times real time. Cached shared-face evaluation raised pipe throughput to roughly 110–140 million updates/s. The final twin is around 1.7 times real time: it does substantially more boundary work than the original, physically inconsistent solver. Early faster twin numbers from before the characteristic/nozzle correction must not be treated as final results. A SIMD comparison measured roughly 111–139 million updates/s with compiler vectorization versus 84–102 million with vectorization disabled. GCC's vectorization report confirms 16-byte SIMD in the primitive-state and face-flux loops. `FLUIDSIM_ENABLE_SIMD=ON` permits vectorization and disables math errno; it does **not** enable fast-math, approximate reciprocal/square-root intrinsics, or machine-specific instruction sets. OFF disables compiler vectorization for repeatable comparison. Scalar and SIMD builds run the same physics tests. Windows/MSVC settings are provided but were not executed in this Linux audit. ## Multithreading investigation `fluidsim_thread_benchmark` measures persistent workers with two barriers per iteration. Boundaries/components must remain in ordered phases; pipes can be advanced independently only after all boundary fluxes are resolved. | Independent pipe workload, 1000 steps | Serial | 2 workers | 4 workers | | --- | ---: | ---: | ---: | | 6 pipes × 10 cells | 0.00093 s | 0.00272 s | 0.00625 s | | 64 pipes × 256 cells | 0.1275 s | 0.0700 s | 0.0410 s | This is an optimistic stage-only benchmark with equilibrium data, excluding worker startup and a real graph's serial boundary work. It supports further work on persistent pools for large networks; it does not justify threading the current small twin. No fluid worker pool is enabled in production. The existing simulation/audio/UI separation remains. ## Reproduce ```sh cmake -S . -B build-audit -DFLUIDSIM_BUILD_DESKTOP=OFF -DCMAKE_BUILD_TYPE=Release cmake --build build-audit -j 4 ctest --test-dir build-audit --output-on-failure ./build-audit/fluidsim_physics_benchmark 44100 ./build-audit/fluidsim_thread_benchmark ``` For a scalar comparison configure a separate directory with `-DFLUIDSIM_ENABLE_SIMD=OFF`. On GCC/Clang, use another directory with `-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer"` to reproduce the sanitizer run. Final Linux desktop regressions, all 29 scalar fluid cases, and both test executables under AddressSanitizer/UndefinedBehaviorSanitizer passed. The final sanitizer run completed in about 13 seconds. Compiler vectorization diagnostics can be produced with GCC `-fopt-info-vec-optimized`. ## Remaining limits and next work - First-order Rusanov flux is dissipative. Spatial/time resolution convergence and attenuation across the full audible band are not yet established. A higher-order limited scheme is a separate change, not silently enabled here. - The default four-substep floor was retained: removing it failed a tiny-volume stress case. CFL alone is not a positivity guarantee for arbitrary stiff pipe/volume networks. Conservative donor budgets can limit transfer; inspect `BoundarySystem::limited_fluxes` and refine time resolution when they activate. Budgets for shared donors are allocated in registration order. Pipe positivity repairs are counted by `Pipe1D::positivity_repairs`; a nonzero count invalidates a claim of exact conservation for that run. - Pipe geometry/cell storage remains public for initialization. Changing its topology or resizing cells after connections have been built is unsupported. - The pressure-only open boundary extrapolates interior entropy. It is an ideal pressure-release model, not a complete external atmosphere, anechoic boundary, or frequency-dependent radiation impedance. Strong inlet flows need richer thermodynamic boundary data. - Junctions and orifices are quasi-1D approximations. Jet separation, vena contracta, discharge coefficients and strong multidimensional area changes need validation; equal-area joint tests do not validate arbitrary fittings. - The optional lumped inertance law is dimensionally checked, but its stored neck kinetic energy is not a separately tracked thermodynamic state. Use resolved pipe cells when evaluating physical neck acoustics and energy. - Core pipe damping and volume thermal relaxation default to zero. Explicit scenario damping/relaxation still represents empirical source terms and must be calibrated before claiming real dissipation or heat transfer. - Engine cylinders retain pressure/temperature safety clamps, approximate combustion/species bookkeeping and unvalidated mechanical work integration. ECU behavior and the broader engine model are not certified by this audit. - Sound radiation remains the documented compact-source approximation. These fluid tests do not establish microphone SPL, high-frequency radiation, thermoviscous losses or full mechanical/chemical energy conservation. ## Physical references - [Clawpack: approximate Euler Riemann solvers](https://www.clawpack.org/riemann_book/html/Euler_approximate.html) — conservative Euler fluxes and total-energy equation of state. - [Clawpack: Euler equations and exact Riemann solutions](https://www.clawpack.org/riemann_book/html/Euler.html) — shock/contact/rarefaction verification and the Sod problem. - [NASA Glenn: mass-flow choking](https://www.grc.nasa.gov/www/k-12/BGP/mflchk.html) — isentropic throat relations and maximum mass flow at Mach one. - [EPFL: quasi-1D Laval nozzle model](https://www.epfl.ch/labs/mathicse/wp-content/uploads/2018/10/25.2016_MP-FN-PL.pdf) — variable-area Euler fluxes and geometric pressure source. ## Sustained-load follow-up A one-second run missed a runtime deadline problem: at full throttle the heated gas raised average CFL work from 4 to approximately 7 substeps per audio frame. By simulated second 5, each second needed about 1.04 seconds of CPU time, so a finite startup buffer could not prevent eventual underruns. Idle stayed near 0.6 seconds per simulated second. The solver now reuses its CFL primitive-state/wave-speed preparation in the finite-volume update. Boundary Newton residual tolerance is matched to the single-precision conserved state (`4e-7` in the normalized squared-flow residual), rather than solving to `1e-12` relative residual each time. The same CFL limits and four-substep floor remain. On the same machine, a nine-second full-throttle run measured approximately 0.74–0.81 seconds per simulated second in the hot portion; idle measured approximately 0.49–0.52 seconds. All 29 fluid cases and existing regressions still pass. This is measured headroom, not a hard real-time guarantee on other workloads or machines. Reproduce sustained-load timings with: ```sh ./build-audit/fluidsim_physics_benchmark --soak 12 ``` The benchmark reports each simulated second, average substeps/frame and boundary iterations/frame. Desktop audio also counts underrun blocks; the counter is shown with the audio-buffer status when a UI font is available. ## Intake reservoir and repeated-blip regression The twin's upstream pressure-only boundary inherited pipe entropy during inflow. Repeated blips could therefore admit progressively hotter gas rather than fresh ambient air: a captured sequence reached approximately 1140 K in the plenum at wide-open throttle and lost fresh charge density. The intake now connects to an explicit infinite `Atmosphere` reservoir (101325 Pa, 300 K, fresh-air fraction one), updated on every fluid substep. Intake radiation uses that reservoir's actual signed mass exchange. The remaining pressure-release open-end index now refers only to the exhaust. The twin also disables pipe relaxation toward ambient **pressure** energy. That source can heat low-density evacuated cells without a physical wall heat transfer law. This does not impose any pressure floor or artificial manifold refill. Hot residual-gas reversion, closed-throttle pumping and pressure waves remain possible; their engine-model accuracy still needs further validation. `fluidsim_intake_regression` runs 16 simulated seconds: idle, an 80% blip, recovery, a full-throttle opening, and return to idle. It checks pressure recovery, fresh-air temperature/composition, finite audio, zero pipe positivity repairs and final idle recovery. Representative results after the fix: - Before the second opening: 35.76 kPa manifold absolute pressure. - After opening: 85.45 kPa near 9950 RPM; manifold 298.96 K, inlet 296.92 K. - After return to idle: 34.51 kPa at 1820 RPM. Manifold vacuum at small/closed throttle is expected and is not removed by the fix. An actual obstruction/regression is distinguished by failure to recover pressure and fresh-charge density when reopening the throttle. The inlet reservoir controls the upstream gas state; it does not thermostat the manifold. See [AEM's engine-management manual](https://documents.aemelectronics.com/techlibrary_30-6905_universal_programmable_engine_management_system.pdf) for the qualitative throttle-angle/manifold-pressure relationship. These are scenario regression bounds, not universal pressure limits for real engines. All three CTest executables pass after this change (existing regressions, 29-case fluid suite, and the new intake transient). A six-second sustained full-throttle follow-up stayed at four substeps/frame and approximately 0.51–0.53 seconds of wall time per simulated second, with RPM around the ECU rev limit. This also identifies the earlier hot-gas CFL growth as a consequence of the incorrect inlet thermodynamic state, not solely an unavoidable engine workload increase. The earlier timing sections are historical measurements of those intermediate implementations.