VertexMesh.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 #ifndef VERTEXMESH_HPP_
00029 #define VERTEXMESH_HPP_
00030 
00031 // Forward declaration prevents circular include chain
00032 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00033 class VertexMeshWriter;
00034 
00035 #include <iostream>
00036 #include <map>
00037 #include <algorithm>
00038 
00039 #include "ChasteSerialization.hpp"
00040 #include <boost/serialization/vector.hpp>
00041 #include <boost/serialization/base_object.hpp>
00042 #include <boost/serialization/split_member.hpp>
00043 
00044 #include "AbstractMesh.hpp"
00045 #include "ArchiveLocationInfo.hpp"
00046 #include "VertexMeshReader.hpp"
00047 #include "VertexMeshWriter.hpp"
00048 #include "VertexElement.hpp"
00049 #include "VertexElementMap.hpp"
00050 #include "TetrahedralMesh.hpp"
00051 
00055 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00056 class VertexMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00057 {
00058     friend class TestVertexMesh;
00059 
00060 protected:
00061 
00063     std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> mElements;
00064 
00066     std::vector<VertexElement<ELEMENT_DIM-1, SPACE_DIM>*> mFaces;
00067 
00075     std::map<unsigned, unsigned> mVoronoiElementIndexMap;
00076 
00084     TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>* mpDelaunayMesh;
00085 
00092     unsigned SolveNodeMapping(unsigned index) const;
00093 
00100     unsigned SolveElementMapping(unsigned index) const;
00101 
00108     unsigned SolveBoundaryElementMapping(unsigned index) const;
00109 
00117     void GenerateVerticesFromElementCircumcentres(TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh);
00118 
00120     //                        2D-specific methods                       //
00122 
00139     bool ElementIncludesPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
00140 
00150     unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
00151 
00153     friend class boost::serialization::access;
00154 
00162     template<class Archive>
00163     void save(Archive & archive, const unsigned int version) const
00164     {
00165         archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00166 
00167         // Create a mesh writer pointing to the correct file and directory
00168         VertexMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00169                                                              ArchiveLocationInfo::GetMeshFilename(),
00170                                                              false);
00171         mesh_writer.WriteFilesUsingMesh(*(const_cast<VertexMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00172     }
00173 
00180     template<class Archive>
00181     void load(Archive & archive, const unsigned int version)
00182     {
00183         archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00184 
00185         VertexMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00186         this->ConstructFromMeshReader(mesh_reader);
00187     }
00188     BOOST_SERIALIZATION_SPLIT_MEMBER()
00189 
00190 public:
00191 
00193     //                            Iterators                             //
00195 
00197     class VertexElementIterator;
00198 
00204     inline VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00205 
00209     inline VertexElementIterator GetElementIteratorEnd();
00210 
00212     //                             Methods                              //
00214 
00221     VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00222                std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
00223 
00231     VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00232                std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*> faces,
00233                std::vector<VertexElement<ELEMENT_DIM,SPACE_DIM>*> vertexElements);
00234 
00244     VertexMesh(TetrahedralMesh<2,2>& rMesh, bool isPeriodic=false);
00245 
00254     VertexMesh(TetrahedralMesh<3,3>& rMesh);
00255 
00259     VertexMesh();
00260 
00264     virtual ~VertexMesh();
00265 
00269     virtual unsigned GetNumNodes() const;
00270 
00274     virtual unsigned GetNumElements() const;
00275 
00279     unsigned GetNumAllElements() const;
00280 
00284     virtual unsigned GetNumFaces() const;
00285 
00291     VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00292 
00298     VertexElement<ELEMENT_DIM-1, SPACE_DIM>* GetFace(unsigned index) const;
00299 
00309     virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index);
00310 
00316     void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00317 
00321     virtual void Clear();
00322 
00329     unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex);
00330 
00338     unsigned GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(unsigned nodeIndex);
00339 
00351     virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
00352                                                           const c_vector<double, SPACE_DIM>& rLocationB);
00353 
00363     virtual double GetVolumeOfElement(unsigned index);
00364 
00374     virtual double GetSurfaceAreaOfElement(unsigned index);
00375 
00377     //                        2D-specific methods                       //
00379 
00391     c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00392 
00404     c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00405 
00417     c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00418 
00428     c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00429 
00437     virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index);
00438 
00445     double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2);
00446 
00448     //                        3D-specific methods                       //
00450 
00460     c_vector<double, SPACE_DIM> GetUnitNormalToFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace);
00461 
00473     virtual double GetAreaOfFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace);
00474 
00485     c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index);
00486 
00493     std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex);
00494 
00507     std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex);
00508 
00515     std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex);
00516 
00518     //                         Nested classes                           //
00520 
00526     class VertexElementIterator
00527     {
00528     public:
00534         inline VertexElement<ELEMENT_DIM, SPACE_DIM>& operator*();
00535 
00539         inline VertexElement<ELEMENT_DIM, SPACE_DIM>* operator->();
00540 
00546         inline bool operator!=(const VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther);
00547 
00551         inline VertexElementIterator& operator++();
00552 
00563         VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00564                         typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00565                         bool skipDeletedElements=true);
00566 
00567     private:
00569         VertexMesh& mrMesh;
00570 
00572         typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00573 
00575         bool mSkipDeletedElements;
00576 
00580         inline bool IsAtEnd();
00581 
00585         inline bool IsAllowedElement();
00586     };
00587 };
00588 
00589 #include "SerializationExportWrapper.hpp"
00590 EXPORT_TEMPLATE_CLASS_ALL_DIMS(VertexMesh)
00591 
00592 
00593 
00594 // VertexElementIterator class implementation - most methods are inlined    //
00596 
00597 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00598 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00599         bool skipDeletedElements)
00600 {
00601     return VertexElementIterator(*this, mElements.begin(), skipDeletedElements);
00602 }
00603 
00604 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00605 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00606 {
00607     return VertexElementIterator(*this, mElements.end());
00608 }
00609 
00610 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00611 VertexElement<ELEMENT_DIM, SPACE_DIM>& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator*()
00612 {
00613     assert(!IsAtEnd());
00614     return **mElementIter;
00615 }
00616 
00617 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00618 VertexElement<ELEMENT_DIM, SPACE_DIM>* VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator->()
00619 {
00620     assert(!IsAtEnd());
00621     return *mElementIter;
00622 }
00623 
00624 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00625 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator!=(const VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther)
00626 {
00627     return mElementIter != rOther.mElementIter;
00628 }
00629 
00630 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00631 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator++()
00632 {
00633     do
00634     {
00635         ++mElementIter;
00636     }
00637     while (!IsAtEnd() && !IsAllowedElement());
00638 
00639     return (*this);
00640 }
00641 
00642 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00643 VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::VertexElementIterator(
00644         VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00645         typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00646         bool skipDeletedElements)
00647     : mrMesh(rMesh),
00648       mElementIter(elementIter),
00649       mSkipDeletedElements(skipDeletedElements)
00650 {
00651     if (mrMesh.mElements.empty())
00652     {
00653         // Cope with empty meshes
00654         mElementIter = mrMesh.mElements.end();
00655     }
00656     else
00657     {
00658         // Make sure we start at an allowed element
00659         if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00660         {
00661             ++(*this);
00662         }
00663     }
00664 }
00665 
00666 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00667 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAtEnd()
00668 {
00669     return mElementIter == mrMesh.mElements.end();
00670 }
00671 
00672 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00673 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAllowedElement()
00674 {
00675     return !(mSkipDeletedElements && (*this)->IsDeleted());
00676 }
00677 
00678 
00679 #endif /*VERTEXMESH_HPP_*/
Generated on Thu Dec 22 13:00:16 2011 for Chaste by  doxygen 1.6.3