AbstractMesh.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 ABSTRACTMESH_HPP_
00030 #define ABSTRACTMESH_HPP_
00031 
00032 #include "ChasteSerialization.hpp"
00033 #include "ClassIsAbstract.hpp"
00034 
00035 #include <vector>
00036 #include <string>
00037 #include <cassert>
00038 
00039 #include "Node.hpp"
00040 #include "DistributedVectorFactory.hpp"
00041 #include "ProcessSpecificArchive.hpp"
00042 
00046 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00047 class AbstractMesh
00048 {
00049 private:
00058     virtual unsigned SolveNodeMapping(unsigned index) const = 0;
00059 
00061     friend class boost::serialization::access;
00068     template<class Archive>
00069     void serialize(Archive & archive, const unsigned int version)
00070     {
00071         archive & mMeshChangesDuringSimulation;
00072         (*ProcessSpecificArchive<Archive>::Get()) & mpDistributedVectorFactory;
00073     }
00074 
00075 protected:  // Give access of these variables to subclasses
00076 
00078     std::vector<Node<SPACE_DIM> *> mNodes;
00079 
00081     std::vector<Node<SPACE_DIM> *> mBoundaryNodes;
00082 
00084     DistributedVectorFactory* mpDistributedVectorFactory;
00085 
00091     std::vector<unsigned> mNodesPermutation;
00092 
00097     std::string mMeshFileBaseName;
00098 
00102     bool mMeshChangesDuringSimulation;
00103 
00104 public:
00105 
00107     //                            Iterators                             //
00109 
00111     typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator BoundaryNodeIterator;
00112 
00114     class NodeIterator;
00115 
00121     inline NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true);
00122 
00126     inline NodeIterator GetNodeIteratorEnd();
00127 
00129     //                             Methods                              //
00131 
00135     AbstractMesh();
00136 
00140     virtual ~AbstractMesh();
00141 
00147     virtual unsigned GetNumNodes() const;
00148 
00152     unsigned GetNumBoundaryNodes() const;
00153 
00157     virtual unsigned GetNumAllNodes() const;
00158 
00165     Node<SPACE_DIM>* GetNode(unsigned index) const;
00166 
00181     Node<SPACE_DIM>* GetNodeFromPrePermutationIndex(unsigned index) const;
00182 
00188     virtual void ReadNodesPerProcessorFile(const std::string& rNodesPerProcessorFile);
00189 
00193     DistributedVectorFactory * GetDistributedVectorFactory();
00194 
00203     virtual void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00204 
00209     virtual void PermuteNodes();
00210 
00214     BoundaryNodeIterator GetBoundaryNodeIteratorBegin() const;
00215 
00220     BoundaryNodeIterator GetBoundaryNodeIteratorEnd() const;
00221 
00225     std::string GetMeshFileBaseName() const;
00226 
00235     const std::vector<unsigned>& rGetNodePermutation() const;
00236 
00247     virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
00248                                                           const c_vector<double, SPACE_DIM>& rLocationB);
00249 
00261     double GetDistanceBetweenNodes(unsigned indexA, unsigned indexB);
00262 
00271     virtual double GetWidth(const unsigned& rDimension) const;
00272 
00279     c_vector<double,2> GetWidthExtremes(const unsigned& rDimension) const;
00280 
00288     virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00289 
00294     virtual void RefreshMesh();
00295 
00299     bool IsMeshChanging() const;
00300 
00306     void SetMeshHasChangedSinceLoading();
00307 
00309     //                         Nested classes                           //
00311 
00315     class NodeIterator
00316     {
00317     public:
00323         inline Node<SPACE_DIM>& operator*();
00324 
00328         inline Node<SPACE_DIM>* operator->();
00329 
00335         inline bool operator!=(const AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther);
00336 
00340         inline NodeIterator& operator++();
00341 
00352         NodeIterator(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00353                      typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00354                      bool skipDeletedNodes=true);
00355     private:
00357         AbstractMesh& mrMesh;
00358 
00360         typename std::vector<Node<SPACE_DIM> *>::iterator mNodeIter;
00361 
00363         bool mSkipDeletedNodes;
00364 
00368         inline bool IsAtEnd();
00369 
00373         inline bool IsAllowedNode();
00374     };
00375 
00376 
00377 };
00378 
00379 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractMesh);
00380 
00382 //      NodeIterator class implementation - most methods are inlined        //
00384 
00385 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00386 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin(
00387         bool skipDeletedNodes)
00388 {
00389     return NodeIterator(*this, mNodes.begin(), skipDeletedNodes);
00390 }
00391 
00392 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00393 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorEnd()
00394 {
00395     return NodeIterator(*this, mNodes.end());
00396 }
00397 
00398 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00399 Node<SPACE_DIM>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator*()
00400 {
00401     assert(!IsAtEnd());
00402     return **mNodeIter;
00403 }
00404 
00405 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00406 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator->()
00407 {
00408     assert(!IsAtEnd());
00409     return *mNodeIter;
00410 }
00411 
00412 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00413 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator!=(const AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther)
00414 {
00415     return mNodeIter != rOther.mNodeIter;
00416 }
00417 
00418 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00419 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator++()
00420 {
00421     do
00422     {
00423         ++mNodeIter;
00424     }
00425     while (!IsAtEnd() && !IsAllowedNode());
00426 
00427     return (*this);
00428 }
00429 
00430 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00431 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::NodeIterator(
00432         AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00433         typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00434         bool skipDeletedNodes)
00435     : mrMesh(rMesh),
00436       mNodeIter(nodeIter),
00437       mSkipDeletedNodes(skipDeletedNodes)
00438 {
00439     if (mrMesh.mNodes.size() == 0)
00440     {
00441         // Cope with empty meshes
00442         mNodeIter = mrMesh.mNodes.end();
00443     }
00444     else
00445     {
00446         // Make sure we start at an allowed node
00447         if (mNodeIter == mrMesh.mNodes.begin() && !IsAllowedNode())
00448         {
00449             ++(*this);
00450         }
00451     }
00452 }
00453 
00454 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00455 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAtEnd()
00456 {
00457     return mNodeIter == mrMesh.mNodes.end();
00458 }
00459 
00460 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00461 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAllowedNode()
00462 {
00463     return !(mSkipDeletedNodes && (*this)->IsDeleted());
00464 }
00465 
00466 
00467 #endif /*ABSTRACTMESH_HPP_*/

Generated by  doxygen 1.6.2