Chaste Release::3.1
|
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_*/