Improve physical geometry, fluid solvers, audio, and profiling
This commit is contained in:
137
README.md
137
README.md
@@ -87,7 +87,9 @@ Controls: W/S raise/lower the pedal over 0.5 seconds, C disengages the clutch,
|
||||
V applies starter torque while held,
|
||||
A/D shift, Z selects neutral, and left/right adjust engine load. The on-screen
|
||||
pedal is direct and springs back on release; zero pedal retains ECU idle control.
|
||||
Page Up/Down change playback speed; Space toggles real time.
|
||||
Space toggles real-time and manual playback. In manual mode, Shift+scroll or
|
||||
Page Up/Down changes speed; ordinary scrolling zooms the view. Rendering uses
|
||||
display VSync independently of simulation speed, including 0.01x slow motion.
|
||||
|
||||
The command-line runner is useful for repeatable checks:
|
||||
|
||||
@@ -113,7 +115,8 @@ cmake --build build-msvc --target fluidsim_parity_trace
|
||||
|
||||
Desktop playback starts at real time: one solver output frame per 44.1 kHz
|
||||
stereo device frame. A simulation worker fills a bounded 8192-frame queue in
|
||||
512-frame batches with a 4096-frame startup reserve (about 93 ms). The device
|
||||
up to 128-frame batches with a 4096-frame startup reserve (about 93 ms). Batches
|
||||
shrink with playback speed so 0.01x does not advance in large bursts. The device
|
||||
callback only reads samples, removes DC, converts to PCM and handles underruns;
|
||||
it performs no simulation, allocation or waiting. An underrun fades out and
|
||||
recovery crossfades over 64 samples rather than stepping abruptly to silence.
|
||||
@@ -155,10 +158,18 @@ or exhaust afterfire chemistry. Filtering cannot recover aliased
|
||||
source information. See [audio verification](verification/AUDIO_RENDERING.md)
|
||||
for capture commands, current renderer details and limitations.
|
||||
|
||||
Use the **Cells/m - / +** control in the sidebar to change the active scenario's
|
||||
pipe resolution. Changes rebuild the mesh in the background and restart the
|
||||
engine, retaining solver, listener, scene and driving-control inputs. Values are
|
||||
remembered separately per scenario until the app closes. Set persistent defaults
|
||||
in each engine TOML's `[simulation] cells_per_meter`. The desktop engine editor
|
||||
has been removed; edit engine calibration in TOML.
|
||||
|
||||
|
||||
Launching `fluidsim_desktop` without `--scenario` opens a small scenario menu.
|
||||
Choose the twin, YZ125, Saab B205, or American V8 card, or select with Up/Down
|
||||
and press Enter.
|
||||
Escape returns from a running scenario to the menu, stopping its simulation and
|
||||
Escape returns from the scenario to the menu, stopping its simulation and
|
||||
audio so another scenario can be selected. Escape closes the menu at the category
|
||||
screen. Simulation and audio start after selection. Passing
|
||||
`--scenario twin`, `--scenario two-stroke`, `--scenario b205`, or `--scenario v8`
|
||||
@@ -176,7 +187,9 @@ cmake --build build-desktop --target fluidsim_desktop -j 4
|
||||
|
||||
Hold **W** to raise the pedal and **S** to lower it. Releasing the keyboard
|
||||
returns the pedal over 0.5 seconds. The UI lever is direct and springs back. Use
|
||||
**Space** to restore real-time playback and **R** to change environment. The two-stroke desktop uses
|
||||
**Space** to toggle real-time/manual playback and **R** to change environment.
|
||||
In manual mode use **Shift+scroll** or **Page Up/Down** to adjust speed;
|
||||
ordinary scrolling continues to zoom the view. The two-stroke desktop uses
|
||||
the existing 125 cc configuration; its dimensions and calibrations must be
|
||||
adapted before it represents a particular engine. Both scenarios use the same
|
||||
motorcycle test model, dashboard and rolling peak dyno graph (kW and Nm versus
|
||||
@@ -310,7 +323,7 @@ runs for every scenario, and finite audio/reverb output.
|
||||
|
||||
## Fuel and throttle control
|
||||
|
||||
Desktop playback has automatic gain enabled by default for every scenario.
|
||||
Desktop playback has automatic gain disabled by default for every scenario.
|
||||
Press **G** to toggle it; the dashboard shows its state. It tracks stereo RMS
|
||||
and peaks after DC removal, lifting quiet idle audio gradually (1.5-second
|
||||
gain-rise time constant) and reducing gain faster for loud revs (30 ms).
|
||||
@@ -410,8 +423,8 @@ Manifold vacuum at closed throttle remains part of the simulated pumping cycle.
|
||||
|
||||
## Pipe solver comparisons
|
||||
|
||||
The desktop accepts `--solver rusanov|hlle|hllc`. Press **F3** during playback to
|
||||
cycle Rusanov, HLLE and HLLC; the dashboard shows the current solver. All pipes
|
||||
The desktop accepts `--solver rusanov|hlle|hllc|muscl`. Press **F3** during playback to
|
||||
cycle Rusanov, HLLE, HLLC and MUSCL; the dashboard shows the current solver. All pipes
|
||||
switch together between simulation samples. Rusanov remains the startup default.
|
||||
Changing solver affects the ongoing engine state; allow several cycles and the
|
||||
audio queue to settle before judging it. Use the same scene and auto-gain setting.
|
||||
@@ -499,16 +512,20 @@ geometry-resolving junction model. Momentum changes
|
||||
are reacted by the fitting. Branch angle losses are not modeled. The separate
|
||||
`Junction` class remains available for explicit finite-volume chambers.
|
||||
|
||||
Each V8 bank now has a 4-2-1 header: four equal 750 mm x 38 mm primaries feed two
|
||||
equal 400 mm x 45 mm secondaries, then a 50 mm exhaust. Pairings are 1+2 / 3+4
|
||||
Each V8 bank has a 4-2-1 header: four primaries feed two secondaries, then a
|
||||
50 mm exhaust. Pairings are 1+2 / 3+4
|
||||
and 5+7 / 6+8 with this simulation's bank numbering and firing order. Two T
|
||||
junctions and a 780 mm x 38 mm tube form the H-pipe. Small configurable port-coupled junction volumes are used by the V8. The intake
|
||||
plenum also remains a storage volume.
|
||||
The TOML `primaries` pipe group configures primary length/diameter, while
|
||||
The TOML `primaries` pipe group configures diameter; measured
|
||||
`geometry.pipes` centerlines configure length and position. Headers now use
|
||||
direct swept bends with revised lengths, and the short/long variants have
|
||||
distinct physical layouts. See [geometry definitions](docs/ENGINE_CONFIG.md).
|
||||
The
|
||||
`[junctions] h_pipe` enables the H crossover;
|
||||
pass it as the fourth `FourStrokeScenario` constructor argument. The renderer
|
||||
routes the primary pairs into Y merges, then the final Y collectors and H-pipe,
|
||||
using local pipe diameter and pressure colors without collector boxes.
|
||||
uses the same centerlines, cross-sections and active storage-volume dimensions
|
||||
as the fluid system, with local pressure colors and mitered hard corners.
|
||||
|
||||
The previous header optimization measurements applied to the earlier finite-volume
|
||||
4-1 layout and do not establish an optimum for this new 4-2-1 network.
|
||||
@@ -619,3 +636,99 @@ The tool also prints CSV diagnostics: run without arguments for the four main
|
||||
operating points, or use `--sweep single-450` for a denser sweep of one scenario.
|
||||
See [carb calibration results](verification/CARB_CALIBRATION.md) for operating
|
||||
conditions, AFR values and the distinction between carb and recirculated charge.
|
||||
|
||||
### Source-separated audio diagnostics
|
||||
|
||||
The capture tool writes `-intake.wav`, `-exhaust.wav`, `-exhaust-2.wav`, and
|
||||
`-valve-contact.wav` alongside the existing rendered, dry, and unfiltered mixes.
|
||||
Source stems contain direct sound and early reflections, before the shared diffuse
|
||||
reverb; `-tail.wav` contains that shared tail. With all sources enabled, the four
|
||||
stems plus the tail reconstruct the rendered mix before WAV quantization/clipping.
|
||||
Absent sources produce silent files. Peak, RMS, maximum sample delta, and clipping
|
||||
counts are reported for every stem, in device full-scale units, without normalization.
|
||||
|
||||
Use `--solo intake`, `--solo exhaust`, `--solo exhaust-2`, or
|
||||
`--solo valve-contact` to select a source in the output mix (default: `--solo all`).
|
||||
All diagnostic stems remain active during soloing. These controls affect audio only;
|
||||
they do not change the fluid simulation. Source controls are simulation-thread APIs.
|
||||
|
||||
```powershell
|
||||
.\out\build\windows-gcc\fluidsim_audio_capture.exe --example single-450 --rpm 3000 --throttle .3 --warmup 1 --seconds 2 --scene dry --out out/audio/single-450-baseline
|
||||
```
|
||||
|
||||
For intake-only listening, repeat with `--solo intake` and a different output prefix.
|
||||
The shared tail can retain decay when controls change during playback.
|
||||
|
||||
Captures use 32-bit IEEE float WAV to preserve very quiet sources without clipping.
|
||||
For audible, individually peak-normalized PCM16 listening copies, run:
|
||||
|
||||
```powershell
|
||||
py tools/audio_preview.py out/audio/single-450-baseline
|
||||
```
|
||||
|
||||
Previews appear in `out/audio/previews/`, with gain reported for each file.
|
||||
Silent sources are skipped. Preview loudness does not represent relative source
|
||||
strength; use the original captures and metrics for calibration.
|
||||
|
||||
### Acoustic pulse diagnostics
|
||||
|
||||
The `fluidsim_acoustic_benchmark` target compares straight connections, idealized
|
||||
three-way junctions, and finite-volume fittings across meshes, timesteps, and
|
||||
all three flux solvers. It exports pressure/velocity traces and acoustic energy
|
||||
ratios, with conservation and numerical-repair diagnostics. See
|
||||
[the benchmark guide and initial findings](docs/ACOUSTIC_BENCHMARK.md).
|
||||
|
||||
### Listening comparison: limited second-order pipes
|
||||
|
||||
Desktop auto gain now starts **off**. Press **G** to enable it if desired.
|
||||
For a direct comparison on the current engine, keep throttle and master volume
|
||||
fixed and press **F3** to cycle `rusanov ? hlle ? hllc ? muscl`.
|
||||
The dashboard shows the selected solver. Rusanov remains the startup default.
|
||||
To start directly in the new mode:
|
||||
|
||||
```powershell
|
||||
.\out\build\windows-gcc\fluidsim_desktop.exe --example single-450 --solver muscl --scene dry
|
||||
```
|
||||
|
||||
`muscl` uses minmod-limited primitive MUSCL-Hancock reconstruction with HLLC
|
||||
fluxes on uniform pipe sections. Matching direct connections share reconstruction
|
||||
stencils. Component boundaries and area/profile transitions retain first-order
|
||||
coupling; nonphysical predicted edges fall back to cell averages, and HLLC keeps
|
||||
its existing HLLE fallback. Reconstruction buffers are allocated at construction.
|
||||
This is a listening candidate, not a calibrated real-engine sound model.
|
||||
|
||||
At 3000 RPM / 0.3 pedal, four-second dry captures are in
|
||||
`out/audio/pipe-ab-rusanov-rendered.wav` and `out/audio/pipe-ab-muscl-rendered.wav`.
|
||||
They preserve the actual level difference. New wave resolution can also change
|
||||
cylinder filling, combustion, and torque. Restart in each solver for clean
|
||||
comparisons; live switching retains the engine's current state.
|
||||
|
||||
For a comparison at equal RMS loudness, use
|
||||
`out/audio/pipe-ab-rusanov-level-matched.wav` and
|
||||
`out/audio/pipe-ab-muscl-level-matched.wav`. Both are PCM16 listening copies;
|
||||
original float captures keep their physical output scale. Equal RMS does not
|
||||
imply identical perceived loudness or identical engine state.
|
||||
|
||||
In one local loaded V8 check, MUSCL took 1.23 wall seconds per simulated second,
|
||||
versus 0.78 for Rusanov. Large engines may underrun in real-time playback;
|
||||
use the single-450 for the first listening comparison.
|
||||
|
||||
### Direction-aware characteristic junctions
|
||||
|
||||
A nonlinear zero-storage exhaust junction solver is now available separately
|
||||
from the pipe solver. Start with Rusanov pipes to isolate the junction change:
|
||||
|
||||
```powershell
|
||||
.\out\build\windows-gcc\fluidsim_desktop.exe --example v8-h --solver rusanov --junctions characteristic --junction-loss 0.5 --scene dry
|
||||
```
|
||||
|
||||
Use `--junctions volume` to compare against the original volume fittings.
|
||||
`--junctions legacy` selects the old dissipative zero-storage Rusanov node.
|
||||
Default engine behavior still uses volume fittings. Direction losses use local
|
||||
route tangents, with explicit TOML branch direction overrides supported. The
|
||||
loss coefficient is an uncalibrated engineering parameter; zero disables angle
|
||||
losses. Auto gain still defaults off.
|
||||
|
||||
The single-450 also supports these switches, but its two-port collector cannot
|
||||
exercise multi-branch turning. Selecting a zero-storage node there removes its
|
||||
collector-volume resonance. See [junction details](docs/JUNCTION_SOLVER.md).
|
||||
|
||||
Reference in New Issue
Block a user