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 00036 #ifndef POTTSMESH_HPP_ 00037 #define POTTSMESH_HPP_ 00038 00039 // Forward declaration prevents circular include chain 00040 template<unsigned DIM> 00041 class PottsMeshWriter; 00042 00043 #include <iostream> 00044 #include <map> 00045 #include <algorithm> 00046 00047 #include "ChasteSerialization.hpp" 00048 #include <boost/serialization/vector.hpp> 00049 #include <boost/serialization/set.hpp> 00050 #include <boost/serialization/base_object.hpp> 00051 #include <boost/serialization/split_member.hpp> 00052 00053 #include "AbstractMesh.hpp" 00054 #include "ArchiveLocationInfo.hpp" 00055 #include "PottsMeshReader.hpp" 00056 #include "PottsMeshWriter.hpp" 00057 #include "PottsElement.hpp" 00058 00062 template<unsigned DIM> 00063 class PottsMesh : public AbstractMesh<DIM, DIM> 00064 { 00065 friend class TestPottsMesh; 00066 00067 protected: 00069 std::vector<PottsElement<DIM>*> mElements; 00070 00075 std::vector<unsigned> mDeletedElementIndices; 00076 00078 std::vector< std::set<unsigned> > mVonNeumannNeighbouringNodeIndices; 00079 00081 std::vector< std::set<unsigned> > mMooreNeighbouringNodeIndices; 00082 00089 unsigned SolveNodeMapping(unsigned index) const; 00090 00097 unsigned SolveElementMapping(unsigned index) const; 00098 00105 unsigned SolveBoundaryElementMapping(unsigned index) const; 00106 00108 friend class boost::serialization::access; 00109 00117 template<class Archive> 00118 void save(Archive & archive, const unsigned int version) const 00119 { 00120 // NOTE - Subclasses must archive their member variables BEFORE calling this method. 00121 archive & mDeletedElementIndices; 00122 archive & mVonNeumannNeighbouringNodeIndices; 00123 archive & mMooreNeighbouringNodeIndices; 00124 archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this); 00125 00126 // Create a mesh writer pointing to the correct file and directory 00127 PottsMeshWriter<DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(), 00128 ArchiveLocationInfo::GetMeshFilename(), 00129 false); 00130 mesh_writer.WriteFilesUsingMesh(*(const_cast<PottsMesh<DIM>*>(this))); 00131 } 00132 00139 template<class Archive> 00140 void load(Archive & archive, const unsigned int version) 00141 { 00142 // NOTE - Subclasses must archive their member variables BEFORE calling this method. 00143 archive & mDeletedElementIndices; 00144 archive & mVonNeumannNeighbouringNodeIndices; 00145 archive & mMooreNeighbouringNodeIndices; 00146 archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this); 00147 00148 PottsMeshReader<DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename()); 00149 this->ConstructFromMeshReader(mesh_reader); 00150 } 00151 BOOST_SERIALIZATION_SPLIT_MEMBER() 00152 00153 public: 00154 00156 // Iterators // 00158 00160 class PottsElementIterator; 00161 00167 inline PottsElementIterator GetElementIteratorBegin(bool skipDeletedElements=true); 00168 00172 inline PottsElementIterator GetElementIteratorEnd(); 00173 00175 // Methods // 00177 00186 PottsMesh(std::vector<Node<DIM>*> nodes, 00187 std::vector<PottsElement<DIM>*> pottsElements, 00188 std::vector< std::set<unsigned> > vonNeumannNeighbouringNodeIndices, 00189 std::vector< std::set<unsigned> > mooreNeighbouringNodeIndices); 00190 00191 00195 PottsMesh(); 00196 00200 virtual ~PottsMesh(); 00201 00205 virtual unsigned GetNumNodes() const; 00206 00210 virtual unsigned GetNumElements() const; 00211 00215 unsigned GetNumAllElements() const; 00216 00222 PottsElement<DIM>* GetElement(unsigned index) const; 00223 00233 virtual c_vector<double, DIM> GetCentroidOfElement(unsigned index); 00234 00240 void ConstructFromMeshReader(AbstractMeshReader<DIM, DIM>& rMeshReader); 00241 00245 virtual void Clear(); 00246 00258 virtual c_vector<double, DIM> GetVectorFromAtoB(const c_vector<double, DIM>& rLocationA, 00259 const c_vector<double, DIM>& rLocationB); 00260 00270 virtual double GetVolumeOfElement(unsigned index); 00271 00281 virtual double GetSurfaceAreaOfElement(unsigned index); 00282 00289 std::set<unsigned> GetMooreNeighbouringNodeIndices(unsigned nodeIndex); 00290 00297 std::set<unsigned> GetVonNeumannNeighbouringNodeIndices(unsigned nodeIndex); 00298 00305 void DeleteElement(unsigned index); 00306 00317 unsigned DivideElement(PottsElement<DIM>* pElement, 00318 bool placeOriginalElementBelow=false); 00319 00327 unsigned AddElement(PottsElement<DIM>* pNewElement); 00328 00330 // Nested classes // 00332 00338 class PottsElementIterator 00339 { 00340 public: 00346 inline PottsElement<DIM>& operator*(); 00347 00351 inline PottsElement<DIM>* operator->(); 00352 00358 inline bool operator!=(const PottsMesh<DIM>::PottsElementIterator& rOther); 00359 00363 inline PottsElementIterator& operator++(); 00364 00375 PottsElementIterator(PottsMesh<DIM>& rMesh, 00376 typename std::vector<PottsElement<DIM> *>::iterator elementIter, 00377 bool skipDeletedElements=true); 00378 00379 private: 00381 PottsMesh<DIM>& mrMesh; 00382 00384 typename std::vector<PottsElement<DIM> *>::iterator mElementIter; 00385 00387 bool mSkipDeletedElements; 00388 00392 inline bool IsAtEnd(); 00393 00397 inline bool IsAllowedElement(); 00398 }; 00399 }; 00400 00401 #include "SerializationExportWrapper.hpp" 00402 EXPORT_TEMPLATE_CLASS_SAME_DIMS(PottsMesh) 00403 00404 00405 // PottsElementIterator class implementation - most methods are inlined // 00407 00408 template<unsigned DIM> 00409 typename PottsMesh<DIM>::PottsElementIterator PottsMesh<DIM>::GetElementIteratorBegin( 00410 bool skipDeletedElements) 00411 { 00412 return PottsElementIterator(*this, mElements.begin(), skipDeletedElements); 00413 } 00414 00415 template<unsigned DIM> 00416 typename PottsMesh<DIM>::PottsElementIterator PottsMesh<DIM>::GetElementIteratorEnd() 00417 { 00418 return PottsElementIterator(*this, mElements.end()); 00419 } 00420 template<unsigned DIM> 00421 PottsElement<DIM>& PottsMesh<DIM>::PottsElementIterator::operator*() 00422 { 00423 assert(!IsAtEnd()); 00424 return **mElementIter; 00425 } 00426 00427 template<unsigned DIM> 00428 PottsElement<DIM>* PottsMesh<DIM>::PottsElementIterator::operator->() 00429 { 00430 assert(!IsAtEnd()); 00431 return *mElementIter; 00432 } 00433 00434 template<unsigned DIM> 00435 bool PottsMesh<DIM>::PottsElementIterator::operator!=(const PottsMesh<DIM>::PottsElementIterator& rOther) 00436 { 00437 return mElementIter != rOther.mElementIter; 00438 } 00439 00440 template<unsigned DIM> 00441 typename PottsMesh<DIM>::PottsElementIterator& PottsMesh<DIM>::PottsElementIterator::operator++() 00442 { 00443 do 00444 { 00445 ++mElementIter; 00446 } 00447 while (!IsAtEnd() && !IsAllowedElement()); 00448 00449 return (*this); 00450 } 00451 00452 template<unsigned DIM> 00453 PottsMesh<DIM>::PottsElementIterator::PottsElementIterator( 00454 PottsMesh<DIM>& rMesh, 00455 typename std::vector<PottsElement<DIM>*>::iterator elementIter, 00456 bool skipDeletedElements) 00457 : mrMesh(rMesh), 00458 mElementIter(elementIter), 00459 mSkipDeletedElements(skipDeletedElements) 00460 { 00461 if (mrMesh.mElements.empty()) 00462 { 00463 // Cope with empty meshes 00464 mElementIter = mrMesh.mElements.end(); 00465 } 00466 else 00467 { 00468 // Make sure we start at an allowed element 00469 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement()) 00470 { 00471 ++(*this); 00472 } 00473 } 00474 } 00475 00476 template<unsigned DIM> 00477 bool PottsMesh<DIM>::PottsElementIterator::IsAtEnd() 00478 { 00479 return mElementIter == mrMesh.mElements.end(); 00480 } 00481 00482 template<unsigned DIM> 00483 bool PottsMesh<DIM>::PottsElementIterator::IsAllowedElement() 00484 { 00485 return !(mSkipDeletedElements && (*this)->IsDeleted()); 00486 } 00487 00488 #endif /*POTTSMESH_HPP_*/