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 SEMMESH_HPP_ 00037 #define SEMMESH_HPP_ 00038 00039 // Forward declaration prevents circular include chain 00040 template<unsigned DIM> 00041 class SemMeshWriter; 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 "SemMeshReader.hpp" 00056 #include "SemMeshWriter.hpp" 00057 #include "PottsElement.hpp" 00058 00062 template<unsigned DIM> 00063 class SemMesh : public AbstractMesh<DIM, DIM> 00064 { 00065 friend class TestSemMesh; 00066 00067 protected: 00068 00070 std::vector<PottsElement<DIM>*> mElements; 00071 00076 std::vector<unsigned> mDeletedElementIndices; 00077 00082 std::vector<unsigned> mDeletedNodeIndices; 00083 00090 unsigned SolveNodeMapping(unsigned index) const; 00091 00098 unsigned SolveElementMapping(unsigned index) const; 00099 00106 unsigned SolveBoundaryElementMapping(unsigned index) const; 00107 00109 friend class boost::serialization::access; 00110 00118 template<class Archive> 00119 void save(Archive & archive, const unsigned int version) const 00120 { 00121 // NOTE - Subclasses must archive their member variables BEFORE calling this method. 00122 archive & mDeletedElementIndices; 00123 archive & mDeletedNodeIndices; 00124 archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this); 00125 00126 // Create a mesh writer pointing to the correct file and directory 00127 SemMeshWriter<DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(), 00128 ArchiveLocationInfo::GetMeshFilename(), 00129 false); 00130 mesh_writer.WriteFilesUsingMesh(*(const_cast<SemMesh<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 & mDeletedNodeIndices; 00145 archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this); 00146 00147 SemMeshReader<DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename()); 00148 this->ConstructFromMeshReader(mesh_reader); 00149 } 00150 BOOST_SERIALIZATION_SPLIT_MEMBER() 00151 00152 public: 00153 00155 // Iterators // 00157 00159 class SemElementIterator; 00160 00166 inline SemElementIterator GetElementIteratorBegin(bool skipDeletedElements=true); 00167 00171 inline SemElementIterator GetElementIteratorEnd(); 00172 00174 // Methods // 00176 00183 SemMesh( std::vector<Node<DIM>*> nodes, 00184 std::vector<PottsElement<DIM>*> pottsElements); 00185 00189 SemMesh(); 00190 00194 virtual ~SemMesh(); 00195 00199 virtual unsigned GetNumNodes() const; 00200 00204 virtual unsigned GetNumAllNodes() const; 00205 00209 virtual unsigned GetNumElements() const; 00210 00214 unsigned GetNumAllElements() const; 00215 00221 PottsElement<DIM>* GetElement(unsigned index) const; 00222 00228 void ConstructFromMeshReader(AbstractMeshReader<DIM, DIM>& rMeshReader); 00229 00233 virtual void Clear(); 00234 00239 void ReMesh(); 00240 00246 void DeleteElement(unsigned index); 00247 00255 unsigned AddElement(PottsElement<DIM>* pNewElement, std::vector<Node<DIM>* > pNewNodes); 00256 00258 // Nested classes // 00260 00266 class SemElementIterator 00267 { 00268 public: 00274 inline PottsElement<DIM>& operator*(); 00275 00279 inline PottsElement<DIM>* operator->(); 00280 00286 inline bool operator!=(const SemMesh<DIM>::SemElementIterator& rOther); 00287 00291 inline SemElementIterator& operator++(); 00292 00303 SemElementIterator(SemMesh<DIM>& rMesh, 00304 typename std::vector<PottsElement<DIM> *>::iterator elementIter, 00305 bool skipDeletedElements=true); 00306 00307 private: 00309 SemMesh<DIM>& mrMesh; 00310 00312 typename std::vector<PottsElement<DIM> *>::iterator mElementIter; 00313 00315 bool mSkipDeletedElements; 00316 00320 inline bool IsAtEnd(); 00321 00325 inline bool IsAllowedElement(); 00326 }; 00327 }; 00328 00329 #include "SerializationExportWrapper.hpp" 00330 EXPORT_TEMPLATE_CLASS_SAME_DIMS(SemMesh) 00331 00332 00333 // SemElementIterator class implementation - most methods are inlined // 00335 00336 template<unsigned DIM> 00337 typename SemMesh<DIM>::SemElementIterator SemMesh<DIM>::GetElementIteratorBegin( 00338 bool skipDeletedElements) 00339 { 00340 return SemElementIterator(*this, mElements.begin(), skipDeletedElements); 00341 } 00342 00343 template<unsigned DIM> 00344 typename SemMesh<DIM>::SemElementIterator SemMesh<DIM>::GetElementIteratorEnd() 00345 { 00346 return SemElementIterator(*this, mElements.end()); 00347 } 00348 template<unsigned DIM> 00349 PottsElement<DIM>& SemMesh<DIM>::SemElementIterator::operator*() 00350 { 00351 assert(!IsAtEnd()); 00352 return **mElementIter; 00353 } 00354 00355 template<unsigned DIM> 00356 PottsElement<DIM>* SemMesh<DIM>::SemElementIterator::operator->() 00357 { 00358 assert(!IsAtEnd()); 00359 return *mElementIter; 00360 } 00361 00362 template<unsigned DIM> 00363 bool SemMesh<DIM>::SemElementIterator::operator!=(const SemMesh<DIM>::SemElementIterator& rOther) 00364 { 00365 return mElementIter != rOther.mElementIter; 00366 } 00367 00368 template<unsigned DIM> 00369 typename SemMesh<DIM>::SemElementIterator& SemMesh<DIM>::SemElementIterator::operator++() 00370 { 00371 do 00372 { 00373 ++mElementIter; 00374 } 00375 while (!IsAtEnd() && !IsAllowedElement()); 00376 00377 return (*this); 00378 } 00379 00380 template<unsigned DIM> 00381 SemMesh<DIM>::SemElementIterator::SemElementIterator( 00382 SemMesh<DIM>& rMesh, 00383 typename std::vector<PottsElement<DIM>*>::iterator elementIter, 00384 bool skipDeletedElements) 00385 : mrMesh(rMesh), 00386 mElementIter(elementIter), 00387 mSkipDeletedElements(skipDeletedElements) 00388 { 00389 if (mrMesh.mElements.empty()) 00390 { 00391 // Cope with empty meshes 00392 mElementIter = mrMesh.mElements.end(); 00393 } 00394 else 00395 { 00396 // Make sure we start at an allowed element 00397 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement()) 00398 { 00399 ++(*this); 00400 } 00401 } 00402 } 00403 00404 template<unsigned DIM> 00405 bool SemMesh<DIM>::SemElementIterator::IsAtEnd() 00406 { 00407 return mElementIter == mrMesh.mElements.end(); 00408 } 00409 00410 template<unsigned DIM> 00411 bool SemMesh<DIM>::SemElementIterator::IsAllowedElement() 00412 { 00413 return !(mSkipDeletedElements && (*this)->IsDeleted()); 00414 } 00415 00416 #endif /*SEMMESH_HPP_*/