Chaste  Release::3.4
DistributedTetrahedralMesh.hpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #ifndef DISTRIBUTEDTETRAHEDRALMESH_HPP_
37 #define DISTRIBUTEDTETRAHEDRALMESH_HPP_
38 
39 #include <map>
40 #include <vector>
41 #include <set>
42 
43 #include "ChasteSerialization.hpp"
44 #include <boost/serialization/base_object.hpp>
45 
46 #include "AbstractTetrahedralMesh.hpp"
47 #include "Node.hpp"
48 #include "AbstractMeshReader.hpp"
49 #include "DistributedTetrahedralMeshPartitionType.hpp"
50 
51 #define UNASSIGNED_NODE UINT_MAX
52 
53 
61 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
62 class DistributedTetrahedralMesh : public AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM>
63 {
64  friend class TestDistributedTetrahedralMesh;
65  friend class TestDistributedQuadraticMesh;
66 private:
67 
70 
73 
75  unsigned mTotalNumNodes;
76 
78  std::vector<Node<SPACE_DIM>* > mHaloNodes;
79 
81  std::map<unsigned, unsigned> mNodesMapping;
82 
84  std::map<unsigned, unsigned> mHaloNodesMapping;
85 
87  std::map<unsigned, unsigned> mElementsMapping;
88 
90  std::map<unsigned, unsigned> mBoundaryElementsMapping;
91 
94 
97 
99  friend class boost::serialization::access;
106  template<class Archive>
107  void serialize(Archive & archive, const unsigned int version)
108  {
109  archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
110  }
111 
112 
120  void SetElementOwnerships();
121 
122 
123 public:
124 
130  DistributedTetrahedralMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod=DistributedTetrahedralMeshPartitionType::PARMETIS_LIBRARY);
131 
135  virtual ~DistributedTetrahedralMesh();
136 
144 
151 
156  unsigned GetNumLocalNodes() const;
157 
161  unsigned GetNumHaloNodes() const;
162 
167  unsigned GetNumLocalElements() const;
168 
173  unsigned GetNumLocalBoundaryElements() const;
174 
178  unsigned GetNumNodes() const;
179 
183  unsigned GetNumAllNodes() const;
184 
188  unsigned GetNumElements() const;
189 
196 
200  unsigned GetNumBoundaryElements() const;
201 
206  void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
207 
214 
221 
229  bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
230 
237  bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
238 
246  void ConstructLinearMesh(unsigned width);
247 
261  void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
262 
273  void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
282  virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
283 
293  Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
294 
303 
312  virtual unsigned GetNearestNodeIndex(const ChastePoint<SPACE_DIM>& rTestPoint);
313 
322  virtual c_vector<double, 2> CalculateMinMaxEdgeLengths();
323 
331  void Rotate(c_matrix<double , SPACE_DIM, SPACE_DIM> rotationMatrix);
332 
340  void Translate(const c_vector<double, SPACE_DIM>& rDisplacement);
341 
342 
343 protected:
350  unsigned SolveNodeMapping(unsigned index) const;
351 
358  unsigned SolveElementMapping(unsigned index) const;
359 
366  unsigned SolveBoundaryElementMapping(unsigned index) const;
367 private:
368 
374  void RegisterNode(unsigned index);
375 
381  void RegisterHaloNode(unsigned index);
382 
388  void RegisterElement(unsigned index);
389 
395  void RegisterBoundaryElement(unsigned index);
396 
397 
410  std::set<unsigned>& rNodesOwned,
411  std::set<unsigned>& rHaloNodesOwned,
412  std::set<unsigned>& rElementsOwned,
413  std::vector<unsigned>& rProcessorsOffset);
414 
427  std::set<unsigned>& rElementsOwned,
428  std::set<unsigned>& rNodesOwned,
429  std::set<unsigned>& rHaloNodesOwned,
430  std::vector<unsigned>& rProcessorsOffset);
431 
438  void ReorderNodes();
439 
441  // Iterators //
443 
444 public:
446  // The other iterators aren't (so only need to be dereferenced once). Consistency would be good...
447 
449  typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator HaloNodeIterator;
450 
455 
460 };
461 
464 
465 namespace boost
466 {
467 namespace serialization
468 {
472 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
473 inline void save_construct_data(
474  Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
475 {
476  unsigned num_procs = PetscTools::GetNumProcs();
478  ar << num_procs;
479  ar << partition_type;
480 }
481 
486 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
487 inline void load_construct_data(
488  Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
489 {
490  unsigned num_procs;
492 
493  ar >> num_procs;
494  ar >> partition_type;
495 
496  // Invoke inplace constructor to initialise instance
498  //::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(partition_type);
499  ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMeshPartitionType::DUMB);
500 
501  /*
502  * The exception needs to be thrown after the call to ::new(t), or Boost will try
503  * to free non-allocated memory when the exception is thrown.
504  */
505  if (DistributedVectorFactory::CheckNumberOfProcessesOnLoad() &&
506  num_procs != PetscTools::GetNumProcs())
507  {
508  EXCEPTION("This archive was written for a different number of processors");
509  }
510 
511 }
512 }
513 } // namespace ...
514 
515 #endif /*DISTRIBUTEDTETRAHEDRALMESH_HPP_*/
Definition: Node.hpp:58
DistributedTetrahedralMeshPartitionType::type GetPartitionType() const
void Rotate(c_matrix< double, SPACE_DIM, SPACE_DIM > rotationMatrix)
void SetProcessRegion(ChasteCuboid< SPACE_DIM > *pRegion)
#define EXCEPTION(message)
Definition: Exception.hpp:143
DistributedTetrahedralMeshPartitionType::type mMetisPartitioning
std::vector< Node< SPACE_DIM > * >::const_iterator HaloNodeIterator
virtual void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
DistributedTetrahedralMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod=DistributedTetrahedralMeshPartitionType::PARMETIS_LIBRARY)
void GetHaloNodeIndices(std::vector< unsigned > &rHaloIndices) const
void SetDistributedVectorFactory(DistributedVectorFactory *pFactory)
bool CalculateDesignatedOwnershipOfBoundaryElement(unsigned faceIndex)
void ComputeMeshPartitioning(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader, std::set< unsigned > &rNodesOwned, std::set< unsigned > &rHaloNodesOwned, std::set< unsigned > &rElementsOwned, std::vector< unsigned > &rProcessorsOffset)
HaloNodeIterator GetHaloNodeIteratorBegin() const
HaloNodeIterator GetHaloNodeIteratorEnd() const
std::map< unsigned, unsigned > mElementsMapping
unsigned SolveBoundaryElementMapping(unsigned index) const
unsigned SolveNodeMapping(unsigned index) const
void Translate(const c_vector< double, SPACE_DIM > &rDisplacement)
unsigned SolveElementMapping(unsigned index) const
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
virtual c_vector< double, 2 > CalculateMinMaxEdgeLengths()
Node< SPACE_DIM > * GetNodeOrHaloNode(unsigned index) const
virtual ChasteCuboid< SPACE_DIM > CalculateBoundingBox() const
ChasteCuboid< SPACE_DIM > * mpSpaceRegion
std::vector< Node< SPACE_DIM > * > mHaloNodes
virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0)
std::map< unsigned, unsigned > mHaloNodesMapping
void ConstructCuboid(unsigned width, unsigned height, unsigned depth)
void serialize(Archive &archive, const unsigned int version)
ChasteCuboid< SPACE_DIM > * GetProcessRegion()
virtual unsigned GetNearestNodeIndex(const ChastePoint< SPACE_DIM > &rTestPoint)
void ParMetisLibraryNodeAndElementPartitioning(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader, std::set< unsigned > &rElementsOwned, std::set< unsigned > &rNodesOwned, std::set< unsigned > &rHaloNodesOwned, std::vector< unsigned > &rProcessorsOffset)
static unsigned GetNumProcs()
Definition: PetscTools.cpp:108
bool CalculateDesignatedOwnershipOfElement(unsigned elementIndex)
std::map< unsigned, unsigned > mBoundaryElementsMapping
void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true)
std::map< unsigned, unsigned > mNodesMapping