Chaste Commit::f2ff7ee04e70ac9d06c57344df8d017dbb12b97b
VertexMesh.hpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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
39template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
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>
50
51#include "AbstractMesh.hpp"
52#include "Edge.hpp"
53#include "EdgeHelper.hpp"
54#include "ArchiveLocationInfo.hpp"
55#include "TetrahedralMesh.hpp"
56#include "VertexElement.hpp"
57#include "VertexElementMap.hpp"
58#include "VertexMeshReader.hpp"
59#include "VertexMeshWriter.hpp"
60
61
76template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
77class VertexMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
78{
79 friend class TestVertexMesh;
80
81
82protected:
84 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> mElements;
85
87 std::vector<VertexElement<ELEMENT_DIM - 1, SPACE_DIM>*> mFaces;
88
91
99 std::map<unsigned, unsigned> mVoronoiElementIndexMap;
100
109
117 unsigned SolveNodeMapping(unsigned index) const;
118
126 unsigned SolveElementMapping(unsigned index) const;
127
135 unsigned SolveBoundaryElementMapping(unsigned index) const;
136
142
151
172 bool ElementIncludesPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
173
183 unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
184
187
195 template <class Archive>
196 void save(Archive& archive, const unsigned int version) const
197 {
198 archive& boost::serialization::base_object<AbstractMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
199 // Create a mesh writer pointing to the correct file and directory
202 false);
203 mesh_writer.WriteFilesUsingMesh(*(const_cast<VertexMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
204 }
205
212 template <class Archive>
213 void load(Archive& archive, const unsigned int version)
214 {
215 archive& boost::serialization::base_object<AbstractMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
216
218 this->ConstructFromMeshReader(mesh_reader);
219 }
220 BOOST_SERIALIZATION_SPLIT_MEMBER()
221
222public:
224 class VertexElementIterator;
225
231 inline VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements = true);
232
236 inline VertexElementIterator GetElementIteratorEnd();
237
244 VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
245 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
246
254 VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
255 std::vector<VertexElement<ELEMENT_DIM - 1, SPACE_DIM>*> faces,
256 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
257
272 VertexMesh(TetrahedralMesh<2, 2>& rMesh, bool isPeriodic = false, bool isBounded = false);
273
283
287 VertexMesh();
288
292 virtual ~VertexMesh();
293
298 unsigned GetNumEdges() const;
299
306 Edge<SPACE_DIM>* GetEdge(unsigned index) const;
307
312 const EdgeHelper<SPACE_DIM>& rGetEdgeHelper() const;
313
317 virtual unsigned GetNumNodes() const;
318
322 virtual unsigned GetNumElements() const;
323
327 unsigned GetNumAllElements() const;
328
332 virtual unsigned GetNumFaces() const;
333
339 VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
340
346 VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* GetFace(unsigned index) const;
347
363 virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index);
364
370 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader);
371
375 virtual void Clear();
376
382 unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex);
383
392
402 unsigned GetRosetteRankOfElement(unsigned index);
403
415 virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
416 const c_vector<double, SPACE_DIM>& rLocationB);
417
427 virtual double GetVolumeOfElement(unsigned index);
428
438 virtual double GetSurfaceAreaOfElement(unsigned index);
439
451 c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
452
464 c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
465
477 c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
478
488 c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
489
519 virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index);
520
527 double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2);
528
539 double GetElongationShapeFactorOfElement(unsigned elementIndex);
540
552 double CalculateUnitNormalToFaceWithArea(VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* pFace, c_vector<double, SPACE_DIM>& rNormal);
553
563 virtual double CalculateAreaOfFace(VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* pFace);
564
590 c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index);
591
598 std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex);
599
612 std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex);
613
620 std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex);
621
630 virtual VertexMesh<ELEMENT_DIM, SPACE_DIM>* GetMeshForVtk();
631
638 {
639 public:
646
652
658 inline bool operator!=(const typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther);
659
664 inline VertexElementIterator& operator++();
665
676 VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
677 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator elementIter,
678 bool skipDeletedElements = true);
679
680 private:
683
685 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator mElementIter;
686
689
694 inline bool IsAtEnd();
695
700 inline bool IsAllowedElement();
701 };
702};
703
706
707
708// VertexElementIterator class implementation - most methods are inlined //
710
711template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
713 bool skipDeletedElements)
714{
715 return VertexElementIterator(*this, mElements.begin(), skipDeletedElements);
716}
717
718template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
723
724template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
730
731template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
737
738template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
743
744template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
746{
747 do
748 {
749 ++mElementIter;
750 } while (!IsAtEnd() && !IsAllowedElement());
751
752 return (*this);
753}
754
755template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
758 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator elementIter,
759 bool skipDeletedElements)
760 : mrMesh(rMesh),
761 mElementIter(elementIter),
762 mSkipDeletedElements(skipDeletedElements)
763{
764 if (mrMesh.mElements.empty())
765 {
766 // Cope with empty meshes
768 }
769 else
770 {
771 // Make sure we start at an allowed element
772 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
773 {
774 ++(*this);
775 }
776 }
777}
778
779template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
781{
782 return mElementIter == mrMesh.mElements.end();
783}
784
785template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
787{
788 return !(mSkipDeletedElements && (*this)->IsDeleted());
789}
790
791#endif /*VERTEXMESH_HPP_*/
gcov doesn't like this file...
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
static std::string GetMeshFilename()
static std::string GetArchiveDirectory()
static std::string GetArchiveRelativePath()
Definition Edge.hpp:52
Definition Node.hpp:59
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)
std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * >::iterator mElementIter
VertexElementIterator & operator++()
bool operator!=(const typename VertexMesh< ELEMENT_DIM, SPACE_DIM >::VertexElementIterator &rOther)
VertexElement< ELEMENT_DIM, SPACE_DIM > & operator*()
VertexElement< ELEMENT_DIM, SPACE_DIM > * operator->()
std::vector< VertexElement< ELEMENT_DIM - 1, SPACE_DIM > * > mFaces
virtual c_vector< double, SPACE_DIM > GetVectorFromAtoB(const c_vector< double, SPACE_DIM > &rLocationA, const c_vector< double, SPACE_DIM > &rLocationB)
double CalculateUnitNormalToFaceWithArea(VertexElement< ELEMENT_DIM - 1, SPACE_DIM > *pFace, c_vector< double, SPACE_DIM > &rNormal)
VertexElement< ELEMENT_DIM - 1, SPACE_DIM > * GetFace(unsigned index) const
VertexElementIterator GetElementIteratorEnd()
virtual unsigned GetNumNodes() const
virtual double GetSurfaceAreaOfElement(unsigned index)
std::set< unsigned > GetNeighbouringNodeIndices(unsigned nodeIndex)
std::set< unsigned > GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex)
void GenerateEdgesFromElements(std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * > &rElements)
virtual double CalculateAreaOfFace(VertexElement< ELEMENT_DIM - 1, SPACE_DIM > *pFace)
const EdgeHelper< SPACE_DIM > & rGetEdgeHelper() const
c_vector< double, SPACE_DIM > GetNextEdgeGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
virtual unsigned GetNumFaces() const
VertexElement< ELEMENT_DIM, SPACE_DIM > * GetElement(unsigned index) const
EdgeHelper< SPACE_DIM > mEdgeHelper
unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector< double, SPACE_DIM > &rTestPoint, unsigned elementIndex)
double GetElongationShapeFactorOfElement(unsigned elementIndex)
unsigned GetNumAllElements() const
unsigned SolveNodeMapping(unsigned index) const
TetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpDelaunayMesh
bool ElementIncludesPoint(const c_vector< double, SPACE_DIM > &rTestPoint, unsigned elementIndex)
c_vector< double, SPACE_DIM > GetAreaGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
std::set< unsigned > GetNeighbouringElementIndices(unsigned elementIndex)
VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
void save(Archive &archive, const unsigned int version) const
c_vector< double, SPACE_DIM > GetPerimeterGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2)
c_vector< double, SPACE_DIM > GetShortAxisOfElement(unsigned index)
unsigned GetRosetteRankOfElement(unsigned index)
Edge< SPACE_DIM > * GetEdge(unsigned index) const
unsigned SolveBoundaryElementMapping(unsigned index) const
unsigned SolveElementMapping(unsigned index) const
unsigned GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(unsigned nodeIndex)
virtual c_vector< double, SPACE_DIM > GetCentroidOfElement(unsigned index)
std::map< unsigned, unsigned > mVoronoiElementIndexMap
friend class boost::serialization::access
void load(Archive &archive, const unsigned int version)
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex)
virtual void Clear()
unsigned GetNumEdges() const
c_vector< double, SPACE_DIM > GetPreviousEdgeGradientOfElementAtNode(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned localIndex)
std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * > mElements
virtual c_vector< double, 3 > CalculateMomentsOfElement(unsigned index)
virtual VertexMesh< ELEMENT_DIM, SPACE_DIM > * GetMeshForVtk()
virtual double GetVolumeOfElement(unsigned index)
virtual unsigned GetNumElements() const
void GenerateVerticesFromElementCircumcentres(TetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)