35 lines
1.6 KiB
C++
35 lines
1.6 KiB
C++
#pragma once
|
|
#include "FluidSim/Fluid.hpp"
|
|
#include <span>
|
|
|
|
namespace fluidsim::port {
|
|
struct JunctionEnd { int pipe; bool left; float discharge{1.f}; };
|
|
// Finite-volume N-port fitting: its specified physical volume stores gas and
|
|
// energy. All ports share pressure and mixture, with bidirectional nozzle flow.
|
|
// T, Y, cross and collectors share this model; angles require calibrated losses.
|
|
class Junction : public Volume0D {
|
|
public:
|
|
using Volume0D::Volume0D;
|
|
void connect(BoundarySystem& boundaries, const std::vector<Pipe1D>& pipes,
|
|
std::span<const JunctionEnd> ends) {
|
|
if(connected_ || ends.size()<2) throw std::invalid_argument("junction needs at least two distinct ends and one connection call");
|
|
for(std::size_t i=0;i<ends.size();++i) {
|
|
const auto& e=ends[i];
|
|
if(e.pipe<0 || std::size_t(e.pipe)>=pipes.size() || !std::isfinite(e.discharge) || e.discharge<=0 || e.discharge>1)
|
|
throw std::invalid_argument("invalid junction endpoint");
|
|
for(std::size_t j=0;j<i;++j) if(e.pipe==ends[j].pipe && e.left==ends[j].left)
|
|
throw std::invalid_argument("duplicate junction endpoint");
|
|
}
|
|
for(const auto& e:ends) {
|
|
const auto& pipe=pipes[e.pipe];
|
|
areas_.push_back(pipe.cell_area(e.left?0:int(pipe.cells.size())-1));
|
|
boundaries.add_orifice(create_port(),e.pipe,e.left,areas_.back(),e.discharge);
|
|
}
|
|
connected_=true;
|
|
}
|
|
private:
|
|
std::deque<float> areas_; // stable addresses for boundary area references
|
|
bool connected_{};
|
|
};
|
|
}
|