Add turbocharged twin scenario and cross-platform test harness
This commit is contained in:
213
README.md
213
README.md
@@ -1,7 +1,16 @@
|
||||
# FluidSimCpp
|
||||
|
||||
Native C++20 port of FluidSim. The C# application remains the reference while
|
||||
the component models and behavior are being ported and checked against it.
|
||||
FluidSimCpp aims to reproduce sound from a physically accurate simulation of
|
||||
compressible flow in pipes and connected volumes, sampled at 44,100 Hz. Each
|
||||
audio sample advances physical time by 1/44100 second; adaptive internal
|
||||
substeps resolve the fluid dynamics. Every subsystem must ultimately follow
|
||||
physical laws with explicit units, assumptions and validation. Matching the
|
||||
C# reference is a regression aid, not proof of physical accuracy.
|
||||
|
||||
This is a work in progress. Physical correctness is the acceptance goal, not
|
||||
a claim about all current models. Validation must include conservation of
|
||||
mass, momentum and energy, analytic acoustic modes, boundary reflection and
|
||||
radiation, thermodynamics and convergence under time/space refinement.
|
||||
|
||||
## Build (Windows / Visual Studio)
|
||||
|
||||
@@ -14,6 +23,28 @@ cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
## Build (Linux / Windows presets)
|
||||
|
||||
The repository includes CMake presets and VS Code tasks for the desktop app.
|
||||
Install CMake 3.28 or newer, a C++20 compiler, and Make on Linux. On Windows,
|
||||
install Visual Studio 2022 with the C++ desktop workload and CMake. Configure
|
||||
and build from the project root with:
|
||||
|
||||
```sh
|
||||
cmake --preset linux
|
||||
cmake --build --preset linux --target fluidsim_desktop
|
||||
```
|
||||
|
||||
On Windows, use the `windows` preset in place of `linux`. CMake fetches SFML
|
||||
3.0.2 if it is not installed, so the first desktop configure needs network
|
||||
access. In VS Code, choose **FluidSim desktop** in Run and Debug; the
|
||||
same configuration selects the Windows executable on Windows. The `.vscode`
|
||||
build task configures and builds the desktop target before launching it.
|
||||
|
||||
The UI uses the optional Fira Code Nerd Font file from `../fonts` when present.
|
||||
Without it, the simulation still runs but text labels are hidden. To bundle a
|
||||
font from another location, configure with `-DFLUIDSIM_FONT_FILE=/path/to/font.ttf`.
|
||||
|
||||
The first configure fetches SFML 3.0.2 with CMake FetchContent for the desktop
|
||||
window and audio stream. `-DFLUIDSIM_BUILD_DESKTOP=OFF` builds only the headless
|
||||
runner and physics tests.
|
||||
@@ -47,6 +78,111 @@ cmake --build build-msvc --target fluidsim_parity_trace
|
||||
.\verification\Compare-ScenarioTrace.ps1
|
||||
```
|
||||
|
||||
## Audio fidelity and playback
|
||||
|
||||
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
|
||||
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.
|
||||
The callback never advances physical time to conceal missing samples.
|
||||
|
||||
The source is a linear compact-monopole approximation,
|
||||
`p(r,t) = (d mass_flow/dt)/(4*pi*r)`. Intake and exhaust have separate static
|
||||
positions, fractional-sample propagation delays, inverse-distance spreading,
|
||||
and left/right ear paths. Playback calibration is 200 Pa per device full scale;
|
||||
this is not calibrated speaker SPL. A second-order 6 kHz monitoring filter
|
||||
reduces sharp sample-to-sample transients without saturation or synthetic bangs.
|
||||
A roughly 3.5 Hz device DC blocker and final PCM clipping protection remain.
|
||||
Use 1x playback for acoustic evaluation.
|
||||
|
||||
The default environment is a nearby wall. Press **R** to cycle dry, field,
|
||||
wall and woodland. Ground/wall image paths provide early reflections; the
|
||||
woodland scatterers and decaying feedback-delay tail are approximate effects,
|
||||
not validated outdoor acoustics. Synthetic mechanical noise remains optional.
|
||||
The compact source does not implement pipe-end radiation impedance, validated
|
||||
directivity, or exhaust afterfire chemistry. Filtering cannot recover aliased
|
||||
source information. See [audio verification](verification/AUDIO_RENDERING.md)
|
||||
for tests, capture commands, limitations and measured transient reductions.
|
||||
|
||||
Launching `fluidsim_desktop` without `--scenario` opens a small scenario menu.
|
||||
Click the twin, YZ125 or Saab B205 card to start, or select with Up/Down and press Enter.
|
||||
Escape closes the menu. Simulation and audio start after selection. Passing
|
||||
`--scenario twin`, `--scenario two-stroke` or `--scenario b205` bypasses the menu; `--scene` and
|
||||
`--exhaust` options also apply when choosing through the menu.
|
||||
|
||||
To test the two desktop engines from the repository root:
|
||||
|
||||
```sh
|
||||
cmake --build build-desktop --target fluidsim_desktop -j 4
|
||||
./build-desktop/fluidsim_desktop --scenario two-stroke --scene wall
|
||||
# Or:
|
||||
./build-desktop/fluidsim_desktop --scenario twin --scene field
|
||||
```
|
||||
|
||||
Hold **W** for throttle, use **Up/Down** to adjust the persistent pedal request,
|
||||
**Space** to restore real-time playback and **R** to change environment. 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
|
||||
RPM). Start in neutral, hold **C** to disengage the clutch, press **D** for first
|
||||
gear, apply throttle and release **C** to pull away. **D/A** shift up/down;
|
||||
**Z** selects neutral. Left/right adjust an external engine load, not a wheel
|
||||
brake. The graph records simulated crank power/torque, not measured wheel power.
|
||||
|
||||
The two-stroke now uses a YZ125 baseline: published 2022 primary, gearbox and
|
||||
final reductions, 54 x 54.5 mm geometry, and an estimated racing expansion
|
||||
chamber. Ports use piston-uncovered window areas. The pipe display follows
|
||||
physical cell diameter and length. Compare exhausts with `--exhaust racing`
|
||||
(default) or `--exhaust straight`; the desktop, CLI and WAV capture tool accept
|
||||
this option. See [YZ125 verification](verification/YZ125_BASELINE.md) for the
|
||||
geometry, assumptions, speed sweep and remaining unloaded-RPM limitation.
|
||||
|
||||
## Twin with a VZ21-size turbo
|
||||
|
||||
Choose **600 cc twin + VZ21-size turbo** in the startup menu, or bypass it:
|
||||
|
||||
```sh
|
||||
./build-desktop/fluidsim_desktop --scenario twin --turbo vz21 --scene field
|
||||
./build-audit/fluidsim_cpp --scenario twin --turbo vz21 --seconds 5 --throttle 0.7
|
||||
```
|
||||
|
||||
`Turbocharger` connects to four existing pipe ends and couples turbine and
|
||||
compressor work through a rigid rotor. Small housing volumes preserve unsteady
|
||||
exhaust pressure. Backpressure, charge temperature and spool speed emerge from
|
||||
flow restrictions and energy exchange. A pressure-can/spring wastegate opens a
|
||||
bypass; no boost pressure is imposed. HUD pressures are absolute. The default
|
||||
unboosted twin is unchanged unless `--turbo vz21` is selected.
|
||||
|
||||
This is an estimated VZ21-size model, not a measured turbo map. Engine exhaust
|
||||
pulses are implemented; blade-passing whistle/wakes are still pending. The
|
||||
seven-second twin transient and all nine CTest suites passed. Sustained high-load
|
||||
performance is close to, or slower than, real time in the current benchmark;
|
||||
watch the underrun counter during testing. See
|
||||
[turbo verification](verification/TURBO_VZ21.md) for assumptions and results.
|
||||
|
||||
## Saab B205 / 9-5 wagon baseline
|
||||
|
||||
Select **Saab B205 / 9-5 wagon** from the desktop menu, or launch directly:
|
||||
|
||||
```sh
|
||||
./build-desktop/fluidsim_desktop --scenario b205 --scene field
|
||||
./build-audit/fluidsim_cpp --scenario b205 --seconds 4 --throttle 0.5
|
||||
```
|
||||
|
||||
The shared four-stroke scenario now supports two or four cylinders. The B205
|
||||
uses 90 x 78 mm geometry, 8.8:1 compression, two intake/two exhaust valves per
|
||||
cylinder and 1-3-4-2 firing order. Four intake runners and four exhaust headers
|
||||
connect shared plenums and a tailpipe. The vehicle approximates a 9-5 wagon:
|
||||
1675 kg with driver, five-speed manual, FM55 B05 overall ratios
|
||||
13.70 / 7.12 / 4.77 / 3.62 / 2.67, and 4.05 final drive. No sixth gear is offered.
|
||||
Controls and dyno match the other scenarios. There is no turbo system yet;
|
||||
this is an atmospheric-breathing B205 geometry baseline. Pipe/cam dimensions,
|
||||
friction, idle/ignition maps, clutch, drag and loaded tire radius are estimates.
|
||||
It does not reproduce factory turbo power or turbo/exhaust acoustics.
|
||||
See [B205 verification](verification/B205_BASELINE.md) for sources and checks.
|
||||
|
||||
## Current port status
|
||||
|
||||
The C++ core now includes the shared `EngineCylinder` model with four-stroke and
|
||||
@@ -59,17 +195,16 @@ intake/exhaust radiation, outdoor feedback-delay reverb, optional mechanical
|
||||
noise, a lock-free simulation audio buffer, a `SoundEngine` lifecycle wrapper,
|
||||
and an SFML desktop frontend. The shared 50-RPM-bin dyno history and graph are
|
||||
also ported. A crankcase-scavenged 125 cc two-stroke scenario is available in
|
||||
the core.
|
||||
the core and desktop, with an ECU, finite-response throttle and dynamic reed.
|
||||
|
||||
This is still an in-progress port, not a claimed complete replacement. All four
|
||||
current C# scenarios (600 cc twin, 125 cc two-stroke, Helmholtz resonator, and
|
||||
pressure pulse) have headless C++ counterparts and can be selected by the CLI.
|
||||
Remaining parity work includes completing the C# drawing/diagnostic controls in
|
||||
the desktop UI and resolving numerical differences reported by the comparison
|
||||
harness. The latest MSVC build completed, CTest passed, and the one-second
|
||||
headless twin run completed with finite output. The desktop executable opened,
|
||||
but its client area rendered blank in the captured run, so desktop rendering is
|
||||
not yet verified.
|
||||
harness. Earlier Windows builds passed CTest, but the current audio and two-stroke
|
||||
changes still need Windows runtime verification. The Linux desktop builds and
|
||||
runs; installed-font fallbacks provide labels when no bundled font is present.
|
||||
|
||||
The one-second twin trace remains substantially outside its 1% tolerance. The
|
||||
latest comparison's largest relative difference is 40.6745 for cylinder 1
|
||||
@@ -81,3 +216,67 @@ geometry and valve timing, dyno-bin interpolation, configurable 0-D volume
|
||||
thermodynamics, crankcase and atmosphere state, profiled-pipe geometry,
|
||||
inertive and closed boundaries, gearing and clutch momentum transfer, finite
|
||||
runs for every scenario, and finite audio/reverb output.
|
||||
|
||||
## ECU and throttle control
|
||||
|
||||
Both desktop engines use `Ecu` (`include/FluidSim/Ecu.hpp`). The desktop and
|
||||
CLI throttle values are pedal requests; the actual throttle is advanced every
|
||||
simulation sample, independently of rendering. Opening and closing use an
|
||||
80 ms first-order actuator response and a maximum travel rate of two full
|
||||
travels per second. An ideal butterfly's projected opening determines orifice
|
||||
area continuously; shaft obstruction and edge leakage are not modeled.
|
||||
|
||||
The ECU uses ideal sensors and direct access to trapped fresh-air mass at
|
||||
intake-valve closure to calculate each cylinder's fuel dose. This explicitly
|
||||
permitted idealization replaces injector flow/duty-cycle and fuel-film models.
|
||||
The nominal AFR is 14.7, enriched progressively toward 12.8 above 70% throttle.
|
||||
A PI idle controller targets 1800 RPM with filtered RPM feedback, bounded idle
|
||||
authority and anti-windup. Overrun fuel cut engages above 3500 RPM on a closed
|
||||
pedal and restores fuel below 2400 RPM to catch idle. The twin's rev limiter cuts fuel
|
||||
and spark at 10000 RPM, recovering below 9750 RPM. The two-stroke has no rev
|
||||
limiter; its idle, overrun and sensor-fault controls remain active. Invalid sensor readings
|
||||
inhibit fuel. A simple RPM-based ignition advance map is provided. An already
|
||||
burning charge completes combustion when a cut begins.
|
||||
|
||||
All ECU parameters are accessible calibrations, not measured engine maps.
|
||||
There is no starter motor, automatic restart, knock sensor, lambda sensor,
|
||||
catalyst, cold-start temperature model or injector electrical model. Idle
|
||||
control can still stall under excessive load and does not impose crankshaft
|
||||
speed or add artificial sustaining torque. Existing combustion/thermal models
|
||||
remain approximations; ECU changes do not establish their physical accuracy.
|
||||
The two-stroke doses fuel after the last scavenging port closes, targets
|
||||
3000 RPM idle, and uses idle ignition trim in addition to throttle control. Its
|
||||
reed is a damped lumped cantilever model with finite opening time and seating
|
||||
contacts. Cylinder and crankcase moving-volume work use adiabatic energy changes.
|
||||
Reed material, combustion and controller parameters still require calibration.
|
||||
C# trace parity is intentionally changed by these control and physics changes.
|
||||
|
||||
VS Code's default build task builds the desktop through CMake. Use
|
||||
Ctrl+Shift+B to build, or choose **FluidSim desktop** in Run and Debug and
|
||||
press F5 to build and run. The single-file C/C++ editor Run shortcut is disabled
|
||||
because this project requires multiple sources and SFML; IntelliSense gets
|
||||
include paths from CMake Tools. Open the repository root as the VS Code folder.
|
||||
|
||||
## Fluid physics verification and performance
|
||||
|
||||
See [the fluid physics audit](verification/FLUID_PHYSICS_AUDIT.md) for corrected
|
||||
conservation/boundary equations, analytic tests, measured performance and
|
||||
remaining model limits. The validation executable exercises 29 cases covering
|
||||
walls, pressure outlets, nozzles, inertance, pipe joints, volumes, species,
|
||||
acoustic modes, shocks and invalid states. The default coupled solver updates
|
||||
components on every substep, uses area-weighted shared fluxes and matches
|
||||
orifice discharge to duct characteristics. These changes intentionally alter
|
||||
older C# trace comparisons.
|
||||
|
||||
Build headless with CMake, then run `ctest --test-dir build-audit
|
||||
--output-on-failure`. `fluidsim_physics_benchmark` and
|
||||
`fluidsim_thread_benchmark` reproduce the performance experiments.
|
||||
`FLUIDSIM_ENABLE_SIMD=OFF` provides a scalar comparison; fast-math is not used.
|
||||
Production fluid solving remains serial because threading was slower for the
|
||||
current small pipe graph. SIMD and scalar Linux checks are covered; Windows
|
||||
execution is still unverified.
|
||||
|
||||
The twin intake is supplied by an explicit 300 K atmospheric reservoir rather
|
||||
than a pressure-only boundary with extrapolated entropy. The repeated-blip
|
||||
`fluidsim_intake_regression` checks fresh-air supply and pressure/idle recovery.
|
||||
Manifold vacuum at closed throttle remains part of the simulated pumping cycle.
|
||||
|
||||
Reference in New Issue
Block a user