Chaste  Release::2017.1
DistributedBoxCollection.hpp
1 /*
2 
3 Copyright (c) 2005-2017, 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> mHaloBoxesMapping;
79 
81  c_vector<double, 2*DIM> mDomainSize;
82 
84  double mBoxWidth;
85 
87  unsigned mNumBoxes;
88 
90  c_vector<unsigned, DIM> mNumBoxesEachDirection;
91 
93  unsigned mNumBoxesInAFace;
94 
96  std::vector< std::set<unsigned> > mLocalBoxes;
97 
99  unsigned mMinBoxIndex;
100 
102  unsigned mMaxBoxIndex;
103 
106 
109 
111  static const double msFudge;
112 
115 
118 
125  void SetupHaloBoxes();
126 
128  friend class boost::serialization::access;
129 
136  template<class Archive>
137  void serialize(Archive & archive, const unsigned int version)
138  {
139  //All methods over-ridden below.
140  }
141 
142 public:
143 
155  DistributedBoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize, bool isPeriodicInX = false, int localRows = PETSC_DECIDE);
156 
157 
162 
166  void EmptyBoxes();
167 
172  void UpdateHaloBoxes();
173 
177  unsigned GetNumLocalRows() const;
178 
183  bool IsBoxOwned(unsigned globalIndex);
184 
192  bool IsInteriorBox(unsigned globalIndex);
193 
198  bool IsHaloBox(unsigned globalIndex);
199 
206  unsigned CalculateGlobalIndex(c_vector<unsigned, DIM> gridIndices);
207 
212  unsigned CalculateContainingBox(Node<DIM>* pNode);
213 
218  unsigned CalculateContainingBox(c_vector<double, DIM>& rLocation);
219 
226  c_vector<unsigned, DIM> CalculateGridIndices(unsigned globalIndex);
227 
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  bool GetIsPeriodicInX() const;
272 
276  unsigned GetNumRowsOfBoxes() const;
277 
285  int LoadBalance(std::vector<int> localDistribution);
286 
293 
297  void SetupAllLocalBoxes();
298 
305  std::set<unsigned>& rGetLocalBoxes(unsigned boxIndex);
306 
311  bool IsOwned(Node<DIM>* pNode);
312 
317  bool IsOwned(c_vector<double, DIM>& location);
318 
326  unsigned GetProcessOwningNode(Node<DIM>* pNode);
327 
331  std::vector<unsigned>& rGetHaloNodesRight();
332 
336  std::vector<unsigned>& rGetHaloNodesLeft();
337 
343  void SetCalculateNodeNeighbours(bool calculateNodeNeighbours);
344 
354  void CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
355 
362  void CalculateInteriorNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
363 
370  void CalculateBoundaryNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
371 
378  void AddPairsFromBox(unsigned boxIndex, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
379 
385  std::vector<int> CalculateNumberOfNodesInEachStrip();
386 };
387 
389 // Declare identifier for the serializer
391 
392 
393 namespace boost
394 {
395 namespace serialization
396 {
400 template<class Archive, unsigned DIM>
401 inline void save_construct_data(
402  Archive & ar, const DistributedBoxCollection<DIM> * t, const unsigned int file_version)
403 {
404  // Save the number of rows that each process owns, so that on loading we can resume with
405  // good load balance
406  int num_local_rows = (int)(t->GetNumRowsOfBoxes());
407  std::vector<int> num_rows(PetscTools::GetNumProcs());
408  MPI_Gather(&num_local_rows, 1, MPI_INT, &num_rows[0], 1, MPI_INT, 0, PETSC_COMM_WORLD);
409 
410  if (PetscTools::AmMaster())
411  {
412  bool are_boxes_set = t->GetAreLocalBoxesSet();
413  ar << are_boxes_set;
414 
415  c_vector<double, 2*DIM> domain_size = t->rGetDomainSize();
416  for (unsigned i=0; i<2*DIM; i++)
417  {
418  ar << domain_size[i];
419  }
420 
421  double box_width = t->GetBoxWidth();
422  ar << box_width;
423 
424  unsigned num_procs = PetscTools::GetNumProcs();
425  ar << num_procs;
426 
427  std::vector<int> const const_num_rows = num_rows;
428  ar << const_num_rows;
429  }
430 }
434 template<class Archive, unsigned DIM>
435 inline void load_construct_data(
436  Archive & ar, DistributedBoxCollection<DIM> * t, const unsigned int file_version)
437 {
438  bool are_boxes_set;
439  ar >> are_boxes_set;
440 
441  // Retrieve data from archive required to construct new instance of Node
442  c_vector<double,2*DIM> domain_size;
443  for (unsigned i=0; i<2*DIM; i++)
444  {
445  double coordinate;
446  ar & coordinate; //resume coordinates one by one
447  domain_size[i] = coordinate;
448  }
449 
450  // Shrink the domain size slightly so we get the correct size on construction
451  for (unsigned i=0; i<DIM; i++)
452  {
453  domain_size[2*i+1] -= 1e-14;
454  }
455  double cut_off;
456  ar >> cut_off;
457 
458  unsigned num_original_procs;
459  ar >> num_original_procs;
460 
461  int num_rows = PETSC_DECIDE;
462  std::vector<int> original_rows;
463  ar >> original_rows;
464  if (num_original_procs == PetscTools::GetNumProcs())
465  {
466  num_rows = original_rows[PetscTools::GetMyRank()];
467  }
468 
469  // Invoke inplace constructor to initialise instance. Assume non-periodic
470  ::new(t)DistributedBoxCollection<DIM>(cut_off, domain_size, false, num_rows);
471 
472  if (are_boxes_set)
473  {
475  }
476 }
477 }
478 } // namespace ...
479 
480 
481 #endif /*DISTRIBUTEDBOXCOLLECTION_HPP_*/
std::vector< Box< DIM > > mBoxes
bool IsBoxOwned(unsigned globalIndex)
std::vector< unsigned > & rGetHaloNodesRight()
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)
Definition: Node.hpp:58
bool IsInteriorBox(unsigned globalIndex)
c_vector< double, 2 *DIM > rGetDomainSize() const
c_vector< double, 2 *DIM > mDomainSize
std::vector< std::set< unsigned > > mLocalBoxes
std::vector< unsigned > mHalosLeft
void SetCalculateNodeNeighbours(bool calculateNodeNeighbours)
unsigned CalculateGlobalIndex(c_vector< unsigned, DIM > gridIndices)
void CalculateBoundaryNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)
static bool AmMaster()
Definition: PetscTools.cpp:120
std::vector< Box< DIM > > mHaloBoxes
std::vector< int > CalculateNumberOfNodesInEachStrip()
unsigned GetProcessOwningNode(Node< DIM > *pNode)
std::set< unsigned > & rGetLocalBoxes(unsigned boxIndex)
#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
void CalculateNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)
std::map< unsigned, unsigned > mHaloBoxesMapping
int LoadBalance(std::vector< int > localDistribution)
Definition: Box.hpp:50
c_vector< unsigned, DIM > CalculateGridIndices(unsigned globalIndex)
bool IsHaloBox(unsigned globalIndex)
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
gcov doesn&#39;t like this file...
DistributedVectorFactory * mpDistributedBoxStackFactory
void AddPairsFromBox(unsigned boxIndex, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)