Chaste  Release::2024.1
DistributedBoxCollection.hpp
1 /*
2 
3 Copyright (c) 2005-2021, 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 
112 
115 
118 
120  static const double msFudge;
121 
124 
127 
134  void SetupHaloBoxes();
135 
137  friend class boost::serialization::access;
138 
145  template<class Archive>
146  void serialize(Archive & archive, const unsigned int version)
147  {
148  //All methods over-ridden below.
149  }
150 
151 public:
152 
166  DistributedBoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize, bool isPeriodicInX = false, bool mIsPeriodicInY=false, bool mIsPeriodicInZ=false, int localRows = PETSC_DECIDE);
167 
172 
176  void EmptyBoxes();
177 
182  void UpdateHaloBoxes();
183 
187  unsigned GetNumLocalRows() const;
188 
193  bool IsBoxOwned(unsigned globalIndex);
194 
202  bool IsInteriorBox(unsigned globalIndex);
203 
208  bool IsHaloBox(unsigned globalIndex);
209 
216  unsigned CalculateGlobalIndex(c_vector<unsigned, DIM> gridIndices);
217 
222  unsigned CalculateContainingBox(Node<DIM>* pNode);
223 
228  unsigned CalculateContainingBox(c_vector<double, DIM>& rLocation);
229 
236  c_vector<unsigned, DIM> CalculateGridIndices(unsigned globalIndex);
237 
244  Box<DIM>& rGetBox(unsigned boxIndex);
245 
251  Box<DIM>& rGetHaloBox(unsigned boxIndex);
252 
256  unsigned GetNumBoxes();
257 
261  unsigned GetNumLocalBoxes();
262 
266  c_vector<double, 2*DIM> rGetDomainSize() const;
267 
271  bool GetAreLocalBoxesSet() const;
272 
276  double GetBoxWidth() const;
277 
281  bool GetIsPeriodicInX() const;
282 
286  bool GetIsPeriodicInY() const;
287 
291  bool GetIsPeriodicInZ() const;
292 
296  bool GetIsPeriodicAcrossProcs() const;
297 
302  c_vector<bool,DIM> GetIsPeriodicAllDims() const;
303 
307  unsigned GetNumRowsOfBoxes() const;
308 
316  int LoadBalance(std::vector<int> localDistribution);
317 
324 
328  void SetupAllLocalBoxes();
329 
336  std::set<unsigned>& rGetLocalBoxes(unsigned boxIndex);
337 
342  bool IsOwned(Node<DIM>* pNode);
343 
348  bool IsOwned(c_vector<double, DIM>& location);
349 
357  unsigned GetProcessOwningNode(Node<DIM>* pNode);
358 
362  std::vector<unsigned>& rGetHaloNodesRight();
363 
367  std::vector<unsigned>& rGetHaloNodesLeft();
368 
374  void SetCalculateNodeNeighbours(bool calculateNodeNeighbours);
375 
385  void CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
386 
393  void CalculateInteriorNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
394 
401  void CalculateBoundaryNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
402 
409  void AddPairsFromBox(unsigned boxIndex, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs);
410 
416  std::vector<int> CalculateNumberOfNodesInEachStrip();
417 };
418 
420 // Declare identifier for the serializer
422 
423 
424 namespace boost
425 {
426 namespace serialization
427 {
431 template<class Archive, unsigned DIM>
432 inline void save_construct_data(
433  Archive & ar, const DistributedBoxCollection<DIM> * t, const unsigned int file_version)
434 {
435  // Save the number of rows that each process owns, so that on loading we can resume with
436  // good load balance
437  int num_local_rows = (int)(t->GetNumRowsOfBoxes());
438  std::vector<int> num_rows(PetscTools::GetNumProcs());
439  MPI_Gather(&num_local_rows, 1, MPI_INT, &num_rows[0], 1, MPI_INT, 0, PETSC_COMM_WORLD);
440 
441  if (PetscTools::AmMaster())
442  {
443  bool are_boxes_set = t->GetAreLocalBoxesSet();
444  ar << are_boxes_set;
445 
446  c_vector<double, 2*DIM> domain_size = t->rGetDomainSize();
447  for (unsigned i=0; i<2*DIM; i++)
448  {
449  ar << domain_size[i];
450  }
451 
452  double box_width = t->GetBoxWidth();
453  ar << box_width;
454 
455  unsigned num_procs = PetscTools::GetNumProcs();
456  ar << num_procs;
457 
458  std::vector<int> const const_num_rows = num_rows;
459  ar << const_num_rows;
460  }
461 }
465 template<class Archive, unsigned DIM>
466 inline void load_construct_data(
467  Archive & ar, DistributedBoxCollection<DIM> * t, const unsigned int file_version)
468 {
469  bool are_boxes_set;
470  ar >> are_boxes_set;
471 
472  // Retrieve data from archive required to construct new instance of Node
473  c_vector<double,2*DIM> domain_size;
474  for (unsigned i=0; i<2*DIM; i++)
475  {
476  double coordinate;
477  ar & coordinate; //resume coordinates one by one
478  domain_size[i] = coordinate;
479  }
480 
481  // Shrink the domain size slightly so we get the correct size on construction
482  for (unsigned i=0; i<DIM; i++)
483  {
484  domain_size[2*i+1] -= 1e-14;
485  }
486  double cut_off;
487  ar >> cut_off;
488 
489  unsigned num_original_procs;
490  ar >> num_original_procs;
491 
492  int num_rows = PETSC_DECIDE;
493  std::vector<int> original_rows;
494  ar >> original_rows;
495  if (num_original_procs == PetscTools::GetNumProcs())
496  {
497  num_rows = original_rows[PetscTools::GetMyRank()];
498  }
499 
500  // Invoke inplace constructor to initialise instance. Assume non-periodic
501  ::new(t)DistributedBoxCollection<DIM>(cut_off, domain_size, false, false, false, num_rows);
502 
503  if (are_boxes_set)
504  {
506  }
507 }
508 }
509 } // namespace ...
510 
511 
512 #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)
Definition: Node.hpp:58
bool IsInteriorBox(unsigned globalIndex)
DistributedBoxCollection(double boxWidth, c_vector< double, 2 *DIM > domainSize, bool isPeriodicInX=false, bool mIsPeriodicInY=false, bool mIsPeriodicInZ=false, int localRows=PETSC_DECIDE)
void CalculateBoundaryNodePairs(std::vector< Node< DIM > *> &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > *> > &rNodePairs)
c_vector< double, 2 *DIM > rGetDomainSize() const
c_vector< double, 2 *DIM > mDomainSize
std::vector< std::set< unsigned > > mLocalBoxes
void AddPairsFromBox(unsigned boxIndex, std::vector< std::pair< Node< DIM > *, Node< DIM > *> > &rNodePairs)
std::vector< unsigned > mHalosLeft
void SetCalculateNodeNeighbours(bool calculateNodeNeighbours)
unsigned CalculateGlobalIndex(c_vector< unsigned, DIM > gridIndices)
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)
std::vector< unsigned > mHaloNodesRight
std::map< unsigned, unsigned > mHaloBoxesMapping
int LoadBalance(std::vector< int > localDistribution)
void CalculateInteriorNodePairs(std::vector< Node< DIM > *> &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > *> > &rNodePairs)
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)
void CalculateNodePairs(std::vector< Node< DIM > *> &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > *> > &rNodePairs)
c_vector< bool, DIM > GetIsPeriodicAllDims() const
std::vector< unsigned > mHaloNodesLeft
gcov doesn&#39;t like this file...
DistributedVectorFactory * mpDistributedBoxStackFactory