Chaste  Release::2018.1
VertexMesh.hpp
1 /*
2 
3 Copyright (c) 2005-2018, 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 #ifndef VERTEXMESH_HPP_
36 #define VERTEXMESH_HPP_
37 
38 // Forward declaration prevents circular include chain
39 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
40 class VertexMeshWriter;
41 
42 #include <algorithm>
43 #include <iostream>
44 #include <map>
45 
46 #include <boost/serialization/base_object.hpp>
47 #include <boost/serialization/split_member.hpp>
48 #include <boost/serialization/vector.hpp>
49 #include "ChasteSerialization.hpp"
50 
51 #include "AbstractMesh.hpp"
52 #include "ArchiveLocationInfo.hpp"
53 #include "TetrahedralMesh.hpp"
54 #include "VertexElement.hpp"
55 #include "VertexElementMap.hpp"
56 #include "VertexMeshReader.hpp"
57 #include "VertexMeshWriter.hpp"
58 
73 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
74 class VertexMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
75 {
76  friend class TestVertexMesh;
77 
78 protected:
80  std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> mElements;
81 
83  std::vector<VertexElement<ELEMENT_DIM - 1, SPACE_DIM>*> mFaces;
84 
92  std::map<unsigned, unsigned> mVoronoiElementIndexMap;
93 
102 
110  unsigned SolveNodeMapping(unsigned index) const;
111 
119  unsigned SolveElementMapping(unsigned index) const;
120 
128  unsigned SolveBoundaryElementMapping(unsigned index) const;
129 
138 
159  bool ElementIncludesPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
160 
170  unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
171 
173  friend class boost::serialization::access;
174 
182  template <class Archive>
183  void save(Archive& archive, const unsigned int version) const
184  {
185  archive& boost::serialization::base_object<AbstractMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
186 
187  // Create a mesh writer pointing to the correct file and directory
190  false);
191  mesh_writer.WriteFilesUsingMesh(*(const_cast<VertexMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
192  }
193 
200  template <class Archive>
201  void load(Archive& archive, const unsigned int version)
202  {
203  archive& boost::serialization::base_object<AbstractMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
204 
206  this->ConstructFromMeshReader(mesh_reader);
207  }
208  BOOST_SERIALIZATION_SPLIT_MEMBER()
209 
210 public:
212  class VertexElementIterator;
213 
219  inline VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements = true);
220 
224  inline VertexElementIterator GetElementIteratorEnd();
225 
232  VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
233  std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
234 
242  VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
243  std::vector<VertexElement<ELEMENT_DIM - 1, SPACE_DIM>*> faces,
244  std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
245 
259  VertexMesh(TetrahedralMesh<2, 2>& rMesh, bool isPeriodic = false);
260 
269  VertexMesh(TetrahedralMesh<3, 3>& rMesh);
270 
274  VertexMesh();
275 
279  virtual ~VertexMesh();
280 
284  virtual unsigned GetNumNodes() const;
285 
289  virtual unsigned GetNumElements() const;
290 
294  unsigned GetNumAllElements() const;
295 
299  virtual unsigned GetNumFaces() const;
300 
306  VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
307 
313  VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* GetFace(unsigned index) const;
314 
330  virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index);
331 
337  void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader);
338 
342  virtual void Clear();
343 
349  unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex);
350 
358  unsigned GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(unsigned nodeIndex);
359 
369  unsigned GetRosetteRankOfElement(unsigned index);
370 
382  virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
383  const c_vector<double, SPACE_DIM>& rLocationB);
384 
394  virtual double GetVolumeOfElement(unsigned index);
395 
405  virtual double GetSurfaceAreaOfElement(unsigned index);
406 
418  c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
419 
431  c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
432 
444  c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
445 
455  c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
456 
486  virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index);
487 
494  double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2);
495 
506  double GetElongationShapeFactorOfElement(unsigned elementIndex);
507 
519  double CalculateUnitNormalToFaceWithArea(VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* pFace, c_vector<double, SPACE_DIM>& rNormal);
520 
530  virtual double CalculateAreaOfFace(VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* pFace);
531 
557  c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index);
558 
565  std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex);
566 
579  std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex);
580 
587  std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex);
588 
597  virtual VertexMesh<ELEMENT_DIM, SPACE_DIM>* GetMeshForVtk();
598 
604  class VertexElementIterator
605  {
606  public:
612  inline VertexElement<ELEMENT_DIM, SPACE_DIM>& operator*();
613 
618  inline VertexElement<ELEMENT_DIM, SPACE_DIM>* operator->();
619 
625  inline bool operator!=(const typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther);
626 
631  inline VertexElementIterator& operator++();
632 
643  VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
644  typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator elementIter,
645  bool skipDeletedElements = true);
646 
647  private:
649  VertexMesh& mrMesh;
650 
652  typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator mElementIter;
653 
656 
661  inline bool IsAtEnd();
662 
667  inline bool IsAllowedElement();
668  };
669 };
670 
673 
674 // VertexElementIterator class implementation - most methods are inlined //
677 
678 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
679 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
680  bool skipDeletedElements)
681 {
682  return VertexElementIterator(*this, mElements.begin(), skipDeletedElements);
683 }
684 
685 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
687 {
688  return VertexElementIterator(*this, mElements.end());
689 }
690 
691 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
693 {
694  assert(!IsAtEnd());
695  return **mElementIter;
696 }
697 
698 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
700 {
701  assert(!IsAtEnd());
702  return *mElementIter;
703 }
704 
705 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
707 {
708  return mElementIter != rOther.mElementIter;
709 }
710 
711 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
713 {
714  do
715  {
716  ++mElementIter;
717  } while (!IsAtEnd() && !IsAllowedElement());
718 
719  return (*this);
720 }
721 
722 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
725  typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator elementIter,
726  bool skipDeletedElements)
727  : mrMesh(rMesh),
728  mElementIter(elementIter),
729  mSkipDeletedElements(skipDeletedElements)
730 {
731  if (mrMesh.mElements.empty())
732  {
733  // Cope with empty meshes
734  mElementIter = mrMesh.mElements.end();
735  }
736  else
737  {
738  // Make sure we start at an allowed element
739  if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
740  {
741  ++(*this);
742  }
743  }
744 }
745 
746 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
748 {
749  return mElementIter == mrMesh.mElements.end();
750 }
751 
752 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
754 {
755  return !(mSkipDeletedElements && (*this)->IsDeleted());
756 }
757 
758 #endif /*VERTEXMESH_HPP_*/
virtual c_vector< double, 3 > CalculateMomentsOfElement(unsigned index)
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
virtual void Clear()
Definition: VertexMesh.cpp:579
VertexElement< ELEMENT_DIM-1, SPACE_DIM > * GetFace(unsigned index) const
Definition: VertexMesh.cpp:635
unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex)
Definition: VertexMesh.cpp:503
virtual unsigned GetNumFaces() const
Definition: VertexMesh.cpp:622
VertexElement< ELEMENT_DIM, SPACE_DIM > * operator->()
Definition: VertexMesh.hpp:699
VertexElement< ELEMENT_DIM, SPACE_DIM > & operator*()
Definition: VertexMesh.hpp:692
virtual c_vector< double, SPACE_DIM > GetVectorFromAtoB(const c_vector< double, SPACE_DIM > &rLocationA, const c_vector< double, SPACE_DIM > &rLocationB)
std::set< unsigned > GetNeighbouringNodeIndices(unsigned nodeIndex)
Definition: VertexMesh.cpp:713
Definition: Node.hpp:58
virtual unsigned GetNumElements() const
Definition: VertexMesh.cpp:610
static std::string GetMeshFilename()
unsigned GetNumAllElements() const
Definition: VertexMesh.cpp:616
void WriteFilesUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
VertexElementIterator(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, typename std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * >::iterator elementIter, bool skipDeletedElements=true)
Definition: VertexMesh.hpp:723
std::vector< VertexElement< ELEMENT_DIM-1, SPACE_DIM > * > mFaces
Definition: VertexMesh.hpp:83
void save(Archive &archive, const unsigned int version) const
Definition: VertexMesh.hpp:183
virtual unsigned GetNumNodes() const
Definition: VertexMesh.cpp:604
void GenerateVerticesFromElementCircumcentres(TetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
Definition: VertexMesh.cpp:390
void load(Archive &archive, const unsigned int version)
Definition: VertexMesh.hpp:201
c_vector< double, SPACE_DIM > GetNextEdgeGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
std::set< unsigned > GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex)
Definition: VertexMesh.cpp:743
bool operator!=(const typename VertexMesh< ELEMENT_DIM, SPACE_DIM >::VertexElementIterator &rOther)
Definition: VertexMesh.hpp:706
VertexElement< ELEMENT_DIM, SPACE_DIM > * GetElement(unsigned index) const
Definition: VertexMesh.cpp:628
VertexElementIterator & operator++()
Definition: VertexMesh.hpp:712
c_vector< double, SPACE_DIM > GetPreviousEdgeGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
Definition: VertexMesh.hpp:679
double CalculateUnitNormalToFaceWithArea(VertexElement< ELEMENT_DIM-1, SPACE_DIM > *pFace, c_vector< double, SPACE_DIM > &rNormal)
virtual double CalculateAreaOfFace(VertexElement< ELEMENT_DIM-1, SPACE_DIM > *pFace)
double GetElongationShapeFactorOfElement(unsigned elementIndex)
Definition: VertexMesh.cpp:450
virtual double GetVolumeOfElement(unsigned index)
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * > mElements
Definition: VertexMesh.hpp:80
unsigned SolveNodeMapping(unsigned index) const
Definition: VertexMesh.cpp:481
c_vector< double, SPACE_DIM > GetPerimeterGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * >::iterator mElementIter
Definition: VertexMesh.hpp:652
unsigned SolveBoundaryElementMapping(unsigned index) const
Definition: VertexMesh.cpp:495
virtual c_vector< double, SPACE_DIM > GetCentroidOfElement(unsigned index)
Definition: VertexMesh.cpp:642
std::set< unsigned > GetNeighbouringElementIndices(unsigned elementIndex)
Definition: VertexMesh.cpp:783
c_vector< double, SPACE_DIM > GetAreaGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
virtual VertexMesh< ELEMENT_DIM, SPACE_DIM > * GetMeshForVtk()
Definition: VertexMesh.cpp:817
static std::string GetArchiveDirectory()
VertexElementIterator GetElementIteratorEnd()
Definition: VertexMesh.hpp:686
double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2)
Definition: VertexMesh.cpp:415
static std::string GetArchiveRelativePath()
unsigned GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(unsigned nodeIndex)
Definition: VertexMesh.cpp:529
virtual double GetSurfaceAreaOfElement(unsigned index)
gcov doesn't like this file...
unsigned SolveElementMapping(unsigned index) const
Definition: VertexMesh.cpp:488
bool ElementIncludesPoint(const c_vector< double, SPACE_DIM > &rTestPoint, unsigned elementIndex)
unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector< double, SPACE_DIM > &rTestPoint, unsigned elementIndex)
c_vector< double, SPACE_DIM > GetShortAxisOfElement(unsigned index)
TetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpDelaunayMesh
Definition: VertexMesh.hpp:101
std::map< unsigned, unsigned > mVoronoiElementIndexMap
Definition: VertexMesh.hpp:92
unsigned GetRosetteRankOfElement(unsigned index)
Definition: VertexMesh.cpp:555