37 #include "Exception.hpp" 38 #include "ReplicatableVector.hpp" 39 #include "PetscTools.hpp" 40 #include "VesselSegment.hpp" 41 #include "FlowSolver.hpp" 42 #include "UnitCollection.hpp" 43 #include "VesselNetworkGraphCalculator.hpp" 45 template<
unsigned DIM>
50 mNodeVesselConnectivity(),
51 mNodeNodeConnectivity(),
52 mBoundaryConditionNodeIndices(),
53 mUnconnectedNodeIndices(),
55 mUseDirectSolver(true),
61 template<
unsigned DIM>
67 template <
unsigned DIM>
74 template<
unsigned DIM>
79 EXCEPTION(
"A vessel network is required before calling SetUp");
84 unsigned num_nodes =
mNodes.size();
88 mpLinearSystem = boost::shared_ptr<LinearSystem>(
new LinearSystem(num_nodes, max_branches + 1));
99 std::vector<boost::shared_ptr<VesselNode<DIM> > > boundary_condition_nodes;
100 for (
unsigned node_index = 0; node_index < num_nodes; node_index++)
102 if (
mNodes[node_index]->GetFlowProperties()->IsInputNode()
103 ||
mNodes[node_index]->GetFlowProperties()->IsOutputNode())
105 boundary_condition_nodes.push_back(
mNodes[node_index]);
116 std::vector<bool> connected = p_graph_calculator->IsConnected(boundary_condition_nodes,
mNodes);
118 for (
unsigned node_index = 0; node_index < num_nodes; node_index++)
120 if (!connected[node_index])
131 template<
unsigned DIM>
137 template<
unsigned DIM>
143 template<
unsigned DIM>
156 std::vector<units::quantity<unit::flow_impedance> > scaled_impedances;
157 units::quantity<unit::flow_impedance> max_impedance = 0.0 * unit::pascal_second_per_metre_cubed;
158 units::quantity<unit::flow_impedance> min_impedance = DBL_MAX * unit::pascal_second_per_metre_cubed;
159 for (
unsigned vessel_index = 0; vessel_index <
mVessels.size(); vessel_index++)
161 units::quantity<unit::flow_impedance> impedance =
mVessels[vessel_index]->GetFlowProperties()->GetImpedance();
162 if (impedance <= 0.0 * unit::pascal_second_per_metre_cubed)
164 EXCEPTION(
"Impedance should be a positive number.");
166 if(impedance > max_impedance)
168 max_impedance = impedance;
170 if(impedance < min_impedance)
172 min_impedance = impedance;
174 scaled_impedances.push_back(impedance);
176 units::quantity<unit::flow_impedance> multiplier = (max_impedance + min_impedance) / 2.0;
179 for (
unsigned node_index = 0; node_index <
mNodes.size(); node_index++)
186 if (is_bc_node or is_unconnected_node)
189 if(
mNodes[node_index]->GetFlowProperties()->UseVelocityBoundaryCondition())
200 units::quantity<unit::flow_impedance> impedance = scaled_impedances[
mNodeVesselConnectivity[node_index][vessel_index]];
203 mpLinearSystem->AddToMatrixElement(node_index, node_index, -multiplier / impedance);
217 units::quantity<unit::flow_rate> flow_rate = boost::units::fabs(p_vessel->GetFlowProperties()->GetFlowRate());
218 units::quantity<unit::flow_impedance> impedance = p_vessel->GetFlowProperties()->GetImpedance();
219 double pressure_drop = flow_rate * impedance/ unit::pascals;
231 template<
unsigned DIM>
241 Vec solution = PetscTools::CreateVec(
mNodes.size());
245 ReplicatableVector a(solution);
247 std::cout <<
"****************" << std::endl;
248 for (
unsigned node_index = 0; node_index <
mNodes.size(); node_index++)
250 std::cout <<
"pressure" << a[node_index] << std::endl;
251 mNodes[node_index]->GetFlowProperties()->SetPressure(a[node_index] * unit::pascals);
253 std::cout <<
"****************" << std::endl;
256 for (
unsigned vessel_index = 0; vessel_index <
mVessels.size(); vessel_index++)
258 units::quantity<unit::pressure> start_node_pressure =
mVessels[vessel_index]->GetStartNode()->GetFlowProperties()->GetPressure();
259 units::quantity<unit::pressure> end_node_pressure =
mVessels[vessel_index]->GetEndNode()->GetFlowProperties()->GetPressure();
260 units::quantity<unit::flow_rate> flow_rate = (start_node_pressure - end_node_pressure) /
mVessels[vessel_index]->GetFlowProperties()->GetImpedance();
263 if (fabs(flow_rate) < pow(10, -20)*unit::metre_cubed_per_second)
265 flow_rate = 0.0 * unit::metre_cubed_per_second;
268 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments =
mVessels[vessel_index]->GetSegments();
269 units::quantity<unit::pressure> pressure = start_node_pressure;
270 for (
unsigned segment_index = 0; segment_index < segments.size() - 1; segment_index++)
272 pressure -= segments[segment_index]->GetFlowProperties()->GetImpedance() * flow_rate;
273 segments[segment_index]->GetNode(1)->GetFlowProperties()->SetPressure(pressure);
274 segments[segment_index]->GetFlowProperties()->SetFlowRate(flow_rate);
276 segments[segments.size() - 1]->GetFlowProperties()->SetFlowRate(flow_rate);
280 PetscTools::Destroy(solution);
std::vector< boost::shared_ptr< VesselNode< DIM > > > mNodes
std::vector< unsigned > mBoundaryConditionNodeIndices
void SetUseDirectSolver(bool useDirectSolver)
boost::shared_ptr< LinearSystem > mpLinearSystem
static boost::shared_ptr< FlowSolver< DIM > > Create()
std::vector< std::vector< unsigned > > mNodeVesselConnectivity
boost::shared_ptr< VesselNetwork< DIM > > mpVesselNetwork
std::vector< unsigned > mUnconnectedNodeIndices
static boost::shared_ptr< VesselNetworkGraphCalculator< DIM > > Create()
std::vector< boost::shared_ptr< Vessel< DIM > > > mVessels
void SetVesselNetwork(boost::shared_ptr< VesselNetwork< DIM > > pVesselNetwork)
std::vector< std::vector< unsigned > > mNodeNodeConnectivity
void Update(bool runSetup=false)