DistributedBoxCollection.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 #ifndef DISTRIBUTEDBOXCOLLECTION_HPP_
00036 #define DISTRIBUTEDBOXCOLLECTION_HPP_
00037 
00038 #include "ChasteSerialization.hpp"
00039 #include <boost/serialization/vector.hpp>
00040 
00041 #include "Node.hpp"
00042 #include "Element.hpp"
00043 #include "Box.hpp"
00044 #include "PetscTools.hpp"
00045 #include "DistributedVectorFactory.hpp"
00046 #include <map>
00047 #include <vector>
00048 
00049 
00053 template<unsigned DIM>
00054 class DistributedBoxCollection
00055 {
00056 private:
00057     friend class TestDistributedBoxCollection;
00058 
00060     std::vector< Box<DIM> > mBoxes;
00061 
00063     std::vector< Box<DIM> > mHaloBoxes;
00064 
00066     std::vector<unsigned> mHalosRight;
00067 
00069     std::vector<unsigned> mHalosLeft;
00070 
00072     std::vector<unsigned> mHaloNodesRight;
00073 
00075     std::vector<unsigned> mHaloNodesLeft;
00076 
00078     std::map<unsigned, unsigned> mBoxesMapping;
00079 
00081     std::map<unsigned, unsigned> mHaloBoxesMapping;
00082 
00084     c_vector<double, 2*DIM> mDomainSize;
00085 
00087     double mBoxWidth;
00088 
00090     unsigned mNumBoxes;
00091 
00093     c_vector<unsigned, DIM> mNumBoxesEachDirection;
00094 
00096     unsigned mNumBoxesInAFace;
00097 
00099     std::vector< std::set<unsigned> > mLocalBoxes;
00100 
00102     unsigned mMinBoxIndex;
00103 
00105     unsigned mMaxBoxIndex;
00106 
00108     bool mIsPeriodicInX;
00109 
00111     bool mAreLocalBoxesSet;
00112 
00114     static const double msFudge;
00115 
00117     DistributedVectorFactory* mpDistributedBoxStackFactory;
00118 
00120     bool mCalculateNodeNeighbours;
00121 
00123     friend class boost::serialization::access;
00124 
00131     template<class Archive>
00132     void serialize(Archive & archive, const unsigned int version)
00133     {
00134         //All methods over-ridden below.
00135     }
00136 
00137 public:
00138 
00150     DistributedBoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize, bool isPeriodicInX = false, int localRows = PETSC_DECIDE);
00151 
00152 
00156     ~DistributedBoxCollection();
00157 
00161     void EmptyBoxes();
00162 
00168     void SetupHaloBoxes();
00169 
00174     void UpdateHaloBoxes();
00175 
00179     unsigned GetNumLocalRows() const;
00180 
00185     bool GetBoxOwnership(unsigned globalIndex);
00186 
00194     bool IsInteriorBox(unsigned globalIndex);
00195 
00200     bool GetHaloBoxOwnership(unsigned globalIndex);
00201 
00208     unsigned CalculateGlobalIndex(c_vector<unsigned, DIM> coordinateIndices);
00209 
00214     unsigned CalculateContainingBox(Node<DIM>* pNode);
00215 
00220     unsigned CalculateContainingBox(c_vector<double, DIM>& rLocation);
00221 
00228     c_vector<unsigned, DIM> CalculateCoordinateIndices(unsigned globalIndex);
00229 
00234     Box<DIM>& rGetBox(unsigned boxIndex);
00235 
00241     Box<DIM>& rGetHaloBox(unsigned boxIndex);
00242 
00246     unsigned GetNumBoxes();
00247 
00251     unsigned GetNumLocalBoxes();
00252 
00256     c_vector<double, 2*DIM> rGetDomainSize() const;
00257 
00261     bool GetAreLocalBoxesSet() const;
00262 
00266     double GetBoxWidth() const;
00267 
00271     unsigned GetNumRowsOfBoxes() const;
00272 
00280     int LoadBalance(std::vector<int> localDistribution);
00281 
00287     void SetupLocalBoxesHalfOnly();
00288 
00292     void SetupAllLocalBoxes();
00293 
00300     std::set<unsigned> GetLocalBoxes(unsigned boxIndex);
00301 
00306     bool IsOwned(Node<DIM>* pNode);
00307 
00312     bool IsOwned(c_vector<double, DIM>& location);
00313 
00321     unsigned GetProcessOwningNode(Node<DIM>* pNode);
00322 
00326     std::vector<unsigned>& rGetHaloNodesRight();
00327 
00331     std::vector<unsigned>& rGetHaloNodesLeft();
00332 
00338     void SetCalculateNodeNeighbours(bool calculateNodeNeighbours);
00339 
00350     void CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00351 
00359     void CalculateInteriorNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00360 
00368     void CalculateBoundaryNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00369 
00377     void AddPairsFromBox(unsigned boxIndex, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00378 
00384     std::vector<int> CalculateNumberOfNodesInEachStrip();
00385 };
00386 
00387 #include "SerializationExportWrapper.hpp"
00388 // Declare identifier for the serializer
00389 EXPORT_TEMPLATE_CLASS_SAME_DIMS(DistributedBoxCollection)
00390 
00391 
00392 namespace boost
00393 {
00394 namespace serialization
00395 {
00399 template<class Archive, unsigned DIM>
00400 inline void save_construct_data(
00401     Archive & ar, const DistributedBoxCollection<DIM> * t, const unsigned int file_version)
00402 {
00403     // Save the number of rows that each process owns, so that on loading we can resume with
00404     // good load balance
00405     int num_local_rows = (int)(t->GetNumRowsOfBoxes());
00406     std::vector<int> num_rows(PetscTools::GetNumProcs());
00407     MPI_Gather(&num_local_rows, 1, MPI_INT, &num_rows[0], 1, MPI_INT, 0, PETSC_COMM_WORLD);
00408 
00409     if (PetscTools::AmMaster())
00410     {
00411         bool are_boxes_set = t->GetAreLocalBoxesSet();
00412         ar << are_boxes_set;
00413 
00414         c_vector<double, 2*DIM> domain_size = t->rGetDomainSize();
00415         for (unsigned i=0; i<2*DIM; i++)
00416         {
00417             ar << domain_size[i];
00418         }
00419 
00420         double box_width = t->GetBoxWidth();
00421         ar << box_width;
00422 
00423         unsigned num_procs = PetscTools::GetNumProcs();
00424         ar << num_procs;
00425 
00426         std::vector<int> const const_num_rows = num_rows;
00427         ar << const_num_rows;
00428     }
00429 }
00433 template<class Archive, unsigned DIM>
00434 inline void load_construct_data(
00435     Archive & ar, DistributedBoxCollection<DIM> * t, const unsigned int file_version)
00436 {
00437     bool are_boxes_set;
00438     ar >> are_boxes_set;
00439 
00440     // Retrieve data from archive required to construct new instance of Node
00441     c_vector<double,2*DIM> domain_size;
00442     for (unsigned i=0; i<2*DIM; i++)
00443     {
00444         double coordinate;
00445         ar & coordinate; //resume coordinates one by one
00446         domain_size[i] = coordinate;
00447     }
00448 
00449     // Shrink the domain size slightly so we get the correct size on construction
00450     for (unsigned i=0; i<DIM; i++)
00451     {
00452         domain_size[2*i+1] -= 1e-14;
00453     }
00454     double cut_off;
00455     ar >> cut_off;
00456 
00457     unsigned num_original_procs;
00458     ar >> num_original_procs;
00459 
00460     int num_rows = PETSC_DECIDE;
00461     std::vector<int> original_rows;
00462     ar >> original_rows;
00463     if (num_original_procs == PetscTools::GetNumProcs())
00464     {
00465         num_rows = original_rows[PetscTools::GetMyRank()];
00466     }
00467 
00468     // Invoke inplace constructor to initialise instance. Assume non-periodic
00469     ::new(t)DistributedBoxCollection<DIM>(cut_off, domain_size, false, num_rows);
00470 
00471     if (are_boxes_set)
00472     {
00473         t->SetupHaloBoxes();
00474         t->SetupLocalBoxesHalfOnly();
00475     }
00476 }
00477 }
00478 } // namespace ...
00479 
00480 
00481 #endif /*DISTRIBUTEDBOXCOLLECTION_HPP_*/

Generated by  doxygen 1.6.2