36 #include "SmartPointers.hpp" 37 #include "Exception.hpp" 38 #include "UblasIncludes.hpp" 39 #include "SimulationTime.hpp" 42 template<
unsigned DIM>
46 mNodesUpToDate(false),
54 template<
unsigned DIM>
61 if (segments.size() > 1)
63 for (
unsigned i = 1; i <
mSegments.size(); i++)
67 EXCEPTION(
"Input vessel segments are not attached in the correct order.");
71 for (
unsigned i = 0; i <
mSegments.size(); i++)
73 for (
unsigned j = 0; j <
mSegments.size(); j++)
75 if (i != j && i != j - 1 && i != j + 1)
79 EXCEPTION(
"Input vessel segments are not correctly connected.");
89 template<
unsigned DIM>
99 EXCEPTION(
"Insufficient number of nodes to define a segment.");
103 for (
unsigned i = 1; i < nodes.size(); i++)
111 template<
unsigned DIM>
122 template<
unsigned DIM>
127 template<
unsigned DIM>
130 boost::shared_ptr<Vessel<DIM> > pSelf(
new Vessel<DIM>(pSegment));
133 pSegment->AddVessel(pSelf->shared_from_this());
137 template<
unsigned DIM>
140 boost::shared_ptr<Vessel<DIM> > pSelf(
new Vessel<DIM>(segments));
143 for (
unsigned i = 0; i < segments.size(); i++)
145 segments[i]->AddVessel(pSelf->shared_from_this());
150 template<
unsigned DIM>
153 boost::shared_ptr<Vessel<DIM> > pSelf(
new Vessel<DIM>(nodes));
155 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = pSelf->GetSegments();
158 for (
unsigned i = 0; i < segments.size(); i++)
160 segments[i]->AddVessel(pSelf->shared_from_this());
165 template<
unsigned DIM>
168 boost::shared_ptr<Vessel<DIM> > pSelf(
new Vessel<DIM>(pStartNode, pEndNode));
170 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = pSelf->GetSegments();
173 for (
unsigned i = 0; i < segments.size(); i++)
175 segments[i]->AddVessel(pSelf->shared_from_this());
180 template<
unsigned DIM>
186 pSegment->AddVessel(
Shared());
187 if(pSegment->GetNode(0) ==
mSegments[0]->GetNode(0))
191 else if(pSegment->GetNode(1) ==
mSegments[0]->GetNode(0))
195 else if(pSegment->GetNode(0) ==
mSegments[0]->GetNode(1))
199 else if(pSegment->GetNode(1) ==
mSegments[0]->GetNode(1))
205 EXCEPTION(
"Input vessel segment does not coincide with any end of the vessel.");
210 if (pSegment->IsConnectedTo(
mSegments.back()))
213 pSegment->AddVessel(
Shared());
216 else if (pSegment->IsConnectedTo(
mSegments.front()))
219 pSegment->AddVessel(
Shared());
224 EXCEPTION(
"Input vessel segment does not coincide with any end of the multi-segment vessel.");
232 template<
unsigned DIM>
236 if (segments.front()->IsConnectedTo(
mSegments.back()))
240 else if (segments.back()->IsConnectedTo(
mSegments.front()))
245 else if (segments.front()->IsConnectedTo(
mSegments.front()))
247 std::reverse(segments.begin(), segments.end());
251 else if (segments.back()->IsConnectedTo(
mSegments.back()))
253 std::reverse(segments.begin(), segments.end());
258 EXCEPTION(
"Input vessel segments do not coincide with any end of the vessel.");
261 for (
unsigned i = 1; i <
mSegments.size(); i++)
265 EXCEPTION(
"Input vessel segments are not attached in the correct order.");
269 for (
unsigned i = 0; i <
mSegments.size(); i++)
271 for (
unsigned j = 0; j <
mSegments.size(); j++)
273 if (i != j && i != j - 1 && i != j + 1)
277 EXCEPTION(
"Input vessel segments are not correctly connected.");
284 for (
unsigned i = 0; i < segments.size(); i++)
286 segments[i]->AddVessel(
Shared());
293 template<
unsigned DIM>
296 this->
mOutputData = pTargetVessel->GetOutputData();
299 template<
unsigned DIM>
303 boost::shared_ptr<VesselSegment<DIM> > pVesselSegment;
304 for (
unsigned i = 0; i <
mSegments.size(); i++)
309 if (pVesselSegment->GetNode(0)->IsCoincident(location))
311 return pVesselSegment->GetNode(0);
313 if (pVesselSegment->GetNode(1)->IsCoincident(location))
315 return pVesselSegment->GetNode(1);
323 EXCEPTION(
"Specified location is not on a segment in this vessel.");
325 for (
unsigned i = 0; i <
mSegments.size(); i++)
327 for (
unsigned j = 0; j <
mSegments.size(); j++)
329 if (i != j && i != j - 1 && i != j + 1)
333 EXCEPTION(
"Input vessel segments are not correctly connected.");
341 units::quantity<unit::length> distance0 = pVesselSegment->GetNode(0)->GetDistance(location);
342 units::quantity<unit::length> distance1 = pVesselSegment->GetNode(1)->GetDistance(location);
343 unsigned closest_index;
345 if (distance0 <= distance1)
355 boost::shared_ptr<VesselNode<DIM> > p_new_node =
VesselNode<DIM>::Create(*pVesselSegment->GetNode(closest_index));
356 p_new_node->SetLocation(location);
357 p_new_node->GetFlowProperties()->SetIsInputNode(
false);
358 p_new_node->GetFlowProperties()->SetIsOutputNode(
false);
363 p_new_segment0->CopyDataFromExistingSegment(pVesselSegment);
367 std::vector<boost::shared_ptr<VesselSegment<DIM> > > newSegments;
368 typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator it = std::find(
mSegments.begin(),
mSegments.end(), pVesselSegment);
372 EXCEPTION(
"Vessel segment is not contained inside vessel.");
377 newSegments.push_back(p_new_segment0);
378 newSegments.push_back(p_new_segment1);
382 if((*(it + 1))->IsConnectedTo(p_new_segment1))
384 newSegments.push_back(p_new_segment0);
385 newSegments.push_back(p_new_segment1);
389 newSegments.push_back(p_new_segment1);
390 newSegments.push_back(p_new_segment0);
395 newSegments.push_back(p_new_segment0);
396 newSegments.push_back(p_new_segment1);
400 newSegments.push_back(p_new_segment1);
401 newSegments.push_back(p_new_segment0);
404 mSegments.insert(it, newSegments.begin(), newSegments.end());
412 pVesselSegment->Remove();
416 EXCEPTION(
"Vessel segment is not contained inside vessel.");
419 for (
unsigned i = 0; i <
mSegments.size(); i++)
421 for (
unsigned j = 0; j <
mSegments.size(); j++)
423 if (i != j && i != j - 1 && i != j + 1)
427 EXCEPTION(
"Input vessel segments are not correctly connected.");
434 for (
unsigned i = 0; i < newSegments.size(); i++)
436 newSegments[i]->AddVessel(
Shared());
444 template<
unsigned DIM>
450 template<
unsigned DIM>
453 std::map<std::string, double> flow_data = this->
mpFlowProperties->GetOutputData();
455 this->
mOutputData.insert(flow_data.begin(), flow_data.end());
461 template<
unsigned DIM>
464 units::quantity<unit::length> distance_1 = this->
GetStartNode()->GetDistance(rLocation);
465 units::quantity<unit::length> distance_2 = this->
GetEndNode()->GetDistance(rLocation);
466 if(distance_1 > distance_2)
476 template<
unsigned DIM>
480 units::quantity<unit::length> nearest_distance = DBL_MAX * unit::metres;
481 for(
unsigned idx=0; idx<
mSegments.size(); idx++)
483 units::quantity<unit::length> seg_distance =
mSegments[idx]->GetDistance(rLocation);
484 if(seg_distance < nearest_distance)
486 nearest_distance = seg_distance;
489 return nearest_distance;
492 template<
unsigned DIM>
495 std::vector<boost::shared_ptr<VesselSegment<DIM> > > start_segments =
GetStartNode()->GetSegments();
496 std::vector<boost::shared_ptr<VesselSegment<DIM> > > end_segments =
GetStartNode()->GetSegments();
498 std::vector<boost::shared_ptr<Vessel<DIM> > > connected;
500 for(
unsigned idx=0; idx<start_segments.size();idx++)
502 if(start_segments[idx]->GetVessel() !=
Shared())
504 connected.push_back(start_segments[idx]->GetVessel());
507 for(
unsigned idx=0; idx<end_segments.size();idx++)
509 if(end_segments[idx]->GetVessel() !=
Shared())
511 connected.push_back(end_segments[idx]->GetVessel());
517 template<
unsigned DIM>
528 template<
unsigned DIM>
547 EXCEPTION(
"Query node is not at either end of the vessel.");
551 template<
unsigned DIM>
554 units::quantity<unit::length> length = 0.0 * unit::metres;
555 for (
unsigned i = 0; i <
mSegments.size(); i++)
562 template<
unsigned DIM>
565 units::quantity<unit::length> radius = 0.0 * unit::metres;
566 for (
unsigned i = 0; i <
mSegments.size(); i++)
570 return radius / (double(
mSegments.size()));
573 template<
unsigned DIM>
580 if(index >=
mNodes.size())
582 EXCEPTION(
"Out of bounds node index requested");
587 template<
unsigned DIM>
597 template<
unsigned DIM>
607 template<
unsigned DIM>
617 template<
unsigned DIM>
623 template<
unsigned DIM>
628 EXCEPTION(
"Requested segment index out of range");
633 template<
unsigned DIM>
639 template<
unsigned DIM>
649 template<
unsigned DIM>
663 template<
unsigned DIM>
667 for (
unsigned idx = 0; idx <
mSegments.size(); idx++)
672 mSegments = std::vector<boost::shared_ptr<VesselSegment<DIM> > >();
675 template<
unsigned DIM>
680 EXCEPTION(
"Vessel must have at least one segment.");
682 if (location == SegmentLocation::Start)
687 else if (location == SegmentLocation::End)
694 EXCEPTION(
"You can only remove segments from the start or end of vessels.");
700 template<
unsigned DIM>
707 template<
unsigned DIM>
710 for (
unsigned i = 0; i <
mSegments.size(); i++)
716 template<
unsigned DIM>
719 return this->shared_from_this();
722 template<
unsigned DIM>
748 for (
unsigned idx = 1; idx <
mSegments.size(); idx++)
std::vector< boost::shared_ptr< VesselSegment< DIM > > > mSegments
static boost::shared_ptr< VesselNode< DIM > > Create(double v1=0.0, double v2=0.0, double v3=0.0)
units::quantity< unit::length > GetLength() const
void CopyDataFromExistingVessel(boost::shared_ptr< Vessel< DIM > > pTargetVessel)
void SetRadius(units::quantity< unit::length > radius)
std::vector< boost::shared_ptr< VesselSegment< DIM > > > GetSegments()
boost::shared_ptr< VesselNode< DIM > > DivideSegment(const DimensionalChastePoint< DIM > &rLocation, double distanceTolerance=1.e-6)
std::vector< boost::shared_ptr< VesselNode< DIM > > > mNodes
units::quantity< unit::length > GetDistance(const DimensionalChastePoint< DIM > &rLocation) const
Vessel(boost::shared_ptr< VesselSegment< DIM > > pSegment)
bool IsConnectedTo(boost::shared_ptr< Vessel< DIM > > pOtherVessel)
std::map< std::string, double > mOutputData
void RemoveSegments(SegmentLocation::Value location)
unsigned GetNumberOfNodes()
const std::vector< boost::shared_ptr< VesselNode< DIM > > > & rGetNodes()
unsigned GetNumberOfSegments()
std::map< std::string, double > GetOutputData()
boost::shared_ptr< VesselNode< DIM > > GetNodeAtOppositeEnd(boost::shared_ptr< VesselNode< DIM > > pQueryNode)
boost::shared_ptr< VesselSegment< DIM > > GetSegment(unsigned index)
boost::shared_ptr< VesselFlowProperties< DIM > > mpFlowProperties
boost::shared_ptr< VesselNode< DIM > > GetEndNode()
static boost::shared_ptr< VesselSegment< DIM > > Create(boost::shared_ptr< VesselNode< DIM > > pNode1, boost::shared_ptr< VesselNode< DIM > > pNode2)
boost::shared_ptr< Vessel< DIM > > Shared()
virtual unsigned GetId() const
static boost::shared_ptr< Vessel< DIM > > Create(boost::shared_ptr< VesselSegment< DIM > > pSegment)
boost::shared_ptr< VesselNode< DIM > > GetNode(unsigned index)
std::vector< boost::shared_ptr< Vessel< DIM > > > GetConnectedVessels()
std::vector< boost::shared_ptr< VesselNode< DIM > > > GetNodes()
void SetFlowProperties(const VesselFlowProperties< DIM > &rFlowProperties)
boost::shared_ptr< VesselNode< DIM > > GetStartNode()
units::quantity< unit::length > GetRadius() const
boost::shared_ptr< VesselFlowProperties< DIM > > GetFlowProperties() const
void AddSegments(std::vector< boost::shared_ptr< VesselSegment< DIM > > > pSegments)
void AddSegment(boost::shared_ptr< VesselSegment< DIM > > pSegment)
void CopyDataFromExistingSegment(const boost::shared_ptr< VesselSegment< DIM > > pTargetSegment)
units::quantity< unit::length > GetClosestEndNodeDistance(const DimensionalChastePoint< DIM > &rLocation)