all of the changes

This commit is contained in:
2026-10-23 18:29:51 +02:00
parent 4c435fdd76
commit 5607dcf2b5
73 changed files with 4365 additions and 2059 deletions

View File

@@ -0,0 +1,54 @@
#pragma once
#include "FluidSim/PipeProfile.hpp"
namespace fluidsim::port {
enum class SilencerType { StraightThrough, ExpansionResonator, Chambered };
struct SilencerConfig {
SilencerType type{SilencerType::Chambered};
float volume{.018f}, length{.65f}, core_diameter{.055f};
int chambers{2};
float passage_diameter{.058f};
float resistance{2.f}; // linear momentum decay, 1/s (packing surrogate)
float loss_coefficient{.35f}; // total dimensionless quadratic flow resistance
float diameter() const { return std::sqrt(4*volume/(pi*length)); }
};
struct ExhaustConfig {
bool enabled{true};
float inlet_length{1.4f}, outlet_length{.35f}, connecting_length{.8f}, diameter{.060f}, cell_length{.035f};
SilencerConfig resonator{SilencerType::StraightThrough,.006f,.40f,.060f,1,.060f,2, .1f};
SilencerConfig muffler{SilencerType::StraightThrough,.018f,.65f,.060f,1,.060f,4, .35f};
};
inline Pipe1D make_silenced_exhaust(const ExhaustConfig& c) {
std::vector<PipeSection> sections;
std::vector<float> linear, quadratic;
auto add=[&](float length,float a,float b,float r=0,float k=0) {
if(!std::isfinite(length)||length<=0||!std::isfinite(r)||r<0||!std::isfinite(k)||k<0)
throw std::invalid_argument("invalid silencer resistance or length");
sections.push_back({length,a,b}); linear.push_back(r); quadratic.push_back(k/length);
};
add(c.inlet_length,c.diameter,c.diameter);
if(c.enabled) for(int index=0;index<2;++index) {
if(index) add(c.connecting_length,c.diameter,c.diameter);
const auto& s=index?c.muffler:c.resonator;
if(!std::isfinite(s.volume)||s.volume<=0||!std::isfinite(s.length)||s.length<=0||s.chambers<1||s.chambers>16 || s.core_diameter<=0 || s.passage_diameter<=0)
throw std::invalid_argument("invalid silencer geometry");
const float d=s.type==SilencerType::StraightThrough?s.core_diameter:s.diameter();
const int n=s.type==SilencerType::Chambered?s.chambers:1;
float previous=c.diameter;
for(int i=0;i<n;++i) {
add(s.length*.1f/n,previous,d,s.resistance,s.loss_coefficient*.5f/n);
add(s.length*.8f/n,d,d,s.resistance,0);
const float end=i+1==n?c.diameter:s.passage_diameter;
add(s.length*.1f/n,d,end,s.resistance,s.loss_coefficient*.5f/n);
previous=end;
}
}
add(c.outlet_length,c.diameter,c.diameter);
auto pipe=make_profiled_pipe(sections,c.cell_length);
for(std::size_t i=0;i<sections.size();++i) {
const int n=int(std::ceil(sections[i].length/c.cell_length));
for(int j=0;j<n;++j) { pipe.linear_resistance.push_back(linear[i]);pipe.quadratic_resistance.push_back(quadratic[i]); }
}
return pipe;
}
}