VertexMesh.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 <climits> // Work around Boost bug
00040 #include "ChasteSerialization.hpp"
00041 #include <boost/serialization/vector.hpp>
00042 #include <boost/serialization/base_object.hpp>
00043 #include <boost/serialization/split_member.hpp>
00044 
00045 #include "AbstractMesh.hpp"
00046 #include "ArchiveLocationInfo.hpp"
00047 #include "VertexMeshReader.hpp"
00048 #include "VertexMeshWriter.hpp"
00049 #include "VertexElement.hpp"
00050 #include "VertexElementMap.hpp"
00051 #include "TetrahedralMesh.hpp"
00052 
00056 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00057 class VertexMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00058 {
00059     friend class TestVertexMesh;
00060 
00061 protected:
00062 
00064     std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> mElements;
00065 
00067     std::vector<VertexElement<ELEMENT_DIM-1, SPACE_DIM>*> mFaces;
00068 
00075     unsigned SolveNodeMapping(unsigned index) const;
00076 
00083     unsigned SolveElementMapping(unsigned index) const;
00084 
00091     unsigned SolveBoundaryElementMapping(unsigned index) const;
00092 
00100     void GenerateVerticesFromElementCircumcentres(TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh);
00101 
00103     //                        2D-specific methods                       //
00105 
00122     bool ElementIncludesPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
00123 
00133     unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex);
00134 
00136     friend class boost::serialization::access;
00137 
00145     template<class Archive>
00146     void save(Archive & archive, const unsigned int version) const
00147     {
00148         archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00149 
00150         // Create a mesh writer pointing to the correct file and directory
00151         VertexMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00152                                                              ArchiveLocationInfo::GetMeshFilename(),
00153                                                              false);
00154         mesh_writer.WriteFilesUsingMesh(*(const_cast<VertexMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00155     }
00156 
00163     template<class Archive>
00164     void load(Archive & archive, const unsigned int version)
00165     {
00166         archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00167 
00168         VertexMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00169         this->ConstructFromMeshReader(mesh_reader);
00170     }
00171     BOOST_SERIALIZATION_SPLIT_MEMBER()
00172 
00173 public:
00174 
00176     //                            Iterators                             //
00178 
00180     class VertexElementIterator;
00181 
00187     inline VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00188 
00192     inline VertexElementIterator GetElementIteratorEnd();
00193 
00195     //                             Methods                              //
00197 
00204     VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00205                std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements);
00206 
00214     VertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00215                std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*> faces,
00216                std::vector<VertexElement<ELEMENT_DIM,SPACE_DIM>*> vertexElements);
00217 
00225     VertexMesh(TetrahedralMesh<2,2>& rMesh,
00226                const std::vector<unsigned> locationIndices=std::vector<unsigned>());
00227 
00235     VertexMesh(TetrahedralMesh<3,3>& rMesh,
00236                const std::vector<unsigned> locationIndices=std::vector<unsigned>());
00237 
00241     VertexMesh();
00242 
00246     virtual ~VertexMesh();
00247 
00251     virtual unsigned GetNumNodes() const;
00252 
00256     virtual unsigned GetNumElements() const;
00257 
00261     unsigned GetNumAllElements() const;
00262 
00266     virtual unsigned GetNumFaces() const;
00267 
00273     VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00274 
00280     VertexElement<ELEMENT_DIM-1, SPACE_DIM>* GetFace(unsigned index) const;
00281 
00291     virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index);
00292 
00298     void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00299 
00303     virtual void Clear();
00304 
00311     void Translate(c_vector<double, SPACE_DIM>& rDisplacement);
00312 
00320     void Translate(const double xMovement=0.0, const double yMovement=0.0, const double zMovement=0.0);
00321 
00323     //                        2D-specific methods                       //
00325 
00335     virtual double GetAreaOfElement(unsigned index);
00336 
00347     double GetPerimeterOfElement(unsigned index);
00348 
00360     c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00361 
00373     c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00374 
00386     c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00387 
00397     c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex);
00398 
00406     virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index);
00407 
00414     double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2);
00415 
00417     //                        3D-specific methods                       //
00419 
00429     c_vector<double, SPACE_DIM> GetUnitNormalToFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace);
00430 
00442     virtual double GetAreaOfFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace);
00443 
00453     virtual double GetVolumeOfElement(unsigned index);
00454 
00464     virtual double GetSurfaceAreaOfElement(unsigned index);
00465 
00479     c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index);
00480 
00487     std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex);
00488 
00501     std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex);
00502 
00504     //                         Nested classes                           //
00506 
00510     class VertexElementIterator
00511     {
00512     public:
00518         inline VertexElement<ELEMENT_DIM, SPACE_DIM>& operator*();
00519 
00523         inline VertexElement<ELEMENT_DIM, SPACE_DIM>* operator->();
00524 
00530         inline bool operator!=(const VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther);
00531 
00535         inline VertexElementIterator& operator++();
00536 
00547         VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00548                         typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00549                         bool skipDeletedElements=true);
00550 
00551     private:
00553         VertexMesh& mrMesh;
00554 
00556         typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00557 
00559         bool mSkipDeletedElements;
00560 
00564         inline bool IsAtEnd();
00565 
00569         inline bool IsAllowedElement();
00570     };
00571 };
00572 
00573 #include "SerializationExportWrapper.hpp"
00574 EXPORT_TEMPLATE_CLASS_ALL_DIMS(VertexMesh);
00575 
00576 
00578 // VertexElementIterator class implementation - most methods are inlined    //
00580 
00581 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00582 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00583         bool skipDeletedElements)
00584 {
00585     return VertexElementIterator(*this, mElements.begin(), skipDeletedElements);
00586 }
00587 
00588 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00589 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00590 {
00591     return VertexElementIterator(*this, mElements.end());
00592 }
00593 
00594 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00595 VertexElement<ELEMENT_DIM, SPACE_DIM>& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator*()
00596 {
00597     assert(!IsAtEnd());
00598     return **mElementIter;
00599 }
00600 
00601 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00602 VertexElement<ELEMENT_DIM, SPACE_DIM>* VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator->()
00603 {
00604     assert(!IsAtEnd());
00605     return *mElementIter;
00606 }
00607 
00608 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00609 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator!=(const VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther)
00610 {
00611     return mElementIter != rOther.mElementIter;
00612 }
00613 
00614 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00615 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator++()
00616 {
00617     do
00618     {
00619         ++mElementIter;
00620     }
00621     while (!IsAtEnd() && !IsAllowedElement());
00622 
00623     return (*this);
00624 }
00625 
00626 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00627 VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::VertexElementIterator(
00628         VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00629         typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00630         bool skipDeletedElements)
00631     : mrMesh(rMesh),
00632       mElementIter(elementIter),
00633       mSkipDeletedElements(skipDeletedElements)
00634 {
00635     if (mrMesh.mElements.size() == 0)
00636     {
00637         // Cope with empty meshes
00638         mElementIter = mrMesh.mElements.end();
00639     }
00640     else
00641     {
00642         // Make sure we start at an allowed element
00643         if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00644         {
00645             ++(*this);
00646         }
00647     }
00648 }
00649 
00650 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00651 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAtEnd()
00652 {
00653     return mElementIter == mrMesh.mElements.end();
00654 }
00655 
00656 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00657 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAllowedElement()
00658 {
00659     return !(mSkipDeletedElements && (*this)->IsDeleted());
00660 }
00661 
00662 
00663 #endif /*VERTEXMESH_HPP_*/

Generated by  doxygen 1.6.2