OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
.PartBunchBase.hpp
Go to the documentation of this file.
1//
2// Class PartBunch
3// Base class for representing particle bunches.
4//
5// Copyright (c) 2008 - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
6// All rights reserved
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
18#ifndef PART_BUNCH_BASE_HPP
19#define PART_BUNCH_BASE_HPP
20
22#include "Algorithms/PartBins.h"
23#include "Algorithms/PartData.h"
26#include "Physics/Physics.h"
27#include "Structure/FieldSolver.h"
30#include "Utilities/Options.h"
31#include "Utilities/Util.h"
32
33#include <cmath>
34#include <numeric>
35
36extern Inform* gmsg;
37
38template <class T, unsigned Dim>
39PartBunch<T, Dim>::PartBunch(AbstractParticle<T, Dim>* pb, const PartData* ref)
40 : R(*(pb->R_p)),
41 ID(*(pb->ID_p)),
42 pbin_m(nullptr),
43 pmsg_m(nullptr),
44 f_stream(nullptr),
45 fixed_grid(false),
46 reference(ref),
47 unit_state_(units),
48 stateOfLastBoundP_(unitless),
49 moments_m(),
50 dt_m(0.0),
51 t_m(0.0),
52 spos_m(0.0),
53 globalMeanR_m(Vector_t<double, 3>(0.0, 0.0, 0.0)),
54 globalToLocalQuaternion_m(Quaternion_t(1.0, 0.0, 0.0, 0.0)),
55 rmax_m(0.0),
56 rmin_m(0.0),
57 hr_m(-1.0),
58 nr_m(0),
59 fs_m(nullptr),
61 qi_m(0.0),
63 distDump_m(0),
64 dh_m(1e-12),
65 bingamma_m(nullptr),
66 binemitted_m(nullptr),
70 numBunch_m(1),
74 globalPartPerNode_m(nullptr),
75 dist_m(nullptr),
76 dcBeam_m(false),
77 periodLength_m(Physics::c / 1e9),
78 pbase_m(pb)
79{
80 setup(pb);
81}
82
83/*
84 * Bunch common member functions
85 */
86
87template <class T, unsigned Dim>
88void PartBunch<T, Dim>::switchToUnitlessPositions(bool use_dt_per_particle) {
89
90 bool hasToReset = false;
91 if (!R.isDirty()) hasToReset = true;
92
93 for (size_t i = 0; i < getLocalNum(); i++) {
94 double dt = getdT();
95 if (use_dt_per_particle)
96 dt = this->dt[i];
97
98 R[i] /= Vector_t<double, 3>(Physics::c * dt);
99 }
100
101 unit_state_ = unitless;
102
103 if (hasToReset) R.resetDirtyFlag();
104}
105
106//FIXME: unify methods, use convention that all particles have own dt
107template <class T, unsigned Dim>
108void PartBunch<T, Dim>::switchOffUnitlessPositions(bool use_dt_per_particle) {
109
110 bool hasToReset = false;
111 if (!R.isDirty()) hasToReset = true;
112
113 for (size_t i = 0; i < getLocalNum(); i++) {
114 double dt = getdT();
115 if (use_dt_per_particle)
116 dt = this->dt[i];
117
118 R[i] *= Vector_t<double, 3>(Physics::c * dt);
119 }
120
121 unit_state_ = units;
122
123 if (hasToReset) R.resetDirtyFlag();
124}
125
126
127template <class T, unsigned Dim>
129
130}
131
132template <class T, unsigned Dim>
134 std::vector<Distribution*> addedDistributions,
135 size_t& np) {
136 Inform m("setDistribution " );
137 dist_m = d;
138 dist_m->createOpalT(this, addedDistributions, np);
139}
140
141template <class T, unsigned Dim>
143 return fixed_grid;
144}
145
146
147template <class T, unsigned Dim>
149 return (pbin_m != nullptr);
150}
151
152
153template <class T, unsigned Dim>
155 size_t numParticles = getLocalNum();
156 reduce(numParticles, numParticles, OpAddAssign());
157 setTotalNum(numParticles);
158}
159
160
161template <class T, unsigned Dim>
163 this->Bin = 0;
164 pbin_m->resetBins();
165 // delete pbin_m; we did not allocate it!
166 pbin_m = nullptr;
167}
168
169
170template <class T, unsigned Dim>
172 if (pbin_m != nullptr)
173 return pbin_m->getLastemittedBin();
174 else
175 return 0;
176}
177
178template <class T, unsigned Dim>
180 return 0;
181}
182
183template <class T, unsigned Dim>
184size_t PartBunch<T, Dim>::emitParticles(double eZ) {
185 return 0;
186}
187
188template <class T, unsigned Dim>
190 return 0.;
191}
192
193
194template <class T, unsigned Dim>
195double PartBunch<T, Dim>::getBinGamma(int bin) {
196 return 1.0;
197}
198
199template <class T, unsigned Dim>
201
202}
203
204template <class T, unsigned Dim>
206
207}
208
209template <class T, unsigned Dim>
211 return false;
212}
213
214template <class T, unsigned Dim>
215void PartBunch<T, Dim>::setLocalBinCount(size_t num, int bin) {
216 if (pbin_m != nullptr) {
217 pbin_m->setPartNum(bin, num);
218 }
219}
220
221
222template <class T, unsigned Dim>
223void PartBunch<T, Dim>::setBinCharge(int bin, double q) {
224 this->Q = where(eq(this->Bin, bin), q, 0.0);
225}
226
227
228template <class T, unsigned Dim>
230 this->Q = where(eq(this->Bin, bin), this->qi_m, 0.0);
231}
232
233
234template <class T, unsigned Dim>
236
237 std::size_t localnum = 0;
238 const Vector_t<double, 3> meanR = get_rmean();
239
240 for (unsigned long k = 0; k < getLocalNum(); ++ k)
241 if (std::abs(R[k](0) - meanR(0)) > x(0) ||
242 std::abs(R[k](1) - meanR(1)) > x(1) ||
243 std::abs(R[k](2) - meanR(2)) > x(2)) {
244
245 ++localnum;
246 }
247
248 gather(&localnum, &globalPartPerNode_m[0], 1);
249
250 size_t npOutside = std::accumulate(globalPartPerNode_m.get(),
251 globalPartPerNode_m.get() + Ippl::getNodes(), 0,
252 std::plus<size_t>());
253
254 return npOutside;
255}
256
257
267template <class T, unsigned Dim>
268void PartBunch<T, Dim>::calcLineDensity(unsigned int nBins,
269 std::vector<double>& lineDensity,
270 std::pair<double, double>& meshInfo) {
271 Vector_t<double, 3> rmin, rmax;
272 get_bounds(rmin, rmax);
273
274 if (nBins < 2) {
275 Vektor<int, 3>/*NDIndex<3>*/ grid;
276 this->updateDomainLength(grid);
277 nBins = grid[2];
278 }
279
280 double length = rmax(2) - rmin(2);
281 double zmin = rmin(2) - dh_m * length, zmax = rmax(2) + dh_m * length;
282 double hz = (zmax - zmin) / (nBins - 2);
283 double perMeter = 1.0 / hz;//(zmax - zmin);
284 zmin -= hz;
285
286 lineDensity.resize(nBins, 0.0);
287 std::fill(lineDensity.begin(), lineDensity.end(), 0.0);
288
289 const unsigned int lN = getLocalNum();
290 for (unsigned int i = 0; i < lN; ++ i) {
291 const double z = R[i](2) - 0.5 * hz;
292 unsigned int idx = (z - zmin) / hz;
293 double tau = (z - zmin) / hz - idx;
294
295 lineDensity[idx] += Q[i] * (1.0 - tau) * perMeter;
296 lineDensity[idx + 1] += Q[i] * tau * perMeter;
297 }
298
299 reduce(&(lineDensity[0]), &(lineDensity[0]) + nBins, &(lineDensity[0]), OpAddAssign());
300
301 meshInfo.first = zmin;
302 meshInfo.second = hz;
303}
304
305
306template <class T, unsigned Dim>
308 /*
309 Assume rmin_m < 0.0
310 */
311
312 IpplTimings::startTimer(boundpTimer_m);
313 //if (!R.isDirty() && stateOfLastBoundP_ == unit_state_) return;
314 if ( !(R.isDirty() || ID.isDirty() ) && stateOfLastBoundP_ == unit_state_) return; //-DW
315
316 stateOfLastBoundP_ = unit_state_;
317
318 if (!isGridFixed()) {
319 const int dimIdx = (dcBeam_m? 2: 3);
320
326
327 this->updateDomainLength(nr_m);
328 IpplTimings::startTimer(boundpBoundsTimer_m);
329 get_bounds(rmin_m, rmax_m);
330 IpplTimings::stopTimer(boundpBoundsTimer_m);
331 Vector_t<double, 3> len = rmax_m - rmin_m;
332
333 double volume = 1.0;
334 for (int i = 0; i < dimIdx; i++) {
335 double length = std::abs(rmax_m[i] - rmin_m[i]);
336 if (length < 1e-10) {
337 rmax_m[i] += 1e-10;
338 rmin_m[i] -= 1e-10;
339 } else {
340 rmax_m[i] += dh_m * length;
341 rmin_m[i] -= dh_m * length;
342 }
343 hr_m[i] = (rmax_m[i] - rmin_m[i]) / (nr_m[i] - 1);
344 }
345 if (dcBeam_m) {
346 rmax_m[2] = rmin_m[2] + periodLength_m;
347 hr_m[2] = periodLength_m / (nr_m[2] - 1);
348 }
349 for (int i = 0; i < dimIdx; ++ i) {
350 volume *= std::abs(rmax_m[i] - rmin_m[i]);
351 }
352
353 if (volume < 1e-21 && getTotalNum() > 1 && std::abs(sum(Q)) > 0.0) {
354 WARNMSG(level1 << "!!! Extremely high particle density detected !!!" << endl);
355 }
356 //*ippl::Info << "It is a full boundp hz= " << hr_m << " rmax= " << rmax_m << " rmin= " << rmin_m << endl);
357
358 if (hr_m[0] * hr_m[1] * hr_m[2] <= 0) {
359 throw GeneralClassicException("boundp() ", "h<0, can not build a mesh");
360 }
361
362 Vector_t<double, 3> origin = rmin_m - Vector_t<double, 3>(hr_m[0] / 2.0, hr_m[1] / 2.0, hr_m[2] / 2.0);
363 this->updateFields(hr_m, origin);
364 }
365 IpplTimings::startTimer(boundpUpdateTimer_m);
366 update();
367 IpplTimings::stopTimer(boundpUpdateTimer_m);
368 R.resetDirtyFlag();
369
370 IpplTimings::stopTimer(boundpTimer_m);
371}
372
373
374template <class T, unsigned Dim>
376
377 this->updateDomainLength(nr_m);
378
379 std::vector<size_t> tmpbinemitted;
380
381 boundp();
382
383 size_t ne = 0;
384 const size_t localNum = getLocalNum();
385
386 double rzmean = 0.0; //momentsComputer_m.getMeanPosition()(2);
387 double rzrms = 0.0; //momentsComputer_m.getStandardDeviationPosition()(2);
388 const bool haveEnergyBins = weHaveEnergyBins();
389 if (haveEnergyBins) {
390 tmpbinemitted.resize(getNumberOfEnergyBins(), 0.0);
391 }
392 for (unsigned int i = 0; i < localNum; i++) {
393 if (Bin[i] < 0 || (Options::remotePartDel > 0 && std::abs(R[i](2) - rzmean) < Options::remotePartDel * rzrms)) {
394 ne++;
395 destroy(1, i);
396 } else if (haveEnergyBins) {
397 tmpbinemitted[Bin[i]]++;
398 }
399 }
400
401 boundp();
402
403 calcBeamParameters();
404 gatherLoadBalanceStatistics();
405
406 reduce(ne, ne, OpAddAssign());
407 return ne;
408}
409
410
411template <class T, unsigned Dim>
413
414 std::unique_ptr<size_t[]> tmpbinemitted;
415
416 const size_t localNum = getLocalNum();
417 const size_t totalNum = getTotalNum();
418 size_t ne = 0;
419
420 if (weHaveEnergyBins()) {
421 tmpbinemitted = std::unique_ptr<size_t[]>(new size_t[getNumberOfEnergyBins()]);
422 for (int i = 0; i < getNumberOfEnergyBins(); i++) {
423 tmpbinemitted[i] = 0;
424 }
425 for (unsigned int i = 0; i < localNum; i++) {
426 if (Bin[i] < 0) {
427 destroy(1, i);
428 ++ ne;
429 } else
430 tmpbinemitted[Bin[i]]++;
431 }
432 } else {
433 Inform dmsg("destroy: ", INFORM_ALL_NODES);
434 for (size_t i = 0; i < localNum; i++) {
435 if ((Bin[i] < 0)) {
436 ne++;
437 destroy(1, i);
438 }
439 }
440 }
441
442 if (ne > 0) {
443 performDestroy(true);
444 }
445
446 calcBeamParameters();
447 gatherLoadBalanceStatistics();
448
449 size_t newTotalNum = getLocalNum();
450 reduce(newTotalNum, newTotalNum, OpAddAssign());
451
452 setTotalNum(newTotalNum);
453
454 return totalNum - newTotalNum;
455}
456
457
458template <class T, unsigned Dim>
459double PartBunch<T, Dim>::getPx(int /*i*/) {
460 return 0.0;
461}
462
463template <class T, unsigned Dim>
464double PartBunch<T, Dim>::getPy(int) {
465 return 0.0;
466}
467
468template <class T, unsigned Dim>
469double PartBunch<T, Dim>::getPz(int) {
470 return 0.0;
471}
472
473template <class T, unsigned Dim>
474double PartBunch<T, Dim>::getPx0(int) {
475 return 0.0;
476}
477
478template <class T, unsigned Dim>
479double PartBunch<T, Dim>::getPy0(int) {
480 return 0;
481}
482
483//ff
484template <class T, unsigned Dim>
485double PartBunch<T, Dim>::getX(int i) {
486 return this->R[i](0);
487}
488
489//ff
490template <class T, unsigned Dim>
491double PartBunch<T, Dim>::getY(int i) {
492 return this->R[i](1);
493}
494
495//ff
496template <class T, unsigned Dim>
497double PartBunch<T, Dim>::getZ(int i) {
498 return this->R[i](2);
499}
500
501//ff
502template <class T, unsigned Dim>
503double PartBunch<T, Dim>::getX0(int /*i*/) {
504 return 0.0;
505}
506
507//ff
508template <class T, unsigned Dim>
509double PartBunch<T, Dim>::getY0(int /*i*/) {
510 return 0.0;
511}
512
513
514template <class T, unsigned Dim>
515void PartBunch<T, Dim>::setZ(int /*i*/, double /*zcoo*/) {
516};
517
518
519template <class T, unsigned Dim>
521
522 this->getLocalBounds(rmin, rmax);
523
524 double min[2*Dim];
525
526 for (unsigned int i = 0; i < Dim; ++i) {
527 min[2*i] = rmin[i];
528 min[2*i + 1] = -rmax[i];
529 }
530
531 allreduce(min, 2*Dim, std::less<double>());
532
533 for (unsigned int i = 0; i < Dim; ++i) {
534 rmin[i] = min[2*i];
535 rmax[i] = -min[2*i + 1];
536 }
537}
538
539
540template <class T, unsigned Dim>
542 const size_t localNum = getLocalNum();
543 if (localNum == 0) {
544 double maxValue = 1e8;
545 rmin = Vector_t<double, 3>(maxValue, maxValue, maxValue);
546 rmax = Vector_t<double, 3>(-maxValue, -maxValue, -maxValue);
547 return;
548 }
549
550 rmin = R[0];
551 rmax = R[0];
552 for (size_t i = 1; i < localNum; ++ i) {
553 for (unsigned short d = 0; d < 3u; ++ d) {
554 if (rmin(d) > R[i](d)) rmin(d) = R[i](d);
555 else if (rmax(d) < R[i](d)) rmax(d) = R[i](d);
556 }
557 }
558}
559
560
561template <class T, unsigned Dim>
562std::pair<Vector_t<double, 3>, double> PartBunch<T, Dim>::getBoundingSphere() {
563 Vector_t<double, 3> rmin, rmax;
564 get_bounds(rmin, rmax);
565
566 std::pair<Vector_t<double, 3>, double> sphere;
567 sphere.first = 0.5 * (rmin + rmax);
568 sphere.second = std::sqrt(dot(rmax - sphere.first, rmax - sphere.first));
569
570 return sphere;
571}
572
573
574template <class T, unsigned Dim>
575std::pair<Vector_t<double, 3>, double> PartBunch<T, Dim>::getLocalBoundingSphere() {
576 Vector_t<double, 3> rmin, rmax;
577 getLocalBounds(rmin, rmax);
578
579 std::pair<Vector_t<double, 3>, double> sphere;
580 sphere.first = 0.5 * (rmin + rmax);
581 sphere.second = std::sqrt(dot(rmax - sphere.first, rmax - sphere.first));
582
583 return sphere;
584}
585
586
587template <class T, unsigned Dim>
588void PartBunch<T, Dim>::push_back(OpalParticle const& particle) {
589 Inform msg("PartBunch ");
590
591 size_t i = getLocalNum();
592 create(1);
593
594 R[i] = particle.getR();
595 P[i] = particle.getP();
596
597 update();
598 msg << "Created one particle i= " << i << endl;
599}
600
601
602
603template <class T, unsigned Dim>
604void PartBunch<T, Dim>::setdT(double dt) {
605 dt_m = dt;
606}
607
608
609template <class T, unsigned Dim>
610double PartBunch<T, Dim>::getdT() const {
611 return dt_m;
612}
613
614
615template <class T, unsigned Dim>
616void PartBunch<T, Dim>::setT(double t) {
617 t_m = t;
618}
619
620
621template <class T, unsigned Dim>
623 t_m += dt_m;
624}
625
626
627template <class T, unsigned Dim>
628double PartBunch<T, Dim>::getT() const {
629 return t_m;
630}
631
632
633template <class T, unsigned Dim>
634double PartBunch<T, Dim>::get_sPos() const {
635 return spos_m;
636}
637
638
639template <class T, unsigned Dim>
640void PartBunch<T, Dim>::set_sPos(double s) {
641 spos_m = s;
642}
643
644
645template <class T, unsigned Dim>
646double PartBunch<T, Dim>::get_gamma() const {
647 return 0.0;
648}
649
650
651template <class T, unsigned Dim>
653 return 0.0;
654}
655
656
657template <class T, unsigned Dim>
659 return rmin_m;
660}
661
662
663template <class T, unsigned Dim>
665 return rmax_m;
666}
667
668
669template <class T, unsigned Dim>
671 return 0.0;
672}
673
674
675template <class T, unsigned Dim>
677 return 0.0;
678}
679
680
681template <class T, unsigned Dim>
683 return 0.0;
684}
685
686
687template <class T, unsigned Dim>
689 return 0.0;
690}
691
692
693template <class T, unsigned Dim>
695 return 0.0;
696}
697
698
699template <class T, unsigned Dim>
701 return 0.0;
702}
703
704
705template <class T, unsigned Dim>
707 if (dist_m)// && dist_m->getType() != DistrTypeT::FROMFILE)
708 return dist_m->get_pmean();
709
710 double gamma = 0.1 / getM() + 1; // set default 0.1 eV
711 return Vector_t<double, 3>(0, 0, std::sqrt(std::pow(gamma, 2) - 1));
712}
713
714
715template <class T, unsigned Dim>
717 return 0.0;
718}
719
720
721template <class T, unsigned Dim>
723 return 0.0;
724}
725
726
727template <class T, unsigned Dim>
729 return 0.0;
730}
731
732template <class T, unsigned Dim>
734 return 0.0;
735}
736
737template <class T, unsigned Dim>
739 return 0.0;
740}
741
742template <class T, unsigned Dim>
744 return 0.0;
745}
746
747template <class T, unsigned Dim>
749 return 0.0;
750}
751
752template <class T, unsigned Dim>
754 return 0.0;
755}
756
757template <class T, unsigned Dim>
759 return 0.0;
760}
761
762template <class T, unsigned Dim>
764 return 0.0;
765}
766
767template <class T, unsigned Dim>
769 return 0.0;
770}
771
772template <class T, unsigned Dim>
773double PartBunch<T, Dim>::get_Dx() const {
774 return 0.0;
775}
776
777
778template <class T, unsigned Dim>
779double PartBunch<T, Dim>::get_Dy() const {
780 return 0.0;
781}
782
783
784template <class T, unsigned Dim>
785double PartBunch<T, Dim>::get_DDx() const {
786 return 0.0;
787}
788
789
790template <class T, unsigned Dim>
791double PartBunch<T, Dim>::get_DDy() const {
792 return 0.0;
793}
794
795
796template <class T, unsigned Dim>
798 return hr_m;
799}
800
801
802template <class T, unsigned Dim>
804 dh_m = dh;
805}
806
807
808template <class T, unsigned Dim>
810
811 for (int i = 0; i < Ippl::getNodes(); i++)
812 globalPartPerNode_m[i] = 0;
813
814 std::size_t localnum = getLocalNum();
815 gather(&localnum, &globalPartPerNode_m[0], 1);
816}
817
818
819template <class T, unsigned Dim>
820size_t PartBunch<T, Dim>::getLoadBalance(int p) const {
821 return globalPartPerNode_m[p];
822}
823
824
825template <class T, unsigned Dim>
827 bounds(this->P, min, max);
828}
829
830
831template <class T, unsigned Dim>
833
834 IpplTimings::startTimer(statParamTimer_m);
835 get_bounds(rmin_m, rmax_m);
836 // momentsComputer_m.compute(*this);
837 IpplTimings::stopTimer(statParamTimer_m);
838}
839
840template <class T, unsigned Dim>
842 return couplingConstant_m;
843}
844
845
846template <class T, unsigned Dim>
848 couplingConstant_m = c;
849}
850
851
852template <class T, unsigned Dim>
853void PartBunch<T, Dim>::setCharge(double q) {
854 qi_m = q;
855 if (getTotalNum() != 0)
856 Q = qi_m;
857 else
858 WARNMSG("Could not set total charge in PartBunch::setCharge based on getTotalNum" << endl);
859}
860
861
862template <class T, unsigned Dim>
864 qi_m = q;
865}
866
867
868template <class T, unsigned Dim>
869void PartBunch<T, Dim>::setMass(double mass) {
870 massPerParticle_m = mass;
871 if (getTotalNum() != 0)
872 M = mass;
873}
874
875template <class T, unsigned Dim>
876void PartBunch<T, Dim>::setMassZeroPart(double mass) {
877 massPerParticle_m = mass;
878}
879
880
881template <class T, unsigned Dim>
882double PartBunch<T, Dim>::getCharge() const {
883 return sum(Q);
884}
885
886
887template <class T, unsigned Dim>
889 return qi_m;
890}
891
892template <class T, unsigned Dim>
894 return massPerParticle_m;
895}
896
897template <class T, unsigned Dim>
899 fs_m = fs;
900 fs_m->initSolver(this);
901
906 if (!OpalData::getInstance()->hasBunchAllocated()) {
907 this->initialize(fs_m->getFieldLayout());
908// this->setMesh(fs_m->getMesh());
909// this->setFieldLayout(fs_m->getFieldLayout());
910 }
911}
912
913
914template <class T, unsigned Dim>
916 if (fs_m)
917 return fs_m->hasValidSolver();
918 else
919 return false;
920}
921
922
924template <class T, unsigned Dim>
925FieldSolverType PartBunch<T, Dim>::getFieldSolverType() const {
926 if (fs_m) {
927 return fs_m->getFieldSolverType();
928 } else {
929 return FieldSolverType::NONE;
930 }
931}
932
933
934template <class T, unsigned Dim>
936 stepsPerTurn_m = n;
937}
938
939
940template <class T, unsigned Dim>
942 return stepsPerTurn_m;
943}
944
945
946template <class T, unsigned Dim>
948 globalTrackStep_m = n;
949}
950
951
952template <class T, unsigned Dim>
954 return globalTrackStep_m;
955}
956
957
958template <class T, unsigned Dim>
959void PartBunch<T, Dim>::setLocalTrackStep(long long n) {
960 localTrackStep_m = n;
961}
962
963
964template <class T, unsigned Dim>
966 globalTrackStep_m++; localTrackStep_m++;
967}
968
969
970template <class T, unsigned Dim>
971long long PartBunch<T, Dim>::getLocalTrackStep() const {
972 return localTrackStep_m;
973}
974
975
976template <class T, unsigned Dim>
977void PartBunch<T, Dim>::setNumBunch(short n) {
978 numBunch_m = n;
979 bunchTotalNum_m.resize(n);
980 bunchLocalNum_m.resize(n);
981}
982
983
984template <class T, unsigned Dim>
985short PartBunch<T, Dim>::getNumBunch() const {
986 return numBunch_m;
987}
988
989
990template <class T, unsigned Dim>
992 globalMeanR_m = globalMeanR;
993}
994
995
996template <class T, unsigned Dim>
998 return globalMeanR_m;
999}
1000
1001
1002template <class T, unsigned Dim>
1003void PartBunch<T, Dim>::setGlobalToLocalQuaternion(Quaternion_t globalToLocalQuaternion) {
1004
1005 globalToLocalQuaternion_m = globalToLocalQuaternion;
1006}
1007
1008
1009template <class T, unsigned Dim>
1011 return globalToLocalQuaternion_m;
1012}
1013
1014
1015template <class T, unsigned Dim>
1017 SteptoLastInj_m = n;
1018}
1019
1020
1021template <class T, unsigned Dim>
1023 return SteptoLastInj_m;
1024}
1025
1026template <class T, unsigned Dim>
1027double PartBunch<T, Dim>::getQ() const {
1028 return reference->getQ();
1029}
1030
1031
1032template <class T, unsigned Dim>
1033double PartBunch<T, Dim>::getM() const {
1034 return reference->getM();
1035}
1036
1037
1038template <class T, unsigned Dim>
1039double PartBunch<T, Dim>::getP() const {
1040 return reference->getP();
1041}
1042
1043
1044template <class T, unsigned Dim>
1045double PartBunch<T, Dim>::getE() const {
1046 return reference->getE();
1047}
1048
1049
1050template <class T, unsigned Dim>
1052 return refPOrigin_m;
1053}
1054
1055template <class T, unsigned Dim>
1057 refPOrigin_m = origin;
1058}
1059
1060
1061template <class T, unsigned Dim>
1063 return refPType_m;
1064}
1065
1066template <class T, unsigned Dim>
1067void PartBunch<T, Dim>::setPType(const std::string& type) {
1068 refPType_m = ParticleProperties::getParticleType(type);
1069}
1070
1071
1072template <class T, unsigned Dim>
1074 return dist_m->getType();
1075}
1076
1077
1078template <class T, unsigned Dim>
1079void PartBunch<T, Dim>::resetQ(double q) {
1080 const_cast<PartData *>(reference)->setQ(q);
1081}
1082
1083
1084template <class T, unsigned Dim>
1085void PartBunch<T, Dim>::resetM(double m) {
1086 const_cast<PartData *>(reference)->setM(m);
1087}
1088
1089
1090template <class T, unsigned Dim>
1091double PartBunch<T, Dim>::getdE() const {
1092 return 0.0;
1093}
1094
1095
1096template <class T, unsigned Dim>
1097double PartBunch<T, Dim>::getInitialBeta() const {
1098 return reference->getBeta();
1099}
1100
1101
1102template <class T, unsigned Dim>
1104 return reference->getGamma();
1105}
1106
1107
1108template <class T, unsigned Dim>
1109double PartBunch<T, Dim>::getGamma(int /*i*/) {
1110 return 0;
1111}
1112
1113
1114template <class T, unsigned Dim>
1115double PartBunch<T, Dim>::getBeta(int /*i*/) {
1116 return 0;
1117}
1118
1119
1120template <class T, unsigned Dim>
1122 // do nothing here
1123};
1124
1125
1126template <class T, unsigned Dim>
1128 return reference;
1129}
1130
1131
1132
1133template <class T, unsigned Dim>
1135 //momentsComputer_m.computeMeanKineticEnergy(*this);
1136}
1137
1138template <class T, unsigned Dim>
1139Inform& PartBunch<T, Dim>::print(Inform& os) {
1140
1141 if (getTotalNum() != 0) { // to suppress Nans
1142 Inform::FmtFlags_t ff = os.flags();
1143
1144 double pathLength = get_sPos();
1145
1146 os << std::scientific;
1147 os << level1 << "\n";
1148 os << "* ************** B U N C H ********************************************************* \n";
1149 os << "* NP = " << getTotalNum() << "\n";
1150 os << "* Qtot = " << std::setw(17) << Util::getChargeString(std::abs(sum(Q))) << " "
1151 << "Qi = " << std::setw(17) << Util::getChargeString(std::abs(qi_m)) << "\n";
1152 os << "* Ekin = " << std::setw(17) << Util::getEnergyString(get_meanKineticEnergy()) << " "
1153 << "dEkin = " << std::setw(17) << Util::getEnergyString(getdE()) << "\n";
1154 os << "* rmax = " << Util::getLengthString(rmax_m, 5) << "\n";
1155 os << "* rmin = " << Util::getLengthString(rmin_m, 5) << "\n";
1156 if (getTotalNum() >= 2) { // to suppress Nans
1157 os << "* rms beam size = " << Util::getLengthString(get_rrms(), 5) << "\n";
1158 os << "* rms momenta = " << std::setw(12) << std::setprecision(5) << get_prms() << " [beta gamma]\n";
1159 os << "* mean position = " << Util::getLengthString(get_rmean(), 5) << "\n";
1160 os << "* mean momenta = " << std::setw(12) << std::setprecision(5) << get_pmean() << " [beta gamma]\n";
1161 os << "* rms emittance = " << std::setw(12) << std::setprecision(5) << get_emit() << " (not normalized)\n";
1162 os << "* rms correlation = " << std::setw(12) << std::setprecision(5) << get_rprms() << "\n";
1163 }
1164 os << "* hr = " << Util::getLengthString(get_hr(), 5) << "\n";
1165 os << "* dh = " << std::setw(13) << std::setprecision(5) << dh_m * 100 << " [%]\n";
1166 os << "* t = " << std::setw(17) << Util::getTimeString(getT()) << " "
1167 << "dT = " << std::setw(17) << Util::getTimeString(getdT()) << "\n";
1168 os << "* spos = " << std::setw(17) << Util::getLengthString(pathLength) << "\n";
1169 os << "* ********************************************************************************** " << endl;
1170 os.flags(ff);
1171 }
1172 return os;
1173}
1174
1175// angle range [0~2PI) degree
1176template <class T, unsigned Dim>
1177double PartBunch<T, Dim>::calculateAngle(double x, double y) {
1178 double thetaXY = atan2(y, x);
1179
1180 return thetaXY >= 0 ? thetaXY : thetaXY + Physics::two_pi;
1181}
1182
1183
1184template <class T, unsigned Dim>
1185Inform& operator<<(Inform &os, PartBunch<T, Dim>& p) {
1186 return p.print(os);
1187}
1188
1189
1190/*
1191 * Virtual member functions
1192 */
1193
1194template <class T, unsigned Dim>
1196 throw OpalException("PartBunch<T, Dim>::runTests() ", "No test supported.");
1197}
1198
1199
1200template <class T, unsigned Dim>
1201void PartBunch<T, Dim>::resetInterpolationCache(bool /*clearCache*/) {
1202
1203}
1204
1205template <class T, unsigned Dim>
1206void PartBunch<T, Dim>::swap(unsigned int i, unsigned int j) {
1207 if (i >= getLocalNum() || j >= getLocalNum() || i == j) return;
1208
1209 std::swap(R[i], R[j]);
1210 std::swap(P[i], P[j]);
1211 std::swap(Q[i], Q[j]);
1212 std::swap(M[i], M[j]);
1213 std::swap(Phi[i], Phi[j]);
1214 std::swap(Ef[i], Ef[j]);
1215 std::swap(Eftmp[i], Eftmp[j]);
1216 std::swap(Bf[i], Bf[j]);
1217 std::swap(Bin[i], Bin[j]);
1218 std::swap(dt[i], dt[j]);
1219 std::swap(PType[i], PType[j]);
1220 std::swap(POrigin[i], POrigin[j]);
1221 std::swap(TriID[i], TriID[j]);
1222 std::swap(cavityGapCrossed[i], cavityGapCrossed[j]);
1223 std::swap(bunchNum[i], bunchNum[j]);
1224}
1225
1226
1227template <class T, unsigned Dim>
1229 throw OpalException("PartBunch<T, Dim>::setBCAllPeriodic() ", "Not supported BC.");
1230}
1231
1232
1233template <class T, unsigned Dim>
1235 throw OpalException("PartBunch<T, Dim>::setBCAllOpen() ", "Not supported BC.");
1236}
1237
1238
1239template <class T, unsigned Dim>
1241 throw OpalException("PartBunch<T, Dim>::setBCForDCBeam() ", "Not supported BC.");
1242}
1243
1244
1245template <class T, unsigned Dim>
1246void PartBunch<T, Dim>::updateFields(const Vector_t<double, 3>& /*hr*/, const Vector_t<double, 3>& /*origin*/) {
1247}
1248
1249
1250template <class T, unsigned Dim>
1251void PartBunch<T, Dim>::setup(AbstractParticle<T, Dim>* pb) {
1252
1253 pb->addAttribute(P);
1254 pb->addAttribute(Q);
1255 pb->addAttribute(M);
1256 pb->addAttribute(Phi);
1257 pb->addAttribute(Ef);
1258 pb->addAttribute(Eftmp);
1259 pb->addAttribute(Bf);
1260 pb->addAttribute(Bin);
1261 pb->addAttribute(dt);
1262 pb->addAttribute(PType);
1263 pb->addAttribute(POrigin);
1264 pb->addAttribute(TriID);
1265 pb->addAttribute(cavityGapCrossed);
1266 pb->addAttribute(bunchNum);
1267
1268 boundpTimer_m = IpplTimings::getTimer("Boundingbox");
1269 boundpBoundsTimer_m = IpplTimings::getTimer("Boundingbox-bounds");
1270 boundpUpdateTimer_m = IpplTimings::getTimer("Boundingbox-update");
1271 statParamTimer_m = IpplTimings::getTimer("Compute Statistics");
1272 selfFieldTimer_m = IpplTimings::getTimer("SelfField total");
1273
1274 histoTimer_m = IpplTimings::getTimer("Histogram");
1275
1276 distrCreate_m = IpplTimings::getTimer("Create Distr");
1277 distrReload_m = IpplTimings::getTimer("Load Distr");
1278
1279 globalPartPerNode_m = std::unique_ptr<size_t[]>(new size_t[Ippl::getNodes()]);
1280
1281 pmsg_m.release();
1282}
1283
1284
1285template <class T, unsigned Dim>
1287 return pbase_m->getTotalNum();
1288}
1289
1290template <class T, unsigned Dim>
1292 return pbase_m->getLocalNum();
1293}
1294
1295
1296template <class T, unsigned Dim>
1298 return pbase_m->getDestroyNum();
1299}
1300
1301template <class T, unsigned Dim>
1303 return pbase_m->getGhostNum();
1304}
1305
1306template <class T, unsigned Dim>
1308 pbase_m->setTotalNum(n);
1309}
1310
1311template <class T, unsigned Dim>
1313 pbase_m->setLocalNum(n);
1314}
1315
1316template <class T, unsigned Dim>
1317ParticleLayout<T, Dim> & PartBunch<T, Dim>::getLayout() {
1318 return pbase_m->getLayout();
1319}
1320
1321template <class T, unsigned Dim>
1322const ParticleLayout<T, Dim>& PartBunch<T, Dim>::getLayout() const {
1323 return pbase_m->getLayout();
1324}
1325
1326template <class T, unsigned Dim>
1327bool PartBunch<T, Dim>::getUpdateFlag(UpdateFlags_t f) const {
1328 return pbase_m->getUpdateFlag(f);
1329}
1330
1331template <class T, unsigned Dim>
1332void PartBunch<T, Dim>::setUpdateFlag(UpdateFlags_t f, bool val) {
1333 pbase_m->setUpdateFlag(f, val);
1334}
1335
1336template <class T, unsigned Dim>
1338 return pbase_m->singleInitNode();
1339}
1340
1341template <class T, unsigned Dim>
1343 pbase_m->resetID();
1344}
1345
1346template <class T, unsigned Dim>
1348 try {
1349 pbase_m->update();
1350 } catch (const IpplException& ex) {
1351 throw OpalException(ex.where(), ex.what());
1352 }
1353}
1354
1355template <class T, unsigned Dim>
1357 try {
1358 pbase_m->update(canSwap);
1359 } catch (const IpplException& ex) {
1360 throw OpalException(ex.where(), ex.what());
1361 }
1362}
1363
1364template <class T, unsigned Dim>
1366 pbase_m->createWithID(id);
1367}
1368
1369template <class T, unsigned Dim>
1371 pbase_m->create(M);
1372}
1373
1374template <class T, unsigned Dim>
1376 pbase_m->globalCreate(np);
1377}
1378
1379template <class T, unsigned Dim>
1380void PartBunch<T, Dim>::destroy(size_t M, size_t I, bool doNow) {
1381 pbase_m->destroy(M, I, doNow);
1382}
1383
1384template <class T, unsigned Dim>
1385void PartBunch<T, Dim>::performDestroy(bool updateLocalNum) {
1386 pbase_m->performDestroy(updateLocalNum);
1387}
1388
1389template <class T, unsigned Dim>
1390void PartBunch<T, Dim>::ghostDestroy(size_t M, size_t I) {
1391 pbase_m->ghostDestroy(M, I);
1392}
1393
1394template <class T, unsigned Dim>
1396 periodLength_m = Physics::c / f;
1397}
1398
1399template <class T, unsigned Dim>
1401
1402}
1403
1404#endif
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
Inform * gmsg
Definition changes.cpp:7
Quaternion Quaternion_t
boost::numeric::ublas::matrix< double > matrix_t
Definition BoostMatrix.h:23
ippl::Vector< T, Dim > Vector_t
Inform & operator<<(Inform &os, PartBunch< T, Dim > &p)
DistributionType
ParticleOrigin
@ units
Definition OPALTypes.h:31
@ unitless
Definition OPALTypes.h:31
ippl::ParticleAttrib< T > ParticleAttrib
constexpr unsigned Dim
Definition datatypes.h:6
Definition Air.h:27
constexpr double two_pi
The value of.
Definition Physics.h:33
constexpr double e
The value of.
Definition Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition Physics.h:45
bool eq(double x, double y)
double remotePartDel
Definition Options.cpp:61
std::string getChargeString(double charge, unsigned int precision=3)
Definition Util.h:163
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
Definition Util.h:140
std::string getTimeString(double time, unsigned int precision=3)
Definition Util.h:70
std::string getLengthString(double spos, unsigned int precision=3)
Definition Util.h:93
static OpalData * getInstance()
Definition OpalData.cpp:195
const Vector_t< double, 3 > & getP() const
Get momentum.
const Vector_t< double, 3 > & getR() const
Get position in m.
int getSteptoLastInj() const
long long localTrackStep_m
step in a TRACK command
double getX(int i)
double get_Dy() const
ParticleAttrib< int > bunchNum
void gatherLoadBalanceStatistics()
void setdT(double dt)
double get_sPos() const
Vector_t< T, Dim > get_hr() const
ParticleAttrib< double > Phi
double getMassPerParticle() const
void setBeamFrequency(double v)
void create(size_t M)
Vector_t< T, Dim > get_prms() const
void getLocalBounds(Vector_t< T, Dim > &rmin, Vector_t< T, Dim > &rmax) const
void updateFields(const Vector_t< T, Dim > &, const Vector_t< T, Dim > &origin)
bool hasFieldSolver()
Vector_t< double, Dim > rmin_m
ParticleLayout< double, 3 > & getLayout()
Definition .PartBunch.h:115
void incTrackSteps()
void setBinCharge(int bin, double q)
Set the charge of one bin to the value of q and all other to zero.
double getPx0(int i)
void performDestroy(bool updateLocalNum=false)
std::unique_ptr< Inform > pmsg_m
size_t destroyT()
double getdT() const
void destroy(size_t M, size_t I, bool doNow=false)
Vector_t< T, Dim > globalMeanR_m
void setT(double t)
double t_m
holds the actual time of the integration
const PartData * reference
relative enlargement of the mesh
void setChargeZeroPart(double q)
Vector_t< T, Dim > get_99_99Percentile() const
ParticleAttrib< Vector_t< T, Dim > > Ef
size_t calcNumPartsOutside(Vector_t< T, Dim > x)
returns the number of particles outside of a box defined by x
Vector_t< T, Dim > get_normalizedEps_99Percentile() const
size_t boundp_destroyT()
void setCharge()
Definition PartBunch.h:332
void setLocalTrackStep(long long n)
step in a TRACK command
int getLastemittedBin()
PartBins * pbin_m
double get_Dx() const
size_t getLoadBalance(int p) const
double massPerParticle_m
void setPType(const std::string &type)
void calcBeamParameters()
Vector_t< T, Dim > get_maxExtent() const
void boundp()
double getdE() const
Vector_t< T, Dim > get_pmean() const
int stepsPerTurn_m
steps per turn for OPAL-cycl
ParticleAttrib< int > Bin
double spos_m
the position along design trajectory
double getQ() const
Access to reference data.
void swap(unsigned int i, unsigned int j)
std::pair< Vector_t< T, Dim >, double > getLocalBoundingSphere()
ParticleAttrib< double > M
Quaternion_t globalToLocalQuaternion_m
Definition PartBunch.h:164
void resetInterpolationCache(bool clearCache=false)
double getE() const
void do_binaryRepart()
double getT() const
void resetQ(double q)
Set reference data.
Vector_t< double, Dim > rmax_m
void setGlobalToLocalQuaternion(Quaternion_t globalToLocalQuaternion)
Definition PartBunch.h:787
std::pair< Vector_t< T, Dim >, double > getBoundingSphere()
void switchToUnitlessPositions(bool use_dt_per_particle=false)
double getCharge() const
get the total charge per simulation particle
double getY(int i)
double getInitialBeta() const
void updateNumTotal()
void get_PBounds(Vector_t< T, Dim > &min, Vector_t< T, Dim > &max) const
Vector_t< T, Dim > get_rrms() const
size_t getDestroyNum() const
void setBCForDCBeam()
std::unique_ptr< size_t[]> binemitted_m
Vector_t< T, Dim > get_halo() const
Vector_t< T, Dim > get_origin() const
short numBunch_m
current bunch number
Vector_t< T, Dim > nr_m
short getNumBunch() const
double getGamma(int i) const
Vector_t< T, Dim > get_68Percentile() const
bool hasBinning() const
void incrementT()
void setLocalBinCount(size_t num, int bin)
ParticleAttrib< double > dt
void setBCAllPeriodic()
double getX0(int i)
PartBunch()=delete
double get_meanKineticEnergy()
int getNumberOfEnergyBins()
double dt_m
6x6 matrix of the moments of the beam
long long getLocalTrackStep() const
double getP() const
void get_bounds(Vector_t< T, Dim > &rmin, Vector_t< T, Dim > &rmax) const
void ghostDestroy(size_t M, size_t I)
void set_sPos(double s)
double calculateAngle(double x, double y)
long long globalTrackStep_m
if multiple TRACK commands
size_t getLocalNum() const
double dh_m
Mesh enlargement.
void setMass()
Definition PartBunch.h:336
std::vector< size_t > bunchTotalNum_m
number of particles per bunch
void setZ(int i, double zcoo)
void setSolver(std::string solver)
double get_DDy() const
bool isGridFixed() const
double getM() const
void setLocalNum(size_t n)
Vector_t< double, Dim > R(size_t i)
Definition PartBunch.h:276
int SteptoLastInj_m
Vector_t< T, Dim > get_99Percentile() const
void resetM(double m)
Vector_t< T, Dim > get_normalizedEps_99_99Percentile() const
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.
Vector_t< T, Dim > get_rmean() const
double getChargePerParticle() const
get the macro particle charge
double getPy(int i)
ParticleAttrib< Vector_t< T, Dim > > P
Vector_t< T, Dim > getGlobalMeanR()
void setup(AbstractParticle< T, Dim > *pb)
void setSteptoLastInj(int n)
double get_DDx() const
ParticleAttrib< Vector_t< T, Dim > > Eftmp
double getPz(int i)
void setStepsPerTurn(int n)
double periodLength_m
Vector_t< T, Dim > get_pmean_Distribution() const
Vector_t< T, Dim > get_emit() const
const PartData * getReference() const
Vector_t< T, Dim > get_95Percentile() const
double get_gamma() const
std::unique_ptr< std::ofstream > f_stream
Vector_t< T, Dim > get_centroid() const
double getY0(int i)
void setUpdateFlag(UpdateFlags_t f, bool val)
void setGlobalTrackStep(long long n)
step in multiple TRACK commands
double getPy0(int i)
Vector_t< double, Dim > hr_m
mesh size [m]
long long getGlobalTrackStep() const
void initialize(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh)
double getInitialGamma() const
void globalCreate(size_t np)
std::vector< size_t > bunchLocalNum_m
Inform & print(Inform &os)
Quaternion_t getGlobalToLocalQuaternion()
Definition PartBunch.h:791
double getBeta(int i) const
void setBCAllOpen()
double getZ(int i)
bool getUpdateFlag(UpdateFlags_t f) const
Vector_t< T, Dim > get_normalizedEps_95Percentile() const
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
void createWithID(unsigned id)
double couplingConstant_m
void setMassZeroPart(double mass)
Vector_t< T, Dim > get_normalizedEps_68Percentile() const
double getCouplingConstant() const
size_t getTotalNum() const
void calcGammas()
Compute the gammas of all bins.
void set_meshEnlargement(double dh)
double getEmissionDeltaT()
Vector_t< T, Dim > get_rprms() const
double getPx(int i)
void setCouplingConstant(double c)
void setGlobalMeanR(Vector_t< T, Dim > globalMeanR)
bool getFieldSolverType() const
Return the fieldsolver type if we have a fieldsolver.
bool weHaveEnergyBins()
void setTotalNum(size_t n)
void setNumBunch(short n)
int getStepsPerTurn() const
ParticleAttrib< double > Q
double getBinGamma(int bin)
Get gamma of one bin.
void runTests()
Vector_t< T, Dim > get_norm_emit() const
std::unique_ptr< size_t[]> globalPartPerNode_m
ParticleAttrib< Vector_t< T, Dim > > Bf
size_t getGhostNum() const
size_t emitParticles(double eZ)
Emit particles in the given bin i.e. copy the particles from the bin structure into the particle cont...
std::unique_ptr< double[]> bingamma_m
holds the gamma of the bin
Particle reference data.
Definition PartData.h:37
double getBeta() const
The relativistic beta per particle.
Definition PartData.h:126
void initSolver() override
static ParticleType getParticleType(const std::string &str)
The base class for all OPAL exceptions.