OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
MultiBunchHandler.cpp
Go to the documentation of this file.
1 //
2 // Class MultiBunchHandler
3 // Helper class that stores bunch injection
4 // information like azimuth, radius etc. of first
5 // bunch in multi-bunch mode of ParallelCyclotronTracker.
6 //
7 // Copyright (c) 2007 - 2014, Jianjun Yang, Paul Scherrer Institut, Villigen PSI, Switzerland
8 // Copyright (c) 2012 - 2023, Paul Scherrer Institut, Villigen PSI, Switzerland
9 // All rights reserved
10 //
11 // Implemented as part of the PhD thesis
12 // "Beam dynamics in high intensity cyclotrons including neighboring bunch effects"
13 // and the paper
14 // "Beam dynamics in high intensity cyclotrons including neighboring bunch effects:
15 // Model, implementation, and application"
16 // (https://journals.aps.org/prab/pdf/10.1103/PhysRevSTAB.13.064201)
17 //
18 // This file is part of OPAL.
19 //
20 // OPAL is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
27 //
29 
31 #ifdef ENABLE_AMR
32  #include "Algorithms/AmrPartBunch.h"
33 #endif
34 #include "Algorithms/PartBinsCyc.h"
35 //FIXME Remove headers and dynamic_cast in
36 #include "Algorithms/PartBunch.h"
37 #include "Physics/Units.h"
40 
41 #include <map>
42 
43 extern Inform *gmsg;
44 
46  const int& numBunch,
47  const double& eta,
48  const double& para,
49  const std::string& mode,
50  const std::string& binning)
51  : onebunch_m(OpalData::getInstance()->getInputBasename() + "-onebunch.h5")
52  , numBunch_m(numBunch)
53  , eta_m(eta)
54  , coeffDBunches_m(para)
55  , radiusLastTurn_m(0.0)
56  , radiusThisTurn_m(0.0)
57  , bunchCount_m(1)
58 {
59  PAssert_GT(numBunch, 1);
60 
61  binfo_m.reserve(numBunch);
62  for (int i = 0; i < beam->getNumBunch(); ++i) {
63  binfo_m.push_back(beaminfo_t());
64  }
65 
66  this->setBinning(binning);
67 
68  // mode of generating new bunches:
69  // "FORCE" means generating one bunch after each revolution, until get "TURNS" bunches.
70  // "AUTO" means only when the distance between two neighbor bunches is below the limitation,
71  // then starts to generate new bunches after each revolution,until get "TURNS" bunches;
72  // otherwise, run single bunch track
73 
74  *gmsg << "***-------------------- MULTI-BUNCHES MULTI-ENERGY-BINS MODE --------------------*** " << endl;
75 
76  // only for regular run of multi bunches, instantiate the PartBins class
77  // note that for restart run of multi bunches, PartBins class is instantiated in function
78  // Distribution::doRestartOpalCycl()
79  if (!OpalData::getInstance()->inRestartRun()) {
80 
81  // already exist bins number initially
82  const int BinCount = 1;
83  //allowed maximal bin
84  const int MaxBinNum = 1000;
85 
86  // initialize particles number for each bin (both existed and not yet emmitted)
87  size_t partInBin[MaxBinNum] = {0};
88  partInBin[0] = beam->getTotalNum();
89 
90  beam->setPBins(new PartBinsCyc(MaxBinNum, BinCount, partInBin));
91  // the allowed maximal bin number is set to 100
92  //beam->setPBins(new PartBins(100));
93 
94  this->setMode(mode);
95 
96  } else {
97  if (beam->pbin_m->getLastemittedBin() < 2) {
98  *gmsg << "In this restart job, the multi-bunches mode is forcely set to AUTO mode." << endl;
100  } else {
101  *gmsg << "In this restart job, the multi-bunches mode is forcely set to FORCE mode." << endl
102  << "If the existing bunch number is less than the specified number of TURN, "
103  << "readin the phase space of STEP#0 from h5 file consecutively" << endl;
105  }
106  }
107 }
108 
109 
111 
112  static IpplTimings::TimerRef saveBunchTimer = IpplTimings::getTimer("Save Bunch H5");
113  IpplTimings::startTimer(saveBunchTimer);
114  *gmsg << endl;
115  *gmsg << "* Store beam to H5 file for multibunch simulation ... ";
116 
117  Ppos_t coord, momentum;
118  ParticleAttrib<double> mass, charge;
120 
121  std::size_t localNum = beam->getLocalNum();
122 
123  coord.create(localNum);
124  coord = beam->R;
125 
126  momentum.create(localNum);
127  momentum = beam->P;
128 
129  mass.create(localNum);
130  mass = beam->M;
131 
132  charge.create(localNum);
133  charge = beam->Q;
134 
135  porigin.create(localNum);
136  porigin = beam->POrigin;
137 
138  std::map<std::string, double> additionalAttributes = {
139  std::make_pair("REFPR", 0.0),
140  std::make_pair("REFPT", 0.0),
141  std::make_pair("REFPZ", 0.0),
142  std::make_pair("REFR", 0.0),
143  std::make_pair("REFTHETA", 0.0),
144  std::make_pair("REFZ", 0.0),
145  std::make_pair("AZIMUTH", 0.0),
146  std::make_pair("ELEVATION", 0.0),
147  std::make_pair("B-ref_x", 0.0),
148  std::make_pair("B-ref_z", 0.0),
149  std::make_pair("B-ref_y", 0.0),
150  std::make_pair("E-ref_x", 0.0),
151  std::make_pair("E-ref_z", 0.0),
152  std::make_pair("E-ref_y", 0.0),
153  std::make_pair("B-head_x", 0.0),
154  std::make_pair("B-head_z", 0.0),
155  std::make_pair("B-head_y", 0.0),
156  std::make_pair("E-head_x", 0.0),
157  std::make_pair("E-head_z", 0.0),
158  std::make_pair("E-head_y", 0.0),
159  std::make_pair("B-tail_x", 0.0),
160  std::make_pair("B-tail_z", 0.0),
161  std::make_pair("B-tail_y", 0.0),
162  std::make_pair("E-tail_x", 0.0),
163  std::make_pair("E-tail_z", 0.0),
164  std::make_pair("E-tail_y", 0.0)
165  };
166 
167  H5PartWrapperForPC h5wrapper(onebunch_m, H5_O_WRONLY);
168  h5wrapper.writeHeader();
169  h5wrapper.writeStep(beam, additionalAttributes);
170  h5wrapper.close();
171 
172  *gmsg << "Done." << endl;
173  IpplTimings::stopTimer(saveBunchTimer);
174 }
175 
176 
178 
179  static IpplTimings::TimerRef readBunchTimer = IpplTimings::getTimer("Read Bunch H5");
180  IpplTimings::startTimer(readBunchTimer);
181  *gmsg << endl;
182  *gmsg << "* Read beam from H5 file for multibunch simulation ... ";
183 
184  std::size_t localNum = beam->getLocalNum();
185 
186  /*
187  * 2nd argument: 0 --> step zero is fine since the file has only this step
188  * 3rd argument: "" --> onebunch_m is used
189  * 4th argument: H5_O_RDONLY does not work with this constructor
190  */
191  H5PartWrapperForPC h5wrapper(onebunch_m, 0, "", H5_O_WRONLY);
192 
193  size_t numParticles = h5wrapper.getNumParticles();
194 
195  const int bunchNum = bunchCount_m - 1;
196 
197  beam->setTotalNumPerBunch(numParticles, bunchNum);
198 
199  if ( numParticles == 0 ) {
200  throw OpalException("MultiBunchHandler::readBunch()",
201  "No particles in file " + onebunch_m + ".");
202  }
203 
204  size_t numParticlesPerNode = numParticles / Ippl::getNodes();
205 
206  size_t firstParticle = numParticlesPerNode * Ippl::myNode();
207  size_t lastParticle = firstParticle + numParticlesPerNode - 1;
208  if (Ippl::myNode() == Ippl::getNodes() - 1)
209  lastParticle = numParticles - 1;
210 
211  PAssert_LT(firstParticle, lastParticle +1);
212 
213  numParticles = lastParticle - firstParticle + 1;
214 
215  beam->setLocalNumPerBunch(numParticles, bunchNum);
216 
217  //FIXME
218  std::unique_ptr<PartBunchBase<double, 3> > tmpBunch = nullptr;
219 #ifdef ENABLE_AMR
220  AmrPartBunch* amrbunch_p = dynamic_cast<AmrPartBunch*>(beam);
221  if ( amrbunch_p != nullptr ) {
222  tmpBunch.reset(new AmrPartBunch(&ref,
223  amrbunch_p->getAmrParticleBase()));
224  } else
225 #endif
226  tmpBunch.reset(new PartBunch(&ref));
227 
228  tmpBunch->create(numParticles);
229 
230  h5wrapper.readStep(tmpBunch.get(), firstParticle, lastParticle);
231  h5wrapper.close();
232 
233  beam->create(numParticles);
234 
235  for(size_t ii = 0; ii < numParticles; ++ ii, ++ localNum) {
236  beam->R[localNum] = tmpBunch->R[ii];
237  beam->P[localNum] = tmpBunch->P[ii];
238  beam->M[localNum] = tmpBunch->M[ii];
239  beam->Q[localNum] = tmpBunch->Q[ii];
240  beam->POrigin[localNum] = ParticleOrigin::REGULAR;
241  beam->Bin[localNum] = bunchNum;
242  beam->bunchNum[localNum] = bunchNum;
243  }
244 
245  beam->boundp();
246 
247  binfo_m.push_back(beaminfo_t(injection_m));
248 
249  *gmsg << "Done." << endl;
250 
251  IpplTimings::stopTimer(readBunchTimer);
252  return true;
253 }
254 
255 
257  const PartData& ref,
258  bool& flagTransition) {
259  short result = 0;
260  if ((bunchCount_m == 1) && (mode_m == MultiBunchMode::AUTO) && (!flagTransition)) {
261 
262  // we have still a single bunch
263  beam->setTotalNumPerBunch(beam->getTotalNum(), 0);
264  beam->setLocalNumPerBunch(beam->getLocalNum(), 0);
265 
266  // If all of the following conditions are met, this code will be executed
267  // to check the distance between two neighboring bunches:
268  // 1. Only one bunch exists (bunchCount_m == 1)
269  // 2. We are in multi-bunch mode, AUTO sub-mode (mode_m == 2)
270  // 3. It has been a full revolution since the last check (stepsNextCheck)
271 
272  *gmsg << "* MBM: Checking for automatically injecting new bunch ..." << endl;
273 
274  beam->calcBeamParameters();
275 
276  Vector_t Rmean = beam->get_centroid(); // m
277 
278  radiusThisTurn_m = std::hypot(Rmean[0],Rmean[1]);
279 
280  Vector_t Rrms = beam->get_rrms(); // m
281 
282  double XYrms = std::hypot(Rrms[0], Rrms[1]);
283 
284  // If the distance between two neighboring bunches is less than 5 times of its 2D rms size
285  // start multi-bunch simulation, fill current phase space to initialR and initialP arrays
287  // since next turn, start multi-bunches
288  saveBunch(beam);
289  flagTransition = true;
290  }
291 
292  *gmsg << "* MBM: RLastTurn = " << radiusLastTurn_m << " [m]" << endl;
293  *gmsg << "* MBM: RThisTurn = " << radiusThisTurn_m << " [m]" << endl;
294  *gmsg << "* MBM: XYrms = " << XYrms << " [m]" << endl;
295 
297  result = 1;
298 
299  } else if (bunchCount_m < numBunch_m) {
300  // Matthias: SteptoLastInj was used in MtsTracker, removed by DW in GenericTracker
301 
302  // If all of the following conditions are met, this code will be executed
303  // to read new bunch from hdf5 format file:
304  // 1. We are in multi-bunch mode (numBunch_m > 1)
305  // 2. It has been a full revolution since the last check
306  // 3. Number of existing bunches is less than the desired number of bunches
307  // 4. FORCE mode, or AUTO mode with flagTransition = true
308  // Note: restart from 1 < BunchCount < numBunch_m must be avoided.
309  *gmsg << "* MBM: Injecting a new bunch ..." << endl;
310 
311  bunchCount_m++;
312 
313  beam->setNumBunch(bunchCount_m);
314 
315  // read initial distribution from h5 file
316  switch ( mode_m ) {
319  readBunch(beam, ref);
320  updateParticleBins(beam);
322  break;
323  default:
324  throw OpalException("MultiBunchHandler::injectBunch()",
325  "We shouldn't be here in single bunch mode.");
326  }
327 
328  Ippl::Comm->barrier();
329 
330  *gmsg << "* MBM: Bunch " << bunchCount_m
331  << " injected, total particle number = "
332  << beam->getTotalNum() << endl;
333  result = 2;
334  }
335  return result;
336 }
337 
338 
340  if (bunchCount_m < 2)
341  return;
342 
343  static IpplTimings::TimerRef binningTimer = IpplTimings::getTimer("Particle Binning");
344  IpplTimings::startTimer(binningTimer);
345  switch (binning_m) {
347  beam->resetPartBinID2(eta_m);
348  break;
350  beam->resetPartBinBunch();
351  break;
352  default:
353  beam->resetPartBinID2(eta_m);
354  }
355  IpplTimings::stopTimer(binningTimer);
356 }
357 
358 
359 void MultiBunchHandler::setMode(const std::string& mbmode) {
360 
361  static const std::map<std::string, MultiBunchMode> stringMBMode_s = {
362  {"FORCE", MultiBunchMode::FORCE},
363  {"AUTO", MultiBunchMode::AUTO},
364  };
365  mode_m = stringMBMode_s.at(mbmode);
366 
367  switch (mode_m) {
369  *gmsg << "FORCE mode: The multi bunches will be injected consecutively" << endl
370  << " after each revolution, until get \"TURNS\" bunches." << endl;
371  break;
373  *gmsg << "AUTO mode: The multi bunches will be injected only when the" << endl
374  << " distance between two neighboring bunches is below" << endl
375  << " the limitation. The control parameter is set to "
376  << coeffDBunches_m << endl;
377  break;
378  default:
379  throw OpalException("MultiBunchHandler::setMode",
380  "Unknown \"MBMODE\" multi-bunch mode for OPAL-cycl");
381  }
382 }
383 
384 
385 void MultiBunchHandler::setBinning(const std::string& binning) {
386 
387  static const std::map<std::string, MultiBunchBinning> stringMBBinning_s = {
388  {"BUNCH_BINNING", MultiBunchBinning::BUNCH},
389  {"GAMMA_BINNING", MultiBunchBinning::GAMMA},
390  };
391  binning_m = stringMBBinning_s.at(binning);
392 
393  switch (binning_m) {
395  *gmsg << "\nUse 'BUNCH_BINNING' injection for binnning.\n" << endl;
396  break;
398  *gmsg << "\nUse 'GAMMA_BINNING' injection for binnning.\n" << endl;
399  break;
400  default:
401  throw OpalException("MultiBunchHandler::setBinning",
402  "Unknown \"MB_BINNING\" type of energy binning in multi-bunch mode");
403  }
404 }
405 
406 
407 void MultiBunchHandler::setRadiusTurns(const double& radius) {
408  if ( mode_m != MultiBunchMode::AUTO )
409  return;
410 
411  radiusLastTurn_m = radius;
413 
414  if (OpalData::getInstance()->inRestartRun()) {
415  *gmsg << "Radial position at restart position = ";
416  } else {
417  *gmsg << "Initial radial position = ";
418  }
419  *gmsg << radiusThisTurn_m << " m" << endl;
420 }
421 
422 
424  short bunchNr) {
425 
426  if (!OpalData::getInstance()->isInOPALCyclMode()) {
427  return false;
428  }
429 
430  const unsigned long localNum = beam->getLocalNum();
431 
432  long int bunchTotalNum = 0;
433  unsigned long bunchLocalNum = 0;
434 
435  /* container:
436  *
437  * ekin, <x>, <y>, <z>, <p_x>, <p_y>, <p_z>,
438  * <x^2>, <y^2>, <z^2>, <p_x^2>, <p_y^2>, <p_z^2>,
439  * <xp_x>, <y_py>, <zp_z>,
440  * <x^3>, <y^3>, <z^3>, <x^4>, <y^4>, <z^4>
441  */
442  const unsigned int dim = PartBunchBase<double, 3>::Dimension;
443  std::vector<double> local(7 * dim + 1);
444 
445  beaminfo_t& binfo = getBunchInfo(bunchNr);
446 
447  for(unsigned long k = 0; k < localNum; ++k) {
448  if ( beam->bunchNum[k] != bunchNr ) { //|| ID[k] == 0 ) {
449  continue;
450  }
451 
452  ++bunchTotalNum;
453  ++bunchLocalNum;
454 
455  // ekin
456  local[0] += std::sqrt(dot(beam->P[k], beam->P[k]) + 1.0);
457 
458  for (unsigned int i = 0; i < dim; ++i) {
459 
460  double r = beam->R[k](i);
461  double p = beam->P[k](i);
462 
463  // <x>, <y>, <z>
464  local[i + 1] += r;
465 
466  // <p_x>, <p_y, <p_z>
467  local[i + dim + 1] += p;
468 
469  // <x^2>, <y^2>, <z^2>
470  double r2 = r * r;
471  local[i + 2 * dim + 1] += r2;
472 
473  // <p_x^2>, <p_y^2>, <p_z^2>
474  local[i + 3 * dim + 1] += p * p;
475 
476  // <xp_x>, <y_py>, <zp_z>
477  local[i + 4 * dim + 1] += r * p;
478 
479  // <x^3>, <y^3>, <z^3>
480  local[i + 5 * dim + 1] += r2 * r;
481 
482  // <x^4>, <y^4>, <z^4>
483  local[i + 6 * dim + 1] += r2 * r2;
484  }
485  }
486 
487  // inefficient
488  allreduce(bunchTotalNum, 1, std::plus<long int>());
489 
490  // here we also update the number of particles of *this* bunch
491  if (bunchNr >= (short)beam->getNumBunch()) {
492  throw OpalException("MultiBunchHandler::calcBunchBeamParameters()",
493  "Bunch number " + std::to_string(bunchNr) +
494  " exceeds bunch index " + std::to_string(beam->getNumBunch() - 1));
495  }
496  beam->setTotalNumPerBunch(bunchTotalNum, bunchNr);
497  beam->setLocalNumPerBunch(bunchLocalNum, bunchNr);
498 
499  if (bunchTotalNum == 0) {
500  return false;
501  }
502 
503  // ekin
504  const double m0 = beam->getM() * Units::eV2MeV;
505  local[0] -= bunchLocalNum;
506  local[0] *= m0;
507 
508  allreduce(local.data(), local.size(), std::plus<double>());
509 
510  double invN = 1.0 / double(bunchTotalNum);
511  binfo.ekin = local[0] * invN;
512 
513  binfo.time = beam->getT();
514  binfo.nParticles = bunchTotalNum;
515 
516  for (unsigned int i = 0; i < dim; ++i) {
517 
518  double w = local[i + 1] * invN;
519  double pw = local[i + dim + 1] * invN;
520  double w2 = local[i + 2 * dim + 1] * invN;
521  double pw2 = local[i + 3 * dim + 1] * invN;
522  double wpw = local[i + 4 * dim + 1] * invN;
523  double w3 = local[i + 5 * dim + 1] * invN;
524  double w4 = local[i + 6 * dim + 1] * invN;
525 
526  // <x>, <y>, <z>
527  binfo.mean[i] = w;
528 
529  // central: <p_w^2> - <p_w>^2 (w = x, y, z)
530  binfo.prms[i] = pw2 - pw * pw;
531  if ( binfo.prms[i] < 0 ) {
532  binfo.prms[i] = 0.0;
533  }
534 
535  // central: <wp_w> - <w><p_w>
536  wpw = wpw - w * pw;
537 
538  // central: <w^2> - <w>^2 (w = x, y, z)
539  binfo.rrms[i] = w2 - w * w;
540 
541  // central: normalized emittance
542  binfo.emit[i] = (binfo.rrms[i] * binfo.prms[i] - wpw * wpw);
543  binfo.emit[i] = std::sqrt(std::max(binfo.emit[i], 0.0));
544 
545  // central: <w^4> - 4 * <w> * <w^3> + 6 * <w>^2 * <w^2> - 3 * <w>^4
546  double tmp = w4
547  - 4.0 * w * w3
548  + 6.0 * w * w * w2
549  - 3.0 * w * w * w * w;
550  binfo.halo[i] = tmp / ( binfo.rrms[i] * binfo.rrms[i] );
551 
552  // central: sqrt(<w^2> - <w>^2) (w = x, y, z)
553  binfo.rrms[i] = std::sqrt(binfo.rrms[i]);
554 
555  // central: sqrt(<p_w^2> - <p_w>^2)
556  binfo.prms[i] = std::sqrt(binfo.prms[i]);
557 
558  // central: rms correlation --> (<wp_w> - <w><p_w>) / sqrt(<w^2> * <p_w^2>)
559  double denom = 1.0 / (binfo.rrms[i] * binfo.prms[i]);
560  binfo.correlation[i] = (std::isfinite(denom)) ? wpw * denom : 0.0;
561  }
562 
563  double tmp = 1.0 / std::pow(binfo.ekin / m0 + 1.0, 2.0);
564  binfo.dEkin = binfo.prms[1] * m0 * std::sqrt(1.0 - tmp);
565 
566  return true;
567 }
568 
569 
570 void MultiBunchHandler::updateTime(const double& dt) {
571  for (short b = 0; b < bunchCount_m; ++b) {
572  binfo_m[b].time += dt;
573  }
574 }
575 
576 
577 void MultiBunchHandler::updatePathLength(const std::vector<double>& lpaths) {
578  PAssert_EQ(bunchCount_m, (short)lpaths.size() - 1);
579  for (short b = 0; b < bunchCount_m; ++b) {
580  binfo_m[b].pathlength += lpaths[b];
581  }
582 }
#define PAssert_EQ(a, b)
Definition: PAssert.h:104
The global OPAL structure.
Definition: OpalData.h:49
static OpalData * getInstance()
Definition: OpalData.cpp:196
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
void setMode(const std::string &mbmode)
size_t getNumParticles() const
ParticleAttrib< ParticleOrigin > POrigin
void setPBins(PartBins *pbin)
void barrier(void)
short numBunch_m
The number of bunches specified in TURNS of RUN command.
void saveBunch(PartBunchBase< double, 3 > *beam)
ParticleAttrib< Vector_t > P
static int myNode()
Definition: IpplInfo.cpp:691
short injectBunch(PartBunchBase< double, 3 > *beam, const PartData &ref, bool &flagTransition)
virtual void writeStep(PartBunchBase< double, 3 > *, const std::map< std::string, double > &additionalStepAttributes)
Vector_t get_centroid() const
ParticleAttrib< short > bunchNum
virtual void readStep(PartBunchBase< double, 3 > *, h5_ssize_t firstParticle, h5_ssize_t lastParticle)
ParticleAttrib< double > M
bool resetPartBinBunch()
int getLastemittedBin()
Definition: PartBins.h:136
pbase_t * getAmrParticleBase()
void calcBeamParameters()
PartBins * pbin_m
Vector_t get_rrms() const
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
double getM() const
Timing::TimerRef TimerRef
Definition: IpplTimings.h:176
virtual void boundp()
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
#define PAssert_LT(a, b)
Definition: PAssert.h:106
std::vector< beaminfo_t > binfo_m
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
bool readBunch(PartBunchBase< double, 3 > *beam, const PartData &ref)
static int getNodes()
Definition: IpplInfo.cpp:670
if write to the Free Software Temple MA USA Also add information on how to contact you by electronic and paper mail If the program is make it output a short notice like this when it starts in an interactive mode
Definition: LICENSE:307
double getT() const
void updateTime(const double &dt)
void setTotalNumPerBunch(size_t numpart, short n)
size_t getTotalNum() const
static Communicate * Comm
Definition: IpplInfo.h:84
The base class for all OPAL exceptions.
Definition: OpalException.h:28
bool calcBunchBeamParameters(PartBunchBase< double, 3 > *beam, short bunchNr)
size_t getLocalNum() const
Definition: Inform.h:42
void allreduce(const T *input, T *output, int count, Op op)
Definition: GlobalComm.hpp:510
ParticleAttrib< double > Q
MultiBunchBinning binning_m
beaminfo_t & getBunchInfo(short bunchNr)
float result
Definition: test.py:2
bool resetPartBinID2(const double eta)
reset Bin[] for each particle according to the method given in paper PAST-AB(064402) by G...
ParticlePos_t & R
MultiBunchMode mode_m
void setNumBunch(short n)
virtual void writeHeader()
void setLocalNumPerBunch(size_t numpart, short n)
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
void create(size_t M)
ParticleAttrib< int > Bin
short getNumBunch() const
MultiBunchHandler(PartBunchBase< double, 3 > *beam, const int &numBunch, const double &eta, const double &para, const std::string &mode, const std::string &binning)
virtual void create(size_t)
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
void setRadiusTurns(const double &radius)
void setBinning(const std::string &binning)
#define PAssert_GT(a, b)
Definition: PAssert.h:108
void updateParticleBins(PartBunchBase< double, 3 > *beam)
void updatePathLength(const std::vector< double > &lpaths)
Inform * gmsg
Definition: Main.cpp:70
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
constexpr double eV2MeV
Definition: Units.h:77