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 #include "DistributedTetrahedralMeshPartitionType.hpp"
00043
00044 #define UNASSIGNED_NODE UINT_MAX
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 extern "C" {
00056 extern void METIS_PartMeshNodal(int*, int*, int*, int*, int*, int*, int*, int*, int*);
00057 }
00058 #include <parmetis.h>
00059
00067 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00068 class DistributedTetrahedralMesh : public AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM>
00069 {
00070 friend class TestDistributedTetrahedralMesh;
00071 private:
00072
00074 unsigned mTotalNumElements;
00075
00077 unsigned mTotalNumBoundaryElements;
00078
00080 unsigned mTotalNumNodes;
00081
00083 std::vector<Node<SPACE_DIM>* > mHaloNodes;
00084
00086 std::map<unsigned, unsigned> mNodesMapping;
00087
00089 std::map<unsigned, unsigned> mHaloNodesMapping;
00090
00092 std::map<unsigned, unsigned> mElementsMapping;
00093
00095 std::map<unsigned, unsigned> mBoundaryElementsMapping;
00096
00098 DistributedTetrahedralMeshPartitionType::type mMetisPartitioning;
00099
00101 friend class boost::serialization::access;
00108 template<class Archive>
00109 void serialize(Archive & archive, const unsigned int version)
00110 {
00111 archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
00112 }
00113
00114
00122 void SetElementOwnerships();
00123
00124
00125 public:
00126
00132 DistributedTetrahedralMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod=DistributedTetrahedralMeshPartitionType::METIS_LIBRARY);
00133
00137 virtual ~DistributedTetrahedralMesh();
00138
00145 void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00146
00152 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00153
00158 unsigned GetNumLocalNodes() const;
00159
00163 unsigned GetNumHaloNodes() const;
00164
00169 unsigned GetNumLocalElements() const;
00170
00175 unsigned GetNumLocalBoundaryElements() const;
00176
00180 unsigned GetNumNodes() const;
00181
00185 unsigned GetNumAllNodes() const;
00186
00190 unsigned GetNumElements() const;
00191
00197 DistributedTetrahedralMeshPartitionType::type GetPartitionType() const;
00198
00202 unsigned GetNumBoundaryElements() const;
00203
00208 void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00209
00210
00217 bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00218
00225 bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00226
00234 void ConstructLinearMesh(unsigned width);
00235
00249 void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00250
00261 void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00270 virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00271
00281 Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
00282
00290 virtual ChasteCuboid<SPACE_DIM> CalculateBoundingBox() const;
00291
00292 protected:
00298 unsigned SolveNodeMapping(unsigned index) const;
00299
00305 unsigned SolveElementMapping(unsigned index) const;
00306
00312 unsigned SolveBoundaryElementMapping(unsigned index) const;
00313 private:
00314
00320 void RegisterNode(unsigned index);
00321
00327 void RegisterHaloNode(unsigned index);
00328
00334 void RegisterElement(unsigned index);
00335
00341 void RegisterBoundaryElement(unsigned index);
00342
00343
00355 void ComputeMeshPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00356 std::set<unsigned>& rNodesOwned,
00357 std::set<unsigned>& rHaloNodesOwned,
00358 std::set<unsigned>& rElementsOwned,
00359 std::vector<unsigned>& rProcessorsOffset);
00360
00368 void DumbNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00369 std::set<unsigned>& rNodesOwned);
00370
00371
00381 void MetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00382 std::set<unsigned>& rNodesOwned,
00383 std::vector<unsigned>& rProcessorsOffset);
00384
00394 void PetscMatrixPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00395 std::set<unsigned>& rNodesOwned,
00396 std::vector<unsigned>& rProcessorsOffset);
00408 void ParMetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00409 std::set<unsigned>& rElementsOwned,
00410 std::set<unsigned>& rNodesOwned,
00411 std::set<unsigned>& rHaloNodesOwned,
00412 std::vector<unsigned>& rProcessorsOffset);
00413
00420 void ReorderNodes();
00421
00423
00425
00426 public:
00428
00429
00431 typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator HaloNodeIterator;
00432
00436 HaloNodeIterator GetHaloNodeIteratorBegin() const;
00437
00441 HaloNodeIterator GetHaloNodeIteratorEnd() const;
00442 };
00443
00444 #include "SerializationExportWrapper.hpp"
00445 EXPORT_TEMPLATE_CLASS_ALL_DIMS(DistributedTetrahedralMesh)
00446
00447 namespace boost
00448 {
00449 namespace serialization
00450 {
00454 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00455 inline void save_construct_data(
00456 Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const BOOST_PFTO unsigned int file_version)
00457 {
00458 unsigned num_procs = PetscTools::GetNumProcs();
00459 const DistributedTetrahedralMeshPartitionType::type partition_type = t->GetPartitionType();
00460 ar << num_procs;
00461 ar << partition_type;
00462 }
00463
00468 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00469 inline void load_construct_data(
00470 Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
00471 {
00472 unsigned num_procs;
00473 DistributedTetrahedralMeshPartitionType::type partition_type;
00474
00475 ar >> num_procs;
00476 ar >> partition_type;
00477
00478
00480
00481 ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMeshPartitionType::DUMB);
00482
00483
00484
00485
00486
00487 if (DistributedVectorFactory::CheckNumberOfProcessesOnLoad() &&
00488 num_procs != PetscTools::GetNumProcs())
00489 {
00490 EXCEPTION("This archive was written for a different number of processors");
00491 }
00492
00493 }
00494 }
00495 }
00496
00497 #endif