OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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.
44template < class T, unsigned Dim, class Mesh, class CachingPolicy>
45bool
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 }
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 }
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)
142template<class T, unsigned Dim>
143bool
145 // for a uniform layout, this repartition method does nothing, so just
146 // exit
147 return true;
148}
149
const unsigned Dim
NDIndex< Dim > CalcBinaryRepartition(FieldLayout< Dim > &, BareField< double, Dim > &)
bool scatter(Communicate &, InputIterator, InputIterator, RandomIterator, int *, int *, const ScatterOp &)
Definition: GlobalComm.hpp:353
bool BinaryRepartition(IpplParticleBase< ParticleSpatialLayout< T, Dim, Mesh, CachingPolicy > > &PB, double offset)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
Definition: Field.h:33
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
Definition: Mesh.h:35
Definition: IntNGP.h:34
bool initialized() const
Definition: RegionLayout.h:128
void RepartitionLayout(NDIndex< Dim > *, NDIndex< Dim > *)
MeshType & getMesh()
Definition: RegionLayout.h:141
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
static void abort(const char *=0)
Definition: IpplInfo.cpp:616