OPAL (Object Oriented Parallel Accelerator Library)  2024.1
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 
47  return amrpbase_mp;
48 }
49 
50 
52  return amrpbase_mp;
53 }
54 
55 
57 // Layout_t* layout = static_cast<Layout_t*>(&getLayout());
58 }
59 
60 
62 
63  if ( amrobj_mp && !amrobj_mp->isRefined() ) {
64  /* In the first call to this function we
65  * intialize all fine levels
66  */
68 
69  } else {
70  bool isForbidTransform = amrpbase_mp->isForbidTransform();
71 
72  if ( !isForbidTransform ) {
73  /*
74  * regrid in boosted frame
75  */
76  this->updateLorentzFactor();
77  // Lorentz transform + mapping to [-1,1]
80  }
81 
82  this->update();
83 
84  if ( !isForbidTransform ) {
86  // map particles back + undo Lorentz transform
88  }
89  }
90 }
91 
92 
94  const double& scalefactor = amrpbase_mp->getScalingFactor();
95  return hr_m * scalefactor;
96 }
97 
98 
100  // set dh_m = dh
102 
103  // update base geometry with new mesh enlargement
104  AmrLayout_t* layout_p = &amrpbase_mp->getAmrLayout();
105  layout_p->setBoundingBox(dh);
106 
107  // if amrobj_mp != nullptr --> we need to regrid
108  this->do_binaryRepart();
109 }
110 
111 
113  return amrobj_mp->getEExtrema();
114 }
115 
116 double AmrPartBunch::getRho(int x, int y, int z) {
117  /* This function is called in
118  * H5PartWrapperForPC::writeStepData(PartBunchBase<double, 3>* bunch)
119  * and
120  * H5PartWrapperForPT::writeStepData(PartBunchBase<double, 3>* bunch)
121  * in case of Options::rhoDump = true.
122  *
123  * Currently, we do not support writing multilevel grid data that's why
124  * we average the values down to the coarsest level.
125  */
126  return amrobj_mp->getRho(x, y, z);
127 }
128 
129 
131  //TODO Implement
132  throw GeneralClassicException("AmrPartBunch::getFieldLayout", "Not yet Implemented.");
133  return *fieldlayout_m;
134 }
135 
136 
139  //if(!R.isDirty() && stateOfLastBoundP_ == unit_state_) return;
140  if ( !(R.isDirty() || ID.isDirty() ) && stateOfLastBoundP_ == unit_state_) return; //-DW
141 
143 
144  if ( amrobj_mp ) {
145  /* we do an explicit domain mapping of the particles and then
146  * forbid it during the regrid process, this way it's only
147  * executed ones --> saves computation
148  */
149  bool isForbidTransform = amrpbase_mp->isForbidTransform();
150 
151  if ( !isForbidTransform ) {
152  this->updateLorentzFactor();
153  // Lorentz transform + mapping to [-1,1]
156  }
157 
158  this->update();
159 
160  if ( !isForbidTransform ) {
162  // map particles back + undo Lorentz transform
163  amrpbase_mp->domainMapping(true);
164  }
165 
166  } else {
167  // At this point an amrobj_mp needs already be set
168  throw GeneralClassicException("AmrPartBunch::boundp",
169  "AmrObject pointer is not set.");
170  }
171 
172  R.resetDirtyFlag();
173 
175 }
176 
177 
180 
181  if ( !fs_m->hasValidSolver() )
182  throw GeneralClassicException("AmrPartBunch::computeSelfFields",
183  "No field solver.");
184 
186 
188 }
189 
190 
195 }
196 
197 
202 }
203 
204 
207 
208  /* make sure it is refined in multi-bunch case
209  */
210  if ( !amrobj_mp->isRefined() ) {
212  }
213 
215 
217 }
218 
219 
220 void AmrPartBunch::setAmrDomainRatio(const std::vector<double>& ratio) {
221  AmrLayout_t* layout_p = &amrpbase_mp->getAmrLayout();
222  layout_p->setDomainRatio(ratio);
223 }
224 
226  int nLevel = amrobj_mp->maxLevel() + 1;
227 
228  std::unique_ptr<size_t[]> partPerLevel( new size_t[nLevel] );
229  globalPartPerLevel_m.reset( new size_t[nLevel] );
230 
231  for (int i = 0; i < nLevel; ++i)
232  partPerLevel[i] = globalPartPerLevel_m[i] = 0.0;
233 
234  // do not modify LocalNumPerLevel in here!!!
235  auto& LocalNumPerLevel = amrpbase_mp->getLocalNumPerLevel();
236 
237  for (size_t i = 0; i < LocalNumPerLevel.size(); ++i)
238  partPerLevel[i] = LocalNumPerLevel[i];
239 
240  reduce(*partPerLevel.get(),
241  *globalPartPerLevel_m.get(),
242  nLevel, std::plus<size_t>());
243 }
244 
245 
246 const size_t& AmrPartBunch::getLevelStatistics(int l) const {
247  return globalPartPerLevel_m[l];
248 }
249 
250 
252  double gamma = this->get_gamma();
253 
254  if ( this->weHaveBins() ) {
255  gamma = this->getBinGamma(bin);
256  }
257 
258  /* At the beginning of simulation the Lorentz factor
259  * is not yet set since PartBunchBase::calcBeamParameters
260  * is not yet called. Therefore, we do this ugly workaround.
261  */
262  bool init = true;
263  if ( gamma >= 1.0 ) {
264  init = false;
265  }
266 
267  if ( init ) {
268  gamma = 1.0;
269  }
270 
271  updateLorentzFactor(gamma);
272 }
273 
274 
276  // keep all 1.0, except longitudinal direction
277  Vector_t lorentzFactor(1.0, 1.0, 1.0);
278 
279  if (OpalData::getInstance()->isInOPALCyclMode()) {
280  lorentzFactor[1] = gamma;
281  } else {
282  lorentzFactor[2] = gamma;
283  }
284 
285  amrpbase_mp->setLorentzFactor(lorentzFactor);
286 }
287 
288 
290 
293 }
294 
295 
296 void AmrPartBunch::updateFields(const Vector_t& /*hr*/, const Vector_t& /*origin*/) {
297  //TODO regrid; called in boundp()
298 // amrobj_mp->updateMesh();
299 }
const double & getScalingFactor() const
static OpalData * getInstance()
Definition: OpalData.cpp:196
virtual void computeSelfFields_cycl(double gamma)=0
const double & domainMapping(bool inverse=false)
Vector_t get_hr() const
std::unique_ptr< size_t[]> globalPartPerLevel_m
Definition: AmrPartBunch.h:153
void updateFields(const Vector_t &hr, const Vector_t &origin)
virtual Vektor< int, 3 > getBaseLevelGridPoints() const =0
PLayout & getAmrLayout()
virtual void computeSelfFields()=0
bool isForbidTransform() const
Vector_t hr_m
meshspacing of cartesian mesh
double getRho(int x, int y, int z)
void updateDomainLength(Vektor< int, 3 > &grid)
bool hasValidSolver()
pbase_t * getAmrParticleBase()
void setLorentzFactor(const Vector_t &lorentzFactor)
AmrPartBunch(const PartData *ref)
virtual const int & maxLevel() const =0
void setBoundingBox(double dh)
FieldLayout_t & getFieldLayout()
FieldLayout_t * fieldlayout_m
Definition: AmrPartBunch.h:151
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
virtual void initFineLevels()=0
const size_t & getLevelStatistics(int l) const
IpplTimings::TimerRef selfFieldTimer_m
timer for selfField calculation
virtual void set_meshEnlargement(double dh)
VectorPair_t getEExtrema()
FieldSolver * fs_m
stores the used field solver
const ParticleLevelCounter_t & getLocalNumPerLevel() const
IpplTimings::TimerRef boundpTimer_m
const bool & isRefined() const
Definition: AmrObject.cpp:98
double getBinGamma(int bin)
Get gamma of one bin.
void computeSelfFields_cycl(double gamma)
void updateLorentzFactor(int bin=0)
void initialize(FieldLayout_t *fLayout)
virtual double getRho(int x, int y, int z)=0
AmrObject * amrobj_mp
Definition: AmrPartBunch.h:145
void setAmrDomainRatio(const std::vector< double > &ratio)
void do_binaryRepart()
virtual VectorPair_t getEExtrema()=0
std::pair< Vector_t, Vector_t > VectorPair_t
Definition: PartBunchBase.h:57
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
void setForbidTransform(bool forbidTransform)
void set_meshEnlargement(double dh)
void updateFieldContainers_m()
void setDomainRatio(const std::vector< double > &ratio)
void gatherLevelStatistics()
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
void computeSelfFields()
pbase_t * amrpbase_mp
Definition: AmrPartBunch.h:146