PottsMesh.hpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 
00090     unsigned SolveNodeMapping(unsigned index) const;
00091 
00099     unsigned SolveElementMapping(unsigned index) const;
00100 
00108     unsigned SolveBoundaryElementMapping(unsigned index) const;
00109 
00111     friend class boost::serialization::access;
00112 
00120     template<class Archive>
00121     void save(Archive & archive, const unsigned int version) const
00122     {
00123         // NOTE - Subclasses must archive their member variables BEFORE calling this method.
00124         archive & mDeletedElementIndices;
00125         archive & mVonNeumannNeighbouringNodeIndices;
00126         archive & mMooreNeighbouringNodeIndices;
00127         archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this);
00128 
00129         // Create a mesh writer pointing to the correct file and directory
00130         PottsMeshWriter<DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00131                                          ArchiveLocationInfo::GetMeshFilename(),
00132                                          false);
00133         mesh_writer.WriteFilesUsingMesh(*(const_cast<PottsMesh<DIM>*>(this)));
00134     }
00135 
00142     template<class Archive>
00143     void load(Archive & archive, const unsigned int version)
00144     {
00145         // NOTE - Subclasses must archive their member variables BEFORE calling this method.
00146         archive & mDeletedElementIndices;
00147         archive & mVonNeumannNeighbouringNodeIndices;
00148         archive & mMooreNeighbouringNodeIndices;
00149         archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this);
00150 
00151         PottsMeshReader<DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00152         this->ConstructFromMeshReader(mesh_reader);
00153     }
00154     BOOST_SERIALIZATION_SPLIT_MEMBER()
00155 
00156 public:
00157 
00159     //                            Iterators                             //
00161 
00163     class PottsElementIterator;
00164 
00170     inline PottsElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00171 
00175     inline PottsElementIterator GetElementIteratorEnd();
00176 
00178     //                             Methods                              //
00180 
00189     PottsMesh(std::vector<Node<DIM>*> nodes,
00190               std::vector<PottsElement<DIM>*> pottsElements,
00191               std::vector< std::set<unsigned> > vonNeumannNeighbouringNodeIndices,
00192               std::vector< std::set<unsigned> > mooreNeighbouringNodeIndices);
00193 
00194 
00198     PottsMesh();
00199 
00203     virtual ~PottsMesh();
00204 
00208     virtual unsigned GetNumNodes() const;
00209 
00213     virtual unsigned GetNumElements() const;
00214 
00218     unsigned GetNumAllElements() const;
00219 
00225     PottsElement<DIM>* GetElement(unsigned index) const;
00226 
00236     virtual c_vector<double, DIM> GetCentroidOfElement(unsigned index);
00237 
00243     void ConstructFromMeshReader(AbstractMeshReader<DIM, DIM>& rMeshReader);
00244 
00248     virtual void Clear();
00249 
00259     virtual double GetVolumeOfElement(unsigned index);
00260 
00270     virtual double GetSurfaceAreaOfElement(unsigned index);
00271 
00278     std::set<unsigned> GetMooreNeighbouringNodeIndices(unsigned nodeIndex);
00279 
00286     std::set<unsigned> GetVonNeumannNeighbouringNodeIndices(unsigned nodeIndex);
00287 
00293     void DeleteNode(unsigned index);
00294 
00301     void DeleteElement(unsigned index);
00302 
00313     unsigned DivideElement(PottsElement<DIM>* pElement,
00314                            bool placeOriginalElementBelow=false);
00315 
00323     unsigned AddElement(PottsElement<DIM>* pNewElement);
00324 
00331     std::set<unsigned> GetNeighbouringElementIndices(unsigned elementIndex);
00332 
00333 
00335     //                         Nested classes                           //
00337 
00343     class PottsElementIterator
00344     {
00345     public:
00352         inline PottsElement<DIM>& operator*();
00353 
00358         inline PottsElement<DIM>* operator->();
00359 
00366         inline bool operator!=(const typename PottsMesh<DIM>::PottsElementIterator& rOther);
00367 
00372         inline PottsElementIterator& operator++();
00373 
00384         PottsElementIterator(PottsMesh<DIM>& rMesh,
00385                              typename std::vector<PottsElement<DIM> *>::iterator elementIter,
00386                              bool skipDeletedElements=true);
00387 
00388     private:
00390         PottsMesh<DIM>& mrMesh;
00391 
00393         typename std::vector<PottsElement<DIM> *>::iterator mElementIter;
00394 
00396         bool mSkipDeletedElements;
00397 
00401         inline bool IsAtEnd();
00402 
00406         inline bool IsAllowedElement();
00407     };
00408 };
00409 
00410 #include "SerializationExportWrapper.hpp"
00411 EXPORT_TEMPLATE_CLASS_SAME_DIMS(PottsMesh)
00412 
00413 
00414 // PottsElementIterator class implementation - most methods are inlined     //
00416 
00417 template<unsigned DIM>
00418 typename PottsMesh<DIM>::PottsElementIterator PottsMesh<DIM>::GetElementIteratorBegin(
00419         bool skipDeletedElements)
00420 {
00421     return PottsElementIterator(*this, mElements.begin(), skipDeletedElements);
00422 }
00423 
00424 template<unsigned DIM>
00425 typename PottsMesh<DIM>::PottsElementIterator PottsMesh<DIM>::GetElementIteratorEnd()
00426 {
00427     return PottsElementIterator(*this, mElements.end());
00428 }
00429 template<unsigned DIM>
00430 PottsElement<DIM>& PottsMesh<DIM>::PottsElementIterator::operator*()
00431 {
00432     assert(!IsAtEnd());
00433     return **mElementIter;
00434 }
00435 
00436 template<unsigned DIM>
00437 PottsElement<DIM>* PottsMesh<DIM>::PottsElementIterator::operator->()
00438 {
00439     assert(!IsAtEnd());
00440     return *mElementIter;
00441 }
00442 
00443 template<unsigned DIM>
00444 bool PottsMesh<DIM>::PottsElementIterator::operator!=(const typename PottsMesh<DIM>::PottsElementIterator& rOther)
00445 {
00446     return mElementIter != rOther.mElementIter;
00447 }
00448 
00449 template<unsigned DIM>
00450 typename PottsMesh<DIM>::PottsElementIterator& PottsMesh<DIM>::PottsElementIterator::operator++()
00451 {
00452     do
00453     {
00454         ++mElementIter;
00455     }
00456     while (!IsAtEnd() && !IsAllowedElement());
00457 
00458     return (*this);
00459 }
00460 
00461 template<unsigned DIM>
00462 PottsMesh<DIM>::PottsElementIterator::PottsElementIterator(
00463         PottsMesh<DIM>& rMesh,
00464         typename std::vector<PottsElement<DIM>*>::iterator elementIter,
00465         bool skipDeletedElements)
00466     : mrMesh(rMesh),
00467       mElementIter(elementIter),
00468       mSkipDeletedElements(skipDeletedElements)
00469 {
00470     if (mrMesh.mElements.empty())
00471     {
00472         // Cope with empty meshes
00473         mElementIter = mrMesh.mElements.end();
00474     }
00475     else
00476     {
00477         // Make sure we start at an allowed element
00478         if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00479         {
00480             ++(*this);
00481         }
00482     }
00483 }
00484 
00485 template<unsigned DIM>
00486 bool PottsMesh<DIM>::PottsElementIterator::IsAtEnd()
00487 {
00488     return mElementIter == mrMesh.mElements.end();
00489 }
00490 
00491 template<unsigned DIM>
00492 bool PottsMesh<DIM>::PottsElementIterator::IsAllowedElement()
00493 {
00494     return !(mSkipDeletedElements && (*this)->IsDeleted());
00495 }
00496 
00497 #endif /*POTTSMESH_HPP_*/

Generated by  doxygen 1.6.2