Chaste  Release::3.4
DistributedBoxCollection.hpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 #ifndef DISTRIBUTEDBOXCOLLECTION_HPP_
36 #define DISTRIBUTEDBOXCOLLECTION_HPP_
37 
38 #include "ChasteSerialization.hpp"
39 #include <boost/serialization/vector.hpp>
40 
41 #include "Node.hpp"
42 #include "Element.hpp"
43 #include "Box.hpp"
44 #include "PetscTools.hpp"
45 #include "DistributedVectorFactory.hpp"
46 #include <map>
47 #include <vector>
48 
49 
53 template<unsigned DIM>
55 {
56 private:
57  friend class TestDistributedBoxCollection;
58 
60  std::vector< Box<DIM> > mBoxes;
61 
63  std::vector< Box<DIM> > mHaloBoxes;
64 
66  std::vector<unsigned> mHalosRight;
67 
69  std::vector<unsigned> mHalosLeft;
70 
72  std::vector<unsigned> mHaloNodesRight;
73 
75  std::vector<unsigned> mHaloNodesLeft;
76 
78  std::map<unsigned, unsigned> mBoxesMapping;
79 
81  std::map<unsigned, unsigned> mHaloBoxesMapping;
82 
84  c_vector<double, 2*DIM> mDomainSize;
85 
87  double mBoxWidth;
88 
90  unsigned mNumBoxes;
91 
93  c_vector<unsigned, DIM> mNumBoxesEachDirection;
94 
96  unsigned mNumBoxesInAFace;
97 
99  std::vector< std::set<unsigned> > mLocalBoxes;
100 
102  unsigned mMinBoxIndex;
103 
105  unsigned mMaxBoxIndex;
106 
109 
112 
114  static const double msFudge;
115 
118 
121 
123  friend class boost::serialization::access;
124 
131  template<class Archive>
132  void serialize(Archive & archive, const unsigned int version)
133  {
134  //All methods over-ridden below.
135  }
136 
137 public:
138 
150  DistributedBoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize, bool isPeriodicInX = false, int localRows = PETSC_DECIDE);
151 
152 
157 
161  void EmptyBoxes();
162 
168  void SetupHaloBoxes();
169 
174  void UpdateHaloBoxes();
175 
179  unsigned GetNumLocalRows() const;
180 
185  bool GetBoxOwnership(unsigned globalIndex);
186 
194  bool IsInteriorBox(unsigned globalIndex);
195 
200  bool GetHaloBoxOwnership(unsigned globalIndex);
201 
208  unsigned CalculateGlobalIndex(c_vector<unsigned, DIM> coordinateIndices);
209 
214  unsigned CalculateContainingBox(Node<DIM>* pNode);
215 
220  unsigned CalculateContainingBox(c_vector<double, DIM>& rLocation);
221 
228  c_vector<unsigned, DIM> CalculateCoordinateIndices(unsigned globalIndex);
229 
234  Box<DIM>& rGetBox(unsigned boxIndex);
235 
241  Box<DIM>& rGetHaloBox(unsigned boxIndex);
242 
246  unsigned GetNumBoxes();
247 
251  unsigned GetNumLocalBoxes();
252 
256  c_vector<double, 2*DIM> rGetDomainSize() const;
257 
261  bool GetAreLocalBoxesSet() const;
262 
266  double GetBoxWidth() const;
267 
271  unsigned GetNumRowsOfBoxes() const;
272 
280  int LoadBalance(std::vector<int> localDistribution);
281 
288 
292  void SetupAllLocalBoxes();
293 
300  std::set<unsigned> GetLocalBoxes(unsigned boxIndex);
301 
306  bool IsOwned(Node<DIM>* pNode);
307 
312  bool IsOwned(c_vector<double, DIM>& location);
313 
321  unsigned GetProcessOwningNode(Node<DIM>* pNode);
322 
326  std::vector<unsigned>& rGetHaloNodesRight();
327 
331  std::vector<unsigned>& rGetHaloNodesLeft();
332 
338  void SetCalculateNodeNeighbours(bool calculateNodeNeighbours);
339 
350  void CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
351 
359  void CalculateInteriorNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
360 
368  void CalculateBoundaryNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
369 
377  void AddPairsFromBox(unsigned boxIndex, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
378 
384  std::vector<int> CalculateNumberOfNodesInEachStrip();
385 };
386 
388 // Declare identifier for the serializer
390 
391 
392 namespace boost
393 {
394 namespace serialization
395 {
399 template<class Archive, unsigned DIM>
400 inline void save_construct_data(
401  Archive & ar, const DistributedBoxCollection<DIM> * t, const unsigned int file_version)
402 {
403  // Save the number of rows that each process owns, so that on loading we can resume with
404  // good load balance
405  int num_local_rows = (int)(t->GetNumRowsOfBoxes());
406  std::vector<int> num_rows(PetscTools::GetNumProcs());
407  MPI_Gather(&num_local_rows, 1, MPI_INT, &num_rows[0], 1, MPI_INT, 0, PETSC_COMM_WORLD);
408 
409  if (PetscTools::AmMaster())
410  {
411  bool are_boxes_set = t->GetAreLocalBoxesSet();
412  ar << are_boxes_set;
413 
414  c_vector<double, 2*DIM> domain_size = t->rGetDomainSize();
415  for (unsigned i=0; i<2*DIM; i++)
416  {
417  ar << domain_size[i];
418  }
419 
420  double box_width = t->GetBoxWidth();
421  ar << box_width;
422 
423  unsigned num_procs = PetscTools::GetNumProcs();
424  ar << num_procs;
425 
426  std::vector<int> const const_num_rows = num_rows;
427  ar << const_num_rows;
428  }
429 }
433 template<class Archive, unsigned DIM>
434 inline void load_construct_data(
435  Archive & ar, DistributedBoxCollection<DIM> * t, const unsigned int file_version)
436 {
437  bool are_boxes_set;
438  ar >> are_boxes_set;
439 
440  // Retrieve data from archive required to construct new instance of Node
441  c_vector<double,2*DIM> domain_size;
442  for (unsigned i=0; i<2*DIM; i++)
443  {
444  double coordinate;
445  ar & coordinate; //resume coordinates one by one
446  domain_size[i] = coordinate;
447  }
448 
449  // Shrink the domain size slightly so we get the correct size on construction
450  for (unsigned i=0; i<DIM; i++)
451  {
452  domain_size[2*i+1] -= 1e-14;
453  }
454  double cut_off;
455  ar >> cut_off;
456 
457  unsigned num_original_procs;
458  ar >> num_original_procs;
459 
460  int num_rows = PETSC_DECIDE;
461  std::vector<int> original_rows;
462  ar >> original_rows;
463  if (num_original_procs == PetscTools::GetNumProcs())
464  {
465  num_rows = original_rows[PetscTools::GetMyRank()];
466  }
467 
468  // Invoke inplace constructor to initialise instance. Assume non-periodic
469  ::new(t)DistributedBoxCollection<DIM>(cut_off, domain_size, false, num_rows);
470 
471  if (are_boxes_set)
472  {
473  t->SetupHaloBoxes();
475  }
476 }
477 }
478 } // namespace ...
479 
480 
481 #endif /*DISTRIBUTEDBOXCOLLECTION_HPP_*/
std::vector< Box< DIM > > mBoxes
std::vector< unsigned > & rGetHaloNodesRight()
std::set< unsigned > GetLocalBoxes(unsigned boxIndex)
std::vector< unsigned > mHalosRight
unsigned CalculateContainingBox(Node< DIM > *pNode)
void serialize(Archive &archive, const unsigned int version)
void CalculateInteriorNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)
Definition: Node.hpp:58
bool IsInteriorBox(unsigned globalIndex)
c_vector< double, 2 *DIM > rGetDomainSize() const
c_vector< double, 2 *DIM > mDomainSize
void AddPairsFromBox(unsigned boxIndex, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)
std::vector< std::set< unsigned > > mLocalBoxes
std::vector< unsigned > mHalosLeft
void SetCalculateNodeNeighbours(bool calculateNodeNeighbours)
static bool AmMaster()
Definition: PetscTools.cpp:120
std::map< unsigned, unsigned > mBoxesMapping
std::vector< Box< DIM > > mHaloBoxes
std::vector< int > CalculateNumberOfNodesInEachStrip()
unsigned CalculateGlobalIndex(c_vector< unsigned, DIM > coordinateIndices)
unsigned GetProcessOwningNode(Node< DIM > *pNode)
c_vector< unsigned, DIM > CalculateCoordinateIndices(unsigned globalIndex)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
c_vector< unsigned, DIM > mNumBoxesEachDirection
std::vector< unsigned > & rGetHaloNodesLeft()
bool IsOwned(Node< DIM > *pNode)
DistributedBoxCollection(double boxWidth, c_vector< double, 2 *DIM > domainSize, bool isPeriodicInX=false, int localRows=PETSC_DECIDE)
std::vector< unsigned > mHaloNodesRight
bool GetHaloBoxOwnership(unsigned globalIndex)
bool GetBoxOwnership(unsigned globalIndex)
std::map< unsigned, unsigned > mHaloBoxesMapping
void CalculateNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)
int LoadBalance(std::vector< int > localDistribution)
Definition: Box.hpp:50
Box< DIM > & rGetHaloBox(unsigned boxIndex)
static unsigned GetNumProcs()
Definition: PetscTools.cpp:108
static unsigned GetMyRank()
Definition: PetscTools.cpp:114
Box< DIM > & rGetBox(unsigned boxIndex)
std::vector< unsigned > mHaloNodesLeft
DistributedVectorFactory * mpDistributedBoxStackFactory
void CalculateBoundaryNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)