#include "FluidSim/TwoStrokeScenario.hpp" #include #include #include using namespace fluidsim::port; int main() { std::cout << "exhaust,rpm,shaft_kW,shaft_Nm,firings_per_revolution,carb_afr,crankcase_afr,repairs,wall_seconds\n"; for (auto exhaust : {TwoStrokeExhaust::Straight, TwoStrokeExhaust::Racing}) { for (float rpm : {6000.f, 8000.f, 10000.f, 12000.f, 14000.f, 17000.f}) { TwoStrokeConfig config; config.exhaust = exhaust; TwoStrokeScenario s(44100, config); s.set_throttle(1); const auto start = std::chrono::steady_clock::now(); double torque = 0, power = 0; std::uint64_t initial_firings = 0; // An ideal absorbing/motoring dyno imposes speed, exchanging shaft // work externally. It never changes gas energy or adds combustion. for (int i = 0; i < 44100; ++i) { s.crankshaft.omega = rpm * 2 * pi / 60; s.process(); if (i == 22049) initial_firings = s.cylinder.combustion_count(); if (i >= 22050) { torque += s.crankshaft.average_torque / 22050; power += s.crankshaft.average_power / (22050 * 1000.f); } } unsigned long long repairs = 0; for (const auto& pipe : s.pipes) repairs += pipe.positivity_repairs; const double wall = std::chrono::duration(std::chrono::steady_clock::now()-start).count(); std::cout << (exhaust == TwoStrokeExhaust::Racing ? "racing" : "straight") << ',' << rpm << ',' << power << ',' << torque << ',' << (s.cylinder.combustion_count()-initial_firings) / (rpm / 120) << ',' << s.carburetor.indicated_afr() << ',' << s.crankcase.mass() * s.crankcase.air_fraction() / std::max(s.crankcase.fuel_mass(), 1e-12f) << ',' << repairs << ',' << wall << std::endl; } } }