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
00078 typedef enum
00079 {
00080 DUMB=0,
00081 PARMETIS_LIBRARY=1,
00082 METIS_LIBRARY=2
00083 } PartitionType;
00084
00085 private:
00086
00088 unsigned mTotalNumElements;
00089
00091 unsigned mTotalNumBoundaryElements;
00092
00094 unsigned mTotalNumNodes;
00095
00097 std::vector<Node<SPACE_DIM>* > mHaloNodes;
00098
00100 std::map<unsigned, unsigned> mNodesMapping;
00101
00103 std::map<unsigned, unsigned> mHaloNodesMapping;
00104
00106 std::map<unsigned, unsigned> mElementsMapping;
00107
00109 std::map<unsigned, unsigned> mBoundaryElementsMapping;
00110
00112 PartitionType mMetisPartitioning;
00113
00115 friend class boost::serialization::access;
00122 template<class Archive>
00123 void serialize(Archive & archive, const unsigned int version)
00124 {
00125 archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
00126 }
00127
00128
00129
00130 public:
00131
00137 DistributedTetrahedralMesh(PartitionType metisPartitioning=METIS_LIBRARY);
00138
00142 virtual ~DistributedTetrahedralMesh();
00143
00150 void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00151
00157 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00158
00163 unsigned GetNumLocalNodes() 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 PartitionType GetPartitionType() const;
00198
00202 unsigned GetNumBoundaryElements() const;
00203
00208 void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00209
00219 void SetElementOwnerships(unsigned lo, unsigned hi);
00220
00221
00228 bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00229
00236 bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00237
00245 void ConstructLinearMesh(unsigned width);
00246
00257 void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00258
00266 void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00275 virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00276
00286 Node<SPACE_DIM>* GetAnyNode(unsigned index) const;
00287
00288 private:
00289
00295 void RegisterNode(unsigned index);
00296
00302 void RegisterHaloNode(unsigned index);
00303
00309 void RegisterElement(unsigned index);
00310
00316 void RegisterBoundaryElement(unsigned index);
00317
00323 unsigned SolveNodeMapping(unsigned index) const;
00324
00330 unsigned SolveElementMapping(unsigned index) const;
00331
00337 unsigned SolveBoundaryElementMapping(unsigned index) const;
00338
00350 void ComputeMeshPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00351 std::set<unsigned>& rNodesOwned,
00352 std::set<unsigned>& rHaloNodesOwned,
00353 std::set<unsigned>& rElementsOwned,
00354 std::vector<unsigned>& rProcessorsOffset);
00355
00363 void DumbNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00364 std::set<unsigned>& rNodesOwned);
00365
00366
00376 void MetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00377 std::set<unsigned>& rNodesOwned,
00378 std::vector<unsigned>& rProcessorsOffset);
00379
00391 void ParMetisLibraryNodePartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00392 std::set<unsigned>& rElementsOwned,
00393 std::set<unsigned>& rNodesOwned,
00394 std::set<unsigned>& rHaloNodesOwned,
00395 std::vector<unsigned>& rProcessorsOffset);
00396
00403 void ReorderNodes();
00404 };
00405
00406 #include "SerializationExportWrapper.hpp"
00407 EXPORT_TEMPLATE_CLASS_ALL_DIMS(DistributedTetrahedralMesh);
00408
00409 namespace boost
00410 {
00411 namespace serialization
00412 {
00416 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00417 inline void save_construct_data(
00418 Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const BOOST_PFTO unsigned int file_version)
00419 {
00420 unsigned num_procs = PetscTools::GetNumProcs();
00421 const typename DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::PartitionType partition_type = t->GetPartitionType();
00422 ar << num_procs;
00423 ar << partition_type;
00424 }
00425
00430 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00431 inline void load_construct_data(
00432 Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version)
00433 {
00434 unsigned num_procs;
00435 typename DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::PartitionType partition_type;
00436
00437 ar >> num_procs;
00438 ar >> partition_type;
00439
00440
00442
00443 ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::DUMB);
00444
00445
00446
00447
00448
00449 if (DistributedVectorFactory::CheckNumberOfProcessesOnLoad() &&
00450 num_procs != PetscTools::GetNumProcs())
00451 {
00452 EXCEPTION("This archive was written for a different number of processors");
00453 }
00454
00455 }
00456 }
00457 }
00458
00459 #endif