#include "FluidSim/Scenario.hpp" #include "FluidSim/ScenarioCatalog.hpp" #include "FluidSim/HelmholtzScenario.hpp" #include "FluidSim/PulseTestScenario.hpp" #include "FluidSim/TwoStrokeScenario.hpp" #include #include #include #include #include #include int main(int argc, char** argv) try { using namespace fluidsim::port; float duration_seconds = 1.0f; float throttle = 0.35f; std::string scenario_name = "twin"; auto two_stroke_config=scenario_example("yz-racing").two; PipeSolver pipe_solver=PipeSolver::Rusanov; for (int i = 1; i + 1 < argc; ++i) { const std::string option = argv[i]; if (option == "--seconds") duration_seconds = std::max(0.0f, std::strtof(argv[++i], nullptr)); else if (option == "--throttle") throttle = std::clamp(std::strtof(argv[++i], nullptr), 0.0f, 1.0f); else if (option == "--scenario") scenario_name = argv[++i]; else if (option == "--solver") { try { pipe_solver=parse_pipe_solver(argv[++i]); } catch(const std::exception& e) { std::cerr<(duration_seconds * sample_rate); const auto report_interval = static_cast(sample_rate / 10); if (scenario_name == "twin" || scenario_name == "b205" || scenario_name == "v8") { FourStrokeScenario scenario(sample_rate, scenario_name == "v8" ? FourStrokePreset::AmericanV8 : scenario_name == "b205" ? FourStrokePreset::SaabB205 : FourStrokePreset::Twin); scenario.set_pipe_solver(pipe_solver); scenario.throttle = throttle; std::cout << (scenario_name == "v8" ? "FluidSimCpp | American 5.0 V8 | throttle " : scenario_name == "b205" ? "FluidSimCpp | Saab B205 / 9-5 wagon | throttle " : "FluidSimCpp | 600 cc parallel twin | throttle ") << std::fixed << std::setprecision(0) << throttle * 100.0f << "%\n"; for (std::uint64_t i = 0; i < total_samples; ++i) { scenario.process(); if ((i + 1) % report_interval == 0 || i + 1 == total_samples) { std::cout << std::fixed << std::setprecision(1) << "t=" << static_cast(i + 1) / sample_rate << " s" << " rpm=" << scenario.crankshaft.omega * 60.0f / (2.0f * pi) << " speed=" << scenario.vehicle.speed * 3.6f << " km/h" << " gear=" << scenario.vehicle.current_gear << " cyl=" << scenario.cylinder1.pressure / 1000.0f << "/" << scenario.cylinder2.pressure / 1000.0f << " kPa" << " intake=" << scenario.intake_plenum.pressure() / 1000.0f << " kPa" << " exhaust=" << scenario.exhaust_collector.pressure() / 1000.0f << " kPa"; std::cout << '\n'; } } } else if (scenario_name == "two-stroke") { TwoStrokeScenario scenario(sample_rate, two_stroke_config); scenario.set_pipe_solver(pipe_solver); scenario.set_throttle(throttle); std::cout << "FluidSimCpp | 125 cc crankcase-scavenged two-stroke | throttle " << std::fixed << std::setprecision(0) << throttle * 100.0f << "%\n"; for (std::uint64_t i = 0; i < total_samples; ++i) { scenario.process(); if ((i + 1) % report_interval == 0 || i + 1 == total_samples) { const auto state = scenario.snapshot(); std::cout << std::fixed << std::setprecision(1) << "t=" << static_cast(i + 1) / sample_rate << " s rpm=" << state.rpm << " cyl=" << state.cylinder_pressure / 100000.0f << " bar" << " crankcase=" << state.crankcase_pressure / 1000.0f << " kPa" << " intake=" << state.intake_pressure / 1000.0f << " kPa" << " reed=" << (state.reed_open ? "open" : "closed") << '\n'; } } } else if (scenario_name == "helmholtz") { HelmholtzScenario scenario; std::cout << "FluidSimCpp | Helmholtz resonator | initial cavity 1.1 bar\n"; for (std::uint64_t i = 0; i < total_samples; ++i) { const float sample = scenario.process(); if ((i + 1) % report_interval == 0 || i + 1 == total_samples) std::cout << std::fixed << std::setprecision(1) << "t=" << static_cast(i + 1) / sample_rate << " s" << " cavity=" << scenario.cavity_pressure() / 1000.0f << " kPa" << " flow=" << scenario.open_end_flow() << " kg/s" << " audio=" << sample << '\n'; } } else if (scenario_name == "pulse") { PulseTestScenario scenario; std::cout << "FluidSimCpp | pressure pulse in a 2 m pipe\n"; for (std::uint64_t i = 0; i < total_samples; ++i) { const float sample = scenario.process(); if ((i + 1) % report_interval == 0 || i + 1 == total_samples) std::cout << std::fixed << std::setprecision(1) << "t=" << static_cast(i + 1) / sample_rate << " s" << " left=" << scenario.pipe().state(0).pressure / 1000.0f << " kPa" << " right=" << scenario.pipe().state(199).pressure / 1000.0f << " kPa" << " flow=" << scenario.pipe().state(199).velocity << " m/s" << " audio=" << sample << '\n'; } } else { std::cerr << "Unknown scenario '" << scenario_name << "'. Choose twin, two-stroke, b205, v8, helmholtz, or pulse.\n"; return 2; } return 0; } catch(const std::exception& error) { std::cerr<