Chaste Commit::baa90ac2819b962188b7562f2326be23c47859a7
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
276 bool isPeriodic = false,
277 bool isBounded = false,
278 bool scaleBoundByEdgeLength = true,
279 double maxDelaunayEdgeLength = DBL_MAX,
280 bool offsetNewBoundaryNodes = false);
281
291
295 VertexMesh();
296
300 virtual ~VertexMesh();
301
306 unsigned GetNumEdges() const;
307
314 Edge<SPACE_DIM>* GetEdge(unsigned index) const;
315
320 const EdgeHelper<SPACE_DIM>& rGetEdgeHelper() const;
321
325 virtual unsigned GetNumNodes() const;
326
330 virtual unsigned GetNumElements() const;
331
335 unsigned GetNumAllElements() const;
336
340 virtual unsigned GetNumFaces() const;
341
347 VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
348
354 VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* GetFace(unsigned index) const;
355
371 virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index);
372
378 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader);
379
383 virtual void Clear();
384
390 unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex);
391
400
410 unsigned GetRosetteRankOfElement(unsigned index);
411
423 virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
424 const c_vector<double, SPACE_DIM>& rLocationB);
425
435 virtual double GetVolumeOfElement(unsigned index);
436
446 virtual double GetSurfaceAreaOfElement(unsigned index);
447
459 c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
460
472 c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
473
485 c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
486
496 c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM, SPACE_DIM>* pElement, unsigned localIndex);
497
527 virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index);
528
535 double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2);
536
547 double GetElongationShapeFactorOfElement(unsigned elementIndex);
548
560 double CalculateUnitNormalToFaceWithArea(VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* pFace, c_vector<double, SPACE_DIM>& rNormal);
561
571 virtual double CalculateAreaOfFace(VertexElement<ELEMENT_DIM - 1, SPACE_DIM>* pFace);
572
598 c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index);
599
606 std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex);
607
620 std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex);
621
628 std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex);
629
638 virtual VertexMesh<ELEMENT_DIM, SPACE_DIM>* GetMeshForVtk();
639
650 bool IsNearExistingNodes(c_vector<double,SPACE_DIM> newNodeLocation, std::vector<Node<SPACE_DIM> *> nodesToCheck, double minClearance);
651
658 {
659 public:
666
672
678 inline bool operator!=(const typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther);
679
684 inline VertexElementIterator& operator++();
685
696 VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
697 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator elementIter,
698 bool skipDeletedElements = true);
699
700 private:
703
705 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator mElementIter;
706
709
714 inline bool IsAtEnd();
715
720 inline bool IsAllowedElement();
721 };
722};
723
726
727
728// VertexElementIterator class implementation - most methods are inlined //
730
731template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
733 bool skipDeletedElements)
734{
735 return VertexElementIterator(*this, mElements.begin(), skipDeletedElements);
736}
737
738template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
743
744template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
750
751template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
757
758template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
763
764template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
766{
767 do
768 {
769 ++mElementIter;
770 } while (!IsAtEnd() && !IsAllowedElement());
771
772 return (*this);
773}
774
775template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
778 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*>::iterator elementIter,
779 bool skipDeletedElements)
780 : mrMesh(rMesh),
781 mElementIter(elementIter),
782 mSkipDeletedElements(skipDeletedElements)
783{
784 if (mrMesh.mElements.empty())
785 {
786 // Cope with empty meshes
788 }
789 else
790 {
791 // Make sure we start at an allowed element
792 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
793 {
794 ++(*this);
795 }
796 }
797}
798
799template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
801{
802 return mElementIter == mrMesh.mElements.end();
803}
804
805template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
807{
808 return !(mSkipDeletedElements && (*this)->IsDeleted());
809}
810
811#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)
bool IsNearExistingNodes(c_vector< double, SPACE_DIM > newNodeLocation, std::vector< Node< SPACE_DIM > * > nodesToCheck, double minClearance)
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)