Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, 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 00062 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00063 class VertexMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM> 00064 { 00065 friend class TestVertexMesh; 00066 00067 protected: 00068 00070 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> mElements; 00071 00073 std::vector<VertexElement<ELEMENT_DIM-1, SPACE_DIM>*> mFaces; 00074 00082 std::map<unsigned, unsigned> mVoronoiElementIndexMap; 00083 00091 TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>* mpDelaunayMesh; 00092 00099 unsigned SolveNodeMapping(unsigned index) const; 00100 00107 unsigned SolveElementMapping(unsigned index) const; 00108 00115 unsigned SolveBoundaryElementMapping(unsigned index) const; 00116 00124 void GenerateVerticesFromElementCircumcentres(TetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh); 00125 00127 // 2D-specific methods // 00129 00146 bool ElementIncludesPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex); 00147 00157 unsigned GetLocalIndexForElementEdgeClosestToPoint(const c_vector<double, SPACE_DIM>& rTestPoint, unsigned elementIndex); 00158 00160 friend class boost::serialization::access; 00161 00169 template<class Archive> 00170 void save(Archive & archive, const unsigned int version) const 00171 { 00172 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this); 00173 00174 // Create a mesh writer pointing to the correct file and directory 00175 VertexMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(), 00176 ArchiveLocationInfo::GetMeshFilename(), 00177 false); 00178 mesh_writer.WriteFilesUsingMesh(*(const_cast<VertexMesh<ELEMENT_DIM, SPACE_DIM>*>(this))); 00179 } 00180 00187 template<class Archive> 00188 void load(Archive & archive, const unsigned int version) 00189 { 00190 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this); 00191 00192 VertexMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename()); 00193 this->ConstructFromMeshReader(mesh_reader); 00194 } 00195 BOOST_SERIALIZATION_SPLIT_MEMBER() 00196 00197 public: 00198 00200 // Iterators // 00202 00204 class VertexElementIterator; 00205 00211 inline VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true); 00212 00216 inline VertexElementIterator GetElementIteratorEnd(); 00217 00219 // Methods // 00221 00228 VertexMesh(std::vector<Node<SPACE_DIM>*> nodes, 00229 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> vertexElements); 00230 00238 VertexMesh(std::vector<Node<SPACE_DIM>*> nodes, 00239 std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*> faces, 00240 std::vector<VertexElement<ELEMENT_DIM,SPACE_DIM>*> vertexElements); 00241 00251 VertexMesh(TetrahedralMesh<2,2>& rMesh, bool isPeriodic=false); 00252 00261 VertexMesh(TetrahedralMesh<3,3>& rMesh); 00262 00266 VertexMesh(); 00267 00271 virtual ~VertexMesh(); 00272 00276 virtual unsigned GetNumNodes() const; 00277 00281 virtual unsigned GetNumElements() const; 00282 00286 unsigned GetNumAllElements() const; 00287 00291 virtual unsigned GetNumFaces() const; 00292 00298 VertexElement<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const; 00299 00305 VertexElement<ELEMENT_DIM-1, SPACE_DIM>* GetFace(unsigned index) const; 00306 00316 virtual c_vector<double, SPACE_DIM> GetCentroidOfElement(unsigned index); 00317 00323 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader); 00324 00328 virtual void Clear(); 00329 00336 unsigned GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(unsigned elementIndex); 00337 00345 unsigned GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(unsigned nodeIndex); 00346 00358 virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA, 00359 const c_vector<double, SPACE_DIM>& rLocationB); 00360 00370 virtual double GetVolumeOfElement(unsigned index); 00371 00381 virtual double GetSurfaceAreaOfElement(unsigned index); 00382 00384 // 2D-specific methods // 00386 00398 c_vector<double, SPACE_DIM> GetAreaGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex); 00399 00411 c_vector<double, SPACE_DIM> GetPreviousEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex); 00412 00424 c_vector<double, SPACE_DIM> GetNextEdgeGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex); 00425 00435 c_vector<double, SPACE_DIM> GetPerimeterGradientOfElementAtNode(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement, unsigned localIndex); 00436 00444 virtual c_vector<double, 3> CalculateMomentsOfElement(unsigned index); 00445 00452 double GetEdgeLength(unsigned elementIndex1, unsigned elementIndex2); 00453 00455 // 3D-specific methods // 00457 00467 c_vector<double, SPACE_DIM> GetUnitNormalToFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace); 00468 00480 virtual double GetAreaOfFace(VertexElement<ELEMENT_DIM-1, SPACE_DIM>* pFace); 00481 00492 c_vector<double, SPACE_DIM> GetShortAxisOfElement(unsigned index); 00493 00500 std::set<unsigned> GetNeighbouringNodeIndices(unsigned nodeIndex); 00501 00514 std::set<unsigned> GetNeighbouringNodeNotAlsoInElement(unsigned nodeIndex, unsigned elemIndex); 00515 00522 std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex); 00523 00525 // Nested classes // 00527 00533 class VertexElementIterator 00534 { 00535 public: 00541 inline VertexElement<ELEMENT_DIM, SPACE_DIM>& operator*(); 00542 00546 inline VertexElement<ELEMENT_DIM, SPACE_DIM>* operator->(); 00547 00553 inline bool operator!=(const VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther); 00554 00558 inline VertexElementIterator& operator++(); 00559 00570 VertexElementIterator(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh, 00571 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter, 00572 bool skipDeletedElements=true); 00573 00574 private: 00576 VertexMesh& mrMesh; 00577 00579 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter; 00580 00582 bool mSkipDeletedElements; 00583 00587 inline bool IsAtEnd(); 00588 00592 inline bool IsAllowedElement(); 00593 }; 00594 }; 00595 00596 #include "SerializationExportWrapper.hpp" 00597 EXPORT_TEMPLATE_CLASS_ALL_DIMS(VertexMesh) 00598 00599 00600 00601 // VertexElementIterator class implementation - most methods are inlined // 00603 00604 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00605 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin( 00606 bool skipDeletedElements) 00607 { 00608 return VertexElementIterator(*this, mElements.begin(), skipDeletedElements); 00609 } 00610 00611 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00612 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator VertexMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd() 00613 { 00614 return VertexElementIterator(*this, mElements.end()); 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 VertexElement<ELEMENT_DIM, SPACE_DIM>* VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator->() 00626 { 00627 assert(!IsAtEnd()); 00628 return *mElementIter; 00629 } 00630 00631 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00632 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator!=(const VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& rOther) 00633 { 00634 return mElementIter != rOther.mElementIter; 00635 } 00636 00637 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00638 typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator& VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::operator++() 00639 { 00640 do 00641 { 00642 ++mElementIter; 00643 } 00644 while (!IsAtEnd() && !IsAllowedElement()); 00645 00646 return (*this); 00647 } 00648 00649 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00650 VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::VertexElementIterator( 00651 VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh, 00652 typename std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter, 00653 bool skipDeletedElements) 00654 : mrMesh(rMesh), 00655 mElementIter(elementIter), 00656 mSkipDeletedElements(skipDeletedElements) 00657 { 00658 if (mrMesh.mElements.empty()) 00659 { 00660 // Cope with empty meshes 00661 mElementIter = mrMesh.mElements.end(); 00662 } 00663 else 00664 { 00665 // Make sure we start at an allowed element 00666 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement()) 00667 { 00668 ++(*this); 00669 } 00670 } 00671 } 00672 00673 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00674 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAtEnd() 00675 { 00676 return mElementIter == mrMesh.mElements.end(); 00677 } 00678 00679 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00680 bool VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator::IsAllowedElement() 00681 { 00682 return !(mSkipDeletedElements && (*this)->IsDeleted()); 00683 } 00684 00685 00686 #endif /*VERTEXMESH_HPP_*/