Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 #ifndef DISTRIBUTEDTETRAHEDRALMESH_HPP_ 00037 #define DISTRIBUTEDTETRAHEDRALMESH_HPP_ 00038 00039 #include <map> 00040 #include <vector> 00041 #include <set> 00042 00043 #include "ChasteSerialization.hpp" 00044 #include <boost/serialization/base_object.hpp> 00045 00046 #include "AbstractTetrahedralMesh.hpp" 00047 #include "Node.hpp" 00048 #include "AbstractMeshReader.hpp" 00049 #include "DistributedTetrahedralMeshPartitionType.hpp" 00050 00051 #define UNASSIGNED_NODE UINT_MAX 00052 00053 #include <parmetis.h> 00054 00062 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00063 class DistributedTetrahedralMesh : public AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM> 00064 { 00065 friend class TestDistributedTetrahedralMesh; 00066 private: 00067 00069 unsigned mTotalNumElements; 00070 00072 unsigned mTotalNumBoundaryElements; 00073 00075 unsigned mTotalNumNodes; 00076 00078 std::vector<Node<SPACE_DIM>* > mHaloNodes; 00079 00081 std::map<unsigned, unsigned> mNodesMapping; 00082 00084 std::map<unsigned, unsigned> mHaloNodesMapping; 00085 00087 std::map<unsigned, unsigned> mElementsMapping; 00088 00090 std::map<unsigned, unsigned> mBoundaryElementsMapping; 00091 00093 DistributedTetrahedralMeshPartitionType::type mMetisPartitioning; 00094 00096 friend class boost::serialization::access; 00103 template<class Archive> 00104 void serialize(Archive & archive, const unsigned int version) 00105 { 00106 archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this); 00107 } 00108 00109 00117 void SetElementOwnerships(); 00118 00119 00120 public: 00121 00127 DistributedTetrahedralMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod=DistributedTetrahedralMeshPartitionType::METIS_LIBRARY); 00128 00132 virtual ~DistributedTetrahedralMesh(); 00133 00140 void SetDistributedVectorFactory(DistributedVectorFactory* pFactory); 00141 00147 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader); 00148 00153 unsigned GetNumLocalNodes() const; 00154 00158 unsigned GetNumHaloNodes() const; 00159 00164 unsigned GetNumLocalElements() const; 00165 00170 unsigned GetNumLocalBoundaryElements() const; 00171 00175 unsigned GetNumNodes() const; 00176 00180 unsigned GetNumAllNodes() const; 00181 00185 unsigned GetNumElements() const; 00186 00192 DistributedTetrahedralMeshPartitionType::type GetPartitionType() const; 00193 00197 unsigned GetNumBoundaryElements() const; 00198 00203 void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const; 00204 00205 00212 bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex ); 00213 00220 bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex ); 00221 00229 void ConstructLinearMesh(unsigned width); 00230 00244 void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true); 00245 00256 void ConstructCuboid(unsigned width, unsigned height, unsigned depth); 00265 virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0); 00266 00276 Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const; 00277 00285 virtual ChasteCuboid<SPACE_DIM> CalculateBoundingBox() const; 00286 00295 virtual c_vector<double, 2> CalculateMinMaxEdgeLengths(); 00296 00297 00298 protected: 00304 unsigned SolveNodeMapping(unsigned index) const; 00305 00311 unsigned SolveElementMapping(unsigned index) const; 00312 00318 unsigned SolveBoundaryElementMapping(unsigned index) const; 00319 private: 00320 00326 void RegisterNode(unsigned index); 00327 00333 void RegisterHaloNode(unsigned index); 00334 00340 void RegisterElement(unsigned index); 00341 00347 void RegisterBoundaryElement(unsigned index); 00348 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 00378 void ParMetisLibraryNodeAndElementPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader, 00379 std::set<unsigned>& rElementsOwned, 00380 std::set<unsigned>& rNodesOwned, 00381 std::set<unsigned>& rHaloNodesOwned, 00382 std::vector<unsigned>& rProcessorsOffset); 00383 00390 void ReorderNodes(); 00391 00393 // Iterators // 00395 00396 public: 00398 // The other iterators aren't (so only need to be dereferenced once). Consistency would be good... 00399 00401 typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator HaloNodeIterator; 00402 00406 HaloNodeIterator GetHaloNodeIteratorBegin() const; 00407 00411 HaloNodeIterator GetHaloNodeIteratorEnd() const; 00412 }; 00413 00414 #include "SerializationExportWrapper.hpp" 00415 EXPORT_TEMPLATE_CLASS_ALL_DIMS(DistributedTetrahedralMesh) 00416 00417 namespace boost 00418 { 00419 namespace serialization 00420 { 00424 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00425 inline void save_construct_data( 00426 Archive & ar, const DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const BOOST_PFTO unsigned int file_version) 00427 { 00428 unsigned num_procs = PetscTools::GetNumProcs(); 00429 const DistributedTetrahedralMeshPartitionType::type partition_type = t->GetPartitionType(); 00430 ar << num_procs; 00431 ar << partition_type; 00432 } 00433 00438 template<class Archive, unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00439 inline void load_construct_data( 00440 Archive & ar, DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> * t, const unsigned int file_version) 00441 { 00442 unsigned num_procs; 00443 DistributedTetrahedralMeshPartitionType::type partition_type; 00444 00445 ar >> num_procs; 00446 ar >> partition_type; 00447 00448 // Invoke inplace constructor to initialise instance 00450 //::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(partition_type); 00451 ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMeshPartitionType::DUMB); 00452 00453 /* 00454 * The exception needs to be thrown after the call to ::new(t), or Boost will try 00455 * to free non-allocated memory when the exception is thrown. 00456 */ 00457 if (DistributedVectorFactory::CheckNumberOfProcessesOnLoad() && 00458 num_procs != PetscTools::GetNumProcs()) 00459 { 00460 EXCEPTION("This archive was written for a different number of processors"); 00461 } 00462 00463 } 00464 } 00465 } // namespace ... 00466 00467 #endif /*DISTRIBUTEDTETRAHEDRALMESH_HPP_*/