#include "FluidSim/Scenario.hpp" #include "FluidSim/TwoStrokeScenario.hpp" #include "FluidSim/HelmholtzScenario.hpp" #include "FluidSim/PulseTestScenario.hpp" #include #include #include #include using namespace fluidsim::port; template void run(const char* name, S& s, int seconds, Control control) { double checksum = 0; std::uint64_t previous_iterations = 0; for (int second = 0; second < seconds; ++second) { const auto begin = std::chrono::steady_clock::now(); for (int i = 0; i < 44100; ++i) { control(second); auto value = s.process(); if constexpr (requires { value.left; }) checksum += value.left; else checksum += value; } const double elapsed = std::chrono::duration(std::chrono::steady_clock::now()-begin).count(); std::cout << name << ',' << second+1 << ',' << elapsed << ',' << checksum << std::endl; if constexpr (requires { s.pipes; }) { unsigned tiny = 0; for (const auto& pipe : s.pipes) for (const auto& cell : pipe.cells) for (float value : {cell.rho, cell.momentum, cell.energy, cell.air}) tiny += std::fpclassify(value) == FP_SUBNORMAL; std::cerr << name << " second=" << second+1 << " subnormal_cell_fields=" << tiny << '\n'; } if constexpr (requires { s.snapshot().boundary_iterations; }) { const auto state = s.snapshot(); std::cerr << name << " iterations_per_frame=" << (state.boundary_iterations-previous_iterations)/44100.0 << '\n'; previous_iterations = state.boundary_iterations; } } } int main(int argc, char** argv) { const int seconds = argc > 1 ? std::stoi(argv[1]) : 6; const std::string mode = argc > 2 ? argv[2] : "pedal"; const std::string only = argc > 3 ? argv[3] : "all"; auto pedal = [&](int second) { return mode == "idle" ? 0.0f : mode == "transient" && (second == 0 || second >= seconds-2) ? 0.0f : .7f; }; std::cout << "scenario,second,wall_seconds,checksum\n"; for (auto name : {"twin", "turbo", "b205", "b205-gt17"}) { if (only != "all" && only != name) continue; auto s = std::make_unique(44100, std::string(name).starts_with("b205") ? FourStrokePreset::SaabB205 : FourStrokePreset::Twin, std::string(name)=="turbo" || std::string(name)=="b205-gt17"); s->throttle = .7f; run(name, *s, seconds, [&](int second) { s->throttle = pedal(second); if (mode == "loaded") s->crankshaft.omega = (std::string(name)=="b205-gt17" ? 5500 : 7000) * 2*pi/60; }); } for (bool racing : {true, false}) { if (only != "all" && only != (racing ? "two-stroke-racing" : "two-stroke-straight")) continue; TwoStrokeConfig config; config.exhaust = racing ? TwoStrokeExhaust::Racing : TwoStrokeExhaust::Straight; TwoStrokeScenario s(44100, config); s.set_throttle(.7f); run(racing ? "two-stroke-racing" : "two-stroke-straight", s, seconds, [&](int second) { s.set_throttle(pedal(second)); if (mode == "loaded") s.crankshaft.omega = 10000 * 2*pi/60; }); } if (only == "all" || only == "helmholtz") { HelmholtzScenario helmholtz; run("helmholtz", helmholtz, seconds, [](int){}); } if (only == "all" || only == "pulse") { PulseTestScenario pulse; run("pulse", pulse, seconds, [](int){}); } }