This commit is contained in:
2026-10-23 03:00:20 +02:00
parent 589d22aa5e
commit 7a5c77c1c8
31 changed files with 1196 additions and 44 deletions

View File

@@ -99,6 +99,7 @@ int main(int argc, char **argv) {
float seconds = 6, pedal = 1;
TwoStrokeConfig config;
bool turbo_enabled = false;
std::string turbo_name;
for (int i = 1; i < argc; i++) {
std::string key = argv[i];
if (i + 1 >= argc)
@@ -113,8 +114,9 @@ int main(int argc, char **argv) {
else if (key == "--throttle")
pedal = std::stof(value);
else if (key == "--turbo") {
if (value != "none" && value != "vz21") throw std::runtime_error("choose none or vz21 turbo");
turbo_enabled = value == "vz21";
if (value != "none" && value != "vz21" && value != "gt17") throw std::runtime_error("choose none, vz21 or gt17 turbo");
turbo_name = value;
turbo_enabled = value != "none";
}
else if (key == "--exhaust") {
if (value == "racing") config.exhaust = TwoStrokeExhaust::Racing;
@@ -143,11 +145,16 @@ int main(int argc, char **argv) {
if (!std::filesystem::path(prefix).parent_path().empty())
std::filesystem::create_directories(std::filesystem::path(prefix).parent_path());
const int frames = int(std::lround(seconds * 44100));
if (turbo_enabled && scenario != "twin") throw std::runtime_error("turbo test uses the twin scenario");
if (turbo_name.empty() && scenario == "b205") turbo_enabled = true;
if (!turbo_name.empty() && turbo_name!="none" &&
!((turbo_name=="vz21" && scenario=="twin") || (turbo_name=="gt17" && scenario=="b205")))
throw std::runtime_error("use gt17 with b205 or vz21 with twin");
if (scenario == "twin" && turbo_enabled)
capture<TurboTwinScenario>(prefix, frames, pedal, selected, config);
else if (scenario == "twin")
capture<FourStrokeTwinScenario>(prefix, frames, pedal, selected, config);
else if (scenario == "b205" && turbo_enabled)
capture<SaabTurboScenario>(prefix, frames, pedal, selected, config);
else if (scenario == "b205")
capture<SaabB205Scenario>(prefix, frames, pedal, selected, config);
else if (scenario == "two-stroke")

View File

@@ -0,0 +1,75 @@
#include "FluidSim/Scenario.hpp"
#include "FluidSim/TwoStrokeScenario.hpp"
#include "FluidSim/HelmholtzScenario.hpp"
#include "FluidSim/PulseTestScenario.hpp"
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
using namespace fluidsim::port;
template<class S, class Control> 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<double>(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<FourStrokeScenario>(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){});
}
}

View File

@@ -1,20 +1,37 @@
#include "FluidSim/Fluid.hpp"
#include "FluidSim/Scenario.hpp"
#include "FluidSim/TwoStrokeScenario.hpp"
#include "FluidSim/HelmholtzScenario.hpp"
#include "FluidSim/PulseTestScenario.hpp"
#include <barrier>
#include <chrono>
#include <iostream>
#include <thread>
using namespace fluidsim::port;
int main() {
for (auto size : {std::pair{6, 10}, std::pair{64, 256}}) {
const int steps = 1000;
for (std::string name : {"twin", "turbo", "b205", "two-stroke-racing", "two-stroke-straight", "helmholtz", "pulse", "large"}) {
std::vector<Pipe1D> geometry;
if (name == "large") {
for (int i=0; i<64; ++i) geometry.emplace_back(.001f, 2, 256);
} else if (name == "helmholtz") {
HelmholtzScenario s; geometry.push_back(s.neck());
} else if (name == "pulse") {
PulseTestScenario s; geometry.push_back(s.pipe());
} else if (name.starts_with("two-stroke")) {
TwoStrokeConfig config;
config.exhaust = name == "two-stroke-straight" ? TwoStrokeExhaust::Straight : TwoStrokeExhaust::Racing;
TwoStrokeScenario s(44100, config); geometry = s.pipes;
} else {
FourStrokeScenario s(44100, name == "b205" ? FourStrokePreset::SaabB205 : FourStrokePreset::Twin, name == "turbo");
geometry = s.pipes;
}
const int steps = 4000;
for (int workers : {1, 2, 4}) {
std::vector<Pipe1D> p;
for (int i = 0; i < size.first; i++)
p.emplace_back(.001f, 2, size.second);
auto p = geometry;
auto advance = [&](int worker) {
for (int k = worker; k < size.first; k += workers) {
for (int k = worker; k < static_cast<int>(p.size()); k += workers) {
auto &a = p[k];
auto l = a.state(0), r = a.state(size.second - 1);
auto l = a.state(0), r = a.state(static_cast<int>(a.cells.size()) - 1);
l.velocity = -l.velocity;
r.velocity = -r.velocity;
a.left_ghost = l;
@@ -47,7 +64,7 @@ int main() {
double sum = 0;
for (auto &q : p)
sum += q.state(0).pressure;
std::cout << "pipes=" << size.first << " cells/pipe=" << size.second << " workers=" << workers
std::cout << "scenario=" << name << " pipes=" << p.size() << " workers=" << workers
<< " steps=" << steps << " seconds=" << sec << " checksum=" << sum << '\n';
}
}