00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef VERTEXMESH_HPP_
00036 #define VERTEXMESH_HPP_
00037
00038
00039 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00040 class VertexMeshWriter;
00041
00042 #include <iostream>
00043 #include <map>
00044 #include <algorithm>
00045
00046 #include "ChasteSerialization.hpp"
00047 #include <boost/serialization/vector.hpp>
00048 #include <boost/serialization/base_object.hpp>
00049 #include <boost/serialization/split_member.hpp>
00050
00051 #include "AbstractMesh.hpp"
00052 #include "ArchiveLocationInfo.hpp"
00053 #include "VertexMeshReader.hpp"
00054 #include "VertexMeshWriter.hpp"
00055 #include "VertexElement.hpp"
00056 #include "VertexElementMap.hpp"
00057 #include "TetrahedralMesh.hpp"
00058
00073 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00074 class VertexMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00075 {
00076 friend class TestVertexMesh;
00077
00078 protected:
00079
00081 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> mElements;
00082
00084 std::vector<VertexElement<ELEMENT_DIM-1, SPACE_DIM>*> mFaces;
00085
00093 std::map<unsigned, unsigned> mVoronoiElementIndexMap;
00094
00102 TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>* mpDelaunayMesh;
00103
00111 unsigned SolveNodeMapping(unsigned index) const;
00112
00120 unsigned SolveElementMapping(unsigned index) const;
00121
00129 unsigned SolveBoundaryElementMapping(unsigned index) const;
00130
00138 void GenerateVerticesFromElementCircumcentres(TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh);
00139
00160 bool ElementIncludesPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
00161
00171 unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
00172
00174 friend class boost::serialization::access;
00175
00183 template<class Archive>
00184 void save(Archive & archive, const unsigned int version) const
00185 {
00186 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00187
00188
00189 VertexMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00190 ArchiveLocationInfo::GetMeshFilename(),
00191 false);
00192 mesh_writer.WriteFilesUsingMesh(*(const_cast<VertexMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00193 }
00194
00201 template<class Archive>
00202 void load(Archive & archive, const unsigned int version)
00203 {
00204 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00205
00206 VertexMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00207 this->ConstructFromMeshReader(mesh_reader);
00208 }
00209 BOOST_SERIALIZATION_SPLIT_MEMBER()
00210
00211 public:
00212
00214 class VertexElementIterator;
00215
00221 inline VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00222
00226 inline VertexElementIterator GetElementIteratorEnd();
00227
00234 VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00235 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
00236
00244 VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00245 std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*> faces,
00246 std::vector<VertexElement<ELEMENT_DIM,SPACE_DIM>*> vertexElements);
00247
00257 VertexMesh(TetrahedralMesh<2,2>& rMesh, bool isPeriodic=false);
00258
00267 VertexMesh(TetrahedralMesh<3,3>& rMesh);
00268
00272 VertexMesh();
00273
00277 virtual ~VertexMesh();
00278
00282 virtual unsigned GetNumNodes() const;
00283
00287 virtual unsigned GetNumElements() const;
00288
00292 unsigned GetNumAllElements() const;
00293
00297 virtual unsigned GetNumFaces() const;
00298
00304 VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00305
00311 VertexElement<ELEMENT_DIM-1, SPACE_DIM>* GetFace(unsigned index) const;
00312
00328 virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index);
00329
00335 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00336
00340 virtual void Clear();
00341
00347 unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex);
00348
00356 unsigned GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(unsigned nodeIndex);
00357
00369 virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
00370 const c_vector<double, SPACE_DIM>& rLocationB);
00371
00381 virtual double GetVolumeOfElement(unsigned index);
00382
00392 virtual double GetSurfaceAreaOfElement(unsigned index);
00393
00405 c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00406
00418 c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00419
00431 c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00432
00442 c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00443
00473 virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index);
00474
00481 double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2);
00482
00493 double GetElongationShapeFactorOfElement(unsigned elementIndex);
00494
00506 double CalculateUnitNormalToFaceWithArea(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace, c_vector<double, SPACE_DIM>& rNormal);
00507
00517 virtual double CalculateAreaOfFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace);
00518
00544 c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index);
00545
00552 std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex);
00553
00566 std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex);
00567
00574 std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex);
00575
00581 class VertexElementIterator
00582 {
00583 public:
00589 inline VertexElement<ELEMENT_DIM, SPACE_DIM>& operator*();
00590
00595 inline VertexElement<ELEMENT_DIM, SPACE_DIM>* operator->();
00596
00602 inline bool operator!=(const typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther);
00603
00608 inline VertexElementIterator& operator++();
00609
00620 VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00621 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00622 bool skipDeletedElements=true);
00623
00624 private:
00626 VertexMesh& mrMesh;
00627
00629 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00630
00632 bool mSkipDeletedElements;
00633
00638 inline bool IsAtEnd();
00639
00644 inline bool IsAllowedElement();
00645 };
00646 };
00647
00648 #include "SerializationExportWrapper.hpp"
00649 EXPORT_TEMPLATE_CLASS_ALL_DIMS(VertexMesh)
00650
00651
00652
00653
00655
00656 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00657 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00658 bool skipDeletedElements)
00659 {
00660 return VertexElementIterator(*this, mElements.begin(), skipDeletedElements);
00661 }
00662
00663 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00664 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00665 {
00666 return VertexElementIterator(*this, mElements.end());
00667 }
00668
00669 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00670 VertexElement<ELEMENT_DIM, SPACE_DIM>& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator*()
00671 {
00672 assert(!IsAtEnd());
00673 return **mElementIter;
00674 }
00675
00676 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00677 VertexElement<ELEMENT_DIM, SPACE_DIM>* VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator->()
00678 {
00679 assert(!IsAtEnd());
00680 return *mElementIter;
00681 }
00682
00683 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00684 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator!=(const typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther)
00685 {
00686 return mElementIter != rOther.mElementIter;
00687 }
00688
00689 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00690 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator++()
00691 {
00692 do
00693 {
00694 ++mElementIter;
00695 }
00696 while (!IsAtEnd() && !IsAllowedElement());
00697
00698 return (*this);
00699 }
00700
00701 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00702 VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::VertexElementIterator(
00703 VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00704 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00705 bool skipDeletedElements)
00706 : mrMesh(rMesh),
00707 mElementIter(elementIter),
00708 mSkipDeletedElements(skipDeletedElements)
00709 {
00710 if (mrMesh.mElements.empty())
00711 {
00712
00713 mElementIter = mrMesh.mElements.end();
00714 }
00715 else
00716 {
00717
00718 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00719 {
00720 ++(*this);
00721 }
00722 }
00723 }
00724
00725 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00726 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAtEnd()
00727 {
00728 return mElementIter == mrMesh.mElements.end();
00729 }
00730
00731 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00732 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAllowedElement()
00733 {
00734 return !(mSkipDeletedElements && (*this)->IsDeleted());
00735 }
00736
00737 #endif