AbstractMesh.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 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:
00076     virtual unsigned SolveNodeMapping(unsigned index) const = 0;
00077 
00079     friend class boost::serialization::access;
00086     template<class Archive>
00087     void serialize(Archive & archive, const unsigned int version)
00088     {
00089         archive & mMeshChangesDuringSimulation;
00090         (*ProcessSpecificArchive<Archive>::Get()) & mpDistributedVectorFactory;
00091     }
00092 
00093 protected:  // Give access of these variables to subclasses
00094 
00096     std::vector<Node<SPACE_DIM> *> mNodes;
00097 
00099     std::vector<Node<SPACE_DIM> *> mBoundaryNodes;
00100 
00102     DistributedVectorFactory* mpDistributedVectorFactory;
00103 
00109     std::vector<unsigned> mNodePermutation;
00110 
00115     std::string mMeshFileBaseName;
00116 
00120     bool mMeshChangesDuringSimulation;
00121 
00125     virtual void SetElementOwnerships();
00126 
00134     ChasteCuboid<SPACE_DIM> CalculateBoundingBox(const std::vector<Node<SPACE_DIM>* >& rNodes) const;
00135 
00136 public:
00137 
00139     //                            Iterators                             //
00141 
00143     typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator BoundaryNodeIterator;
00144 
00146     class NodeIterator;
00147 
00153     inline NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true);
00154 
00158     inline NodeIterator GetNodeIteratorEnd();
00159 
00161     //                             Methods                              //
00163 
00167     AbstractMesh();
00168 
00172     virtual ~AbstractMesh();
00173 
00179     virtual unsigned GetNumNodes() const;
00180 
00184     unsigned GetNumBoundaryNodes() const;
00185 
00189     virtual unsigned GetNumAllNodes() const;
00190 
00196     unsigned GetNumNodeAttributes() const;
00197 
00204     Node<SPACE_DIM>* GetNode(unsigned index) const;
00205 
00212     virtual Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
00213 
00228     Node<SPACE_DIM>* GetNodeFromPrePermutationIndex(unsigned index) const;
00229 
00235     virtual void ReadNodesPerProcessorFile(const std::string& rNodesPerProcessorFile);
00236 
00240     virtual DistributedVectorFactory * GetDistributedVectorFactory();
00241 
00250     virtual void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00251 
00256     virtual void PermuteNodes();
00257 
00261     BoundaryNodeIterator GetBoundaryNodeIteratorBegin() const;
00262 
00267     BoundaryNodeIterator GetBoundaryNodeIteratorEnd() const;
00268 
00272     std::string GetMeshFileBaseName() const;
00273 
00279     bool IsMeshOnDisk() const;
00280 
00289     const std::vector<unsigned>& rGetNodePermutation() const;
00290 
00301     virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA,
00302                                                           const c_vector<double, SPACE_DIM>& rLocationB);
00303 
00315     double GetDistanceBetweenNodes(unsigned indexA, unsigned indexB);
00316 
00325     virtual double GetWidth(const unsigned& rDimension) const;
00326 
00334     virtual ChasteCuboid<SPACE_DIM> CalculateBoundingBox() const;
00335 
00348     virtual unsigned GetNearestNodeIndex(const ChastePoint<SPACE_DIM>& rTestPoint);
00349 
00357     virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00358 
00365      void Translate(const c_vector<double, SPACE_DIM>& rDisplacement);
00366 
00374      void Translate(const double xMovement=0.0, const double yMovement=0.0, const double zMovement=0.0);
00375 
00382      void Rotate(c_matrix<double , SPACE_DIM, SPACE_DIM> rotationMatrix);
00383 
00390      void Rotate(c_vector<double,3> axis, double angle);
00391 
00397      void RotateX(const double theta);
00398 
00404      void RotateY(const double theta);
00405 
00411      void RotateZ(const double theta);
00412 
00418      void Rotate(double theta);
00419 
00424     virtual void RefreshMesh();
00425 
00429     bool IsMeshChanging() const;
00430 
00435     unsigned CalculateMaximumContainingElementsPerProcess() const;
00436 
00442     void SetMeshHasChangedSinceLoading();
00443 
00445     //                         Nested classes                           //
00447 
00451     class NodeIterator
00452     {
00453     public:
00459         inline Node<SPACE_DIM>& operator*();
00460 
00465         inline Node<SPACE_DIM>* operator->();
00466 
00472         inline bool operator!=(const typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther);
00473 
00478         inline NodeIterator& operator++();
00479 
00490         NodeIterator(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00491                      typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00492                      bool skipDeletedNodes=true);
00493     private:
00495         AbstractMesh& mrMesh;
00496 
00498         typename std::vector<Node<SPACE_DIM> *>::iterator mNodeIter;
00499 
00501         bool mSkipDeletedNodes;
00502 
00507         inline bool IsAtEnd();
00508 
00513         inline bool IsAllowedNode();
00514     };
00515 
00516 
00517 };
00518 
00519 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractMesh)
00520 
00521 
00522 //      NodeIterator class implementation - most methods are inlined        //
00524 
00525 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00526 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin(
00527         bool skipDeletedNodes)
00528 {
00529     return NodeIterator(*this, mNodes.begin(), skipDeletedNodes);
00530 }
00531 
00532 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00533 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorEnd()
00534 {
00535     return NodeIterator(*this, mNodes.end());
00536 }
00537 
00538 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00539 Node<SPACE_DIM>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator*()
00540 {
00541     assert(!IsAtEnd());
00542     return **mNodeIter;
00543 }
00544 
00545 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00546 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator->()
00547 {
00548     assert(!IsAtEnd());
00549     return *mNodeIter;
00550 }
00551 
00552 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00553 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator!=(const typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther)
00554 {
00555     return mNodeIter != rOther.mNodeIter;
00556 }
00557 
00558 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00559 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator++()
00560 {
00561     do
00562     {
00563         ++mNodeIter;
00564     }
00565     while (!IsAtEnd() && !IsAllowedNode());
00566 
00567     return (*this);
00568 }
00569 
00570 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00571 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::NodeIterator(
00572         AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00573         typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00574         bool skipDeletedNodes)
00575     : mrMesh(rMesh),
00576       mNodeIter(nodeIter),
00577       mSkipDeletedNodes(skipDeletedNodes)
00578 {
00579     if (mrMesh.mNodes.size() == 0)
00580     {
00581         // Cope with empty meshes
00582         mNodeIter = mrMesh.mNodes.end();
00583     }
00584     else
00585     {
00586         // Make sure we start at an allowed node
00587         if (mNodeIter == mrMesh.mNodes.begin() && !IsAllowedNode())
00588         {
00589             ++(*this);
00590         }
00591     }
00592 }
00593 
00594 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00595 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAtEnd()
00596 {
00597     return mNodeIter == mrMesh.mNodes.end();
00598 }
00599 
00600 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00601 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAllowedNode()
00602 {
00603     return !(mSkipDeletedNodes && (*this)->IsDeleted());
00604 }
00605 
00606 
00607 #endif /*ABSTRACTMESH_HPP_*/

Generated by  doxygen 1.6.2