PottsMesh.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
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 
00029 #ifndef POTTSMESH_HPP_
00030 #define POTTSMESH_HPP_
00031 
00032 // Forward declaration prevents circular include chain
00033 template<unsigned DIM>
00034 class PottsMeshWriter;
00035 
00036 #include <iostream>
00037 #include <map>
00038 #include <algorithm>
00039 
00040 #include "ChasteSerialization.hpp"
00041 #include <boost/serialization/vector.hpp>
00042 #include <boost/serialization/set.hpp>
00043 #include <boost/serialization/base_object.hpp>
00044 #include <boost/serialization/split_member.hpp>
00045 
00046 #include "AbstractMesh.hpp"
00047 #include "ArchiveLocationInfo.hpp"
00048 #include "PottsMeshReader.hpp"
00049 #include "PottsMeshWriter.hpp"
00050 #include "PottsElement.hpp"
00051 
00055 template<unsigned DIM>
00056 class PottsMesh : public AbstractMesh<DIM, DIM>
00057 {
00058     friend class TestPottsMesh;
00059 
00060 protected:
00062     std::vector<PottsElement<DIM>*> mElements;
00063 
00068     std::vector<unsigned> mDeletedElementIndices;
00069 
00071     std::vector< std::set<unsigned> > mVonNeumannNeighbouringNodeIndices;
00072 
00074     std::vector< std::set<unsigned> > mMooreNeighbouringNodeIndices;
00075 
00082     unsigned SolveNodeMapping(unsigned index) const;
00083 
00090     unsigned SolveElementMapping(unsigned index) const;
00091 
00098     unsigned SolveBoundaryElementMapping(unsigned index) const;
00099 
00101     friend class boost::serialization::access;
00102 
00110     template<class Archive>
00111     void save(Archive & archive, const unsigned int version) const
00112     {
00113         // NOTE - Subclasses must archive their member variables BEFORE calling this method.
00114         archive & mDeletedElementIndices;
00115         archive & mVonNeumannNeighbouringNodeIndices;
00116         archive & mMooreNeighbouringNodeIndices;
00117         archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this);
00118 
00119         // Create a mesh writer pointing to the correct file and directory
00120         PottsMeshWriter<DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00121                                          ArchiveLocationInfo::GetMeshFilename(),
00122                                          false);
00123         mesh_writer.WriteFilesUsingMesh(*(const_cast<PottsMesh<DIM>*>(this)));
00124     }
00125 
00132     template<class Archive>
00133     void load(Archive & archive, const unsigned int version)
00134     {
00135         // NOTE - Subclasses must archive their member variables BEFORE calling this method.
00136         archive & mDeletedElementIndices;
00137         archive & mVonNeumannNeighbouringNodeIndices;
00138         archive & mMooreNeighbouringNodeIndices;
00139         archive & boost::serialization::base_object<AbstractMesh<DIM, DIM> >(*this);
00140 
00141         PottsMeshReader<DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00142         this->ConstructFromMeshReader(mesh_reader);
00143     }
00144     BOOST_SERIALIZATION_SPLIT_MEMBER()
00145 
00146 public:
00147 
00149     //                            Iterators                             //
00151 
00153     class PottsElementIterator;
00154 
00160     inline PottsElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00161 
00165     inline PottsElementIterator GetElementIteratorEnd();
00166 
00168     //                             Methods                              //
00170 
00179     PottsMesh(std::vector<Node<DIM>*> nodes,
00180               std::vector<PottsElement<DIM>*> pottsElements,
00181               std::vector< std::set<unsigned> > vonNeumannNeighbouringNodeIndices,
00182               std::vector< std::set<unsigned> > mooreNeighbouringNodeIndices);
00183 
00184 
00188     PottsMesh();
00189 
00193     virtual ~PottsMesh();
00194 
00198     virtual unsigned GetNumNodes() const;
00199 
00203     virtual unsigned GetNumElements() const;
00204 
00208     unsigned GetNumAllElements() const;
00209 
00215     PottsElement<DIM>* GetElement(unsigned index) const;
00216 
00226     virtual c_vector<double, DIM> GetCentroidOfElement(unsigned index);
00227 
00233     void ConstructFromMeshReader(AbstractMeshReader<DIM, DIM>& rMeshReader);
00234 
00238     virtual void Clear();
00239 
00251     virtual c_vector<double, DIM> GetVectorFromAtoB(const c_vector<double, DIM>& rLocationA,
00252                                                     const c_vector<double, DIM>& rLocationB);
00253 
00263     virtual double GetVolumeOfElement(unsigned index);
00264 
00274     virtual double GetSurfaceAreaOfElement(unsigned index);
00275 
00282     std::set<unsigned> GetMooreNeighbouringNodeIndices(unsigned nodeIndex);
00283 
00290     std::set<unsigned> GetVonNeumannNeighbouringNodeIndices(unsigned nodeIndex);
00291 
00298     void DeleteElement(unsigned index);
00299 
00310     unsigned DivideElement(PottsElement<DIM>* pElement,
00311                            bool placeOriginalElementBelow=false);
00312 
00320     unsigned AddElement(PottsElement<DIM>* pNewElement);
00321 
00323     //                         Nested classes                           //
00325 
00331     class PottsElementIterator
00332     {
00333     public:
00339         inline PottsElement<DIM>& operator*();
00340 
00344         inline PottsElement<DIM>* operator->();
00345 
00351         inline bool operator!=(const PottsMesh<DIM>::PottsElementIterator& rOther);
00352 
00356         inline PottsElementIterator& operator++();
00357 
00368         PottsElementIterator(PottsMesh<DIM>& rMesh,
00369                              typename std::vector<PottsElement<DIM> *>::iterator elementIter,
00370                              bool skipDeletedElements=true);
00371 
00372     private:
00374         PottsMesh<DIM>& mrMesh;
00375 
00377         typename std::vector<PottsElement<DIM> *>::iterator mElementIter;
00378 
00380         bool mSkipDeletedElements;
00381 
00385         inline bool IsAtEnd();
00386 
00390         inline bool IsAllowedElement();
00391     };
00392 };
00393 
00394 #include "SerializationExportWrapper.hpp"
00395 EXPORT_TEMPLATE_CLASS_SAME_DIMS(PottsMesh)
00396 
00397 
00398 // PottsElementIterator class implementation - most methods are inlined     //
00400 
00401 template<unsigned DIM>
00402 typename PottsMesh<DIM>::PottsElementIterator PottsMesh<DIM>::GetElementIteratorBegin(
00403         bool skipDeletedElements)
00404 {
00405     return PottsElementIterator(*this, mElements.begin(), skipDeletedElements);
00406 }
00407 
00408 template<unsigned DIM>
00409 typename PottsMesh<DIM>::PottsElementIterator PottsMesh<DIM>::GetElementIteratorEnd()
00410 {
00411     return PottsElementIterator(*this, mElements.end());
00412 }
00413 template<unsigned DIM>
00414 PottsElement<DIM>& PottsMesh<DIM>::PottsElementIterator::operator*()
00415 {
00416     assert(!IsAtEnd());
00417     return **mElementIter;
00418 }
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 bool PottsMesh<DIM>::PottsElementIterator::operator!=(const PottsMesh<DIM>::PottsElementIterator& rOther)
00429 {
00430     return mElementIter != rOther.mElementIter;
00431 }
00432 
00433 template<unsigned DIM>
00434 typename PottsMesh<DIM>::PottsElementIterator& PottsMesh<DIM>::PottsElementIterator::operator++()
00435 {
00436     do
00437     {
00438         ++mElementIter;
00439     }
00440     while (!IsAtEnd() && !IsAllowedElement());
00441 
00442     return (*this);
00443 }
00444 
00445 template<unsigned DIM>
00446 PottsMesh<DIM>::PottsElementIterator::PottsElementIterator(
00447         PottsMesh<DIM>& rMesh,
00448         typename std::vector<PottsElement<DIM>*>::iterator elementIter,
00449         bool skipDeletedElements)
00450     : mrMesh(rMesh),
00451       mElementIter(elementIter),
00452       mSkipDeletedElements(skipDeletedElements)
00453 {
00454     if (mrMesh.mElements.empty())
00455     {
00456         // Cope with empty meshes
00457         mElementIter = mrMesh.mElements.end();
00458     }
00459     else
00460     {
00461         // Make sure we start at an allowed element
00462         if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00463         {
00464             ++(*this);
00465         }
00466     }
00467 }
00468 
00469 template<unsigned DIM>
00470 bool PottsMesh<DIM>::PottsElementIterator::IsAtEnd()
00471 {
00472     return mElementIter == mrMesh.mElements.end();
00473 }
00474 
00475 template<unsigned DIM>
00476 bool PottsMesh<DIM>::PottsElementIterator::IsAllowedElement()
00477 {
00478     return !(mSkipDeletedElements && (*this)->IsDeleted());
00479 }
00480 
00481 #endif /*POTTSMESH_HPP_*/
Generated on Thu Dec 22 13:00:04 2011 for Chaste by  doxygen 1.6.3