OPAL (Object Oriented Parallel Accelerator Library) 2022.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}
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
118double 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
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
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
222void 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(),
244 nLevel, std::plus<size_t>());
245}
246
247
248const 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
301void 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:57
Vector_t hr_m
meshspacing of cartesian mesh
IpplTimings::TimerRef selfFieldTimer_m
timer for selfField calculation
static OpalData * getInstance()
Definition: OpalData.cpp:196
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 Vektor< int, 3 > getBaseLevelGridPoints() const =0
virtual void computeSelfFields()=0
virtual const int & maxLevel() const =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
const ParticleLevelCounter_t & getLocalNumPerLevel() const
PLayout & getAmrLayout()
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