VertexMesh.hpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 #ifndef VERTEXMESH_HPP_
00036 #define VERTEXMESH_HPP_
00037 
00038 // Forward declaration prevents circular include chain
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         // Create a mesh writer pointing to the correct file and directory
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 // VertexElementIterator class implementation - most methods are inlined    //
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         // Cope with empty meshes
00713         mElementIter = mrMesh.mElements.end();
00714     }
00715     else
00716     {
00717         // Make sure we start at an allowed element
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 /*VERTEXMESH_HPP_*/

Generated by  doxygen 1.6.2