all of the changes
This commit is contained in:
54
include/FluidSim/Silencer.hpp
Normal file
54
include/FluidSim/Silencer.hpp
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user