OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
AmrPartBunch.cpp
Go to the documentation of this file.
1 //
2 // Class AmrPartBunch
3 // This class is used to represent a bunch in AMR mode.
4 //
5 // Copyright (c) 2017 - 2019, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved
7 //
8 // Implemented as part of the PhD thesis
9 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
10 //
11 // This file is part of OPAL.
12 //
13 // OPAL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20 //
21 #include "AmrPartBunch.h"
22 
24 
26  : PartBunchBase<double, 3>(new AmrPartBunch::pbase_t(new AmrLayout_t()), ref)
27  , amrobj_mp(nullptr)
28  , amrpbase_mp(dynamic_cast<AmrPartBunch::pbase_t*>(pbase_m.get()))
29  , fieldlayout_m(nullptr)
30 {
32 }
33 
35  : PartBunchBase<double, 3>(new AmrPartBunch::pbase_t(new AmrLayout_t(&pbase_p->getAmrLayout())), ref)
36  , amrobj_mp(nullptr)
37  , amrpbase_mp(dynamic_cast<AmrPartBunch::pbase_t*>(pbase_m.get()))
38  , fieldlayout_m(nullptr)
39 {
41 }
42 
44 
45 }
46 
47 
49  return amrpbase_mp;
50 }
51 
52 
54  return amrpbase_mp;
55 }
56 
57 
59 // Layout_t* layout = static_cast<Layout_t*>(&getLayout());
60 }
61 
62 
64 
65  if ( amrobj_mp && !amrobj_mp->isRefined() ) {
66  /* In the first call to this function we
67  * intialize all fine levels
68  */
70 
71  } else {
72  bool isForbidTransform = amrpbase_mp->isForbidTransform();
73 
74  if ( !isForbidTransform ) {
75  /*
76  * regrid in boosted frame
77  */
78  this->updateLorentzFactor();
79  // Lorentz transform + mapping to [-1,1]
82  }
83 
84  this->update();
85 
86  if ( !isForbidTransform ) {
88  // map particles back + undo Lorentz transform
90  }
91  }
92 }
93 
94 
96  const double& scalefactor = amrpbase_mp->getScalingFactor();
97  return hr_m * scalefactor;
98 }
99 
100 
102  // set dh_m = dh
104 
105  // update base geometry with new mesh enlargement
106  AmrLayout_t* layout_p = &amrpbase_mp->getAmrLayout();
107  layout_p->setBoundingBox(dh);
108 
109  // if amrobj_mp != nullptr --> we need to regrid
110  this->do_binaryRepart();
111 }
112 
113 
115  return amrobj_mp->getEExtrema();
116 }
117 
118 double AmrPartBunch::getRho(int x, int y, int z) {
119  /* This function is called in
120  * H5PartWrapperForPC::writeStepData(PartBunchBase<double, 3>* bunch)
121  * and
122  * H5PartWrapperForPT::writeStepData(PartBunchBase<double, 3>* bunch)
123  * in case of Options::rhoDump = true.
124  *
125  * Currently, we do not support writing multilevel grid data that's why
126  * we average the values down to the coarsest level.
127  */
128  return amrobj_mp->getRho(x, y, z);
129 }
130 
131 
133  //TODO Implement
134  throw OpalException("AmrPartBunch::getFieldLayout() ", "Not yet Implemented.");
135  return *fieldlayout_m;
136 }
137 
138 
141  //if(!R.isDirty() && stateOfLastBoundP_ == unit_state_) return;
142  if ( !(R.isDirty() || ID.isDirty() ) && stateOfLastBoundP_ == unit_state_) return; //-DW
143 
145 
146  if ( amrobj_mp ) {
147  /* we do an explicit domain mapping of the particles and then
148  * forbid it during the regrid process, this way it's only
149  * executed ones --> saves computation
150  */
151  bool isForbidTransform = amrpbase_mp->isForbidTransform();
152 
153  if ( !isForbidTransform ) {
154  this->updateLorentzFactor();
155  // Lorentz transform + mapping to [-1,1]
158  }
159 
160  this->update();
161 
162  if ( !isForbidTransform ) {
164  // map particles back + undo Lorentz transform
165  amrpbase_mp->domainMapping(true);
166  }
167 
168  } else {
169  // At this point an amrobj_mp needs already be set
170  throw GeneralClassicException("AmrPartBunch::boundp() ",
171  "AmrObject pointer is not set.");
172  }
173 
174  R.resetDirtyFlag();
175 
177 }
178 
179 
182 
183  if ( !fs_m->hasValidSolver() )
184  throw OpalException("AmrPartBunch::computeSelfFields() ",
185  "No field solver.");
186 
188 
190 }
191 
192 
197 }
198 
199 
204 }
205 
206 
209 
210  /* make sure it is refined in multi-bunch case
211  */
212  if ( !amrobj_mp->isRefined() ) {
214  }
215 
217 
219 }
220 
221 
222 void AmrPartBunch::setAmrDomainRatio(const std::vector<double>& ratio) {
223  AmrLayout_t* layout_p = &amrpbase_mp->getAmrLayout();
224  layout_p->setDomainRatio(ratio);
225 }
226 
228  int nLevel = amrobj_mp->maxLevel() + 1;
229 
230  std::unique_ptr<size_t[]> partPerLevel( new size_t[nLevel] );
231  globalPartPerLevel_m.reset( new size_t[nLevel] );
232 
233  for (int i = 0; i < nLevel; ++i)
234  partPerLevel[i] = globalPartPerLevel_m[i] = 0.0;
235 
236  // do not modify LocalNumPerLevel in here!!!
237  auto& LocalNumPerLevel = amrpbase_mp->getLocalNumPerLevel();
238 
239  for (size_t i = 0; i < LocalNumPerLevel.size(); ++i)
240  partPerLevel[i] = LocalNumPerLevel[i];
241 
242  reduce(*partPerLevel.get(),
243  *globalPartPerLevel_m.get(),
244  nLevel, std::plus<size_t>());
245 }
246 
247 
248 const size_t& AmrPartBunch::getLevelStatistics(int l) const {
249  return globalPartPerLevel_m[l];
250 }
251 
252 
254  double gamma = this->get_gamma();
255 
256  if ( this->weHaveBins() ) {
257  gamma = this->getBinGamma(bin);
258  }
259 
260 
261  /* At the beginning of simulation the Lorentz factor
262  * is not yet set since PartBunchBase::calcBeamParameters
263  * is not yet called. Therefore, we do this ugly workaround.
264  */
265  bool init = true;
266  if ( gamma >= 1.0 ) {
267  init = false;
268  }
269 
270  if ( init ) {
271  gamma = 1.0;
272  }
273 
274  updateLorentzFactor(gamma);
275 }
276 
277 
279  // keep all 1.0, except longitudinal direction
280  Vector_t lorentzFactor(1.0, 1.0, 1.0);
281 
282  if (OpalData::getInstance()->isInOPALCyclMode()) {
283  lorentzFactor[1] = gamma;
284  } else {
285  lorentzFactor[2] = gamma;
286  }
287 
288  amrpbase_mp->setLorentzFactor(lorentzFactor);
289 }
290 
291 
293 
294 }
295 
298 }
299 
300 
301 void AmrPartBunch::updateFields(const Vector_t& /*hr*/, const Vector_t& /*origin*/) {
302  //TODO regrid; called in boundp()
303 // amrobj_mp->updateMesh();
304 }
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
virtual void set_meshEnlargement(double dh)
IpplTimings::TimerRef boundpTimer_m
double getBinGamma(int bin)
Get gamma of one bin.
FieldSolver * fs_m
stores the used field solver
std::pair< Vector_t, Vector_t > VectorPair_t
Definition: PartBunchBase.h:75
Vector_t hr_m
meshspacing of cartesian mesh
IpplTimings::TimerRef selfFieldTimer_m
timer for selfField calculation
static OpalData * getInstance()
Definition: OpalData.cpp:195
virtual Vektor< int, 3 > getBaseLevelGridPoints() const =0
virtual void initFineLevels()=0
virtual double getRho(int x, int y, int z)=0
const bool & isRefined() const
Definition: AmrObject.cpp:95
virtual void computeSelfFields_cycl(double gamma)=0
virtual VectorPair_t getEExtrema()=0
virtual const int & maxLevel() const =0
virtual void computeSelfFields()=0
void setBoundingBox(double dh)
void setDomainRatio(const std::vector< double > &ratio)
void computeSelfFields_cycl(double gamma)
void updateDomainLength(Vektor< int, 3 > &grid)
void initialize(FieldLayout_t *fLayout)
void updateLorentzFactor(int bin=0)
void computeSelfFields()
AmrPartBunch(const PartData *ref)
VectorPair_t getEExtrema()
FieldLayout_t * fieldlayout_m
Definition: AmrPartBunch.h:155
void set_meshEnlargement(double dh)
void do_binaryRepart()
const size_t & getLevelStatistics(int l) const
Vector_t get_hr() const
pbase_t * amrpbase_mp
Definition: AmrPartBunch.h:150
AmrObject * amrobj_mp
Definition: AmrPartBunch.h:149
std::unique_ptr< size_t[]> globalPartPerLevel_m
Definition: AmrPartBunch.h:157
void gatherLevelStatistics()
void updateFieldContainers_m()
void setAmrDomainRatio(const std::vector< double > &ratio)
void updateFields(const Vector_t &hr, const Vector_t &origin)
pbase_t * getAmrParticleBase()
double getRho(int x, int y, int z)
FieldLayout_t & getFieldLayout()
Particle reference data.
Definition: PartData.h:35
bool hasValidSolver()
The base class for all OPAL exceptions.
Definition: OpalException.h:28
void setLorentzFactor(const Vector_t &lorentzFactor)
bool isForbidTransform() const
const double & getScalingFactor() const
PLayout & getAmrLayout()
const ParticleLevelCounter_t & getLocalNumPerLevel() const
void setForbidTransform(bool forbidTransform)
const double & domainMapping(bool inverse=false)
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187