OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
ParticleBalancer.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
32 #include "Particle/IntNGP.h"
33 #include "Region/RegionLayout.h"
34 #include "Index/NDIndex.h"
37 #include "Utility/IpplInfo.h"
38 
39 
40 
42 // calculate a new RegionLayout for a given ParticleBase, and distribute the
43 // new RegionLayout to all the nodes. This uses a Field BinaryBalancer.
44 template < class T, unsigned Dim, class Mesh, class CachingPolicy>
45 bool
47 
48 
49 
50  static IntNGP interp; // to scatter particle density
51 
52  //Inform dbgmsg("Particle BinaryRepartition", INFORM_ALL_NODES);
53  //dbgmsg << "Performing particle load balancing, for ";
54  //dbgmsg << PB.getTotalNum() << " particles ..." << endl;
55 
56  // get the internal FieldLayout from the Particle object's internal
57  // RegionLayout. From this, we make a new Field (we do not need a
58  RegionLayout<T,Dim,Mesh>& RL = PB.getLayout().getLayout();
59  if ( ! RL.initialized()) {
60  ERRORMSG("Cannot repartition particles: uninitialized layout." << endl);
61  return false;
62  }
64  Mesh& mesh = RL.getMesh();
65 
66  // NDIndex which describes the entire domain ... if a particle is
67  // outside this region, we are in trouble!
68  const NDIndex<Dim>& TotalDomain = FL.getDomain();
69 
70  // for all the particles, do the following:
71  // 1. get the position, and invert to the 'FieldLayout' index space
72  // 2. increment the field at the position near this index position
73  NDIndex<Dim> indx;
74 
75  // By default, we do the number density computation and repartition of
76  // index space on a cell-centered Field. If FieldLayout is vertex-centered,
77  // we'll need to make some adjustments here.
78  bool CenterOffset[Dim];
79  int CenteringTotal = 0;
80  unsigned int d;
81  for (d=0; d<Dim; ++d) {
82  CenterOffset[d] = (TotalDomain[d].length() < mesh.gridSizes[d]);
83  CenteringTotal += CenterOffset[d];
84  }
85 
86 
87  if (CenteringTotal == Dim) { // allCell centering
89 
90  // Now do a number density scatter on this Field
91  // Afterwards, the Field will be deleted, and will checkout of the
92  // FieldLayout. This is desired so that when we repartition the
93  // FieldLayout, we do not waste time redistributing the Field's data.
94  BF = offset;
95  scatter(BF,PB.R,interp);
96 
97  // calculate a new repartitioning of the field, and use this to repartition
98  // the FieldLayout used inside the Particle object
99  try
100  {
101  indx = CalcBinaryRepartition(FL, BF);
102  }
103  catch(BinaryRepartitionFailed bf)
104  {
105  return false;
106  }
107  }
108  else if (CenteringTotal == 0) { // allVert centering
110 
111  // Now do a number density scatter on this Field
112  // Afterwards, the Field will be deleted, and will checkout of the
113  // FieldLayout. This is desired so that when we repartition the
114  // FieldLayout, we do not waste time redistributing the Field's data.
115  BF = offset;
116  scatter(BF,PB.R,interp);
117 
118  // calculate a new repartitioning of the field, and use this to repartition
119  // the FieldLayout used inside the Particle object
120  try
121  {
122  indx = CalcBinaryRepartition(FL, BF);
123  }
124  catch(BinaryRepartitionFailed bf)
125  {
126  return false;
127  }
128  }
129  else {
130  ERRORMSG("Not implemented for face- and edge-centered Fields!!" << endl);
131  Ippl::abort();
132  }
133 
134  // now, we can repartition the FieldLayout within the RegionLayout
135  RL.RepartitionLayout(indx);
136  PB.update();
137  return true;
138 }
139 
140 
141 // the same, but taking a uniform layout (this will not actually do anything)
142 template<class T, unsigned Dim>
143 bool
145  // for a uniform layout, this repartition method does nothing, so just
146  // exit
147  return true;
148 }
149 
150 
151 /***************************************************************************
152  * $RCSfile: ParticleBalancer.cpp,v $ $Author: adelmann $
153  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:28 $
154  * IPPL_VERSION_ID: $Id: ParticleBalancer.cpp,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $
155  ***************************************************************************/
static void abort(const char *=0, int exitcode=(-1))
Definition: IpplInfo.cpp:696
Definition: Mesh.h:35
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
bool initialized() const
Definition: RegionLayout.h:128
bool scatter(Communicate &, InputIterator, InputIterator, RandomIterator, int *, int *, const ScatterOp &)
Definition: GlobalComm.hpp:353
void BinaryRepartition(FieldLayout< Dim > &layout, BareField< double, Dim > &weights)
NDIndex< Dim > CalcBinaryRepartition(FieldLayout< Dim > &, BareField< double, Dim > &)
MeshType & getMesh()
Definition: RegionLayout.h:141
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
void RepartitionLayout(NDIndex< Dim > *, NDIndex< Dim > *)
const unsigned Dim
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Definition: IntNGP.h:34