DistributedTetrahedralMesh.hpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 
00061 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00062 class DistributedTetrahedralMesh : public AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM>
00063 {
00064     friend class TestDistributedTetrahedralMesh;
00065     friend class TestDistributedQuadraticMesh;
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     ChasteCuboid<SPACE_DIM>* mpSpaceRegion;
00094 
00096     DistributedTetrahedralMeshPartitionType::type mMetisPartitioning;
00097 
00099     friend class boost::serialization::access;
00106     template<class Archive>
00107     void serialize(Archive & archive, const unsigned int version)
00108     {
00109         archive & boost::serialization::base_object<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >(*this);
00110     }
00111 
00112 
00120     void SetElementOwnerships();
00121 
00122 
00123 public:
00124 
00130     DistributedTetrahedralMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod=DistributedTetrahedralMeshPartitionType::PARMETIS_LIBRARY);
00131 
00135     virtual ~DistributedTetrahedralMesh();
00136 
00143     void SetDistributedVectorFactory(DistributedVectorFactory* pFactory);
00144 
00150     virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader);
00151 
00156     unsigned GetNumLocalNodes() const;
00157 
00161     unsigned GetNumHaloNodes() const;
00162 
00167     unsigned GetNumLocalElements() const;
00168 
00173     unsigned GetNumLocalBoundaryElements() const;
00174 
00178     unsigned GetNumNodes() const;
00179 
00183     unsigned GetNumAllNodes() const;
00184 
00188     unsigned GetNumElements() const;
00189 
00195     DistributedTetrahedralMeshPartitionType::type GetPartitionType() const;
00196 
00200     unsigned GetNumBoundaryElements() const;
00201 
00206     void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00207 
00213     void SetProcessRegion(ChasteCuboid<SPACE_DIM>* pRegion);
00214 
00220     ChasteCuboid<SPACE_DIM>* GetProcessRegion();
00221 
00229     bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00230 
00237     bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00238 
00246      void ConstructLinearMesh(unsigned width);
00247 
00261     void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00262 
00273     void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00282     virtual void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00283 
00293     Node<SPACE_DIM>* GetNodeOrHaloNode(unsigned index) const;
00294 
00302     virtual ChasteCuboid<SPACE_DIM> CalculateBoundingBox() const;
00303 
00312     virtual unsigned GetNearestNodeIndex(const ChastePoint<SPACE_DIM>& rTestPoint);
00313 
00322     virtual c_vector<double, 2> CalculateMinMaxEdgeLengths();
00323 
00324 
00325 protected:
00332     unsigned SolveNodeMapping(unsigned index) const;
00333 
00340     unsigned SolveElementMapping(unsigned index) const;
00341 
00348     unsigned SolveBoundaryElementMapping(unsigned index) const;
00349 private:
00350 
00356     void RegisterNode(unsigned index);
00357 
00363     void RegisterHaloNode(unsigned index);
00364 
00370     void RegisterElement(unsigned index);
00371 
00377     void RegisterBoundaryElement(unsigned index);
00378 
00379 
00391     void ComputeMeshPartitioning(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00392                                  std::set<unsigned>& rNodesOwned,
00393                                  std::set<unsigned>& rHaloNodesOwned,
00394                                  std::set<unsigned>& rElementsOwned,
00395                                  std::vector<unsigned>& rProcessorsOffset);
00396 
00408      void ParMetisLibraryNodeAndElementPartitioning(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     //                            Iterators                             //
00425 
00426 public:
00428     // The other iterators aren't (so only need to be dereferenced once). Consistency would be good...
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     // Invoke inplace constructor to initialise instance
00480     //::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(partition_type);
00481     ::new(t)DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>(DistributedTetrahedralMeshPartitionType::DUMB);
00482 
00483     /*
00484      * The exception needs to be thrown after the call to ::new(t), or Boost will try
00485      * to free non-allocated memory when the exception is thrown.
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 } // namespace ...
00496 
00497 #endif /*DISTRIBUTEDTETRAHEDRALMESH_HPP_*/

Generated by  doxygen 1.6.2