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 private:
00293
00299 void RegisterNode(unsigned index);
00300
00306 void RegisterHaloNode(unsigned index);
00307
00313 void RegisterElement(unsigned index);
00314
00320 void RegisterBoundaryElement(unsigned index);
00321
00327 unsigned SolveNodeMapping(unsigned index) const;
00328
00334 unsigned SolveElementMapping(unsigned index) const;
00335
00341 unsigned SolveBoundaryElementMapping(unsigned index) const;
00342
00354 void ComputeMeshPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00355 std::set<unsigned>& rNodesOwned,
00356 std::set<unsigned>& rHaloNodesOwned,
00357 std::set<unsigned>& rElementsOwned,
00358 std::vector<unsigned>& rProcessorsOffset);
00359
00367 void DumbNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00368 std::set<unsigned>& rNodesOwned);
00369
00370
00380 void MetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00381 std::set<unsigned>& rNodesOwned,
00382 std::vector<unsigned>& rProcessorsOffset);
00383
00393 void PetscMatrixPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00394 std::set<unsigned>& rNodesOwned,
00395 std::vector<unsigned>& rProcessorsOffset);
00407 void ParMetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00408 std::set<unsigned>& rElementsOwned,
00409 std::set<unsigned>& rNodesOwned,
00410 std::set<unsigned>& rHaloNodesOwned,
00411 std::vector<unsigned>& rProcessorsOffset);
00412
00419 void ReorderNodes();
00420
00422
00424
00425 public:
00427
00428
00430 typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator HaloNodeIterator;
00431
00435 HaloNodeIterator GetHaloNodeIteratorBegin() const;
00436
00440 HaloNodeIterator GetHaloNodeIteratorEnd() const;
00441 };
00442
00443 #include "SerializationExportWrapper.hpp"
00444 EXPORT_TEMPLATE_CLASS_ALL_DIMS(DistributedTetrahedralMesh)
00445
00446 namespace boost
00447 {
00448 namespace serialization
00449 {
00453 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00454 inline void save_construct_data(
00455 Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const BOOST_PFTO unsigned int file_version)
00456 {
00457 unsigned num_procs = PetscTools::GetNumProcs();
00458 const DistributedTetrahedralMeshPartitionType::type partition_type = t->GetPartitionType();
00459 ar << num_procs;
00460 ar << partition_type;
00461 }
00462
00467 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00468 inline void load_construct_data(
00469 Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
00470 {
00471 unsigned num_procs;
00472 DistributedTetrahedralMeshPartitionType::type partition_type;
00473
00474 ar >> num_procs;
00475 ar >> partition_type;
00476
00477
00479
00480 ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMeshPartitionType::DUMB);
00481
00482
00483
00484
00485
00486 if (DistributedVectorFactory::CheckNumberOfProcessesOnLoad() &&
00487 num_procs != PetscTools::GetNumProcs())
00488 {
00489 EXCEPTION("This archive was written for a different number of processors");
00490 }
00491
00492 }
00493 }
00494 }
00495
00496 #endif