00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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;
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:
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
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
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
00343 virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00344
00351 void Translate(const c_vector<double, SPACE_DIM>& rDisplacement);
00352
00360 void Translate(const double xMovement=0.0, const double yMovement=0.0, const double zMovement=0.0);
00361
00368 void Rotate(c_matrix<double , SPACE_DIM, SPACE_DIM> rotationMatrix);
00369
00376 void Rotate(c_vector<double,3> axis, double angle);
00377
00383 void RotateX(const double theta);
00384
00390 void RotateY(const double theta);
00391
00397 void RotateZ(const double theta);
00398
00404 void Rotate(double theta);
00405
00410 virtual void RefreshMesh();
00411
00415 bool IsMeshChanging() const;
00416
00421 unsigned CalculateMaximumContainingElementsPerProcess() const;
00422
00428 void SetMeshHasChangedSinceLoading();
00429
00431
00433
00437 class NodeIterator
00438 {
00439 public:
00445 inline Node<SPACE_DIM>& operator*();
00446
00451 inline Node<SPACE_DIM>* operator->();
00452
00458 inline bool operator!=(const typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther);
00459
00464 inline NodeIterator& operator++();
00465
00476 NodeIterator(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00477 typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00478 bool skipDeletedNodes=true);
00479 private:
00481 AbstractMesh& mrMesh;
00482
00484 typename std::vector<Node<SPACE_DIM> *>::iterator mNodeIter;
00485
00487 bool mSkipDeletedNodes;
00488
00493 inline bool IsAtEnd();
00494
00499 inline bool IsAllowedNode();
00500 };
00501
00502
00503 };
00504
00505 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractMesh)
00506
00507
00508
00510
00511 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00512 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin(
00513 bool skipDeletedNodes)
00514 {
00515 return NodeIterator(*this, mNodes.begin(), skipDeletedNodes);
00516 }
00517
00518 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00519 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorEnd()
00520 {
00521 return NodeIterator(*this, mNodes.end());
00522 }
00523
00524 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00525 Node<SPACE_DIM>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator*()
00526 {
00527 assert(!IsAtEnd());
00528 return **mNodeIter;
00529 }
00530
00531 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00532 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator->()
00533 {
00534 assert(!IsAtEnd());
00535 return *mNodeIter;
00536 }
00537
00538 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00539 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator!=(const typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& rOther)
00540 {
00541 return mNodeIter != rOther.mNodeIter;
00542 }
00543
00544 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00545 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::operator++()
00546 {
00547 do
00548 {
00549 ++mNodeIter;
00550 }
00551 while (!IsAtEnd() && !IsAllowedNode());
00552
00553 return (*this);
00554 }
00555
00556 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00557 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::NodeIterator(
00558 AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00559 typename std::vector<Node<SPACE_DIM> *>::iterator nodeIter,
00560 bool skipDeletedNodes)
00561 : mrMesh(rMesh),
00562 mNodeIter(nodeIter),
00563 mSkipDeletedNodes(skipDeletedNodes)
00564 {
00565 if (mrMesh.mNodes.size() == 0)
00566 {
00567
00568 mNodeIter = mrMesh.mNodes.end();
00569 }
00570 else
00571 {
00572
00573 if (mNodeIter == mrMesh.mNodes.begin() && !IsAllowedNode())
00574 {
00575 ++(*this);
00576 }
00577 }
00578 }
00579
00580 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00581 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAtEnd()
00582 {
00583 return mNodeIter == mrMesh.mNodes.end();
00584 }
00585
00586 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00587 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator::IsAllowedNode()
00588 {
00589 return !(mSkipDeletedNodes && (*this)->IsDeleted());
00590 }
00591
00592
00593 #endif