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 #ifndef DISTRIBUTEDTETRAHEDRALMESH_HPP_
00030 #define DISTRIBUTEDTETRAHEDRALMESH_HPP_
00031
00032 #include <map>
00033 #include <vector>
00034 #include <set>
00035
00036 #include "ChasteSerialization.hpp"
00037 #include <boost/serialization/base_object.hpp>
00038
00039 #include "AbstractTetrahedralMesh.hpp"
00040 #include "Node.hpp"
00041 #include "AbstractMeshReader.hpp"
00042
00043 #define UNASSIGNED_NODE UINT_MAX
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 extern "C" {
00055 extern void METIS_PartMeshNodal(int*, int*, int*, int*, int*, int*, int*, int*, int*);
00056 }
00057 #include <parmetis.h>
00058
00066 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00067 class DistributedTetrahedralMesh : public AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM>
00068 {
00069 friend class TestDistributedTetrahedralMesh;
00070
00071 public:
00072
00079 typedef enum
00080 {
00081 DUMB=0,
00082 PARMETIS_LIBRARY=1,
00083 METIS_LIBRARY=2,
00084 PETSC_MAT_PARTITION=3
00085 } PartitionType;
00086
00087 private:
00088
00090 unsigned mTotalNumElements;
00091
00093 unsigned mTotalNumBoundaryElements;
00094
00096 unsigned mTotalNumNodes;
00097
00099 std::vector<Node<SPACE_DIM>* > mHaloNodes;
00100
00102 std::map<unsigned, unsigned> mNodesMapping;
00103
00105 std::map<unsigned, unsigned> mHaloNodesMapping;
00106
00108 std::map<unsigned, unsigned> mElementsMapping;
00109
00111 std::map<unsigned, unsigned> mBoundaryElementsMapping;
00112
00114 PartitionType mMetisPartitioning;
00115
00117 friend class boost::serialization::access;
00124 template<class Archive>
00125 void serialize(Archive & archive, const unsigned int version)
00126 {
00127 archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
00128 }
00129
00130
00131
00132 public:
00133
00139 DistributedTetrahedralMesh(PartitionType metisPartitioning=METIS_LIBRARY);
00140
00144 virtual ~DistributedTetrahedralMesh();
00145
00152 void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00153
00159 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00160
00165 unsigned GetNumLocalNodes() const;
00166
00171 unsigned GetNumLocalElements() const;
00172
00177 unsigned GetNumLocalBoundaryElements() const;
00178
00182 unsigned GetNumNodes() const;
00183
00187 unsigned GetNumAllNodes() const;
00188
00192 unsigned GetNumElements() const;
00193
00199 PartitionType GetPartitionType() const;
00200
00204 unsigned GetNumBoundaryElements() const;
00205
00210 void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00211
00221 void SetElementOwnerships(unsigned lo, unsigned hi);
00222
00223
00230 bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00231
00238 bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00239
00247 void ConstructLinearMesh(unsigned width);
00248
00259 void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00260
00268 void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00277 virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00278
00288 Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
00289
00297 virtual ChasteCuboid<SPACE_DIM> CalculateBoundingBox() const;
00298
00299 private:
00300
00306 void RegisterNode(unsigned index);
00307
00313 void RegisterHaloNode(unsigned index);
00314
00320 void RegisterElement(unsigned index);
00321
00327 void RegisterBoundaryElement(unsigned index);
00328
00334 unsigned SolveNodeMapping(unsigned index) const;
00335
00341 unsigned SolveElementMapping(unsigned index) const;
00342
00348 unsigned SolveBoundaryElementMapping(unsigned index) const;
00349
00361 void ComputeMeshPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00362 std::set<unsigned>& rNodesOwned,
00363 std::set<unsigned>& rHaloNodesOwned,
00364 std::set<unsigned>& rElementsOwned,
00365 std::vector<unsigned>& rProcessorsOffset);
00366
00374 void DumbNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00375 std::set<unsigned>& rNodesOwned);
00376
00377
00387 void MetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00388 std::set<unsigned>& rNodesOwned,
00389 std::vector<unsigned>& rProcessorsOffset);
00390
00400 void PetscMatrixPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00401 std::set<unsigned>& rNodesOwned,
00402 std::vector<unsigned>& rProcessorsOffset);
00414 void ParMetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00415 std::set<unsigned>& rElementsOwned,
00416 std::set<unsigned>& rNodesOwned,
00417 std::set<unsigned>& rHaloNodesOwned,
00418 std::vector<unsigned>& rProcessorsOffset);
00419
00426 void ReorderNodes();
00427 };
00428
00429 #include "SerializationExportWrapper.hpp"
00430 EXPORT_TEMPLATE_CLASS_ALL_DIMS(DistributedTetrahedralMesh)
00431
00432 namespace boost
00433 {
00434 namespace serialization
00435 {
00439 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00440 inline void save_construct_data(
00441 Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const BOOST_PFTO unsigned int file_version)
00442 {
00443 unsigned num_procs = PetscTools::GetNumProcs();
00444 const typename DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::PartitionType partition_type = t->GetPartitionType();
00445 ar << num_procs;
00446 ar << partition_type;
00447 }
00448
00453 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00454 inline void load_construct_data(
00455 Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
00456 {
00457 unsigned num_procs;
00458 typename DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::PartitionType partition_type;
00459
00460 ar >> num_procs;
00461 ar >> partition_type;
00462
00463
00465
00466 ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::DUMB);
00467
00468
00469
00470
00471
00472 if (DistributedVectorFactory::CheckNumberOfProcessesOnLoad() &&
00473 num_procs != PetscTools::GetNumProcs())
00474 {
00475 EXCEPTION("This archive was written for a different number of processors");
00476 }
00477
00478 }
00479 }
00480 }
00481
00482 #endif