Chaste  Build::
VesselNetwork.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34  */
35 
36 #include <iostream>
37 #include <math.h>
38 #include "SmartPointers.hpp"
39 #include "OutputFileHandler.hpp"
40 #include "SegmentFlowProperties.hpp"
41 #include "VesselNetwork.hpp"
42 #include "VesselNetworkWriter.hpp"
43 
44 template <unsigned DIM>
46  mVessels(),
47  mSegments(),
48  mSegmentsUpToDate(false),
49  mNodes(),
50  mNodesUpToDate(false),
51  mVesselNodes(),
52  mVesselNodesUpToDate(false)
53 {
54 
55 }
56 
57 template <unsigned DIM>
59 {
60 
61 }
62 
63 template <unsigned DIM>
64 boost::shared_ptr<VesselNetwork<DIM> > VesselNetwork<DIM>::Create()
65 {
66  MAKE_PTR(VesselNetwork<DIM>, pSelf);
67  return pSelf;
68 }
69 
70 template <unsigned DIM>
71 void VesselNetwork<DIM>::AddVessel(boost::shared_ptr<Vessel<DIM> > pVessel)
72 {
73  mVessels.push_back(pVessel);
74  mSegmentsUpToDate = false;
75  mNodesUpToDate = false;
76  mVesselNodesUpToDate = false;
77 }
78 
79 template <unsigned DIM>
80 void VesselNetwork<DIM>::AddVessels(std::vector<boost::shared_ptr<Vessel<DIM> > > vessels)
81 {
82  mVessels.insert(mVessels.end(), vessels.begin(), vessels.end());
83  mSegmentsUpToDate = false;
84  mNodesUpToDate = false;
85  mVesselNodesUpToDate = false;
86 }
87 
88 template <unsigned DIM>
90 {
91  boost::shared_ptr<SegmentFlowProperties<DIM> > properties = GetVesselSegments()[index]->GetFlowProperties();
92  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
93  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator it;
94  for(it = segments.begin(); it != segments.end(); it++)
95  {
96  (*it)->SetFlowProperties(*properties);
97  }
98 }
99 
100 template <unsigned DIM>
101 std::vector<boost::shared_ptr<Vessel<DIM> > > VesselNetwork<DIM>::CopyVessels()
102 {
103  return CopyVessels(mVessels);
104 }
105 
106 template <unsigned DIM>
107 std::vector<boost::shared_ptr<Vessel<DIM> > > VesselNetwork<DIM>::CopyVessels(std::vector<boost::shared_ptr<Vessel<DIM> > > vessels)
108 {
109  typename std::vector<boost::shared_ptr<Vessel<DIM> > >::iterator vessel_iter;
110  std::vector<boost::shared_ptr<Vessel<DIM> > > new_vessels;
111  for(vessel_iter = vessels.begin(); vessel_iter != vessels.end(); vessel_iter++)
112  {
113  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator segment_iter;
114  std::vector<boost::shared_ptr<VesselSegment<DIM> > > new_segments;
115  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = (*vessel_iter)->GetSegments();
116  for(segment_iter = segments.begin(); segment_iter != segments.end(); segment_iter++)
117  {
118  new_segments.push_back(VesselSegment<DIM>::Create(VesselNode<DIM>::Create((*segment_iter)->GetNode(0)->rGetLocation()),
119  VesselNode<DIM>::Create((*segment_iter)->GetNode(1)->rGetLocation())));
120  }
121  new_vessels.push_back(Vessel<DIM>::Create(new_segments));
122  }
123 
124  MergeCoincidentNodes(new_vessels);
125  AddVessels(new_vessels);
126  return new_vessels;
127 }
128 
129 template <unsigned DIM>
130 boost::shared_ptr<VesselNode<DIM> > VesselNetwork<DIM>::DivideVessel(boost::shared_ptr<Vessel<DIM> > pVessel,
131  const DimensionalChastePoint<DIM>& location)
132 {
133  boost::shared_ptr<VesselSegment<DIM> > p_segment;
134 
135  // If the divide location coincides with one of the end nodes don't divide and return that node
136  if (pVessel->GetStartNode()->IsCoincident(location) || pVessel->GetEndNode()->IsCoincident(location))
137  {
138 
139  if (pVessel->GetStartNode()->IsCoincident(location))
140  {
141  return pVessel->GetStartNode();
142  }
143  else
144  {
145  return pVessel->GetEndNode();
146  }
147  }
148  else
149  {
150  bool locatedInsideVessel = false;
151  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = pVessel->GetSegments();
152  for (unsigned idx = 0; idx < segments.size(); idx++)
153  {
154  if (segments[idx]->GetDistance(location)/segments[idx]->GetNode(0)->GetReferenceLengthScale() <= 1e-6)
155  {
156  locatedInsideVessel = true;
157  p_segment = segments[idx];
158  break;
159  }
160  }
161  if(!locatedInsideVessel)
162  {
163  EXCEPTION("There is no segment at the requested division location.");
164  }
165  }
166 
167  boost::shared_ptr<VesselNode<DIM> > p_new_node = pVessel->DivideSegment(location); // network segments and nodes out of date
168 
169  // create two new vessels and assign them the old vessel's properties
170  std::vector<boost::shared_ptr<VesselSegment<DIM> > > start_segments;
171  std::vector<boost::shared_ptr<VesselSegment<DIM> > > end_segments;
172  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = pVessel->GetSegments();
173  unsigned segment_index = segments.size()+1;
174  for (unsigned idx = 0; idx < segments.size(); idx++)
175  {
176  start_segments.push_back(segments[idx]);
177  if (segments[idx]->GetNode(1)->IsCoincident(location))
178  {
179  segment_index = idx;
180  break;
181  }
182  }
183 
184  if (segment_index == segments.size()-1)
185  {
186  EXCEPTION("Vessel segment not found.");
187  }
188  for (unsigned idx = segment_index+1; idx < segments.size(); idx++)
189  {
190  end_segments.push_back(segments[idx]);
191  }
192 
193  boost::shared_ptr<Vessel<DIM> > p_new_vessel1 = Vessel<DIM>::Create(start_segments);
194  boost::shared_ptr<Vessel<DIM> > p_new_vessel2 = Vessel<DIM>::Create(end_segments);
195  p_new_vessel1->CopyDataFromExistingVessel(pVessel);
196  p_new_vessel2->CopyDataFromExistingVessel(pVessel);
197  p_new_vessel1->GetFlowProperties()->SetRegressionTime(pVessel->GetFlowProperties()->GetRegressionTime());
198  p_new_vessel2->GetFlowProperties()->SetRegressionTime(pVessel->GetFlowProperties()->GetRegressionTime());
199 
200  AddVessel(p_new_vessel1);
201  AddVessel(p_new_vessel2);
202  RemoveVessel(pVessel, false);
203  mSegmentsUpToDate = false;
204  mNodesUpToDate = false;
205  mVesselNodesUpToDate = false;
206 
207  return p_new_node;
208 }
209 
210 template <unsigned DIM>
211 void VesselNetwork<DIM>::ExtendVessel(boost::shared_ptr<Vessel<DIM> > pVessel, boost::shared_ptr<VesselNode<DIM> > pEndNode,
212  boost::shared_ptr<VesselNode<DIM> > pNewNode)
213 {
214  if(pVessel->GetStartNode() == pEndNode)
215  {
216  boost::shared_ptr<VesselSegment<DIM> > p_segment = VesselSegment<DIM>::Create(pNewNode, pEndNode);
217  p_segment->SetFlowProperties(*(pEndNode->GetSegments()[0]->GetFlowProperties()));
218  p_segment->SetRadius(pEndNode->GetSegments()[0]->GetRadius());
219  pVessel->AddSegment(p_segment);
220  }
221  else
222  {
223  boost::shared_ptr<VesselSegment<DIM> > p_segment = VesselSegment<DIM>::Create(pEndNode, pNewNode);
224  p_segment->SetFlowProperties(*(pEndNode->GetSegments()[0]->GetFlowProperties()));
225  p_segment->SetRadius(pEndNode->GetSegments()[0]->GetRadius());
226  pVessel->AddSegment(p_segment);
227  }
228 
229  mSegmentsUpToDate = false;
230  mNodesUpToDate = false;
231  mVesselNodesUpToDate = false;
232 }
233 
234 template <unsigned DIM>
235 boost::shared_ptr<Vessel<DIM> > VesselNetwork<DIM>::FormSprout(const DimensionalChastePoint<DIM>& sproutBaseLocation,
236  const DimensionalChastePoint<DIM>& sproutTipLocation)
237 {
238  // locate vessel at which the location of the sprout base exists
239  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > nearest_segment = GetNearestSegment(sproutBaseLocation);
240  if (nearest_segment.second / nearest_segment.first->GetNode(0)->GetReferenceLengthScale() > 1e-6)
241  {
242  EXCEPTION("No vessel located at sprout base.");
243  }
244 
245  // divide vessel at location of sprout base
246  boost::shared_ptr<VesselNode<DIM> > p_new_node = DivideVessel(nearest_segment.first->GetVessel(), sproutBaseLocation);
247 
248  // create new vessel
249  boost::shared_ptr<VesselNode<DIM> > p_new_node_at_tip = VesselNode<DIM>::Create(p_new_node);
250  p_new_node_at_tip->SetLocation(sproutTipLocation);
251  p_new_node_at_tip->SetIsMigrating(true);
252  p_new_node_at_tip->GetFlowProperties()->SetIsInputNode(false);
253  p_new_node_at_tip->GetFlowProperties()->SetIsOutputNode(false);
254  boost::shared_ptr<VesselSegment<DIM> > p_new_segment = VesselSegment<DIM>::Create(p_new_node, p_new_node_at_tip);
255  p_new_segment->CopyDataFromExistingSegment(nearest_segment.first);
256  p_new_segment->GetFlowProperties()->SetFlowRate(0.0*unit::metre_cubed_per_second);
257  p_new_segment->GetFlowProperties()->SetImpedance(0.0*unit::pascal_second_per_metre_cubed);
258  p_new_segment->GetFlowProperties()->SetHaematocrit(0.0);
259  p_new_segment->GetFlowProperties()->SetGrowthStimulus(0.0*unit::per_second);
260 
261  boost::shared_ptr<Vessel<DIM> > p_new_vessel = Vessel<DIM>::Create(p_new_segment);
262  // Sprouting won't save you.
263  p_new_vessel->GetFlowProperties()->SetRegressionTime(nearest_segment.first->GetVessel()->GetFlowProperties()->GetRegressionTime());
264  AddVessel(p_new_vessel);
265  return p_new_vessel;
266 }
267 
268 template <unsigned DIM>
270 {
271  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
272  for(unsigned idx=0; idx<nodes.size(); idx++)
273  {
274  units::quantity<unit::length> av_radius = 0.0 * unit::metres;
275  for(unsigned jdx=0; jdx<nodes[idx]->GetNumberOfSegments(); jdx++)
276  {
277  av_radius += nodes[idx]->GetSegment(jdx)->GetRadius();
278  }
279  av_radius /= double(nodes[idx]->GetNumberOfSegments());
280  nodes[idx]->SetRadius(av_radius);
281  }
282 }
283 
284 template <unsigned DIM>
285 std::pair<DimensionalChastePoint<DIM>, DimensionalChastePoint<DIM> > VesselNetwork<DIM>::GetExtents(bool useRadii)
286 {
287  units::quantity<unit::length> x_max = -DBL_MAX*unit::metres;
288  units::quantity<unit::length> y_max = -DBL_MAX*unit::metres;
289  units::quantity<unit::length> z_max = -DBL_MAX*unit::metres;
290 
291  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
292  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator it;
293  for(it = nodes.begin(); it != nodes.end(); it++)
294  {
295  units::quantity<unit::length> length_scale = (*it)->rGetLocation().GetReferenceLengthScale();
296  c_vector<double, DIM> location = (*it)->rGetLocation().GetLocation(length_scale);
297  if(location[0]*length_scale > x_max)
298  {
299  x_max = location[0]*length_scale;
300  if(useRadii)
301  {
302  x_max += (*it)->GetRadius();
303  }
304  }
305  if(location[1]*length_scale > y_max)
306  {
307  y_max = location[1]*length_scale;
308  if(useRadii)
309  {
310  y_max += (*it)->GetRadius();
311  }
312  }
313  if(DIM > 2)
314  {
315  if(location[2]*length_scale > z_max)
316  {
317  z_max = location[2]*length_scale;
318  if(useRadii)
319  {
320  z_max += (*it)->GetRadius();
321  }
322  }
323  }
324  }
325 
326  units::quantity<unit::length> x_min = x_max;
327  units::quantity<unit::length> y_min = y_max;
328  units::quantity<unit::length> z_min = z_max;
329  for(it = nodes.begin(); it != nodes.end(); it++)
330  {
331  units::quantity<unit::length> length_scale = (*it)->rGetLocation().GetReferenceLengthScale();
332  c_vector<double, DIM> location = (*it)->rGetLocation().GetLocation(length_scale);
333  if(location[0]*length_scale < x_min)
334  {
335  x_min = location[0]*length_scale;
336  if(useRadii)
337  {
338  x_min -= (*it)->GetRadius();
339  }
340  }
341  if(location[1]*length_scale < y_min)
342  {
343  y_min = location[1]*length_scale;
344  if(useRadii)
345  {
346  y_min -= (*it)->GetRadius();
347  }
348  }
349  if(DIM > 2)
350  {
351  if(location[2]*length_scale < z_min)
352  {
353  z_min = location[2]*length_scale;
354  if(useRadii)
355  {
356  z_min -= (*it)->GetRadius();
357  }
358  }
359  }
360  }
361 
362  units::quantity<unit::length> base_length = BaseUnits::Instance()->GetReferenceLengthScale();
363  std::pair<DimensionalChastePoint<DIM>, DimensionalChastePoint<DIM> > bbox(DimensionalChastePoint<DIM>(x_min/base_length, y_min/base_length, z_min/base_length, base_length),
364  DimensionalChastePoint<DIM>(x_max/base_length, y_max/base_length, z_max/base_length, base_length));
365  return bbox;
366 }
367 
368 template<unsigned DIM>
369 std::map<std::string, double> VesselNetwork<DIM>::GetOutputData()
370 {
371  this->mOutputData.clear();
372  return this->mOutputData;
373 }
374 
375 template <unsigned DIM>
376 units::quantity<unit::length> VesselNetwork<DIM>::GetDistanceToNearestNode(const DimensionalChastePoint<DIM>& rLocation)
377 {
378  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
379  boost::shared_ptr<VesselNode<DIM> > nearest_node;
380  units::quantity<unit::length> min_distance = DBL_MAX*unit::metres;
381 
382  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator node_iter;
383  for(node_iter = nodes.begin(); node_iter != nodes.end(); node_iter++)
384  {
385  units::quantity<unit::length> node_distance = (*node_iter)->GetDistance(rLocation);
386  if (node_distance < min_distance)
387  {
388  min_distance = node_distance;
389  nearest_node = (*node_iter) ;
390  }
391  }
392  return min_distance;
393 }
394 
395 template <unsigned DIM>
396 boost::shared_ptr<VesselNode<DIM> > VesselNetwork<DIM>::GetNearestNode(boost::shared_ptr<VesselNode<DIM> > pInputNode)
397 {
398  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
399  boost::shared_ptr<VesselNode<DIM> > nearest_node;
400  units::quantity<unit::length> min_distance = DBL_MAX*unit::metres;
401 
402  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator node_iter;
403  for(node_iter = nodes.begin(); node_iter != nodes.end(); node_iter++)
404  {
405  if((*node_iter) != pInputNode)
406  {
407  units::quantity<unit::length> node_distance = (*node_iter)->GetDistance(pInputNode->rGetLocation());
408  if (node_distance < min_distance)
409  {
410  min_distance = node_distance;
411  nearest_node = (*node_iter) ;
412  }
413  }
414  }
415  return nearest_node;
416 }
417 
418 template <unsigned DIM>
419 boost::shared_ptr<VesselNode<DIM> > VesselNetwork<DIM>::GetNearestNode(const DimensionalChastePoint<DIM>& location)
420 {
421  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
422  boost::shared_ptr<VesselNode<DIM> > nearest_node;
423  units::quantity<unit::length> min_distance = DBL_MAX*unit::metres;
424 
425  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator node_iter;
426  for(node_iter = nodes.begin(); node_iter != nodes.end(); node_iter++)
427  {
428  units::quantity<unit::length> node_distance = (*node_iter)->GetDistance(location);
429  if (node_distance < min_distance)
430  {
431  min_distance = node_distance;
432  nearest_node = (*node_iter) ;
433  }
434  }
435 
436  return nearest_node;
437 }
438 
439 template <unsigned DIM>
440 std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > VesselNetwork<DIM>::GetNearestSegment(boost::shared_ptr<VesselSegment<DIM> > pSegment)
441 {
442  boost::shared_ptr<VesselSegment<DIM> > nearest_segment;
443  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
444  units::quantity<unit::length> length_scale = segments[0]->GetNode(0)->GetReferenceLengthScale();
445 
446  double min_distance = DBL_MAX;
447  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator segment_iter;
448  for(segment_iter = segments.begin(); segment_iter != segments.end(); segment_iter++)
449  {
450  if(!pSegment->IsConnectedTo((*segment_iter)))
451  {
452  // Get the segment to segment distance (http://geomalgorithms.com/a07-_distance.html#dist3D_Segment_to_Segment())
453  c_vector<double, DIM> u = (*segment_iter)->GetNode(1)->rGetLocation().GetLocation(length_scale) -
454  (*segment_iter)->GetNode(0)->rGetLocation().GetLocation(length_scale);
455  c_vector<double, DIM> v = pSegment->GetNode(1)->rGetLocation().GetLocation(length_scale) -
456  pSegment->GetNode(0)->rGetLocation().GetLocation(length_scale);
457  c_vector<double, DIM> w = (*segment_iter)->GetNode(0)->rGetLocation().GetLocation(length_scale) -
458  pSegment->GetNode(0)->rGetLocation().GetLocation(length_scale);
459 
460  double a = inner_prod(u,u);
461  double b = inner_prod(u,v);
462  double c = inner_prod(v,v);
463  double d = inner_prod(u,w);
464  double e = inner_prod(v,w);
465 
466  double dv = a * c - b * b;
467  double sc, sn, sd = dv;
468  double tc, tn ,td = dv;
469 
470  if(dv < 1.e-12) // almost parallel segments
471  {
472  sn = 0.0;
473  sd = 1.0;
474  tn = e;
475  td = c;
476  }
477  else // get the closest point on the equivalent infinite lines
478  {
479  sn = (b*e - c*d);
480  tn = (a*e - b*d);
481  if ( sn < 0.0)
482  {
483  sn = 0.0;
484  tn = e;
485  td = c;
486  }
487  else if(sn > sd)
488  {
489  sn =sd;
490  tn = e+ b;
491  td = c;
492  }
493  }
494 
495  if(tn < 0.0)
496  {
497  tn = 0.0;
498  if(-d < 0.0)
499  {
500  sn = 0.0;
501  }
502  else if(-d > a)
503  {
504  sn = sd;
505  }
506  else
507  {
508  sn = -d;
509  sd = a;
510  }
511  }
512  else if(tn > td)
513  {
514  tn = td;
515  if((-d + b) < 0.0)
516  {
517  sn = 0.0;
518  }
519  else if((-d + b) > a)
520  {
521  sn = sd;
522  }
523  else
524  {
525  sn = (-d + b);
526  sd = a;
527  }
528  }
529 
530  sc = (std::abs(sn) < 1.e-12 ? 0.0 : sn/sd);
531  tc = (std::abs(tn) < 1.e-12 ? 0.0 : tn/td);
532  c_vector<double, DIM> dp = w + (sc * u) - (tc * v);
533 
534  double segment_distance = norm_2(dp);
535  if (segment_distance < min_distance)
536  {
537  min_distance = segment_distance;
538  nearest_segment = (*segment_iter) ;
539  }
540  }
541 
542  }
543  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > return_pair =
544  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> >(nearest_segment, min_distance * length_scale);
545  return return_pair;
546 }
547 
548 template <unsigned DIM>
549 std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > VesselNetwork<DIM>::GetNearestSegment(boost::shared_ptr<VesselNode<DIM> > pNode,
550  bool sameVessel)
551 {
552  boost::shared_ptr<VesselSegment<DIM> > nearest_segment;
553  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
554 
555  units::quantity<unit::length> min_distance = DBL_MAX * unit::metres;
556  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator segment_iter;
557  for(segment_iter = segments.begin(); segment_iter != segments.end(); segment_iter++)
558  {
559  units::quantity<unit::length> segment_distance = (*segment_iter)->GetDistance(pNode->rGetLocation());
560 
561  if (segment_distance < min_distance && (*segment_iter)->GetNode(0) != pNode && (*segment_iter)->GetNode(1) != pNode)
562  {
563  if(sameVessel)
564  {
565  min_distance = segment_distance;
566  nearest_segment = (*segment_iter) ;
567  }
568  else
569  {
570  bool same_vessel = false;
571  std::vector<boost::shared_ptr<VesselSegment<DIM> > > node_segs = pNode->GetSegments();
572  for(unsigned idx=0;idx<node_segs.size();idx++)
573  {
574  if(node_segs[idx]->GetVessel() == (*segment_iter)->GetVessel())
575  {
576  same_vessel = true;
577  }
578  }
579  if(!same_vessel)
580  {
581  min_distance = segment_distance;
582  nearest_segment = (*segment_iter);
583  }
584  }
585  }
586  }
587  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > return_pair =
588  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> >(nearest_segment, min_distance);
589  return return_pair;
590 }
591 
592 template <unsigned DIM>
593 std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > VesselNetwork<DIM>::GetNearestSegment(const DimensionalChastePoint<DIM>& location)
594 {
595  boost::shared_ptr<VesselSegment<DIM> > nearest_segment;
596  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
597 
598  units::quantity<unit::length> min_distance = DBL_MAX * unit::metres;
599  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator segment_iter;
600  for(segment_iter = segments.begin(); segment_iter != segments.end(); segment_iter++)
601  {
602  units::quantity<unit::length> segment_distance = (*segment_iter)->GetDistance(location);
603  if (segment_distance < min_distance)
604  {
605  min_distance = segment_distance;
606  nearest_segment = (*segment_iter) ;
607  }
608  }
609  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > return_pair =
610  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> >(nearest_segment, min_distance);
611  return return_pair;
612 }
613 
614 template <unsigned DIM>
615 boost::shared_ptr<Vessel<DIM> > VesselNetwork<DIM>::GetNearestVessel(const DimensionalChastePoint<DIM>& location)
616 {
617  return GetNearestSegment(location).first->GetVessel();
618 }
619 
620 template <unsigned DIM>
621 void VesselNetwork<DIM>::RemoveShortVessels(units::quantity<unit::length> cutoff, bool endsOnly)
622 {
623  std::vector<boost::shared_ptr<Vessel<DIM> > > vessels_to_remove;
624 
625  for(unsigned idx=0; idx<mVessels.size(); idx++)
626  {
627  if(mVessels[idx]->GetLength() < cutoff)
628  {
629  if(endsOnly && (mVessels[idx]->GetStartNode()->GetNumberOfSegments() == 1 || mVessels[idx]->GetEndNode()->GetNumberOfSegments() == 1 ))
630  {
631  vessels_to_remove.push_back(mVessels[idx]);
632  }
633  else if(!endsOnly)
634  {
635  vessels_to_remove.push_back(mVessels[idx]);
636  }
637  }
638  }
639 
640  for(unsigned idx=0; idx<vessels_to_remove.size(); idx++)
641  {
642  RemoveVessel(vessels_to_remove[idx]);
643  }
644 }
645 
646 template <unsigned DIM>
647 void VesselNetwork<DIM>::MergeShortVessels(units::quantity<unit::length> cutoff)
648 {
649  std::vector<boost::shared_ptr<Vessel<DIM> > > vessels_to_merge;
650  for(unsigned idx=0; idx<mVessels.size(); idx++)
651  {
652  if(mVessels[idx]->GetLength() < cutoff)
653  {
654  vessels_to_merge.push_back(mVessels[idx]);
655  }
656  }
657 
658  // Get the nodes, remove the vessel, move the nodes together
659  for(unsigned idx=0; idx<vessels_to_merge.size(); idx++)
660  {
661  vessels_to_merge[idx]->GetEndNode()->SetLocation(vessels_to_merge[idx]->GetStartNode()->rGetLocation());
662  RemoveVessel(vessels_to_merge[idx], true);
663  }
664 
665  mSegmentsUpToDate = false;
666  mNodesUpToDate = false;
667  mVesselNodesUpToDate = false;
669 }
670 
671 template <unsigned DIM>
673 {
674  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
675  unsigned num_nodes = 0;
676 
677  for(unsigned idx = 0; idx < nodes.size(); idx++)
678  {
679  if(nodes[idx]->GetDistance(rLocation)/nodes[idx]->GetReferenceLengthScale() <= tolerance + 1.e-6)
680  {
681  num_nodes++;
682  }
683  }
684  return num_nodes;
685 }
686 
687 template <unsigned DIM>
688 std::vector<boost::shared_ptr<VesselNode<DIM> > > VesselNetwork<DIM>::GetNodes()
689 {
690  if(!mNodesUpToDate)
691  {
692  UpdateNodes();
693  }
694 
695  return mNodes;
696 }
697 
698 template <unsigned DIM>
699 boost::shared_ptr<VesselNode<DIM> > VesselNetwork<DIM>::GetNode(unsigned index)
700 {
701  if(!mNodesUpToDate)
702  {
703  UpdateNodes();
704  }
705 
706  return mNodes[index];
707 }
708 
709 template <unsigned DIM>
711 {
712  if(!mNodesUpToDate)
713  {
714  UpdateNodes();
715  }
716 
717  return mNodes.size();
718 }
719 
720 template <unsigned DIM>
722 {
724  {
726  }
727 
728  return mVesselNodes.size();
729 }
730 
731 template <unsigned DIM>
732 unsigned VesselNetwork<DIM>::GetNodeIndex(boost::shared_ptr<VesselNode<DIM> > node)
733 {
734  std::vector<boost::shared_ptr<VesselNode<DIM> > > vec_nodes = GetNodes();
735 
736  unsigned index = 0;
737 
738  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator it;
739  for(it = vec_nodes.begin(); it != vec_nodes.end(); it++)
740  {
741  if(*it == node)
742  {
743  return index;
744  }
745  index ++;
746  }
747  EXCEPTION("Node is not in the network.");
748 
749 }
750 
751 template <unsigned DIM>
753 {
754  return mVessels.size();
755 }
756 
757 template <unsigned DIM>
758 std::vector<boost::shared_ptr<VesselNode<DIM> > > VesselNetwork<DIM>::GetVesselEndNodes()
759 {
761  {
763  }
764  return mVesselNodes;
765 }
766 
767 template <unsigned DIM>
768 boost::shared_ptr<Vessel<DIM> > VesselNetwork<DIM>::GetVessel(unsigned index)
769 {
770  if(index >= mVessels.size())
771  {
772  EXCEPTION("Requested vessel index out of range");
773  }
774 
775  return mVessels[index];
776 }
777 
778 template <unsigned DIM>
779 std::vector<boost::shared_ptr<Vessel<DIM> > > VesselNetwork<DIM>::GetVessels()
780 {
781  return mVessels;
782 }
783 
784 
785 template <unsigned DIM>
787 {
788  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetVesselEndNodes();
789  unsigned num_nodes = nodes.size();
790 
791  // Get maximum number of segments attached to a node in the whole network.
792  unsigned max_num_branches = 0;
793  for(unsigned node_index = 0; node_index < num_nodes; node_index++)
794  {
795  boost::shared_ptr<VesselNode<DIM> > p_each_node = nodes[node_index];
796  unsigned num_segments_on_node = nodes[node_index]->GetNumberOfSegments();
797 
798  if (num_segments_on_node > max_num_branches)
799  {
800  max_num_branches = num_segments_on_node;
801  }
802  }
803  return max_num_branches;
804 }
805 
806 template <unsigned DIM>
807 unsigned VesselNetwork<DIM>::GetVesselIndex(boost::shared_ptr<Vessel<DIM> > pVessel)
808 {
809  unsigned index = 0;
810  typename std::vector<boost::shared_ptr<Vessel<DIM> > >::iterator it;
811  for(it = mVessels.begin(); it != mVessels.end(); it++)
812  {
813  if(*it == pVessel)
814  {
815  return index;
816  }
817  index ++;
818  }
819  EXCEPTION("Input vessel is not in the network.");
820 }
821 
822 template <unsigned DIM>
823 unsigned VesselNetwork<DIM>::GetVesselSegmentIndex(boost::shared_ptr<VesselSegment<DIM> > pVesselSegment)
824 {
825  unsigned index = 0;
826  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
827  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator it;
828  for(it = segments.begin(); it != segments.end(); it++)
829  {
830  if(*it == pVesselSegment)
831  {
832  return index;
833  }
834  index++;
835  }
836  EXCEPTION("Input vessel is not in the network.");
837 }
838 
839 template <unsigned DIM>
840 std::vector<boost::shared_ptr<VesselSegment<DIM> > > VesselNetwork<DIM>::GetVesselSegments()
841 {
842  if(!mSegmentsUpToDate)
843  {
844  UpdateSegments();
845  }
846 
847  return mSegments;
848 }
849 
850 template <unsigned DIM>
851 bool VesselNetwork<DIM>::NodeIsInNetwork(boost::shared_ptr<VesselNode<DIM> > pSourceNode)
852 {
853  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
854  return (std::find(nodes.begin(), nodes.end(), pSourceNode) != nodes.end());
855 }
856 
857 template <unsigned DIM>
859 {
860  MergeCoincidentNodes(GetNodes(), tolerance);
861 }
862 
863 template <unsigned DIM>
864 void VesselNetwork<DIM>::MergeCoincidentNodes(std::vector<boost::shared_ptr<Vessel<DIM> > > pVessels, double tolerance)
865 {
866  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes;
867  for(unsigned idx = 0; idx <pVessels.size(); idx++)
868  {
869  std::vector<boost::shared_ptr<VesselNode<DIM> > > vessel_nodes = pVessels[idx]->GetNodes();
870  nodes.insert(nodes.end(), vessel_nodes.begin(), vessel_nodes.end());
871  }
872  MergeCoincidentNodes(nodes, tolerance);
873 }
874 
875 template <unsigned DIM>
876 void VesselNetwork<DIM>::MergeCoincidentNodes(std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes, double tolerance)
877 {
878  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator it;
879  typename std::vector<boost::shared_ptr<VesselNode<DIM> > >::iterator it2;
880  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator it3;
881 
882  for(it = nodes.begin(); it != nodes.end(); it++)
883  {
884  for(it2 = nodes.begin(); it2 != nodes.end(); it2++)
885  {
886  // If the nodes are not identical
887  if ((*it) != (*it2))
888  {
889  // If the node locations are the same - according to the ChastePoint definition
890  bool is_coincident = false;
891  if(tolerance >0.0)
892  {
893  is_coincident = (*it)->GetDistance((*it2)->rGetLocation())/(*it)->GetReferenceLengthScale() <= tolerance;
894  }
895  else
896  {
897  is_coincident = (*it)->IsCoincident((*it2)->rGetLocation());
898  }
899 
900  if(is_coincident)
901  {
902  // Replace the node corresponding to 'it2' with the one corresponding to 'it'
903  // in all segments.
904  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = (*it2)->GetSegments();
905  for(it3 = segments.begin(); it3 != segments.end(); it3++)
906  {
907  if ((*it3)->GetNode(0) == (*it2))
908  {
909  (*it3)->ReplaceNode(0, (*it));
910  }
911  else if(((*it3)->GetNode(1) == (*it2)))
912  {
913  (*it3)->ReplaceNode(1, (*it));
914  }
915  }
916  }
917  }
918  }
919  }
920  mSegmentsUpToDate = false;
921  mNodesUpToDate = false;
922  mVesselNodesUpToDate = false;
923 }
924 
925 template <unsigned DIM>
927 {
928  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
929 
930  typename std::vector<boost::shared_ptr<VesselSegment<DIM> > >::iterator it;
931  for(it = segments.begin(); it != segments.end(); it++)
932  {
933  (*it)->SetRadius(prototype->GetRadius());
934  (*it)->GetFlowProperties()->SetImpedance(prototype->GetFlowProperties()->GetImpedance());
935  (*it)->GetFlowProperties()->SetHaematocrit(prototype->GetFlowProperties()->GetHaematocrit());
936  (*it)->GetFlowProperties()->SetFlowRate(prototype->GetFlowProperties()->GetFlowRate());
937  (*it)->GetFlowProperties()->SetViscosity(prototype->GetFlowProperties()->GetViscosity());
938  }
939 }
940 
941 template <unsigned DIM>
943 {
944  Translate(rTranslationVector, mVessels);
945 }
946 
947 template <unsigned DIM>
948 void VesselNetwork<DIM>::Translate(DimensionalChastePoint<DIM> rTranslationVector, std::vector<boost::shared_ptr<Vessel<DIM> > > vessels)
949 {
950  std::set<boost::shared_ptr<VesselNode<DIM> > > nodes;
951  for(unsigned idx = 0; idx <vessels.size(); idx++)
952  {
953  std::vector<boost::shared_ptr<VesselNode<DIM> > > vessel_nodes = vessels[idx]->GetNodes();
954  std::copy(vessel_nodes.begin(), vessel_nodes.end(), std::inserter(nodes, nodes.begin()));
955  }
956 
957  typename std::set<boost::shared_ptr<VesselNode<DIM> > >::iterator node_iter;
958  for(node_iter = nodes.begin(); node_iter != nodes.end(); node_iter++)
959  {
960  DimensionalChastePoint<DIM> old_loc = (*node_iter)->rGetLocation();
961  old_loc.Translate(rTranslationVector);
962  (*node_iter)->SetLocation(old_loc);
963  }
964 }
965 
966 template <unsigned DIM>
967 void VesselNetwork<DIM>::RemoveVessel(boost::shared_ptr<Vessel<DIM> > pVessel, bool deleteVessel)
968 {
969 
970  typename std::vector<boost::shared_ptr<Vessel<DIM> > >::iterator it = std::find(mVessels.begin(), mVessels.end(), pVessel);
971  if(it != mVessels.end())
972  {
973  if(deleteVessel)
974  {
975  (*it)->Remove();
976  }
977  mVessels.erase(it);
978  }
979  else
980  {
981  EXCEPTION("Vessel is not contained inside network.");
982  }
983 
984  mSegmentsUpToDate = false;
985  mNodesUpToDate = false;
986  mVesselNodesUpToDate = false;
987 }
988 
989 template <unsigned DIM>
990 void VesselNetwork<DIM>::SetNodeRadii(units::quantity<unit::length> radius)
991 {
992  std::vector<boost::shared_ptr<VesselNode<DIM> > > nodes = GetNodes();
993 
994  for(unsigned idx=0; idx<nodes.size();idx++)
995  {
996  nodes[idx]->SetRadius(radius);
997  }
998 
999 }
1000 
1001 template <unsigned DIM>
1002 void VesselNetwork<DIM>::SetSegmentRadii(units::quantity<unit::length> radius)
1003 {
1004  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
1005 
1006  for(unsigned idx=0; idx<segments.size();idx++)
1007  {
1008  segments[idx]->SetRadius(radius);
1009  }
1010 }
1011 
1012 template <unsigned DIM>
1013 void VesselNetwork<DIM>::SetSegmentViscosity(units::quantity<unit::dynamic_viscosity> viscosity)
1014 {
1015  std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments = GetVesselSegments();
1016  for(unsigned idx=0; idx<segments.size(); idx++)
1017  {
1018  segments[idx]->GetFlowProperties()->SetViscosity(viscosity);
1019  }
1020 }
1021 
1022 template <unsigned DIM>
1024 {
1025  if(merge)
1026  {
1028  }
1029  UpdateSegments();
1031  UpdateNodes();
1032  UpdateVesselIds();
1033 }
1034 
1035 template<unsigned DIM>
1037 {
1038  mNodes.clear();
1039  typename std::vector<boost::shared_ptr<Vessel<DIM> > >::iterator it;
1040  for(it = mVessels.begin(); it != mVessels.end(); it++)
1041  {
1042  for (unsigned idx=0; idx<(*it)->GetNumberOfNodes(); idx++)
1043  {
1044  (*it)->GetNode(idx)->SetComparisonId(0);
1045  }
1046  }
1047  for(it = mVessels.begin(); it != mVessels.end(); it++)
1048  {
1049  for (unsigned idx=0; idx<(*it)->GetNumberOfNodes(); idx++)
1050  {
1051  if((*it)->GetNode(idx)->GetComparisonId()==0)
1052  {
1053  mNodes.push_back((*it)->GetNode(idx));
1054  (*it)->GetNode(idx)->SetComparisonId(1);
1055  }
1056  }
1057  }
1058  mNodesUpToDate = true;
1059 }
1060 
1061 template<unsigned DIM>
1063 {
1064  mSegments.clear();
1065  typename std::vector<boost::shared_ptr<Vessel<DIM> > >::iterator it;
1066  for(it = mVessels.begin(); it != mVessels.end(); it++)
1067  {
1068  std::vector<boost::shared_ptr<VesselSegment<DIM> > > vessel_segments = (*it)->GetSegments();
1069  std::copy(vessel_segments.begin(), vessel_segments.end(), std::back_inserter(mSegments));
1070  }
1071  mSegmentsUpToDate = true;
1072 }
1073 
1074 template<unsigned DIM>
1076 {
1077  mVesselNodes.clear();
1078  typename std::vector<boost::shared_ptr<Vessel<DIM> > >::iterator it;
1079  for(it = mVessels.begin(); it != mVessels.end(); it++)
1080  {
1081  (*it)->UpdateNodes();
1082  (*it)->GetStartNode()->SetComparisonId(0);
1083  (*it)->GetEndNode()->SetComparisonId(0);
1084  }
1085  for(it = mVessels.begin(); it != mVessels.end(); it++)
1086  {
1087  if((*it)->GetStartNode()->GetComparisonId()==0)
1088  {
1089  mVesselNodes.push_back((*it)->GetStartNode());
1090  (*it)->GetStartNode()->SetComparisonId(1);
1091  }
1092  if((*it)->GetEndNode()->GetComparisonId()==0)
1093  {
1094  mVesselNodes.push_back((*it)->GetEndNode());
1095  (*it)->GetEndNode()->SetComparisonId(1);
1096  }
1097  }
1098  mVesselNodesUpToDate = true;
1099 }
1100 
1101 template<unsigned DIM>
1103 {
1104  for(unsigned idx=0;idx<mVessels.size();idx++)
1105  {
1106  mVessels[idx]->SetId(idx);
1107  }
1108 }
1109 
1110 template<unsigned DIM>
1112  const DimensionalChastePoint<DIM>& coordinate_2,
1113  double tolerance)
1114 {
1115  boost::shared_ptr<VesselSegment<DIM> > temp_segment = VesselSegment<DIM>::Create(VesselNode<DIM>::Create(coordinate_1), VesselNode<DIM>::Create(coordinate_2));
1116  std::pair<boost::shared_ptr<VesselSegment<DIM> >, units::quantity<unit::length> > nearest_segment = GetNearestSegment(temp_segment);
1117 
1118  // todo a false here does not necessarily guarantee that a vessel does not cross a line segment since get nearest
1119  // segment only returns one segment
1120  double nearest_seg_dist = nearest_segment.second / nearest_segment.first->GetNode(0)->GetReferenceLengthScale();
1121  double coord1_distance = nearest_segment.first->GetDistance(coordinate_1) / nearest_segment.first->GetNode(0)->GetReferenceLengthScale();
1122  double coord2_distance = nearest_segment.first->GetDistance(coordinate_2) / nearest_segment.first->GetNode(0)->GetReferenceLengthScale();
1123 
1124  bool crosses_segment = (nearest_seg_dist<= tolerance) && (coord1_distance > tolerance) && (coord2_distance > tolerance);
1125  return crosses_segment;
1126 }
1127 
1128 template<unsigned DIM>
1129 void VesselNetwork<DIM>::Write(const std::string& rFileName)
1130 {
1131  boost::shared_ptr<VesselNetworkWriter<DIM> > p_writer = VesselNetworkWriter<DIM>::Create();
1132  p_writer->SetFileName(rFileName);
1133  p_writer->SetVesselNetwork(this->shared_from_this());
1134  p_writer->Write();
1135 }
1136 
1137 // Explicit instantiation
1138 template class VesselNetwork<2>;
1139 template class VesselNetwork<3>;
1140 
virtual boost::shared_ptr< Vessel< DIM > > FormSprout(const DimensionalChastePoint< DIM > &sproutBaseLocation, const DimensionalChastePoint< DIM > &sproutTipLocation)
void CopySegmentFlowProperties(unsigned index=0)
void MergeShortVessels(units::quantity< unit::length > cutoff=10.0 *1.e-6 *unit::metres)
std::pair< DimensionalChastePoint< DIM >, DimensionalChastePoint< DIM > > GetExtents(bool useRadii=false)
static boost::shared_ptr< VesselNode< DIM > > Create(double v1=0.0, double v2=0.0, double v3=0.0)
Definition: VesselNode.cpp:100
void RemoveShortVessels(units::quantity< unit::length > cutoff=10.0 *1.e-6 *unit::metres, bool endsOnly=true)
boost::shared_ptr< Vessel< DIM > > GetNearestVessel(const DimensionalChastePoint< DIM > &rLocation)
static boost::shared_ptr< VesselNetworkWriter< DIM > > Create()
std::vector< boost::shared_ptr< VesselNode< DIM > > > GetVesselEndNodes()
std::vector< boost::shared_ptr< VesselSegment< DIM > > > GetVesselSegments()
unsigned GetNumberOfVessels()
bool VesselCrossesLineSegment(const DimensionalChastePoint< DIM > &rCoord1, const DimensionalChastePoint< DIM > &rCoord2, double tolerance=1e-6)
void SetNodeRadiiFromSegments()
void UpdateAll(bool merge=false)
virtual void ExtendVessel(boost::shared_ptr< Vessel< DIM > > pVessel, boost::shared_ptr< VesselNode< DIM > > pEndNode, boost::shared_ptr< VesselNode< DIM > > pNewNode)
unsigned GetNodeIndex(boost::shared_ptr< VesselNode< DIM > > pNode)
void AddVessel(boost::shared_ptr< Vessel< DIM > > pVessel)
void SetSegmentProperties(boost::shared_ptr< VesselSegment< DIM > > prototype)
static boost::shared_ptr< VesselNetwork< DIM > > Create()
boost::shared_ptr< VesselNode< DIM > > GetNearestNode(const DimensionalChastePoint< DIM > &rLocation)
unsigned GetVesselIndex(boost::shared_ptr< Vessel< DIM > > pVessel)
std::map< std::string, double > mOutputData
boost::shared_ptr< VesselNode< DIM > > GetNode(unsigned index)
unsigned NumberOfNodesNearLocation(const DimensionalChastePoint< DIM > &rLocation, double tolerance=0.0)
void Write(const std::string &rFileName)
bool NodeIsInNetwork(boost::shared_ptr< VesselNode< DIM > > pSourceNode)
std::vector< boost::shared_ptr< VesselSegment< DIM > > > mSegments
void SetSegmentViscosity(units::quantity< unit::dynamic_viscosity > viscosity)
static boost::shared_ptr< VesselSegment< DIM > > Create(boost::shared_ptr< VesselNode< DIM > > pNode1, boost::shared_ptr< VesselNode< DIM > > pNode2)
std::vector< boost::shared_ptr< Vessel< DIM > > > mVessels
static boost::shared_ptr< Vessel< DIM > > Create(boost::shared_ptr< VesselSegment< DIM > > pSegment)
Definition: Vessel.cpp:128
unsigned GetNumberOfVesselNodes()
bool mVesselNodesUpToDate
std::pair< boost::shared_ptr< VesselSegment< DIM > >, units::quantity< unit::length > > GetNearestSegment(boost::shared_ptr< VesselSegment< DIM > > pSegment)
void Translate(DimensionalChastePoint< DIM > rTranslationVector)
void MergeCoincidentNodes(double tolerance=0.0)
static BaseUnits * Instance()
Definition: BaseUnits.cpp:53
void SetNodeRadii(units::quantity< unit::length > radius)
boost::shared_ptr< Vessel< DIM > > GetVessel(unsigned index)
void SetSegmentRadii(units::quantity< unit::length > radius)
virtual boost::shared_ptr< VesselNode< DIM > > DivideVessel(boost::shared_ptr< Vessel< DIM > > pVessel, const DimensionalChastePoint< DIM > &rLocation)
std::vector< boost::shared_ptr< VesselNode< DIM > > > mNodes
void UpdateVesselNodes()
void AddVessels(std::vector< boost::shared_ptr< Vessel< DIM > > > vessels)
unsigned GetVesselSegmentIndex(boost::shared_ptr< VesselSegment< DIM > > pVesselSegment)
virtual ~VesselNetwork()
std::vector< boost::shared_ptr< VesselNode< DIM > > > mVesselNodes
units::quantity< unit::length > GetDistanceToNearestNode(const DimensionalChastePoint< DIM > &rLocation)
std::vector< boost::shared_ptr< VesselNode< DIM > > > GetNodes()
unsigned GetMaxBranchesOnNode()
void Translate(DimensionalChastePoint< DIM > rVector)
std::vector< boost::shared_ptr< Vessel< DIM > > > GetVessels()
std::map< std::string, double > GetOutputData()
std::vector< boost::shared_ptr< Vessel< DIM > > > CopyVessels()
units::quantity< unit::length > GetReferenceLengthScale()
Definition: BaseUnits.cpp:82
unsigned GetNumberOfNodes()
void RemoveVessel(boost::shared_ptr< Vessel< DIM > > pVessel, bool deleteVessel=false)