Chaste Commit::675f9facbe008c5eacb9006feaeb6423206579ea
DistributedTetrahedralMesh.hpp
1/*
2
3Copyright (c) 2005-2025, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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
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#include <parmetis.h>
51
52#ifdef PARMETIS_MAJOR_VERSION
53#if PARMETIS_MAJOR_VERSION != 4
54#error "ParMETIS version is not supported. Please use version 4."
55#endif
56#else //ndef PARMETIS_MAJOR_VERSION
57// If there's no PARMETIS then assume we have Scotch
58#include <scotch/ptscotch.h>
59#define idx_t SCOTCH_Num
60#define real_t float
61#define CHASTE_SCOTCH_PARMETIS
62// Conditionally turn off the interface to ParMETIS_V3_Mesh2Dual which should be added into PTScotch at 7.0.9
63#if ((SCOTCH_VERSION < 7) || (SCOTCH_RELEASE < 0) || (SCOTCH_PATCHLEVEL < 9))
64#define CHASTE_HOMEMADE_MESH_TO_DUAL
65#endif
66#endif
67
68#define UNASSIGNED_NODE UINT_MAX
69
70
78template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
79class DistributedTetrahedralMesh : public AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM>
80{
81 friend class TestDistributedTetrahedralMesh;
82 friend class TestDistributedQuadraticMesh;
83private:
84
87
90
93
95 std::vector<Node<SPACE_DIM>* > mHaloNodes;
96
98 std::map<unsigned, unsigned> mNodesMapping;
99
101 std::map<unsigned, unsigned> mHaloNodesMapping;
102
104 std::map<unsigned, unsigned> mElementsMapping;
105
107 std::map<unsigned, unsigned> mBoundaryElementsMapping;
108
111
114
123 template<class Archive>
124 void serialize(Archive & archive, const unsigned int version)
125 {
126 archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
127 }
128
129
138
139
140public:
141
147 DistributedTetrahedralMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod=DistributedTetrahedralMeshPartitionType::PARMETIS_LIBRARY);
148
153
160
167
172 unsigned GetNumLocalNodes() const;
173
177 unsigned GetNumHaloNodes() const;
178
183 unsigned GetNumLocalElements() const;
184
189 unsigned GetNumLocalBoundaryElements() const;
190
194 unsigned GetNumNodes() const;
195
199 unsigned GetNumAllNodes() const;
200
204 unsigned GetNumElements() const;
205
212
216 unsigned GetNumBoundaryElements() const;
217
222 void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
223
230
237
245 bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
246
253 bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
254
262 void ConstructLinearMesh(unsigned width);
263
277 void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
278
289 void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
298 virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
299
309 Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
310
319
328 virtual unsigned GetNearestNodeIndex(const ChastePoint<SPACE_DIM>& rTestPoint);
329
338 virtual c_vector<double, 2> CalculateMinMaxEdgeLengths();
339
347 void Rotate(c_matrix<double , SPACE_DIM, SPACE_DIM> rotationMatrix);
348
356 void Translate(const c_vector<double, SPACE_DIM>& rDisplacement);
357
358
359protected:
366 unsigned SolveNodeMapping(unsigned index) const;
367
374 unsigned SolveElementMapping(unsigned index) const;
375
382 unsigned SolveBoundaryElementMapping(unsigned index) const;
383private:
384
390 void RegisterNode(unsigned index);
391
397 void RegisterHaloNode(unsigned index);
398
404 void RegisterElement(unsigned index);
405
411 void RegisterBoundaryElement(unsigned index);
412
413
426 std::set<unsigned>& rNodesOwned,
427 std::set<unsigned>& rHaloNodesOwned,
428 std::set<unsigned>& rElementsOwned,
429 std::vector<unsigned>& rProcessorsOffset);
430
443 std::set<unsigned>& rElementsOwned,
444 std::set<unsigned>& rNodesOwned,
445 std::set<unsigned>& rHaloNodesOwned,
446 std::vector<unsigned>& rProcessorsOffset);
447
454 void ReorderNodes();
455
457 // Iterators //
459
460public:
462 // The other iterators aren't (so only need to be dereferenced once). Consistency would be good...
463
465 typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator HaloNodeIterator;
466
471
476};
477
480
481namespace boost
482{
483namespace serialization
484{
488template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
489inline void save_construct_data(
490 Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
491{
492 unsigned num_procs = PetscTools::GetNumProcs();
493 const DistributedTetrahedralMeshPartitionType::type partition_type = t->GetPartitionType();
494 ar << num_procs;
495 ar << partition_type;
496}
497
502template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
503inline void load_construct_data(
504 Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
505{
506 unsigned num_procs;
508
509 ar >> num_procs;
510 ar >> partition_type;
511
512 // Invoke inplace constructor to initialise instance
514 //::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(partition_type);
515 ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMeshPartitionType::DUMB);
516
517 /*
518 * The exception needs to be thrown after the call to ::new(t), or Boost will try
519 * to free non-allocated memory when the exception is thrown.
520 */
522 num_procs != PetscTools::GetNumProcs())
523 {
524 EXCEPTION("This archive was written for a different number of processors");
525 }
526
527}
528}
529} // namespace ...
530
531#endif /*DISTRIBUTEDTETRAHEDRALMESH_HPP_*/
#define EXCEPTION(message)
gcov doesn't like this file...
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
void serialize(Archive &archive, const unsigned int version)
std::map< unsigned, unsigned > mNodesMapping
bool CalculateDesignatedOwnershipOfElement(unsigned elementIndex)
virtual void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
ChasteCuboid< SPACE_DIM > * GetProcessRegion()
virtual c_vector< double, 2 > CalculateMinMaxEdgeLengths()
std::map< unsigned, unsigned > mElementsMapping
Node< SPACE_DIM > * GetNodeOrHaloNode(unsigned index) const
void ComputeMeshPartitioning(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader, std::set< unsigned > &rNodesOwned, std::set< unsigned > &rHaloNodesOwned, std::set< unsigned > &rElementsOwned, std::vector< unsigned > &rProcessorsOffset)
virtual unsigned GetNearestNodeIndex(const ChastePoint< SPACE_DIM > &rTestPoint)
HaloNodeIterator GetHaloNodeIteratorEnd() const
unsigned SolveElementMapping(unsigned index) const
void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true)
void Translate(const c_vector< double, SPACE_DIM > &rDisplacement)
DistributedTetrahedralMeshPartitionType::type GetPartitionType() const
unsigned SolveBoundaryElementMapping(unsigned index) const
void SetDistributedVectorFactory(DistributedVectorFactory *pFactory)
bool CalculateDesignatedOwnershipOfBoundaryElement(unsigned faceIndex)
HaloNodeIterator GetHaloNodeIteratorBegin() const
std::map< unsigned, unsigned > mHaloNodesMapping
std::map< unsigned, unsigned > mBoundaryElementsMapping
unsigned SolveNodeMapping(unsigned index) const
void ParMetisLibraryNodeAndElementPartitioning(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader, std::set< unsigned > &rElementsOwned, std::set< unsigned > &rNodesOwned, std::set< unsigned > &rHaloNodesOwned, std::vector< unsigned > &rProcessorsOffset)
virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0)
std::vector< Node< SPACE_DIM > * > mHaloNodes
void ConstructCuboid(unsigned width, unsigned height, unsigned depth)
friend class boost::serialization::access
void Rotate(c_matrix< double, SPACE_DIM, SPACE_DIM > rotationMatrix)
std::vector< Node< SPACE_DIM > * >::const_iterator HaloNodeIterator
void SetProcessRegion(ChasteCuboid< SPACE_DIM > *pRegion)
void GetHaloNodeIndices(std::vector< unsigned > &rHaloIndices) const
virtual ChasteCuboid< SPACE_DIM > CalculateBoundingBox() const
DistributedTetrahedralMeshPartitionType::type mPartitioning
ChasteCuboid< SPACE_DIM > * mpSpaceRegion
Definition Node.hpp:59
static unsigned GetNumProcs()