Chaste Release::3.1
AbstractMesh.hpp
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 ABSTRACTMESH_HPP_
00037 #define ABSTRACTMESH_HPP_
00038 
00039 #include "ChasteSerialization.hpp"
00040 #include "ClassIsAbstract.hpp"
00041 
00042 #include "UblasVectorInclude.hpp"
00043 #include "UblasMatrixInclude.hpp"
00044 
00045 #include <vector>
00046 #include <string>
00047 #include <cassert>
00048 
00049 #include "Node.hpp"
00050 #include "DistributedVectorFactory.hpp"
00051 #include "ProcessSpecificArchive.hpp"
00052 #include "ChasteCuboid.hpp"
00053 
00054 #include <boost/utility.hpp>
00055 
00059 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00060 class AbstractMesh : private boost::noncopyable
00061 {
00062     friend class TestDistributedTetrahedralMesh;
00063     template <unsigned A_DIMENSION> friend class NodesOnlyMesh; //NodesOnlyMesh is able to grab the node information in order to copy
00064     template <unsigned A_DIMENSION> friend class QuadraticMeshHelper;
00065 
00066 private:
00075     virtual unsigned SolveNodeMapping(unsigned index) const = 0;
00076 
00078     friend class boost::serialization::access;
00085     template<class Archive>
00086     void serialize(Archive & archive, const unsigned int version)
00087     {
00088         archive & mMeshChangesDuringSimulation;
00089         (*ProcessSpecificArchive<Archive>::Get()) & mpDistributedVectorFactory;
00090     }
00091 
00092 protected:  // Give access of these variables to subclasses
00093 
00095     std::vector<Node<SPACE_DIM> *> mNodes;
00096 
00098     std::vector<Node<SPACE_DIM> *> mBoundaryNodes;
00099 
00101     DistributedVectorFactory* mpDistributedVectorFactory;
00102 
00108     std::vector<unsigned> mNodesPermutation;
00109 
00114     std::string mMeshFileBaseName;
00115 
00119     bool mMeshChangesDuringSimulation;
00120 
00124     virtual void SetElementOwnerships();
00125 public:
00126 
00128     //                            Iterators                             //
00130 
00132     typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator BoundaryNodeIterator;
00133 
00135     class NodeIterator;
00136 
00142     inline NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true);
00143 
00147     inline NodeIterator GetNodeIteratorEnd();
00148 
00150     //                             Methods                              //
00152 
00156     AbstractMesh();
00157 
00161     virtual ~AbstractMesh();
00162 
00168     virtual unsigned GetNumNodes() const;
00169 
00173     unsigned GetNumBoundaryNodes() const;
00174 
00178     virtual unsigned GetNumAllNodes() const;
00179 
00186     Node<SPACE_DIM>* GetNode(unsigned index) const;
00187 
00194     virtual Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
00195 
00210     Node<SPACE_DIM>* GetNodeFromPrePermutationIndex(unsigned index) const;
00211 
00217     virtual void ReadNodesPerProcessorFile(const std::string& rNodesPerProcessorFile);
00218 
00222     virtual DistributedVectorFactory * GetDistributedVectorFactory();
00223 
00232     virtual void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00233 
00238     virtual void PermuteNodes();
00239 
00243     BoundaryNodeIterator GetBoundaryNodeIteratorBegin() const;
00244 
00249     BoundaryNodeIterator GetBoundaryNodeIteratorEnd() const;
00250 
00254     std::string GetMeshFileBaseName() const;
00255 
00261     bool IsMeshOnDisk() const;
00262 
00271     const std::vector<unsigned>& rGetNodePermutation() const;
00272 
00283     virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
00284                                                           const c_vector<double, SPACE_DIM>& rLocationB);
00285 
00297     double GetDistanceBetweenNodes(unsigned indexA, unsigned indexB);
00298 
00307     virtual double GetWidth(const unsigned& rDimension) const;
00308 
00316     virtual ChasteCuboid<SPACE_DIM> CalculateBoundingBox() const;
00317 
00325     virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00326 
00333      void Translate(const c_vector<double, SPACE_DIM>& rDisplacement);
00334 
00342      void Translate(const double xMovement=0.0, const double yMovement=0.0, const double zMovement=0.0);
00343 
00350      void Rotate(c_matrix<double , SPACE_DIM, SPACE_DIM> rotationMatrix);
00351 
00358      void Rotate(c_vector<double,3> axis, double angle);
00359 
00365      void RotateX(const double theta);
00366 
00372      void RotateY(const double theta);
00373 
00379      void RotateZ(const double theta);
00380 
00386      void Rotate(double theta);
00387 
00392     virtual void RefreshMesh();
00393 
00397     bool IsMeshChanging() const;
00398 
00403     unsigned CalculateMaximumContainingElementsPerProcess() const;
00404 
00410     void SetMeshHasChangedSinceLoading();
00411 
00413     //                         Nested classes                           //
00415 
00419     class NodeIterator
00420     {
00421     public:
00427         inline Node<SPACE_DIM>& operator*();
00428 
00432         inline Node<SPACE_DIM>* operator->();
00433 
00439         inline bool operator!=(const AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther);
00440 
00444         inline NodeIterator& operator++();
00445 
00456         NodeIterator(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00457                      typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00458                      bool skipDeletedNodes=true);
00459     private:
00461         AbstractMesh& mrMesh;
00462 
00464         typename std::vector<Node<SPACE_DIM> *>::iterator mNodeIter;
00465 
00467         bool mSkipDeletedNodes;
00468 
00472         inline bool IsAtEnd();
00473 
00477         inline bool IsAllowedNode();
00478     };
00479 
00480 
00481 };
00482 
00483 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractMesh)
00484 
00485 
00486 //      NodeIterator class implementation - most methods are inlined        //
00488 
00489 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00490 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin(
00491         bool skipDeletedNodes)
00492 {
00493     return NodeIterator(*this, mNodes.begin(), skipDeletedNodes);
00494 }
00495 
00496 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00497 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorEnd()
00498 {
00499     return NodeIterator(*this, mNodes.end());
00500 }
00501 
00502 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00503 Node<SPACE_DIM>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator*()
00504 {
00505     assert(!IsAtEnd());
00506     return **mNodeIter;
00507 }
00508 
00509 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00510 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator->()
00511 {
00512     assert(!IsAtEnd());
00513     return *mNodeIter;
00514 }
00515 
00516 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00517 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator!=(const AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther)
00518 {
00519     return mNodeIter != rOther.mNodeIter;
00520 }
00521 
00522 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00523 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator++()
00524 {
00525     do
00526     {
00527         ++mNodeIter;
00528     }
00529     while (!IsAtEnd() && !IsAllowedNode());
00530 
00531     return (*this);
00532 }
00533 
00534 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00535 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::NodeIterator(
00536         AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00537         typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00538         bool skipDeletedNodes)
00539     : mrMesh(rMesh),
00540       mNodeIter(nodeIter),
00541       mSkipDeletedNodes(skipDeletedNodes)
00542 {
00543     if (mrMesh.mNodes.size() == 0)
00544     {
00545         // Cope with empty meshes
00546         mNodeIter = mrMesh.mNodes.end();
00547     }
00548     else
00549     {
00550         // Make sure we start at an allowed node
00551         if (mNodeIter == mrMesh.mNodes.begin() && !IsAllowedNode())
00552         {
00553             ++(*this);
00554         }
00555     }
00556 }
00557 
00558 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00559 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAtEnd()
00560 {
00561     return mNodeIter == mrMesh.mNodes.end();
00562 }
00563 
00564 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00565 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAllowedNode()
00566 {
00567     return !(mSkipDeletedNodes && (*this)->IsDeleted());
00568 }
00569 
00570 
00571 #endif /*ABSTRACTMESH_HPP_*/