OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
PartBunchBase.hpp
Go to the documentation of this file.
1 #ifndef PART_BUNCH_BASE_HPP
2 #define PART_BUNCH_BASE_HPP
3 
4 #include <numeric>
5 
7 
8 #include "AbstractObjects/OpalData.h" // OPAL file
9 #include "Physics/Physics.h"
11 #include "Utilities/Options.h"
13 #include "Utilities/Util.h"
14 
15 extern Inform *gmsg;
16 
17 template <class T, unsigned Dim>
19  : R(*(pb->R_p)),
20  ID(*(pb->ID_p)),
21  myNode_m(Ippl::myNode()),
22  nodes_m(Ippl::getNodes()),
23  fixed_grid(false),
24  pbin_m(nullptr),
25  lossDs_m(nullptr),
26  pmsg_m(nullptr),
27  f_stream(nullptr),
28  lowParticleCount_m(false),
29 // reference(ref), //FIXME
30  unit_state_(units),
31  stateOfLastBoundP_(unitless),
32  moments_m(),
33  dt_m(0.0),
34  t_m(0.0),
35  eKin_m(0.0),
36  dE_m(0.0),
37  spos_m(0.0),
38  globalMeanR_m(Vector_t(0.0, 0.0, 0.0)),
39  globalToLocalQuaternion_m(Quaternion_t(1.0, 0.0, 0.0, 0.0)),
40  rmax_m(0.0),
41  rmin_m(0.0),
42  rrms_m(0.0),
43  prms_m(0.0),
44  rmean_m(0.0),
45  pmean_m(0.0),
46  eps_m(0.0),
47  eps_norm_m(0.0),
48  halo_m(Vector_t(0.0, 0.0, 0.0)),
49  rprms_m(0.0),
50  Dx_m(0.0),
51  Dy_m(0.0),
52  DDx_m(0.0),
53  DDy_m(0.0),
54  hr_m(-1.0),
55  nr_m(0),
56  fs_m(nullptr),
57  couplingConstant_m(0.0),
58  qi_m(0.0),
59  distDump_m(0),
60  fieldDBGStep_m(0),
61  dh_m(1e-12),
62  tEmission_m(0.0),
63  bingamma_m(nullptr),
64  binemitted_m(nullptr),
65  stepsPerTurn_m(0),
66  localTrackStep_m(0),
67  globalTrackStep_m(0),
68  numBunch_m(1),
69  bunchTotalNum_m(1),
70  bunchLocalNum_m(1),
71  SteptoLastInj_m(0),
72  globalPartPerNode_m(nullptr),
73  dist_m(nullptr),
74  dcBeam_m(false),
75  periodLength_m(Physics::c / 1e9),
76  pbase(pb)
77 {
78  setup(pb);
79 
80  boundpTimer_m = IpplTimings::getTimer("Boundingbox");
81  boundpBoundsTimer_m = IpplTimings::getTimer("Boundingbox-bounds");
82  boundpUpdateTimer_m = IpplTimings::getTimer("Boundingbox-update");
83 
84  statParamTimer_m = IpplTimings::getTimer("Compute Statistics");
85  selfFieldTimer_m = IpplTimings::getTimer("SelfField total");
86 
87  histoTimer_m = IpplTimings::getTimer("Histogram");
88 
89  distrCreate_m = IpplTimings::getTimer("Create Distr");
90  distrReload_m = IpplTimings::getTimer("Load Distr");
91 
92  globalPartPerNode_m = std::unique_ptr<size_t[]>(new size_t[Ippl::getNodes()]);
93 
94  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(std::string("GlobalLosses"), !Options::asciidump));
95 
96  pmsg_m.release();
97  // f_stream.release();
98  /*
99  if(Ippl::getNodes() == 1) {
100  f_stream = std::unique_ptr<ofstream>(new ofstream);
101  f_stream->open("data/dist.dat", ios::out);
102  pmsg_m = std::unique_ptr<Inform>(new Inform(0, *f_stream, 0));
103  }
104  */
105 }
106 
107 template <class T, unsigned Dim>
109  : PartBunchBase(pb)
110 {
111  reference = ref;
112 }
113 
114 /*
115  * Bunch common member functions
116  */
117 
118 template <class T, unsigned Dim>
120  if (dist_m != NULL) {
121  size_t isBeamEmitted = dist_m->getIfDistEmitting();
122  reduce(isBeamEmitted, isBeamEmitted, OpAddAssign());
123  if (isBeamEmitted > 0)
124  return true;
125  else
126  return false;
127  } else
128  return false;
129 }
130 
131 
132 template <class T, unsigned Dim>
134  /*
135  * Get maximum last emitted energy bin.
136  */
137  int lastEmittedBin = dist_m->getLastEmittedEnergyBin();
138  reduce(lastEmittedBin, lastEmittedBin, OpMaxAssign());
139  return lastEmittedBin;
140 }
141 
142 
143 template <class T, unsigned Dim>
145  return dist_m->getNumberOfEmissionSteps();
146 }
147 
148 
149 template <class T, unsigned Dim>
151  return dist_m->getNumberOfEnergyBins();
152 }
153 
154 
155 template <class T, unsigned Dim>
157 
158  size_t isBeamEmitting = dist_m->getIfDistEmitting();
159  reduce(isBeamEmitting, isBeamEmitting, OpAddAssign());
160  if (isBeamEmitting > 0) {
161  *gmsg << "*****************************************************" << endl
162  << "Warning: attempted to rebin, but not all distribution" << endl
163  << "particles have been emitted. Rebin failed." << endl
164  << "*****************************************************" << endl;
165  } else {
166  if (dist_m->Rebin())
167  this->Bin = 0;
168  }
169 }
170 
171 
172 template <class T, unsigned Dim>
173 void PartBunchBase<T, Dim>::setEnergyBins(int numberOfEnergyBins) {
174  bingamma_m = std::unique_ptr<double[]>(new double[numberOfEnergyBins]);
175  binemitted_m = std::unique_ptr<size_t[]>(new size_t[numberOfEnergyBins]);
176  for(int i = 0; i < numberOfEnergyBins; i++)
177  binemitted_m[i] = 0;
178 }
179 
180 
181 template <class T, unsigned Dim>
183 
184  if (dist_m != NULL)
185  return dist_m->getNumberOfEnergyBins() > 0;
186  else
187  return false;
188 }
189 
190 
191 template <class T, unsigned Dim>
192 void PartBunchBase<T, Dim>::switchToUnitlessPositions(bool use_dt_per_particle) {
193 
194  if(unit_state_ == unitless)
195  throw SwitcherError("PartBunch::switchToUnitlessPositions",
196  "Cannot make a unitless PartBunch unitless");
197 
198  bool hasToReset = false;
199  if(!R.isDirty()) hasToReset = true;
200 
201  for(size_t i = 0; i < getLocalNum(); i++) {
202  double dt = getdT();
203  if(use_dt_per_particle)
204  dt = this->dt[i];
205 
206  R[i] /= Vector_t(Physics::c * dt);
207  }
208 
209  unit_state_ = unitless;
210 
211  if(hasToReset) R.resetDirtyFlag();
212 }
213 
214 
215 //FIXME: unify methods, use convention that all particles have own dt
216 template <class T, unsigned Dim>
218 
219  if(unit_state_ == units)
220  throw SwitcherError("PartBunch::switchOffUnitlessPositions",
221  "Cannot apply units twice to PartBunch");
222 
223  bool hasToReset = false;
224  if(!R.isDirty()) hasToReset = true;
225 
226  for(size_t i = 0; i < getLocalNum(); i++) {
227  double dt = getdT();
228  if(use_dt_per_particle)
229  dt = this->dt[i];
230 
231  R[i] *= Vector_t(Physics::c * dt);
232  }
233 
234  unit_state_ = units;
235 
236  if(hasToReset) R.resetDirtyFlag();
237 }
238 
239 
240 template <class T, unsigned Dim>
242  // do nothing here
243 }
244 
245 
246 template <class T, unsigned Dim>
248  std::vector<Distribution *> addedDistributions,
249  size_t &np)
250 {
251  Inform m("setDistribution " );
252  dist_m = d;
253 
254  dist_m->createOpalT(this, addedDistributions, np);
255 
256 // if (Options::cZero)
257 // dist_m->create(this, addedDistributions, np / 2);
258 // else
259 // dist_m->create(this, addedDistributions, np);
260 }
261 
262 
263 template <class T, unsigned Dim>
265  return fixed_grid;
266 }
267 
268 
269 template <class T, unsigned Dim>
271  return (pbin_m != nullptr);
272 }
273 
274 
275 template <class T, unsigned Dim>
277  tEmission_m = t;
278 }
279 
280 
281 template <class T, unsigned Dim>
283  return tEmission_m;
284 }
285 
286 
287 template <class T, unsigned Dim>
289  if (dist_m != NULL)
290  return dist_m->getIfDistEmitting();
291  else
292  return false;
293 }
294 
295 
296 template <class T, unsigned Dim>
298 
299  if(pbin_m != NULL)
300  return pbin_m->weHaveBins();
301  else
302  return false;
303 }
304 
305 
306 template <class T, unsigned Dim>
308  pbin_m = pbin;
309  *gmsg << *pbin_m << endl;
310  setEnergyBins(pbin_m->getNBins());
311 }
312 
313 
314 template <class T, unsigned Dim>
316  pbin_m = pbin;
317  setEnergyBins(pbin_m->getNBins());
318 }
319 
320 
321 template <class T, unsigned Dim>
323  return dist_m->emitParticles(this, eZ);
324 }
325 
326 
327 template <class T, unsigned Dim>
329  size_t numParticles = getLocalNum();
330  reduce(numParticles, numParticles, OpAddAssign());
331  setTotalNum(numParticles);
332 }
333 
334 
335 template <class T, unsigned Dim>
337  this->Bin = 0;
338  pbin_m->resetBins();
339  // delete pbin_m; we did not allocate it!
340  pbin_m = NULL;
341 }
342 
343 
344 template <class T, unsigned Dim>
346  if(pbin_m != NULL)
347  return pbin_m->getNBins();
348  else
349  return 0;
350 }
351 
352 
353 template <class T, unsigned Dim>
355  if(pbin_m != NULL)
356  return pbin_m->getLastemittedBin();
357  else
358  return 0;
359 }
360 
361 
362 template <class T, unsigned Dim>
363 void PartBunchBase<T, Dim>::setLocalBinCount(size_t num, int bin) {
364  if(pbin_m != NULL) {
365  pbin_m->setPartNum(bin, num);
366  }
367 }
368 
369 
370 template <class T, unsigned Dim>
372 
373  const int emittedBins = dist_m->getNumberOfEnergyBins();
374 
375  size_t s = 0;
376 
377  for(int i = 0; i < emittedBins; i++)
378  bingamma_m[i] = 0.0;
379 
380  for(unsigned int n = 0; n < getLocalNum(); n++)
381  bingamma_m[this->Bin[n]] += sqrt(1.0 + dot(this->P[n], this->P[n]));
382 
383  std::unique_ptr<size_t[]> particlesInBin(new size_t[emittedBins]);
384  reduce(bingamma_m.get(), bingamma_m.get() + emittedBins, bingamma_m.get(), OpAddAssign());
385  reduce(binemitted_m.get(), binemitted_m.get() + emittedBins, particlesInBin.get(), OpAddAssign());
386  for(int i = 0; i < emittedBins; i++) {
387  size_t &pInBin = particlesInBin[i];
388  if(pInBin != 0) {
389  bingamma_m[i] /= pInBin;
390  INFOMSG(level2 << "Bin " << std::setw(3) << i
391  << " gamma = " << std::setw(8) << std::scientific
392  << std::setprecision(5) << bingamma_m[i]
393  << "; NpInBin= " << std::setw(8)
394  << std::setfill(' ') << pInBin << endl);
395  } else {
396  bingamma_m[i] = 1.0;
397  INFOMSG(level2 << "Bin " << std::setw(3) << i << " has no particles " << endl);
398  }
399  s += pInBin;
400  }
401  particlesInBin.reset();
402 
403 
404  if(s != getTotalNum() && !OpalData::getInstance()->hasGlobalGeometry())
405  ERRORMSG("sum(Bins)= " << s << " != sum(R)= " << getTotalNum() << endl;);
406 
407  if(emittedBins >= 2) {
408  for(int i = 1; i < emittedBins; i++) {
409  if(binemitted_m[i - 1] != 0 && binemitted_m[i] != 0)
410  INFOMSG(level2 << "d(gamma)= " << 100.0 * std::abs(bingamma_m[i - 1] - bingamma_m[i]) / bingamma_m[i] << " [%] "
411  << "between bin " << i - 1 << " and " << i << endl);
412  }
413  }
414 }
415 
416 
417 template <class T, unsigned Dim>
419 
420  const int emittedBins = pbin_m->getLastemittedBin();
421 
422  for(int i = 0; i < emittedBins; i++)
423  bingamma_m[i] = 0.0;
424  for(unsigned int n = 0; n < getLocalNum(); n++) {
425  if ( this->Bin[n] > -1 ) {
426  bingamma_m[this->Bin[n]] += sqrt(1.0 + dot(this->P[n], this->P[n]));
427  }
428  }
429 
430  allreduce(*bingamma_m.get(), emittedBins, std::plus<double>());
431 
432  for(int i = 0; i < emittedBins; i++) {
433  if(pbin_m->getTotalNumPerBin(i) > 0)
434  bingamma_m[i] /= pbin_m->getTotalNumPerBin(i);
435  else
436  bingamma_m[i] = 0.0;
437  INFOMSG("Bin " << i << " : particle number = " << pbin_m->getTotalNumPerBin(i)
438  << " gamma = " << bingamma_m[i] << endl);
439  }
440 
441 }
442 
443 
444 template <class T, unsigned Dim>
446  return bingamma_m[bin];
447 }
448 
449 
450 template <class T, unsigned Dim>
451 void PartBunchBase<T, Dim>::setBinCharge(int bin, double q) {
452  this->Q = where(eq(this->Bin, bin), q, 0.0);
453 }
454 
455 
456 template <class T, unsigned Dim>
458  this->Q = where(eq(this->Bin, bin), this->qi_m, 0.0);
459 }
460 
461 
462 template <class T, unsigned Dim>
464 
465  std::size_t localnum = 0;
466  const Vector_t meanR = get_rmean();
467 
468  for(unsigned long k = 0; k < getLocalNum(); ++ k)
469  if (std::abs(R[k](0) - meanR(0)) > x(0) ||
470  std::abs(R[k](1) - meanR(1)) > x(1) ||
471  std::abs(R[k](2) - meanR(2)) > x(2)) {
472 
473  ++localnum;
474  }
475 
476  gather(&localnum, &globalPartPerNode_m[0], 1);
477 
478  size_t npOutside = std::accumulate(globalPartPerNode_m.get(),
479  globalPartPerNode_m.get() + Ippl::getNodes(), 0,
480  std::plus<size_t>());
481 
482  return npOutside;
483 }
484 
485 
495 template <class T, unsigned Dim>
497  std::vector<double> &lineDensity,
498  std::pair<double, double> &meshInfo)
499 {
500  Vector_t rmin, rmax;
501  get_bounds(rmin, rmax);
502 
503  if (nBins < 2) {
504  Vektor<int, 3>/*NDIndex<3>*/ grid;
505  this->updateDomainLength(grid);
506  nBins = grid[2];
507  }
508 
509  double length = rmax(2) - rmin(2);
510  double zmin = rmin(2) - dh_m * length, zmax = rmax(2) + dh_m * length;
511  double hz = (zmax - zmin) / (nBins - 2);
512  double perMeter = 1.0 / hz;//(zmax - zmin);
513  zmin -= hz;
514 
515  lineDensity.resize(nBins, 0.0);
516  std::fill(lineDensity.begin(), lineDensity.end(), 0.0);
517 
518  const unsigned int lN = getLocalNum();
519  for (unsigned int i = 0; i < lN; ++ i) {
520  const double z = R[i](2) - 0.5 * hz;
521  unsigned int idx = (z - zmin) / hz;
522  double tau = (z - zmin) / hz - idx;
523 
524  lineDensity[idx] += Q[i] * (1.0 - tau) * perMeter;
525  lineDensity[idx + 1] += Q[i] * tau * perMeter;
526  }
527 
528  reduce(&(lineDensity[0]), &(lineDensity[0]) + nBins, &(lineDensity[0]), OpAddAssign());
529 
530  meshInfo.first = zmin;
531  meshInfo.second = hz;
532 }
533 
534 
535 
536 template <class T, unsigned Dim>
538  /*
539  Assume rmin_m < 0.0
540  */
541 
542  IpplTimings::startTimer(boundpTimer_m);
543  //if(!R.isDirty() && stateOfLastBoundP_ == unit_state_) return;
544  if ( !(R.isDirty() || ID.isDirty() ) && stateOfLastBoundP_ == unit_state_) return; //-DW
545 
546  stateOfLastBoundP_ = unit_state_;
547 
548  if(!isGridFixed()) {
549  const int dimIdx = (dcBeam_m? 2: 3);
550 
557  this->updateDomainLength(nr_m);
558  IpplTimings::startTimer(boundpBoundsTimer_m);
559  get_bounds(rmin_m, rmax_m);
560  IpplTimings::stopTimer(boundpBoundsTimer_m);
561  Vector_t len = rmax_m - rmin_m;
562 
563  double volume = 1.0;
564  for(int i = 0; i < dimIdx; i++) {
565  double length = std::abs(rmax_m[i] - rmin_m[i]);
566  if (length < 1e-10) {
567  rmax_m[i] += 1e-10;
568  rmin_m[i] -= 1e-10;
569  } else {
570  rmax_m[i] += dh_m * length;
571  rmin_m[i] -= dh_m * length;
572  }
573  hr_m[i] = (rmax_m[i] - rmin_m[i]) / (nr_m[i] - 1);
574  }
575  if (dcBeam_m) {
576  rmax_m[2] = rmin_m[2] + periodLength_m;
577  hr_m[2] = periodLength_m / (nr_m[2] - 1);
578  }
579  for (int i = 0; i < dimIdx; ++ i) {
580  volume *= std::abs(rmax_m[i] - rmin_m[i]);
581  }
582 
583  if (getIfBeamEmitting() && dist_m != NULL) {
584  // keep particles per cell ratio high, don't spread a hand full particles across the whole grid
585  double percent = std::max(1.0 / (nr_m[2] - 1), dist_m->getPercentageEmitted());
586  double length = std::abs(rmax_m[2] - rmin_m[2]) / (1.0 + 2 * dh_m);
587  if (percent < 1.0 && percent > 0.0) {
588  rmax_m[2] -= dh_m * length;
589  rmin_m[2] = rmax_m[2] - length / percent;
590 
591  length /= percent;
592 
593  rmax_m[2] += dh_m * length;
594  rmin_m[2] -= dh_m * length;
595 
596  hr_m[2] = (rmax_m[2] - rmin_m[2]) / (nr_m[2] - 1);
597  }
598  }
599 
600  if (volume < 1e-21 && getTotalNum() > 1 && std::abs(sum(Q)) > 0.0) {
601  WARNMSG(level1 << "!!! Extremely high particle density detected !!!" << endl);
602  }
603  //INFOMSG("It is a full boundp hz= " << hr_m << " rmax= " << rmax_m << " rmin= " << rmin_m << endl);
604 
605  if(hr_m[0] * hr_m[1] * hr_m[2] <= 0) {
606  throw GeneralClassicException("boundp() ", "h<0, can not build a mesh");
607  }
608 
609  Vector_t origin = rmin_m - Vector_t(hr_m[0] / 2.0, hr_m[1] / 2.0, hr_m[2] / 2.0);
610  this->updateFields(hr_m, origin);
611  }
612  IpplTimings::startTimer(boundpUpdateTimer_m);
613  update();
614  IpplTimings::stopTimer(boundpUpdateTimer_m);
615  R.resetDirtyFlag();
616 
617  IpplTimings::stopTimer(boundpTimer_m);
618 }
619 
620 
621 template <class T, unsigned Dim>
623 
624  Inform gmsgAll("boundp_destroy ", INFORM_ALL_NODES);
625 
626  Vector_t len;
627  const int dimIdx = 3;
628  IpplTimings::startTimer(boundpTimer_m);
629 
630  std::unique_ptr<size_t[]> countLost;
631  if(weHaveBins()) {
632  const int tempN = pbin_m->getLastemittedBin();
633  countLost = std::unique_ptr<size_t[]>(new size_t[tempN]);
634  for(int ii = 0; ii < tempN; ii++) countLost[ii] = 0;
635  }
636 
637  this->updateDomainLength(nr_m);
638 
639 
640  IpplTimings::startTimer(boundpBoundsTimer_m);
641  get_bounds(rmin_m, rmax_m);
642  IpplTimings::stopTimer(boundpBoundsTimer_m);
643 
644  len = rmax_m - rmin_m;
645 
646  calcBeamParameters();
647 
648  int checkfactor = Options::remotePartDel;
649  if (checkfactor != 0) {
650  //INFOMSG("checkfactor= " << checkfactor << endl);
651  // check the bunch if its full size is larger than checkfactor times of its rms size
652  if(checkfactor < 0) {
653  checkfactor *= -1;
654  if (len[0] > checkfactor * rrms_m[0] ||
655  len[1] > checkfactor * rrms_m[1] ||
656  len[2] > checkfactor * rrms_m[2])
657  {
658  for(unsigned int ii = 0; ii < this->getLocalNum(); ii++) {
659  /* delete the particle if the distance to the beam center
660  * is larger than 8 times of beam's rms size
661  */
662  if (std::abs(R[ii](0) - rmean_m(0)) > checkfactor * rrms_m[0] ||
663  std::abs(R[ii](1) - rmean_m(1)) > checkfactor * rrms_m[1] ||
664  std::abs(R[ii](2) - rmean_m(2)) > checkfactor * rrms_m[2])
665  {
666  // put particle onto deletion list
667  destroy(1, ii);
668  //update bin parameter
669  if (weHaveBins())
670  countLost[Bin[ii]] += 1 ;
671  /* INFOMSG("REMOTE PARTICLE DELETION: ID = " << ID[ii] << ", R = " << R[ii]
672  * << ", beam rms = " << rrms_m << endl;);
673  */
674  }
675  }
676  }
677  }
678  else {
679  if (len[0] > checkfactor * rrms_m[0] ||
680  len[2] > checkfactor * rrms_m[2])
681  {
682  for(unsigned int ii = 0; ii < this->getLocalNum(); ii++) {
683  /* delete the particle if the distance to the beam center
684  * is larger than 8 times of beam's rms size
685  */
686  if (std::abs(R[ii](0) - rmean_m(0)) > checkfactor * rrms_m[0] ||
687  std::abs(R[ii](2) - rmean_m(2)) > checkfactor * rrms_m[2])
688  {
689  // put particle onto deletion list
690  destroy(1, ii);
691  //update bin parameter
692  if (weHaveBins())
693  countLost[Bin[ii]] += 1 ;
694  /* INFOMSG("REMOTE PARTICLE DELETION: ID = " << ID[ii] << ", R = " << R[ii]
695  * << ", beam rms = " << rrms_m << endl;);
696  */
697  }
698  }
699  }
700  }
701  }
702 
703  for(int i = 0; i < dimIdx; i++) {
704  double length = std::abs(rmax_m[i] - rmin_m[i]);
705  rmax_m[i] += dh_m * length;
706  rmin_m[i] -= dh_m * length;
707  hr_m[i] = (rmax_m[i] - rmin_m[i]) / (nr_m[i] - 1);
708  }
709 
710  // rescale mesh
711  this->updateFields(hr_m, rmin_m);
712 
713  if(weHaveBins()) {
714  pbin_m->updatePartInBin_cyc(countLost.get());
715  }
716 
717  /* we also need to update the number of particles per bunch
718  * expensive since does an allreduce!
719  */
720  countTotalNumPerBunch();
721 
722  IpplTimings::startTimer(boundpUpdateTimer_m);
723  update();
724  IpplTimings::stopTimer(boundpUpdateTimer_m);
725 
726  IpplTimings::stopTimer(boundpTimer_m);
727 }
728 
729 
730 template <class T, unsigned Dim>
732 
733  const unsigned int minNumParticlesPerCore = getMinimumNumberOfParticlesPerCore();
734 
735  this->updateDomainLength(nr_m);
736 
737  std::unique_ptr<size_t[]> tmpbinemitted;
738 
739  boundp();
740 
741  size_t ne = 0;
742  const size_t localNum = getLocalNum();
743 
744  if(weHaveEnergyBins()) {
745  tmpbinemitted = std::unique_ptr<size_t[]>(new size_t[getNumberOfEnergyBins()]);
746  for(int i = 0; i < getNumberOfEnergyBins(); i++) {
747  tmpbinemitted[i] = 0;
748  }
749  for(unsigned int i = 0; i < localNum; i++) {
750  if (Bin[i] < 0) {
751  ne++;
752  destroy(1, i);
753  } else
754  tmpbinemitted[Bin[i]]++;
755  }
756  } else {
757  for(unsigned int i = 0; i < localNum; i++) {
758  if((Bin[i] < 0) && ((localNum - ne) > minNumParticlesPerCore)) { // need in minimum x particles per node
759  ne++;
760  destroy(1, i);
761  }
762  }
763  lowParticleCount_m = ((localNum - ne) <= minNumParticlesPerCore);
764  reduce(lowParticleCount_m, lowParticleCount_m, OpOr());
765  }
766 
767  if (lowParticleCount_m) {
768  Inform m ("boundp_destroyT a) ", INFORM_ALL_NODES);
769  m << level3 << "Warning low number of particles on some cores localNum= "
770  << localNum << " ne= " << ne << " NLocal= " << getLocalNum() << endl;
771  } else {
772  boundp();
773  }
774  calcBeamParameters();
775  gatherLoadBalanceStatistics();
776 
777  if(weHaveEnergyBins()) {
778  const int lastBin = dist_m->getLastEmittedEnergyBin();
779  for(int i = 0; i < lastBin; i++) {
780  binemitted_m[i] = tmpbinemitted[i];
781  }
782  }
783  reduce(ne, ne, OpAddAssign());
784  return ne;
785 }
786 
787 
788 template <class T, unsigned Dim>
790 
791  const unsigned int minNumParticlesPerCore = getMinimumNumberOfParticlesPerCore();
792  std::unique_ptr<size_t[]> tmpbinemitted;
793 
794  const size_t localNum = getLocalNum();
795  const size_t totalNum = getTotalNum();
796  size_t ne = 0;
797 
798  if(weHaveEnergyBins()) {
799  tmpbinemitted = std::unique_ptr<size_t[]>(new size_t[getNumberOfEnergyBins()]);
800  for(int i = 0; i < getNumberOfEnergyBins(); i++) {
801  tmpbinemitted[i] = 0;
802  }
803  for(unsigned int i = 0; i < localNum; i++) {
804  if (Bin[i] < 0) {
805  destroy(1, i);
806  ++ ne;
807  } else
808  tmpbinemitted[Bin[i]]++;
809  }
810  } else {
811  Inform dmsg("destroy: ", INFORM_ALL_NODES);
812  for(size_t i = 0; i < localNum; i++) {
813  if((Bin[i] < 0)) {
814  if ((localNum - ne) > minNumParticlesPerCore) { // need in minimum x particles per node
815  ne++;
816  destroy(1, i);
817  }
818  }
819  }
820  lowParticleCount_m = ((localNum - ne) <= minNumParticlesPerCore);
821  reduce(lowParticleCount_m, lowParticleCount_m, OpOr());
822  }
823 
824  if (ne > 0) {
825  performDestroy(true);
826  }
827 
828  calcBeamParameters();
829  gatherLoadBalanceStatistics();
830 
831  if (weHaveEnergyBins()) {
832  const int lastBin = dist_m->getLastEmittedEnergyBin();
833  for(int i = 0; i < lastBin; i++) {
834  binemitted_m[i] = tmpbinemitted[i];
835  }
836  }
837  size_t newTotalNum = getLocalNum();
838  reduce(newTotalNum, newTotalNum, OpAddAssign());
839 
840  setTotalNum(newTotalNum);
841 
842  return totalNum - newTotalNum;
843 }
844 
845 template <class T, unsigned Dim>
847  return 0.0;
848 }
849 
850 
851 template <class T, unsigned Dim>
853  return 0.0;
854 }
855 
856 
857 template <class T, unsigned Dim>
859  return 0.0;
860 }
861 
862 
863 template <class T, unsigned Dim>
865  return 0.0;
866 }
867 
868 
869 template <class T, unsigned Dim>
871  return 0;
872 }
873 
874 
875 //ff
876 template <class T, unsigned Dim>
878  return this->R[i](0);
879 }
880 
881 
882 //ff
883 template <class T, unsigned Dim>
885  return this->R[i](1);
886 }
887 
888 
889 //ff
890 template <class T, unsigned Dim>
892  return this->R[i](2);
893 }
894 
895 
896 //ff
897 template <class T, unsigned Dim>
899  return 0.0;
900 }
901 
902 
903 //ff
904 template <class T, unsigned Dim>
906  return 0.0;
907 }
908 
909 
910 template <class T, unsigned Dim>
911 void PartBunchBase<T, Dim>::setZ(int i, double zcoo)
912 {
913  // nothing done here
914 };
915 
916 
917 template <class T, unsigned Dim>
919 
920  this->getLocalBounds(rmin, rmax);
921 
922  double min[2*Dim];
923 
924  for (unsigned int i = 0; i < Dim; ++i) {
925  min[2*i] = rmin[i];
926  min[2*i + 1] = -rmax[i];
927  }
928 
929  allreduce(min, 2*Dim, std::less<double>());
930 
931  for (unsigned int i = 0; i < Dim; ++i) {
932  rmin[i] = min[2*i];
933  rmax[i] = -min[2*i + 1];
934  }
935 }
936 
937 
938 template <class T, unsigned Dim>
940  const size_t localNum = getLocalNum();
941  if (localNum == 0) {
942  double maxValue = 1e8;
943  rmin = Vector_t(maxValue, maxValue, maxValue);
944  rmax = Vector_t(-maxValue, -maxValue, -maxValue);
945  return;
946  }
947 
948  rmin = R[0];
949  rmax = R[0];
950  for (size_t i = 1; i < localNum; ++ i) {
951  for (unsigned short d = 0; d < 3u; ++ d) {
952  if (rmin(d) > R[i](d)) rmin(d) = R[i](d);
953  else if (rmax(d) < R[i](d)) rmax(d) = R[i](d);
954  }
955  }
956 }
957 
958 
959 template <class T, unsigned Dim>
960 std::pair<Vector_t, double> PartBunchBase<T, Dim>::getBoundingSphere() {
961  Vector_t rmin, rmax;
962  get_bounds(rmin, rmax);
963 
964  std::pair<Vector_t, double> sphere;
965  sphere.first = 0.5 * (rmin + rmax);
966  sphere.second = sqrt(dot(rmax - sphere.first, rmax - sphere.first));
967 
968  return sphere;
969 }
970 
971 
972 template <class T, unsigned Dim>
973 std::pair<Vector_t, double> PartBunchBase<T, Dim>::getLocalBoundingSphere() {
974  Vector_t rmin, rmax;
975  getLocalBounds(rmin, rmax);
976 
977  std::pair<Vector_t, double> sphere;
978  sphere.first = 0.5 * (rmin + rmax);
979  sphere.second = sqrt(dot(rmax - sphere.first, rmax - sphere.first));
980 
981  return sphere;
982 }
983 
984 
985 template <class T, unsigned Dim>
987  Inform msg("PartBunch ");
988 
989  create(1);
990  size_t i = getTotalNum();
991 
992  R[i](0) = p[0];
993  R[i](1) = p[1];
994  R[i](2) = p[2];
995 
996  P[i](0) = p[3];
997  P[i](1) = p[4];
998  P[i](2) = p[5];
999 
1000  update();
1001  msg << "Created one particle i= " << i << endl;
1002 }
1003 
1004 
1005 template <class T, unsigned Dim>
1007  R[ii](0) = z[0];
1008  P[ii](0) = z[1];
1009  R[ii](1) = z[2];
1010  P[ii](1) = z[3];
1011  R[ii](2) = z[4];
1012  P[ii](2) = z[5];
1013 }
1014 
1015 
1016 template <class T, unsigned Dim>
1018  R[ii](0) = p[0];
1019  P[ii](0) = p[1];
1020  R[ii](1) = p[2];
1021  P[ii](1) = p[3];
1022  R[ii](2) = p[4];
1023  P[ii](2) = p[5];
1024 }
1025 
1026 
1027 template <class T, unsigned Dim>
1029  OpalParticle part;
1030  part[0] = R[ii](0);
1031  part[1] = P[ii](0);
1032  part[2] = R[ii](1);
1033  part[3] = P[ii](1);
1034  part[4] = R[ii](2);
1035  part[5] = P[ii](2);
1036  return part;
1037 }
1038 
1039 
1040 template <class T, unsigned Dim>
1042  double &axmax, double &aymax) {
1043  axmax = aymax = 0.0;
1044  OpalParticle part;
1045 
1046  for(unsigned int ii = 0; ii < getLocalNum(); ii++) {
1047 
1048  part = get_part(ii);
1049 
1050  double xnor =
1051  D(0, 0) * part.x() + D(0, 1) * part.px() + D(0, 2) * part.y() +
1052  D(0, 3) * part.py() + D(0, 4) * part.t() + D(0, 5) * part.pt();
1053  double pxnor =
1054  D(1, 0) * part.x() + D(1, 1) * part.px() + D(1, 2) * part.y() +
1055  D(1, 3) * part.py() + D(1, 4) * part.t() + D(1, 5) * part.pt();
1056  double ynor =
1057  D(2, 0) * part.x() + D(2, 1) * part.px() + D(2, 2) * part.y() +
1058  D(2, 3) * part.py() + D(2, 4) * part.t() + D(2, 5) * part.pt();
1059  double pynor =
1060  D(3, 0) * part.x() + D(3, 1) * part.px() + D(3, 2) * part.y() +
1061  D(3, 3) * part.py() + D(3, 4) * part.t() + D(3, 5) * part.pt();
1062 
1063  axmax = std::max(axmax, (xnor * xnor + pxnor * pxnor));
1064  aymax = std::max(aymax, (ynor * ynor + pynor * pynor));
1065  }
1066 }
1067 
1068 
1069 template <class T, unsigned Dim>
1071  dt_m = dt;
1072 }
1073 
1074 
1075 template <class T, unsigned Dim>
1077  return dt_m;
1078 }
1079 
1080 
1081 template <class T, unsigned Dim>
1083  t_m = t;
1084 }
1085 
1086 
1087 template <class T, unsigned Dim>
1089  t_m += dt_m;
1090 }
1091 
1092 
1093 template <class T, unsigned Dim>
1095  return t_m;
1096 }
1097 
1098 
1099 template <class T, unsigned Dim>
1101  return spos_m;
1102 }
1103 
1104 
1105 template <class T, unsigned Dim>
1107  spos_m = s;
1108 }
1109 
1110 
1111 template <class T, unsigned Dim>
1113  return eKin_m / (getM()*1e-6) + 1.0;
1114 }
1115 
1116 
1117 template <class T, unsigned Dim>
1119  return eKin_m;
1120 }
1121 
1122 
1123 template <class T, unsigned Dim>
1125  return rmin_m;
1126 }
1127 
1128 
1129 template <class T, unsigned Dim>
1131  return rmax_m;
1132 }
1133 
1134 
1135 template <class T, unsigned Dim>
1137  return rmean_m;
1138 }
1139 
1140 
1141 template <class T, unsigned Dim>
1143  return rrms_m;
1144 }
1145 
1146 
1147 template <class T, unsigned Dim>
1149  return rprms_m;
1150 }
1151 
1152 
1153 template <class T, unsigned Dim>
1155  return rmean_m;
1156 }
1157 
1158 
1159 template <class T, unsigned Dim>
1161  return prms_m;
1162 }
1163 
1164 
1165 template <class T, unsigned Dim>
1167  return pmean_m;
1168 }
1169 
1170 
1171 template <class T, unsigned Dim>
1173  if (dist_m)// && dist_m->getType() != DistrTypeT::FROMFILE)
1174  return dist_m->get_pmean();
1175 
1176  double gamma = 0.1 / getM() + 1; // set default 0.1 eV
1177  return Vector_t(0, 0, sqrt(std::pow(gamma, 2) - 1));
1178 }
1179 
1180 
1181 template <class T, unsigned Dim>
1183  return eps_m;
1184 }
1185 
1186 
1187 template <class T, unsigned Dim>
1189  return eps_norm_m;
1190 }
1191 
1192 
1193 template <class T, unsigned Dim>
1195  return halo_m;
1196 }
1197 
1198 
1199 template <class T, unsigned Dim>
1201  return hr_m;
1202 }
1203 
1204 
1205 template <class T, unsigned Dim>
1207  return Dx_m;
1208 }
1209 
1210 
1211 template <class T, unsigned Dim>
1213  return Dy_m;
1214 }
1215 
1216 
1217 template <class T, unsigned Dim>
1219  return DDx_m;
1220 }
1221 
1222 
1223 template <class T, unsigned Dim>
1225  return DDy_m;
1226 }
1227 
1228 
1229 template <class T, unsigned Dim>
1231  dh_m = dh;
1232 }
1233 
1234 
1235 template <class T, unsigned Dim>
1237 
1238  for(int i = 0; i < Ippl::getNodes(); i++)
1239  globalPartPerNode_m[i] = 0;
1240 
1241  std::size_t localnum = getLocalNum();
1242  gather(&localnum, &globalPartPerNode_m[0], 1);
1243 }
1244 
1245 
1246 template <class T, unsigned Dim>
1248  return globalPartPerNode_m[p];
1249 }
1250 
1251 
1252 template <class T, unsigned Dim>
1254  bounds(this->P, min, max);
1255 }
1256 
1257 
1258 template <class T, unsigned Dim>
1260 
1261  Vector_t eps2, fac, rsqsum, psqsum, rpsum;
1262 
1263  IpplTimings::startTimer(statParamTimer_m);
1264 
1265  const size_t locNp = getLocalNum();
1266  const size_t totalNum = getTotalNum();
1267  const double zero = 0.0;
1268 
1269  get_bounds(rmin_m, rmax_m);
1270 
1271  if(totalNum == 0) {
1272  for(unsigned int i = 0 ; i < Dim; i++) {
1273  rmean_m(i) = 0.0;
1274  pmean_m(i) = 0.0;
1275  rrms_m(i) = 0.0;
1276  prms_m(i) = 0.0;
1277  eps_norm_m(i) = 0.0;
1278  }
1279  rprms_m = 0.0;
1280  eKin_m = 0.0;
1281  eps_m = 0.0;
1282  IpplTimings::stopTimer(statParamTimer_m);
1283  return;
1284  }
1285 
1286  const size_t intN = calcMoments();
1287  const double N = static_cast<double>(intN);
1288 
1289  for(unsigned int i = 0 ; i < Dim; i++) {
1290  rmean_m(i) = centroid_m[2 * i] / N;
1291  pmean_m(i) = centroid_m[(2 * i) + 1] / N;
1292  rsqsum(i) = moments_m(2 * i, 2 * i) - N * rmean_m(i) * rmean_m(i);
1293  psqsum(i) = moments_m((2 * i) + 1, (2 * i) + 1) - N * pmean_m(i) * pmean_m(i);
1294  if(psqsum(i) < 0)
1295  psqsum(i) = 0;
1296  rpsum(i) = moments_m((2 * i), (2 * i) + 1) - N * rmean_m(i) * pmean_m(i);
1297  }
1298  eps2 = (rsqsum * psqsum - rpsum * rpsum) / (N * N);
1299  rpsum /= N;
1300 
1301  for(unsigned int i = 0 ; i < Dim; i++) {
1302  rrms_m(i) = sqrt(rsqsum(i) / N);
1303  prms_m(i) = sqrt(psqsum(i) / N);
1304  eps_norm_m(i) = std::sqrt(std::max(eps2(i), zero));
1305  double tmp = rrms_m(i) * prms_m(i);
1306  fac(i) = (tmp == 0) ? zero : 1.0 / tmp;
1307  }
1308 
1309  rprms_m = rpsum * fac;
1310 
1311  Dx_m = moments_m(0, 5) / N;
1312  DDx_m = moments_m(1, 5) / N;
1313 
1314  Dy_m = moments_m(2, 5) / N;
1315  DDy_m = moments_m(3, 5) / N;
1316 
1317  // Find unnormalized emittance.
1318  double gamma = 0.0;
1319  for(size_t i = 0; i < locNp; i++)
1320  gamma += sqrt(1.0 + dot(P[i], P[i]));
1321 
1322  allreduce(&gamma, 1, std::plus<double>());
1323  gamma /= N;
1324 
1325  calcEMean();
1326 
1327  // The computation of the energy spread is an estimation
1328  // based on the standard deviation of the longitudinal
1329  // momentum:
1330  // Var[f(P)] ~= (df/dP)(E[P])^2 Var[P]
1331  const double m0 = getM() * 1.E-6;
1332  double tmp = 1.0 / std::pow(eKin_m / m0 + 1., 2.0);
1333  if (OpalData::getInstance()->isInOPALCyclMode()) {
1334  dE_m = prms_m(1) * m0 * sqrt(1.0 - tmp);
1335  } else {
1336  dE_m = prms_m(2) * m0 * sqrt(1.0 - tmp);
1337  }
1338 
1339  eps_m = eps_norm_m / Vector_t(gamma * sqrt(1.0 - 1.0 / (gamma * gamma)));
1340  IpplTimings::stopTimer(statParamTimer_m);
1341 
1342 }
1343 
1344 
1345 template <class T, unsigned Dim>
1347  using Physics::c;
1348 
1349  const double N = static_cast<double>(getTotalNum());
1350 
1351  if(N == 0) {
1352  rmean_m = Vector_t(0.0);
1353  pmean_m = Vector_t(0.0);
1354  rrms_m = Vector_t(0.0);
1355  prms_m = Vector_t(0.0);
1356  eps_m = Vector_t(0.0);
1357  } else {
1358  if(Ippl::myNode() == 0) {
1359  // fixme: the following code is crap!
1360  // Only use one node as this function will get called only once before
1361  // particles have been emitted (at least in principle).
1362  Vector_t eps2, fac, rsqsum, psqsum, rpsum;
1363 
1364  const double zero = 0.0;
1365  const double N = static_cast<double>(pbin_m->getNp());
1366  calcMomentsInitial();
1367 
1368  for(unsigned int i = 0 ; i < Dim; i++) {
1369  rmean_m(i) = centroid_m[2 * i] / N;
1370  pmean_m(i) = centroid_m[(2 * i) + 1] / N;
1371  rsqsum(i) = moments_m(2 * i, 2 * i) - N * rmean_m(i) * rmean_m(i);
1372  psqsum(i) = moments_m((2 * i) + 1, (2 * i) + 1) - N * pmean_m(i) * pmean_m(i);
1373  if(psqsum(i) < 0)
1374  psqsum(i) = 0;
1375  rpsum(i) = moments_m((2 * i), (2 * i) + 1) - N * rmean_m(i) * pmean_m(i);
1376  }
1377  eps2 = (rsqsum * psqsum - rpsum * rpsum) / (N * N);
1378  rpsum /= N;
1379 
1380  for(unsigned int i = 0 ; i < Dim; i++) {
1381 
1382  rrms_m(i) = sqrt(rsqsum(i) / N);
1383  prms_m(i) = sqrt(psqsum(i) / N);
1384  eps_m(i) = sqrt(std::max(eps2(i), zero));
1385  double tmp = rrms_m(i) * prms_m(i);
1386  fac(i) = (tmp == 0) ? zero : 1.0 / tmp;
1387  }
1388  rprms_m = rpsum * fac;
1389  }
1390  }
1391 }
1392 
1393 
1394 template <class T, unsigned Dim>
1396  return couplingConstant_m;
1397 }
1398 
1399 
1400 template <class T, unsigned Dim>
1402  couplingConstant_m = c;
1403 }
1404 
1405 
1406 template <class T, unsigned Dim>
1408  qi_m = q;
1409  if(getTotalNum() != 0)
1410  Q = qi_m;
1411  else
1412  WARNMSG("Could not set total charge in PartBunch::setCharge based on getTotalNum" << endl);
1413 }
1414 
1415 
1416 template <class T, unsigned Dim>
1418  qi_m = q;
1419 }
1420 
1421 
1422 template <class T, unsigned Dim>
1424  M = mass;
1425 }
1426 
1427 
1429 template <class T, unsigned Dim>
1431  if(dist_m)
1432  return dist_m->getEkin();
1433  else
1434  return 0.0;
1435 }
1436 
1438 template <class T, unsigned Dim>
1440  if(dist_m)
1441  return dist_m->getWorkFunctionRf();
1442  else
1443  return 0.0;
1444 }
1446 template <class T, unsigned Dim>
1448  if(dist_m)
1449  return dist_m->getLaserEnergy();
1450  else
1451  return 0.0;
1452 }
1453 
1454 
1455 template <class T, unsigned Dim>
1457  return sum(Q);
1458 }
1459 
1460 
1461 template <class T, unsigned Dim>
1463  return qi_m;
1464 }
1465 
1466 
1467 template <class T, unsigned Dim>
1469  fs_m = fs;
1470  fs_m->initSolver(this);
1471 
1476  if(!OpalData::getInstance()->hasBunchAllocated()) {
1477  this->initialize(fs_m->getFieldLayout());
1478 // this->setMesh(fs_m->getMesh());
1479 // this->setFieldLayout(fs_m->getFieldLayout());
1480  }
1481 }
1482 
1483 
1484 template <class T, unsigned Dim>
1486  if(fs_m)
1487  return fs_m->hasValidSolver();
1488  else
1489  return false;
1490 }
1491 
1492 
1494 template <class T, unsigned Dim>
1496  if(fs_m)
1497  return fs_m->getFieldSolverType();
1498  else
1499  return "";
1500 }
1501 
1502 
1503 template <class T, unsigned Dim>
1505  stepsPerTurn_m = n;
1506 }
1507 
1508 
1509 template <class T, unsigned Dim>
1511  return stepsPerTurn_m;
1512 }
1513 
1514 
1515 template <class T, unsigned Dim>
1517  globalTrackStep_m = n;
1518 }
1519 
1520 
1521 template <class T, unsigned Dim>
1523  return globalTrackStep_m;
1524 }
1525 
1526 
1527 template <class T, unsigned Dim>
1529  localTrackStep_m = n;
1530 }
1531 
1532 
1533 template <class T, unsigned Dim>
1535  globalTrackStep_m++; localTrackStep_m++;
1536 }
1537 
1538 
1539 template <class T, unsigned Dim>
1541  return localTrackStep_m;
1542 }
1543 
1544 
1545 template <class T, unsigned Dim>
1547  numBunch_m = n;
1548  bunchTotalNum_m.resize(n);
1549  bunchLocalNum_m.resize(n);
1550 }
1551 
1552 
1553 template <class T, unsigned Dim>
1555  return numBunch_m;
1556 }
1557 
1558 
1559 template <class T, unsigned Dim>
1560 void PartBunchBase<T, Dim>::setTotalNumPerBunch(size_t totalnum, short n) {
1561  PAssert_LT(n, (short)bunchTotalNum_m.size());
1562  bunchTotalNum_m[n] = totalnum;
1563 }
1564 
1565 
1566 template <class T, unsigned Dim>
1568  PAssert_LT(n, (short)bunchTotalNum_m.size());
1569  return bunchTotalNum_m[n];
1570 }
1571 
1572 
1573 template <class T, unsigned Dim>
1574 void PartBunchBase<T, Dim>::setLocalNumPerBunch(size_t localnum, short n) {
1575  PAssert_LT(n, (short)bunchLocalNum_m.size());
1576  bunchLocalNum_m[n] = localnum;
1577 }
1578 
1579 
1580 template <class T, unsigned Dim>
1582  PAssert_LT(n, (short)bunchLocalNum_m.size());
1583  return bunchLocalNum_m[n];
1584 }
1585 
1586 
1587 template <class T, unsigned Dim>
1589  bunchTotalNum_m.clear();
1590  bunchTotalNum_m.resize(numBunch_m);
1591  bunchLocalNum_m.clear();
1592  bunchLocalNum_m.resize(numBunch_m);
1593 
1594  for (size_t i = 0; i < this->getLocalNum(); ++i) {
1595  PAssert_LT(this->bunchNum[i], numBunch_m);
1596  ++bunchLocalNum_m[this->bunchNum[i]];
1597  }
1598 
1599  allreduce(bunchLocalNum_m.data(), bunchTotalNum_m.data(),
1600  bunchLocalNum_m.size(), std::plus<size_t>());
1601 
1602  size_t totalnum = std::accumulate(bunchTotalNum_m.begin(),
1603  bunchTotalNum_m.end(), 0);
1604 
1605  if ( totalnum != this->getTotalNum() )
1606  throw OpalException("PartBunchBase::countTotalNumPerBunch()",
1607  "Sum of total number of particles per bunch (" +
1608  std::to_string(totalnum) + ") != total number of particles (" +
1609  std::to_string(this->getTotalNum()) + ")");
1610 }
1611 
1612 
1613 template <class T, unsigned Dim>
1615  globalMeanR_m = globalMeanR;
1616 }
1617 
1618 
1619 template <class T, unsigned Dim>
1621  return globalMeanR_m;
1622 }
1623 
1624 
1625 template <class T, unsigned Dim>
1627 
1628  globalToLocalQuaternion_m = globalToLocalQuaternion;
1629 }
1630 
1631 
1632 template <class T, unsigned Dim>
1634  return globalToLocalQuaternion_m;
1635 }
1636 
1637 
1638 template <class T, unsigned Dim>
1640  SteptoLastInj_m = n;
1641 }
1642 
1643 
1644 template <class T, unsigned Dim>
1646  return SteptoLastInj_m;
1647 }
1648 
1649 
1650 template <class T, unsigned Dim>
1652 
1653  const int emittedBins = pbin_m->getLastemittedBin();
1654  double phi[emittedBins];
1655  double px[emittedBins];
1656  double py[emittedBins];
1657  double meanPhi = 0.0;
1658 
1659  for(int ii = 0; ii < emittedBins; ii++) {
1660  phi[ii] = 0.0;
1661  px[ii] = 0.0;
1662  py[ii] = 0.0;
1663  }
1664 
1665  for(unsigned int ii = 0; ii < getLocalNum(); ii++) {
1666 
1667  px[Bin[ii]] += P[ii](0);
1668  py[Bin[ii]] += P[ii](1);
1669  }
1670 
1671  reduce(px, px + emittedBins, px, OpAddAssign());
1672  reduce(py, py + emittedBins, py, OpAddAssign());
1673  for(int ii = 0; ii < emittedBins; ii++) {
1674  phi[ii] = calculateAngle(px[ii], py[ii]);
1675  meanPhi += phi[ii];
1676  INFOMSG("Bin " << ii << " mean phi = " << phi[ii] * 180.0 / Physics::pi - 90.0 << "[degree]" << endl);
1677  }
1678 
1679  meanPhi /= emittedBins;
1680 
1681  INFOMSG("mean phi of all particles " << meanPhi * 180.0 / Physics::pi - 90.0 << "[degree]" << endl);
1682 
1683  return meanPhi;
1684 }
1685 
1686 // this function reset the BinID for each particles according to its current beta*gamma
1687 // it is for multi-turn extraction cyclotron with small energy gain
1688 // the bin number can be different with the bunch number
1689 
1690 template <class T, unsigned Dim>
1692 
1693 
1694  INFOMSG("Before reset Bin: " << endl);
1695  calcGammas_cycl();
1696  int maxbin = pbin_m->getNBins();
1697  size_t partInBin[maxbin];
1698  for(int ii = 0; ii < maxbin; ii++) partInBin[ii] = 0;
1699 
1700  double pMin0 = 1.0e9;
1701  double pMin = 0.0;
1702  double maxbinIndex = 0;
1703 
1704  for(unsigned long int n = 0; n < getLocalNum(); n++) {
1705  double temp_betagamma = sqrt(pow(P[n](0), 2) + pow(P[n](1), 2));
1706  if(pMin0 > temp_betagamma)
1707  pMin0 = temp_betagamma;
1708  }
1709  reduce(pMin0, pMin, OpMinAssign());
1710  INFOMSG("minimal beta*gamma = " << pMin << endl);
1711 
1712  double asinh0 = asinh(pMin);
1713  for(unsigned long int n = 0; n < getLocalNum(); n++) {
1714 
1715  double temp_betagamma = sqrt(pow(P[n](0), 2) + pow(P[n](1), 2));
1716  int itsBinID = floor((asinh(temp_betagamma) - asinh0) / eta + 1.0E-6);
1717  Bin[n] = itsBinID;
1718  if(maxbinIndex < itsBinID) {
1719  maxbinIndex = itsBinID;
1720  }
1721 
1722  if(itsBinID >= maxbin) {
1723  ERRORMSG("The bin number limit is " << maxbin << ", please increase the energy interval and try again" << endl);
1724  return false;
1725  } else
1726  partInBin[itsBinID]++;
1727 
1728  }
1729 
1730  // partInBin only count particle on the local node.
1731  pbin_m->resetPartInBin_cyc(partInBin, maxbinIndex);
1732 
1733  // after reset Particle Bin ID, update mass gamma of each bin again
1734  INFOMSG("After reset Bin: " << endl);
1735  calcGammas_cycl();
1736 
1737  return true;
1738 
1739 }
1740 
1741 
1742 template <class T, unsigned Dim>
1744  int maxbin = pbin_m->getNBins();
1745  std::size_t partInBin[maxbin];
1746  for (int i = 0; i < maxbin; ++i) {
1747  partInBin[i] = 0;
1748  }
1749 
1750  for (std::size_t i = 0; i < getLocalNum(); ++i) {
1751  partInBin[Bin[i]]++;
1752  }
1753 
1754  // partInBin only count particle on the local node.
1755  pbin_m->resetPartInBin_cyc(partInBin, numBunch_m - 1);
1756 
1757  // after reset Particle Bin ID, update mass gamma of each bin again
1758  calcGammas_cycl();
1759 
1760  return true;
1761 }
1762 
1763 
1764 template <class T, unsigned Dim>
1766  return reference->getQ();
1767 }
1768 
1769 
1770 template <class T, unsigned Dim>
1772  return reference->getM();
1773 }
1774 
1775 
1776 template <class T, unsigned Dim>
1778  return reference->getP();
1779 }
1780 
1781 
1782 template <class T, unsigned Dim>
1784  return reference->getE();
1785 }
1786 
1787 
1788 template <class T, unsigned Dim>
1790  return refPType_m;
1791 }
1792 
1793 template <class T, unsigned Dim>
1795  refPType_m = type;
1796 }
1797 
1798 template <class T, unsigned Dim>
1800  const_cast<PartData *>(reference)->setQ(q);
1801 }
1802 
1803 
1804 template <class T, unsigned Dim>
1806  const_cast<PartData *>(reference)->setM(m);
1807 }
1808 
1809 
1810 template <class T, unsigned Dim>
1812  return dE_m;
1813 }
1814 
1815 
1816 template <class T, unsigned Dim>
1818  return reference->getBeta();
1819 }
1820 
1821 
1822 template <class T, unsigned Dim>
1824  return reference->getGamma();
1825 }
1826 
1827 
1828 template <class T, unsigned Dim>
1830  return 0;
1831 }
1832 
1833 
1834 template <class T, unsigned Dim>
1836  return 0;
1837 }
1838 
1839 
1840 template <class T, unsigned Dim>
1842 {
1843  // do nothing here
1844 };
1845 
1846 
1847 template <class T, unsigned Dim>
1849  return reference;
1850 }
1851 
1852 
1853 template <class T, unsigned Dim>
1855  return dist_m->getEmissionDeltaT();
1856 }
1857 
1858 
1859 template <class T, unsigned Dim>
1861  binemitted_m[binNumber]++;
1862 }
1863 
1864 
1865 template <class T, unsigned Dim>
1867 
1868  const double totalNp = static_cast<double>(getTotalNum());
1869  const double locNp = static_cast<double>(getLocalNum());
1870 
1871  eKin_m = 0.0;
1872 
1873  for(unsigned int k = 0; k < locNp; k++) {
1874  eKin_m += sqrt(dot(P[k], P[k]) + 1.0);
1875  }
1876 
1877  eKin_m -= locNp;
1878  eKin_m *= getM() * 1.0e-6;
1879 
1880  reduce(eKin_m, eKin_m, OpAddAssign());
1881 
1882  eKin_m /= totalNp;
1883 }
1884 
1885 
1886 template <class T, unsigned Dim>
1888 
1889  const double totalNp = static_cast<double>(getTotalNum());
1890  const double locNp = static_cast<double>(getLocalNum());
1891 
1892  double avrgp = 0.0;
1893  for(unsigned int k = 0; k < locNp; k++)
1894  avrgp += sqrt(dot(P[k], P[k]));
1895 
1896  reduce(avrgp, avrgp, OpAddAssign());
1897  avrgp /= totalNp;
1898 
1899  for(unsigned int k = 0; k < locNp; k++)
1900  P[k](2) = P[k](2) - avrgp + avrgp_m;
1901 }
1902 
1903 
1904 template <class T, unsigned Dim>
1906 
1907  if(getTotalNum() != 0) { // to suppress Nans
1908  Inform::FmtFlags_t ff = os.flags();
1909 
1910  double pathLength = get_sPos();
1911 
1912  os << std::scientific;
1913  os << level1 << "\n";
1914  os << "* ************** B U N C H ********************************************************* \n";
1915  os << "* NP = " << getTotalNum() << "\n";
1916  os << "* Qtot = " << std::setw(17) << Util::getChargeString(std::abs(sum(Q))) << " "
1917  << "Qi = " << std::setw(17) << Util::getChargeString(std::abs(qi_m)) << "\n";
1918  os << "* Ekin = " << std::setw(17) << Util::getEnergyString(eKin_m) << " "
1919  << "dEkin = " << std::setw(17) << Util::getEnergyString(dE_m) << "\n";
1920  os << "* rmax = " << Util::getLengthString(rmax_m, 5) << "\n";
1921  os << "* rmin = " << Util::getLengthString(rmin_m, 5) << "\n";
1922  if (getTotalNum() >= 2) { // to suppress Nans
1923  os << "* rms beam size = " << Util::getLengthString(rrms_m, 5) << "\n";
1924  os << "* rms momenta = " << std::setw(12) << std::setprecision(5) << prms_m << " [beta gamma]\n";
1925  os << "* mean position = " << Util::getLengthString(rmean_m, 5) << "\n";
1926  os << "* mean momenta = " << std::setw(12) << std::setprecision(5) << pmean_m << " [beta gamma]\n";
1927  os << "* rms emittance = " << std::setw(12) << std::setprecision(5) << eps_m << " (not normalized)\n";
1928  os << "* rms correlation = " << std::setw(12) << std::setprecision(5) << rprms_m << "\n";
1929  }
1930  os << "* hr = " << Util::getLengthString(get_hr(), 5) << "\n";
1931  os << "* dh = " << std::setw(13) << std::setprecision(5) << dh_m * 100 << " [%]\n";
1932  os << "* t = " << std::setw(17) << Util::getTimeString(getT()) << " "
1933  << "dT = " << std::setw(17) << Util::getTimeString(getdT()) << "\n";
1934  os << "* spos = " << std::setw(17) << Util::getLengthString(pathLength) << "\n";
1935  os << "* ********************************************************************************** " << endl;
1936  os.flags(ff);
1937  }
1938  return os;
1939 }
1940 
1941 
1942 template <class T, unsigned Dim>
1944 
1945  double part[2 * Dim];
1946 
1947  const unsigned long localNum = getLocalNum();
1948 
1949  /* 2 * Dim centroids + Dim * ( 2 * Dim + 1 ) 2nd moments + 2 * Dim (3rd and 4th order moments)
1950  * --> 1st order moments: 0, ..., 2 * Dim - 1
1951  * --> 2nd order moments: 2 * Dim, ..., Dim * ( 2 * Dim + 1 )
1952  * --> 3rd order moments: Dim * ( 2 * Dim + 1 ) + 1, ..., Dim * ( 2 * Dim + 1 ) + Dim
1953  * (only, <x^3>, <y^3> and <z^3>)
1954  * --> 4th order moments: Dim * ( 2 * Dim + 1 ) + Dim + 1, ..., Dim * ( 2 * Dim + 1 ) + 2 * Dim
1955  *
1956  * For a 6x6 matrix we have each 2nd order moment (except diagonal
1957  * entries) twice. We only store the upper half of the matrix.
1958  */
1959  std::vector<double> loc_moments(4 * Dim + Dim * ( 2 * Dim + 1 ));
1960 
1961  long int totalNum = this->getTotalNum();
1962  if (OpalData::getInstance()->isInOPALCyclMode()) {
1963  /* FIXME After issue 287 is resolved this shouldn't be necessary
1964  * anymore
1965  */
1966  for(unsigned long k = 0; k < localNum; ++ k) {
1967  if (ID[k] == 0) {
1968  part[1] = P[k](0);
1969  part[3] = P[k](1);
1970  part[5] = P[k](2);
1971  part[0] = R[k](0);
1972  part[2] = R[k](1);
1973  part[4] = R[k](2);
1974 
1975  unsigned int l = 2 * Dim;
1976  for (unsigned int i = 0; i < 2 * Dim; ++i) {
1977  loc_moments[i] -= part[i];
1978  for(unsigned int j = 0; j <= i; j++) {
1979  loc_moments[l++] -= part[i] * part[j];
1980  }
1981  }
1982 
1983  for (unsigned int i = 0; i < Dim; ++i) {
1984  double r2 = R[k](i) * R[k](i);
1985  loc_moments[l] -= r2 * R[k](i);
1986  loc_moments[Dim + l++] -= r2 * r2;
1987  }
1988 
1989  --totalNum;
1990  break;
1991  }
1992  }
1993  allreduce(totalNum, 1, std::less<long int>());
1994  }
1995 
1996  for(unsigned long k = 0; k < localNum; ++ k) {
1997  part[1] = P[k](0);
1998  part[3] = P[k](1);
1999  part[5] = P[k](2);
2000  part[0] = R[k](0);
2001  part[2] = R[k](1);
2002  part[4] = R[k](2);
2003 
2004  unsigned int l = 2 * Dim;
2005  for (unsigned int i = 0; i < 2 * Dim; ++i) {
2006  loc_moments[i] += part[i];
2007  for(unsigned int j = 0; j <= i; j++) {
2008  loc_moments[l++] += part[i] * part[j];
2009  }
2010  }
2011 
2012  for (unsigned int i = 0; i < Dim; ++i) {
2013  double r2 = R[k](i) * R[k](i);
2014  loc_moments[l] += r2 * R[k](i);
2015  loc_moments[Dim + l++] += r2 * r2;
2016  }
2017  }
2018 
2019  allreduce(loc_moments.data(), loc_moments.size(), std::plus<double>());
2020 
2021  // copy to member variables
2022  for (unsigned int i = 0; i< 2 * Dim; ++i)
2023  centroid_m[i] = loc_moments[i];
2024 
2025  unsigned int l = 2 * Dim;
2026  for (unsigned int i = 0; i < 2 * Dim; ++i) {
2027  for(unsigned int j = 0; j <= i; j++) {
2028  moments_m(i, j) = loc_moments[l++];
2029  moments_m(j, i) = moments_m(i, j);
2030  }
2031  }
2032 
2033  /* 4th order central moment: <w^4> - 4<w><w^3> + 6<w>^2<w^2> - 3<w>^4
2034  * 2nd order central moment: <w^2> - <w>^2
2035  *
2036  * with w = x, y, z.
2037  */
2038  int j = 2 * Dim + Dim * ( 2 * Dim + 1 );
2039  double invN = 1.0 / double(totalNum);
2040  for (unsigned int i = 0; i < Dim; ++i) {
2041  double w1 = centroid_m[2 * i] * invN;
2042  double w2 = moments_m(2 * i, 2 * i) * invN;
2043  double w3 = loc_moments[j + i] * invN;
2044  double w4 = loc_moments[j + Dim + i] * invN;
2045 
2046  halo_m(i) = w4 + w1 * (-4.0 * w3 + w1 * (6.0 * w2 - 3.0 * w1 * w1));
2047  double tmp = w2 - w1 * w1;
2048  halo_m(i) /= ( tmp * tmp );
2049  halo_m(i) -= Options::haloShift;
2050  }
2051 
2052  return totalNum;
2053 }
2054 
2055 
2056 template <class T, unsigned Dim>
2058 
2059  double part[2 * Dim];
2060 
2061  for(unsigned int i = 0; i < 2 * Dim; ++i) {
2062  centroid_m[i] = 0.0;
2063  for(unsigned int j = 0; j <= i; ++j) {
2064  moments_m(i, j) = 0.0;
2065  moments_m(j, i) = moments_m(i, j);
2066  }
2067  }
2068 
2069  for(size_t k = 0; k < pbin_m->getNp(); k++) {
2070  for(int binNumber = 0; binNumber < pbin_m->getNBins(); binNumber++) {
2071  std::vector<double> p;
2072 
2073  if(pbin_m->getPart(k, binNumber, p)) {
2074  part[0] = p.at(0);
2075  part[1] = p.at(3);
2076  part[2] = p.at(1);
2077  part[3] = p.at(4);
2078  part[4] = p.at(2);
2079  part[5] = p.at(5);
2080 
2081  for(unsigned int i = 0; i < 2 * Dim; ++i) {
2082  centroid_m[i] += part[i];
2083  for(unsigned int j = 0; j <= i; ++j) {
2084  moments_m(i, j) += part[i] * part[j];
2085  }
2086  }
2087  }
2088  }
2089  }
2090 
2091  for(unsigned int i = 0; i < 2 * Dim; ++i) {
2092  for(unsigned int j = 0; j < i; ++j) {
2093  moments_m(j, i) = moments_m(i, j);
2094  }
2095  }
2096 }
2097 
2098 
2099 // angle range [0~2PI) degree
2100 template <class T, unsigned Dim>
2101 double PartBunchBase<T, Dim>::calculateAngle(double x, double y) {
2102  double thetaXY = atan2(y, x);
2103 
2104  return thetaXY >= 0 ? thetaXY : thetaXY + Physics::two_pi;
2105 }
2106 
2107 
2108 template <class T, unsigned Dim>
2109 Inform &operator<<(Inform &os, PartBunchBase<T, Dim> &p) {
2110  return p.print(os);
2111 }
2112 
2113 
2114 /*
2115  * Virtual member functions
2116  */
2117 
2118 template <class T, unsigned Dim>
2120  throw OpalException("PartBunchBase<T, Dim>::runTests() ", "No test supported.");
2121 }
2122 
2123 
2124 template <class T, unsigned Dim>
2126 
2127 }
2128 
2129 template <class T, unsigned Dim>
2130 void PartBunchBase<T, Dim>::swap(unsigned int i, unsigned int j) {
2131  if (i >= getLocalNum() || j >= getLocalNum() || i == j) return;
2132 
2133  std::swap(R[i], R[j]);
2134  std::swap(P[i], P[j]);
2135  std::swap(Q[i], Q[j]);
2136  std::swap(M[i], M[j]);
2137  std::swap(Phi[i], Phi[j]);
2138  std::swap(Ef[i], Ef[j]);
2139  std::swap(Eftmp[i], Eftmp[j]);
2140  std::swap(Bf[i], Bf[j]);
2141  std::swap(Bin[i], Bin[j]);
2142  std::swap(dt[i], dt[j]);
2143  std::swap(PType[i], PType[j]);
2144  std::swap(TriID[i], TriID[j]);
2145  std::swap(cavityGapCrossed[i], cavityGapCrossed[j]);
2146  std::swap(bunchNum[i], bunchNum[j]);
2147 }
2148 
2149 
2150 template <class T, unsigned Dim>
2152  throw OpalException("PartBunchBase<T, Dim>::setBCAllPeriodic() ", "Not supported BC.");
2153 }
2154 
2155 
2156 template <class T, unsigned Dim>
2158  throw OpalException("PartBunchBase<T, Dim>::setBCAllOpen() ", "Not supported BC.");
2159 }
2160 
2161 
2162 template <class T, unsigned Dim>
2164  throw OpalException("PartBunchBase<T, Dim>::setBCForDCBeam() ", "Not supported BC.");
2165 }
2166 
2167 
2168 template <class T, unsigned Dim>
2170 {
2171 
2172 }
2173 
2174 
2175 template <class T, unsigned Dim>
2177  pb->addAttribute(P);
2178  pb->addAttribute(Q);
2179  pb->addAttribute(M);
2180  pb->addAttribute(Phi);
2181  pb->addAttribute(Ef);
2182  pb->addAttribute(Eftmp);
2183 
2184  pb->addAttribute(Bf);
2185  pb->addAttribute(Bin);
2186  pb->addAttribute(dt);
2187  pb->addAttribute(PType);
2188  pb->addAttribute(TriID);
2189  pb->addAttribute(cavityGapCrossed);
2190 
2191  pb->addAttribute(bunchNum);
2192 
2193  boundpTimer_m = IpplTimings::getTimer("Boundingbox");
2194  boundpBoundsTimer_m = IpplTimings::getTimer("Boundingbox-bounds");
2195  boundpUpdateTimer_m = IpplTimings::getTimer("Boundingbox-update");
2196  statParamTimer_m = IpplTimings::getTimer("Compute Statistics");
2197  selfFieldTimer_m = IpplTimings::getTimer("SelfField total");
2198 
2199  histoTimer_m = IpplTimings::getTimer("Histogram");
2200 
2201  distrCreate_m = IpplTimings::getTimer("Create Distr");
2202  distrReload_m = IpplTimings::getTimer("Load Distr");
2203 
2204 
2205  globalPartPerNode_m = std::unique_ptr<size_t[]>(new size_t[Ippl::getNodes()]);
2206 
2207  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(std::string("GlobalLosses"), !Options::asciidump));
2208 
2209  pmsg_m.release();
2210  // f_stream.release();
2211  /*
2212  if(Ippl::getNodes() == 1) {
2213  f_stream = std::unique_ptr<ofstream>(new ofstream);
2214  f_stream->open("data/dist.dat", ios::out);
2215  pmsg_m = std::unique_ptr<Inform>(new Inform(0, *f_stream, 0));
2216  }
2217  */
2218 
2219  // set the default IPPL behaviour
2220  setMinimumNumberOfParticlesPerCore(0);
2221 }
2222 
2223 
2224 template <class T, unsigned Dim>
2226  return pbase->getTotalNum();
2227 }
2228 
2229 template <class T, unsigned Dim>
2231  return pbase->getLocalNum();
2232 }
2233 
2234 
2235 template <class T, unsigned Dim>
2237  return pbase->getDestroyNum();
2238 }
2239 
2240 template <class T, unsigned Dim>
2242  return pbase->getGhostNum();
2243 }
2244 
2245 template <class T, unsigned Dim>
2247  pbase->setTotalNum(n);
2248 }
2249 
2250 template <class T, unsigned Dim>
2252  pbase->setLocalNum(n);
2253 }
2254 
2255 template <class T, unsigned Dim>
2257  return pbase->getMinimumNumberOfParticlesPerCore();
2258 }
2259 
2260 template <class T, unsigned Dim>
2262  pbase->setMinimumNumberOfParticlesPerCore(n);
2263 }
2264 
2265 template <class T, unsigned Dim>
2267  return pbase->getLayout();
2268 }
2269 
2270 template <class T, unsigned Dim>
2272  return pbase->getLayout();
2273 }
2274 
2275 template <class T, unsigned Dim>
2277  return pbase->getUpdateFlag(f);
2278 }
2279 
2280 template <class T, unsigned Dim>
2282  pbase->setUpdateFlag(f, val);
2283 }
2284 
2285 template <class T, unsigned Dim>
2287  return pbase->singleInitNode();
2288 }
2289 
2290 template <class T, unsigned Dim>
2292  pbase->resetID();
2293 }
2294 
2295 template <class T, unsigned Dim>
2297  try {
2298  pbase->update();
2299  } catch (const IpplException &ex) {
2300  throw OpalException(ex.where(), ex.what());
2301  }
2302 }
2303 
2304 template <class T, unsigned Dim>
2306  try {
2307  pbase->update(canSwap);
2308  } catch (const IpplException &ex) {
2309  throw OpalException(ex.where(), ex.what());
2310  }
2311 }
2312 
2313 template <class T, unsigned Dim>
2315  pbase->createWithID(id);
2316 }
2317 
2318 template <class T, unsigned Dim>
2320  pbase->create(M);
2321 }
2322 
2323 template <class T, unsigned Dim>
2325  pbase->globalCreate(np);
2326 }
2327 
2328 template <class T, unsigned Dim>
2329 void PartBunchBase<T, Dim>::destroy(size_t M, size_t I, bool doNow) {
2330  pbase->destroy(M, I, doNow);
2331 }
2332 
2333 template <class T, unsigned Dim>
2334 void PartBunchBase<T, Dim>::performDestroy(bool updateLocalNum) {
2335  pbase->performDestroy(updateLocalNum);
2336 }
2337 
2338 template <class T, unsigned Dim>
2339 void PartBunchBase<T, Dim>::ghostDestroy(size_t M, size_t I) {
2340  pbase->ghostDestroy(M, I);
2341 }
2342 
2343 template <class T, unsigned Dim>
2345  periodLength_m = Physics::c / f;
2346 }
2347 
2348 template <class T, unsigned Dim>
2350  //const double N = static_cast<double>(this->getTotalNum());
2351 
2352  Vektor<double, 2*Dim> rpmean;
2353  for (unsigned int i = 0; i < Dim; i++) {
2354  rpmean(2*i)= rmean_m(i);
2355  rpmean((2*i)+1)= pmean_m(i);
2356  }
2357 
2358  FMatrix<double, 2 * Dim, 2 * Dim> sigmaMatrix;// = moments_m / N;
2359  for (unsigned int i = 0; i < 2 * Dim; i++) {
2360  for (unsigned int j = 0; j <= i; j++) {
2361  sigmaMatrix[i][j] = moments_m(i, j) - rpmean(i) * rpmean(j);
2362  sigmaMatrix[j][i] = sigmaMatrix[i][j];
2363  }
2364  }
2365  return sigmaMatrix;
2366 }
2367 
2368 #endif
virtual void swap(unsigned int i, unsigned int j)
bool weHaveBins() const
double getWorkFunctionRf() const
Need the work function for the Schottky effect calculation (eV)
double & py()
Get reference to vertical momentum (no dimension).
Definition: OpalParticle.h:122
Vector_t get_rprms() const
virtual double getPy0(int i)
static int getNodes()
Definition: IpplInfo.cpp:773
double get_Dx() const
IpplTimings::TimerRef selfFieldTimer_m
timer for selfField calculation
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
double getT() const
double haloShift
The constant parameter C to shift halo, by &lt; w^4 &gt; / &lt; w^2 &gt; ^2 - C (w=x,y,z)
Definition: Options.cpp:110
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
void getLocalBounds(Vector_t &rmin, Vector_t &rmax)
IpplTimings::TimerRef distrCreate_m
double get_DDy() const
int getLastEmittedEnergyBin()
constexpr double e
The value of .
Definition: Physics.h:40
void destroy(size_t M, size_t I, bool doNow=false)
void setMinimumNumberOfParticlesPerCore(unsigned int n)
double calcMeanPhi()
calculate average angle of longitudinal direction of bins
Definition: TSVMeta.h:24
std::string getFieldSolverType() const
Return the fieldsolver type if we have a fieldsolver.
void setPType(ParticleType::type)
void create(size_t M)
long long getLocalTrackStep() const
ParticleType::type getPType() const
#define INFORM_ALL_NODES
Definition: Inform.h:38
bool resetPartBinBunch()
void gatherLoadBalanceStatistics()
The FieldSolver definition.
Definition: FieldSolver.h:43
unsigned int getMinimumNumberOfParticlesPerCore() const
void setLocalNum(size_t n)
virtual void set_meshEnlargement(double dh)
void setLocalNumPerBunch(size_t numpart, short n)
void setGlobalMeanR(Vector_t globalMeanR)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
virtual void actT()
The base class for all OPAL exceptions.
Definition: OpalException.h:28
void setDistribution(Distribution *d, std::vector< Distribution * > addedDistributions, size_t &np)
double & x()
Get reference to horizontal position in m.
Definition: OpalParticle.h:110
void setGlobalToLocalQuaternion(Quaternion_t globalToLocalQuaternion)
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
constexpr double two_pi
The value of .
Definition: Physics.h:34
PETE_TBTree< OpEQ, Index::PETE_Expr_t, PETE_Scalar< double > > eq(const Index &idx, double x)
Definition: IndexInlines.h:356
Vector_t get_rrms() const
virtual void updateFields(const Vector_t &hr, const Vector_t &origin)
int getNumberOfEnergyBins()
Particle reference data.
Definition: PartData.h:38
double getCouplingConstant() const
double getdT() const
Inform * gmsg
Definition: Main.cpp:21
virtual void do_binaryRepart()
double getM() const
const PartData * getReference() const
double get_meanKineticEnergy() const
virtual void setBCForDCBeam()
void setLocalTrackStep(long long n)
step in a TRACK command
static int myNode()
Definition: IpplInfo.cpp:794
void calcMomentsInitial()
FRONT * fs
Definition: hypervolume.cpp:59
void push_back(OpalParticle p)
Vector_t get_pmean_Distribution() const
void setdT(double dt)
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
Definition: IndexInlines.h:357
virtual double getY(int i)
Vector_t get_emit() const
void resetQ(double q)
std::string getLengthString(double spos, unsigned int precision=3)
Definition: Util.h:63
void resetM(double m)
void setTotalNumPerBunch(size_t numpart, short n)
double getE() const
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1213
size_t getGhostNum() const
FMatrix< double, 2 *Dim, 2 *Dim > getSigmaMatrix()
size_t getTotalNum() const
virtual void resetInterpolationCache(bool clearCache=false)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
Vector_t get_prms() const
virtual void setBCAllOpen()
virtual const std::string & where() const
Definition: IpplException.h:19
double getP() const
void calcGammas_cycl()
double getInitialBeta() const
std::string getChargeString(double charge, unsigned int precision=3)
Definition: Util.h:136
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
void ghostDestroy(size_t M, size_t I)
#define PAssert_LT(a, b)
Definition: PAssert.h:121
std::unique_ptr< size_t[]> globalPartPerNode_m
void set_sPos(double s)
void bounds(const PETE_Expr< T1 > &expr, Vektor< T2, D > &minval, Vektor< T2, D > &maxval)
IpplTimings::TimerRef distrReload_m
timer for IC, can not be in Distribution.h
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
Vector_t get_rmean() const
static OpalData * getInstance()
Definition: OpalData.cpp:209
void setCouplingConstant(double c)
void calcBeamParameters()
virtual double getPy(int i)
virtual double getGamma(int i)
Vector_t get_pmean() const
Vector_t get_maxExtent() const
Class: DataSink.
Definition: OpalData.h:29
Vector_t get_halo() const
ParticleLayout< T, Dim > & getLayout()
PartBunchBase(AbstractParticle< T, Dim > *pb)
FmtFlags_t flags() const
Definition: Inform.h:109
constexpr double pi
The value of .
Definition: Physics.h:31
IpplTimings::TimerRef boundpTimer_m
void gather(const T *input, T *output, int count, int root=0)
Definition: GlobalComm.hpp:449
bool singleInitNode() const
void setUpdateFlag(UpdateFlags_t f, bool val)
void countTotalNumPerBunch()
IpplTimings::TimerRef boundpBoundsTimer_m
OpalParticle get_part(int ii)
virtual double getBeta(int i)
double remotePartDel
Definition: Options.cpp:22
bool getIfBeamEmitting()
std::string getTimeString(double time, unsigned int precision=3)
Definition: Util.h:40
Quaternion_t getGlobalToLocalQuaternion()
void allreduce(const T *input, T *output, int count, Op op)
Definition: GlobalComm.hpp:510
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
void setEnergyBins(int numberOfEnergyBins)
size_t getTotalNumPerBunch(short n) const
void setStepsPerTurn(int n)
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
void get_PBounds(Vector_t &min, Vector_t &max) const
double getChargePerParticle() const
get the macro particle charge
virtual void addAttribute(ParticleAttribBase &pa)=0
double get_Dy() const
void setTEmission(double t)
virtual double getY0(int i)
std::unique_ptr< Inform > pmsg_m
#define INFOMSG(msg)
Definition: IpplInfo.h:397
double getTEmission()
size_t calcNumPartsOutside(Vector_t x)
returns the number of particles outside of a box defined by x
PETE_TTTree< OpWhere, typename Cond_t::PETE_Expr_t, typename True_t::PETE_Expr_t, PETE_Scalar< Vektor< T, Dim > > > where(const PETE_Expr< Cond_t > &c, const PETE_Expr< True_t > &t, const Vektor< T, Dim > &f)
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Vector_t get_norm_emit() const
#define WARNMSG(msg)
Definition: IpplInfo.h:398
void switchToUnitlessPositions(bool use_dt_per_particle=false)
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
double getInitialGamma() const
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
void setMass(double mass)
void setTotalNum(size_t n)
Vector_t get_origin() const
double get_DDx() const
void maximumAmplitudes(const FMatrix< double, 6, 6 > &D, double &axmax, double &aymax)
Return maximum amplitudes.
size_t getLocalNum() const
Vector_t get_centroid() const
void set_part(FVector< double, 6 > z, int ii)
double & pt()
Get reference to relative momentum error (no dimension).
Definition: OpalParticle.h:125
virtual double getPx0(int i)
size_t getLocalNumPerBunch(short n) const
Inform & print(Inform &os)
IpplTimings::TimerRef histoTimer_m
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
double getCharge() const
get the total charge per simulation particle
void setLocalBinCount(size_t num, int bin)
size_t boundp_destroyT()
short getNumBunch() const
void performDestroy(bool updateLocalNum=false)
IpplTimings::TimerRef boundpUpdateTimer_m
bool resetPartBinID2(const double eta)
reset Bin[] for each particle according to the method given in paper PAST-AB(064402) by G...
bool asciidump
Definition: Options.cpp:18
std::pair< Vector_t, double > getLocalBoundingSphere()
virtual double getPz(int i)
double get_gamma() const
void createWithID(unsigned id)
void setCharge(double q)
void globalCreate(size_t np)
virtual double getX0(int i)
virtual Vector_t get_hr() const
bool weHaveEnergyBins()
void setNumBunch(short n)
double getBinGamma(int bin)
Get gamma of one bin.
void setT(double t)
double getQ() const
Access to reference data.
size_t getLoadBalance(int p) const
double & y()
Get reference to vertical displacement in m.
Definition: OpalParticle.h:113
size_t getDestroyNum() const
size_t getNumberOfEmissionSteps()
size_t calcMoments()
std::unique_ptr< LossDataSink > lossDs_m
virtual void setBCAllPeriodic()
std::ios_base::fmtflags FmtFlags_t
Definition: Inform.h:101
virtual void boundp()
void calcGammas()
Compute the gammas of all bins.
virtual const char * what() const
Definition: IpplException.h:15
virtual void setBinCharge(int bin, double q)
Set the charge of one bin to the value of q and all other to zero.
virtual double getZ(int i)
double & t()
Get reference to longitudinal displacement c*t in m.
Definition: OpalParticle.h:116
std::pair< Vector_t, double > getBoundingSphere()
virtual void setSolver(FieldSolver *fs)
void iterateEmittedBin(int binNumber)
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
double & px()
Get reference to horizontal momentum (no dimension).
Definition: OpalParticle.h:119
const PartData * reference
void setBeamFrequency(double v)
const unsigned Dim
double getEmissionDeltaT()
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
IpplTimings::TimerRef statParamTimer_m
double getLaserEnergy() const
Need the laser energy for the Schottky effect calculation (eV)
void get_bounds(Vector_t &rmin, Vector_t &rmax)
virtual void setZ(int i, double zcoo)
virtual double getX(int i)
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
virtual double getPx(int i)
int getStepsPerTurn() const
void calcBeamParametersInitial()
Definition: Inform.h:41
OpalParticle position.
Definition: OpalParticle.h:38
Inform & level1(Inform &inf)
Definition: Inform.cpp:45
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
Definition: Util.h:113
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
bool getUpdateFlag(UpdateFlags_t f) const
void createOpalT(PartBunchBase< double, 3 > *beam, std::vector< Distribution * > addedDistributions, size_t &numberOfParticles)
virtual void runTests()
void setChargeZeroPart(double q)
void calcLineDensity(unsigned int nBins, std::vector< double > &lineDensity, std::pair< double, double > &meshInfo)
calculates the 1d line density (not normalized) and append it to a file.
double getEkin() const
Need Ek for the Schottky effect calculation (eV)
void setPBins(PartBins *pbin)
void setup(AbstractParticle< T, Dim > *pb)
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:816
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Vector_t getGlobalMeanR()
void setGlobalTrackStep(long long n)
step in multiple TRACK commands
double calculateAngle(double x, double y)
angle range [0~2PI) degree
void setSteptoLastInj(int n)
size_t emitParticles(double eZ)
Emit particles in the given bin i.e. copy the particles from the bin structure into the particle cont...
long long getGlobalTrackStep() const
void correctEnergy(double avrgp)