18 #ifndef PART_BUNCH_BASE_HPP
19 #define PART_BUNCH_BASE_HPP
40 template <
class T,
unsigned Dim>
50 stateOfLastBoundP_(unitless),
55 globalMeanR_m(
Vector_t(0.0, 0.0, 0.0)),
56 globalToLocalQuaternion_m(
Quaternion_t(1.0, 0.0, 0.0, 0.0)),
62 couplingConstant_m(0.0),
64 massPerParticle_m(0.0),
69 binemitted_m(nullptr),
77 globalPartPerNode_m(nullptr),
90 template <
class T,
unsigned Dim>
93 size_t isBeamEmitted = dist_m->getIfDistEmitting();
95 if (isBeamEmitted > 0)
104 template <
class T,
unsigned Dim>
109 int lastEmittedBin = dist_m->getLastEmittedEnergyBin();
111 return lastEmittedBin;
115 template <
class T,
unsigned Dim>
117 return dist_m->getNumberOfEmissionSteps();
121 template <
class T,
unsigned Dim>
123 return dist_m->getNumberOfEnergyBins();
127 template <
class T,
unsigned Dim>
130 size_t isBeamEmitting = dist_m->getIfDistEmitting();
132 if (isBeamEmitting > 0) {
133 *
gmsg <<
"*****************************************************" <<
endl
134 <<
"Warning: attempted to rebin, but not all distribution" <<
endl
135 <<
"particles have been emitted. Rebin failed." <<
endl
136 <<
"*****************************************************" <<
endl;
144 template <
class T,
unsigned Dim>
146 bingamma_m = std::unique_ptr<double[]>(
new double[numberOfEnergyBins]);
147 binemitted_m = std::unique_ptr<size_t[]>(
new size_t[numberOfEnergyBins]);
148 for (
int i = 0; i < numberOfEnergyBins; i++)
153 template <
class T,
unsigned Dim>
157 return dist_m->getNumberOfEnergyBins() > 0;
163 template <
class T,
unsigned Dim>
166 if (unit_state_ == unitless)
168 "Cannot make a unitless PartBunch unitless");
170 bool hasToReset =
false;
171 if (!
R.isDirty()) hasToReset =
true;
173 for (
size_t i = 0; i < getLocalNum(); i++) {
175 if (use_dt_per_particle)
181 unit_state_ = unitless;
183 if (hasToReset)
R.resetDirtyFlag();
187 template <
class T,
unsigned Dim>
190 if (unit_state_ == units)
192 "Cannot apply units twice to PartBunch");
194 bool hasToReset =
false;
195 if (!
R.isDirty()) hasToReset =
true;
197 for (
size_t i = 0; i < getLocalNum(); i++) {
199 if (use_dt_per_particle)
207 if (hasToReset)
R.resetDirtyFlag();
211 template <
class T,
unsigned Dim>
217 template <
class T,
unsigned Dim>
219 std::vector<Distribution*> addedDistributions,
232 template <
class T,
unsigned Dim>
238 template <
class T,
unsigned Dim>
240 return (pbin_m !=
nullptr);
244 template <
class T,
unsigned Dim>
250 template <
class T,
unsigned Dim>
256 template <
class T,
unsigned Dim>
259 return dist_m->getIfDistEmitting();
265 template <
class T,
unsigned Dim>
268 return pbin_m->weHaveBins();
274 template <
class T,
unsigned Dim>
278 setEnergyBins(pbin_m->getNBins());
282 template <
class T,
unsigned Dim>
285 setEnergyBins(pbin_m->getNBins());
289 template <
class T,
unsigned Dim>
291 return dist_m->emitParticles(
this, eZ);
295 template <
class T,
unsigned Dim>
297 size_t numParticles = getLocalNum();
299 setTotalNum(numParticles);
303 template <
class T,
unsigned Dim>
312 template <
class T,
unsigned Dim>
315 return pbin_m->getLastemittedBin();
321 template <
class T,
unsigned Dim>
323 if (pbin_m != NULL) {
324 pbin_m->setPartNum(bin, num);
329 template <
class T,
unsigned Dim>
332 const int emittedBins = dist_m->getNumberOfEnergyBins();
336 for (
int i = 0; i < emittedBins; i++)
339 for (
unsigned int n = 0;
n < getLocalNum();
n++)
342 std::unique_ptr<size_t[]> particlesInBin(
new size_t[emittedBins]);
343 reduce(bingamma_m.get(), bingamma_m.get() + emittedBins, bingamma_m.get(),
OpAddAssign());
344 reduce(binemitted_m.get(), binemitted_m.get() + emittedBins, particlesInBin.get(),
OpAddAssign());
345 for (
int i = 0; i < emittedBins; i++) {
346 size_t &pInBin = particlesInBin[i];
348 bingamma_m[i] /= pInBin;
350 <<
" gamma = " << std::setw(8) << std::scientific
351 << std::setprecision(5) << bingamma_m[i]
352 <<
"; NpInBin= " << std::setw(8)
353 << std::setfill(
' ') << pInBin <<
endl);
360 particlesInBin.reset();
364 ERRORMSG(
"sum(Bins)= " << s <<
" != sum(R)= " << getTotalNum() <<
endl;);
366 if (emittedBins >= 2) {
367 for (
int i = 1; i < emittedBins; i++) {
368 if (binemitted_m[i - 1] != 0 && binemitted_m[i] != 0)
369 INFOMSG(
level2 <<
"d(gamma)= " << 100.0 *
std::abs(bingamma_m[i - 1] - bingamma_m[i]) / bingamma_m[i] <<
" [%] "
370 <<
"between bin " << i - 1 <<
" and " << i <<
endl);
376 template <
class T,
unsigned Dim>
379 const int emittedBins = pbin_m->getLastemittedBin();
381 for (
int i = 0; i < emittedBins; i++)
383 for (
unsigned int n = 0;
n < getLocalNum();
n++) {
384 if ( this->Bin[
n] > -1 ) {
389 allreduce(*bingamma_m.get(), emittedBins, std::plus<double>());
391 for (
int i = 0; i < emittedBins; i++) {
392 if (pbin_m->getTotalNumPerBin(i) > 0) {
393 bingamma_m[i] /= pbin_m->getTotalNumPerBin(i);
397 INFOMSG(
"Bin " << i <<
" : particle number = " << pbin_m->getTotalNumPerBin(i)
398 <<
" gamma = " << bingamma_m[i] <<
endl);
404 template <
class T,
unsigned Dim>
406 return bingamma_m[bin];
410 template <
class T,
unsigned Dim>
416 template <
class T,
unsigned Dim>
418 this->Q =
where(
eq(this->Bin, bin), this->qi_m, 0.0);
422 template <
class T,
unsigned Dim>
425 std::size_t localnum = 0;
428 for (
unsigned long k = 0; k < getLocalNum(); ++ k)
436 gather(&localnum, &globalPartPerNode_m[0], 1);
438 size_t npOutside = std::accumulate(globalPartPerNode_m.get(),
440 std::plus<size_t>());
455 template <
class T,
unsigned Dim>
457 std::vector<double>& lineDensity,
458 std::pair<double, double>& meshInfo) {
460 get_bounds(rmin, rmax);
464 this->updateDomainLength(grid);
468 double length = rmax(2) - rmin(2);
469 double zmin = rmin(2) - dh_m * length, zmax = rmax(2) + dh_m * length;
470 double hz = (zmax - zmin) / (nBins - 2);
471 double perMeter = 1.0 / hz;
474 lineDensity.resize(nBins, 0.0);
475 std::fill(lineDensity.begin(), lineDensity.end(), 0.0);
477 const unsigned int lN = getLocalNum();
478 for (
unsigned int i = 0; i < lN; ++ i) {
479 const double z =
R[i](2) - 0.5 * hz;
480 unsigned int idx = (z - zmin) / hz;
481 double tau = (z - zmin) / hz - idx;
483 lineDensity[idx] += Q[i] * (1.0 - tau) * perMeter;
484 lineDensity[idx + 1] += Q[i] * tau * perMeter;
487 reduce(&(lineDensity[0]), &(lineDensity[0]) + nBins, &(lineDensity[0]),
OpAddAssign());
489 meshInfo.first = zmin;
490 meshInfo.second = hz;
494 template <
class T,
unsigned Dim>
502 if ( !(
R.isDirty() || ID.isDirty() ) && stateOfLastBoundP_ == unit_state_)
return;
504 stateOfLastBoundP_ = unit_state_;
506 if (!isGridFixed()) {
507 const int dimIdx = (dcBeam_m? 2: 3);
515 this->updateDomainLength(nr_m);
517 get_bounds(rmin_m, rmax_m);
522 for (
int i = 0; i < dimIdx; i++) {
523 double length =
std::abs(rmax_m[i] - rmin_m[i]);
524 if (length < 1
e-10) {
528 rmax_m[i] += dh_m * length;
529 rmin_m[i] -= dh_m * length;
531 hr_m[i] = (rmax_m[i] - rmin_m[i]) / (nr_m[i] - 1);
534 rmax_m[2] = rmin_m[2] + periodLength_m;
535 hr_m[2] = periodLength_m / (nr_m[2] - 1);
537 for (
int i = 0; i < dimIdx; ++ i) {
538 volume *=
std::abs(rmax_m[i] - rmin_m[i]);
541 if (getIfBeamEmitting() && dist_m != NULL) {
543 double percent =
std::max(1.0 / (nr_m[2] - 1), dist_m->getPercentageEmitted());
544 double length =
std::abs(rmax_m[2] - rmin_m[2]) / (1.0 + 2 * dh_m);
545 if (percent < 1.0 && percent > 0.0) {
546 rmax_m[2] -= dh_m * length;
547 rmin_m[2] = rmax_m[2] - length / percent;
551 rmax_m[2] += dh_m * length;
552 rmin_m[2] -= dh_m * length;
554 hr_m[2] = (rmax_m[2] - rmin_m[2]) / (nr_m[2] - 1);
558 if (volume < 1
e-21 && getTotalNum() > 1 &&
std::abs(
sum(Q)) > 0.0) {
563 if (hr_m[0] * hr_m[1] * hr_m[2] <= 0) {
567 Vector_t origin = rmin_m -
Vector_t(hr_m[0] / 2.0, hr_m[1] / 2.0, hr_m[2] / 2.0);
568 this->updateFields(hr_m, origin);
579 template <
class T,
unsigned Dim>
583 const int dimIdx = 3;
586 std::unique_ptr<size_t[]> countLost;
588 const int tempN = pbin_m->getLastemittedBin();
589 countLost = std::unique_ptr<size_t[]>(
new size_t[tempN]);
590 for (
int ii = 0; ii < tempN; ii++) countLost[ii] = 0;
593 this->updateDomainLength(nr_m);
596 get_bounds(rmin_m, rmax_m);
599 len = rmax_m - rmin_m;
601 calcBeamParameters();
604 if (checkfactor != 0) {
607 Vector_t rmean = momentsComputer_m.getMeanPosition();
608 Vector_t rrms = momentsComputer_m.getStandardDeviationPosition();
609 if(checkfactor < 0) {
611 if (len[0] > checkfactor * rrms[0] ||
612 len[1] > checkfactor * rrms[1] ||
613 len[2] > checkfactor * rrms[2])
615 for(
unsigned int ii = 0; ii < this->getLocalNum(); ii++) {
619 if (
std::abs(
R[ii](0) - rmean(0)) > checkfactor * rrms[0] ||
620 std::abs(
R[ii](1) - rmean(1)) > checkfactor * rrms[1] ||
621 std::abs(
R[ii](2) - rmean(2)) > checkfactor * rrms[2])
627 countLost[Bin[ii]] += 1 ;
636 if (len[0] > checkfactor * rrms[0] ||
637 len[2] > checkfactor * rrms[2])
639 for(
unsigned int ii = 0; ii < this->getLocalNum(); ii++) {
643 if (
std::abs(
R[ii](0) - rmean(0)) > checkfactor * rrms[0] ||
644 std::abs(
R[ii](2) - rmean(2)) > checkfactor * rrms[2])
650 countLost[Bin[ii]] += 1 ;
660 for (
int i = 0; i < dimIdx; i++) {
661 double length =
std::abs(rmax_m[i] - rmin_m[i]);
662 rmax_m[i] += dh_m * length;
663 rmin_m[i] -= dh_m * length;
664 hr_m[i] = (rmax_m[i] - rmin_m[i]) / (nr_m[i] - 1);
668 this->updateFields(hr_m, rmin_m);
671 pbin_m->updatePartInBin_cyc(countLost.get());
677 countTotalNumPerBunch();
687 template <
class T,
unsigned Dim>
690 this->updateDomainLength(nr_m);
692 std::vector<size_t> tmpbinemitted;
697 const size_t localNum = getLocalNum();
699 double rzmean = momentsComputer_m.getMeanPosition()(2);
700 double rzrms = momentsComputer_m.getStandardDeviationPosition()(2);
701 const bool haveEnergyBins = weHaveEnergyBins();
702 if (haveEnergyBins) {
703 tmpbinemitted.resize(getNumberOfEnergyBins(), 0.0);
705 for (
unsigned int i = 0; i < localNum; i++) {
709 }
else if (haveEnergyBins) {
710 tmpbinemitted[Bin[i]]++;
716 calcBeamParameters();
717 gatherLoadBalanceStatistics();
719 if (haveEnergyBins) {
720 const int lastBin = dist_m->getLastEmittedEnergyBin();
721 for (
int i = 0; i < lastBin; i++) {
722 binemitted_m[i] = tmpbinemitted[i];
730 template <
class T,
unsigned Dim>
733 std::unique_ptr<size_t[]> tmpbinemitted;
735 const size_t localNum = getLocalNum();
736 const size_t totalNum = getTotalNum();
739 if (weHaveEnergyBins()) {
740 tmpbinemitted = std::unique_ptr<size_t[]>(
new size_t[getNumberOfEnergyBins()]);
741 for (
int i = 0; i < getNumberOfEnergyBins(); i++) {
742 tmpbinemitted[i] = 0;
744 for (
unsigned int i = 0; i < localNum; i++) {
749 tmpbinemitted[Bin[i]]++;
753 for (
size_t i = 0; i < localNum; i++) {
762 performDestroy(
true);
765 calcBeamParameters();
766 gatherLoadBalanceStatistics();
768 if (weHaveEnergyBins()) {
769 const int lastBin = dist_m->getLastEmittedEnergyBin();
770 for (
int i = 0; i < lastBin; i++) {
771 binemitted_m[i] = tmpbinemitted[i];
774 size_t newTotalNum = getLocalNum();
777 setTotalNum(newTotalNum);
779 return totalNum - newTotalNum;
783 template <
class T,
unsigned Dim>
788 template <
class T,
unsigned Dim>
793 template <
class T,
unsigned Dim>
798 template <
class T,
unsigned Dim>
803 template <
class T,
unsigned Dim>
809 template <
class T,
unsigned Dim>
811 return this->
R[i](0);
815 template <
class T,
unsigned Dim>
817 return this->
R[i](1);
821 template <
class T,
unsigned Dim>
823 return this->
R[i](2);
827 template <
class T,
unsigned Dim>
833 template <
class T,
unsigned Dim>
839 template <
class T,
unsigned Dim>
844 template <
class T,
unsigned Dim>
847 this->getLocalBounds(rmin, rmax);
851 for (
unsigned int i = 0; i <
Dim; ++i) {
853 min[2*i + 1] = -rmax[i];
858 for (
unsigned int i = 0; i <
Dim; ++i) {
860 rmax[i] = -
min[2*i + 1];
865 template <
class T,
unsigned Dim>
867 const size_t localNum = getLocalNum();
869 double maxValue = 1e8;
870 rmin =
Vector_t(maxValue, maxValue, maxValue);
871 rmax =
Vector_t(-maxValue, -maxValue, -maxValue);
877 for (
size_t i = 1; i < localNum; ++ i) {
878 for (
unsigned short d = 0; d < 3u; ++ d) {
879 if (rmin(d) >
R[i](d)) rmin(d) =
R[i](d);
880 else if (rmax(d) <
R[i](d)) rmax(d) =
R[i](d);
886 template <
class T,
unsigned Dim>
889 get_bounds(rmin, rmax);
891 std::pair<Vector_t, double> sphere;
892 sphere.first = 0.5 * (rmin + rmax);
893 sphere.second =
std::sqrt(
dot(rmax - sphere.first, rmax - sphere.first));
899 template <
class T,
unsigned Dim>
902 getLocalBounds(rmin, rmax);
904 std::pair<Vector_t, double> sphere;
905 sphere.first = 0.5 * (rmin + rmax);
906 sphere.second =
std::sqrt(
dot(rmax - sphere.first, rmax - sphere.first));
912 template <
class T,
unsigned Dim>
916 size_t i = getLocalNum();
919 R[i] = particle.
getR();
920 P[i] = particle.
getP();
923 msg <<
"Created one particle i= " << i <<
endl;
927 template <
class T,
unsigned Dim>
938 template <
class T,
unsigned Dim>
940 R[ii] = particle.
getR();
941 P[ii] = particle.
getP();
945 template <
class T,
unsigned Dim>
949 R[ii](2), Q[ii], M[ii]);
954 template <
class T,
unsigned Dim>
956 double& axmax,
double& aymax) {
960 for (
unsigned int ii = 0; ii < getLocalNum(); ii++) {
962 particle = getParticle(ii);
987 template <
class T,
unsigned Dim>
993 template <
class T,
unsigned Dim>
999 template <
class T,
unsigned Dim>
1005 template <
class T,
unsigned Dim>
1011 template <
class T,
unsigned Dim>
1017 template <
class T,
unsigned Dim>
1023 template <
class T,
unsigned Dim>
1029 template <
class T,
unsigned Dim>
1031 return momentsComputer_m.getMeanGamma();
1035 template <
class T,
unsigned Dim>
1037 return momentsComputer_m.getMeanKineticEnergy();
1041 template <
class T,
unsigned Dim>
1047 template <
class T,
unsigned Dim>
1053 template <
class T,
unsigned Dim>
1055 return momentsComputer_m.getMeanPosition();
1059 template <
class T,
unsigned Dim>
1061 return momentsComputer_m.getStandardDeviationPosition();
1065 template <
class T,
unsigned Dim>
1067 return momentsComputer_m.getStandardDeviationRP();
1071 template <
class T,
unsigned Dim>
1073 return momentsComputer_m.getMeanPosition();
1077 template <
class T,
unsigned Dim>
1079 return momentsComputer_m.getStandardDeviationMomentum();
1083 template <
class T,
unsigned Dim>
1085 return momentsComputer_m.getMeanMomentum();
1089 template <
class T,
unsigned Dim>
1092 return dist_m->get_pmean();
1094 double gamma = 0.1 / getM() + 1;
1099 template <
class T,
unsigned Dim>
1101 return momentsComputer_m.getGeometricEmittance();
1105 template <
class T,
unsigned Dim>
1107 return momentsComputer_m.getNormalizedEmittance();
1111 template <
class T,
unsigned Dim>
1113 return momentsComputer_m.getHalo();
1117 template <
class T,
unsigned Dim>
1119 return momentsComputer_m.getDx();
1123 template <
class T,
unsigned Dim>
1125 return momentsComputer_m.getDy();
1129 template <
class T,
unsigned Dim>
1131 return momentsComputer_m.getDDx();
1135 template <
class T,
unsigned Dim>
1137 return momentsComputer_m.getDDy();
1141 template <
class T,
unsigned Dim>
1147 template <
class T,
unsigned Dim>
1153 template <
class T,
unsigned Dim>
1157 globalPartPerNode_m[i] = 0;
1159 std::size_t localnum = getLocalNum();
1160 gather(&localnum, &globalPartPerNode_m[0], 1);
1164 template <
class T,
unsigned Dim>
1166 return globalPartPerNode_m[p];
1170 template <
class T,
unsigned Dim>
1176 template <
class T,
unsigned Dim>
1180 get_bounds(rmin_m, rmax_m);
1181 momentsComputer_m.compute(*
this);
1185 template <
class T,
unsigned Dim>
1187 return couplingConstant_m;
1191 template <
class T,
unsigned Dim>
1193 couplingConstant_m =
c;
1197 template <
class T,
unsigned Dim>
1200 if (getTotalNum() != 0)
1203 WARNMSG(
"Could not set total charge in PartBunch::setCharge based on getTotalNum" <<
endl);
1207 template <
class T,
unsigned Dim>
1213 template <
class T,
unsigned Dim>
1215 massPerParticle_m = mass;
1216 if (getTotalNum() != 0)
1220 template <
class T,
unsigned Dim>
1222 massPerParticle_m = mass;
1226 template <
class T,
unsigned Dim>
1232 template <
class T,
unsigned Dim>
1237 template <
class T,
unsigned Dim>
1239 return massPerParticle_m;
1242 template <
class T,
unsigned Dim>
1245 fs_m->initSolver(
this);
1252 this->initialize(fs_m->getFieldLayout());
1259 template <
class T,
unsigned Dim>
1262 return fs_m->hasValidSolver();
1269 template <
class T,
unsigned Dim>
1272 return fs_m->getFieldSolverType();
1278 template <
class T,
unsigned Dim>
1284 template <
class T,
unsigned Dim>
1286 return stepsPerTurn_m;
1290 template <
class T,
unsigned Dim>
1292 globalTrackStep_m =
n;
1296 template <
class T,
unsigned Dim>
1298 return globalTrackStep_m;
1302 template <
class T,
unsigned Dim>
1304 localTrackStep_m =
n;
1308 template <
class T,
unsigned Dim>
1310 globalTrackStep_m++; localTrackStep_m++;
1314 template <
class T,
unsigned Dim>
1316 return localTrackStep_m;
1320 template <
class T,
unsigned Dim>
1323 bunchTotalNum_m.resize(
n);
1324 bunchLocalNum_m.resize(
n);
1328 template <
class T,
unsigned Dim>
1334 template <
class T,
unsigned Dim>
1337 bunchTotalNum_m[
n] = totalnum;
1341 template <
class T,
unsigned Dim>
1344 return bunchTotalNum_m[
n];
1348 template <
class T,
unsigned Dim>
1351 bunchLocalNum_m[
n] = localnum;
1355 template <
class T,
unsigned Dim>
1358 return bunchLocalNum_m[
n];
1362 template <
class T,
unsigned Dim>
1364 bunchTotalNum_m.clear();
1365 bunchTotalNum_m.resize(numBunch_m);
1366 bunchLocalNum_m.clear();
1367 bunchLocalNum_m.resize(numBunch_m);
1369 for (
size_t i = 0; i < this->getLocalNum(); ++i) {
1371 ++bunchLocalNum_m[this->bunchNum[i]];
1374 allreduce(bunchLocalNum_m.data(), bunchTotalNum_m.data(),
1375 bunchLocalNum_m.size(), std::plus<size_t>());
1377 size_t totalnum = std::accumulate(bunchTotalNum_m.begin(),
1378 bunchTotalNum_m.end(), 0);
1380 if ( totalnum != this->getTotalNum() )
1381 throw OpalException(
"PartBunchBase::countTotalNumPerBunch()",
1382 "Sum of total number of particles per bunch (" +
1383 std::to_string(totalnum) +
") != total number of particles (" +
1384 std::to_string(this->getTotalNum()) +
")");
1388 template <
class T,
unsigned Dim>
1390 globalMeanR_m = globalMeanR;
1394 template <
class T,
unsigned Dim>
1396 return globalMeanR_m;
1400 template <
class T,
unsigned Dim>
1403 globalToLocalQuaternion_m = globalToLocalQuaternion;
1407 template <
class T,
unsigned Dim>
1409 return globalToLocalQuaternion_m;
1413 template <
class T,
unsigned Dim>
1415 SteptoLastInj_m =
n;
1419 template <
class T,
unsigned Dim>
1421 return SteptoLastInj_m;
1425 template <
class T,
unsigned Dim>
1428 const int emittedBins = pbin_m->getLastemittedBin();
1429 double phi[emittedBins];
1430 double px[emittedBins];
1431 double py[emittedBins];
1432 double meanPhi = 0.0;
1434 for (
int ii = 0; ii < emittedBins; ii++) {
1440 for (
unsigned int ii = 0; ii < getLocalNum(); ii++) {
1441 px[Bin[ii]] += P[ii](0);
1442 py[Bin[ii]] += P[ii](1);
1447 for (
int ii = 0; ii < emittedBins; ii++) {
1448 phi[ii] = calculateAngle(px[ii], py[ii]);
1453 meanPhi /= emittedBins;
1464 template <
class T,
unsigned Dim>
1470 int maxbin = pbin_m->getNBins();
1471 size_t partInBin[maxbin];
1472 for (
int ii = 0; ii < maxbin; ii++) partInBin[ii] = 0;
1474 double pMin0 = 1.0e9;
1476 double maxbinIndex = 0;
1478 for (
unsigned long int n = 0;
n < getLocalNum();
n++) {
1480 if (pMin0 > temp_betagamma)
1481 pMin0 = temp_betagamma;
1486 double asinh0 = std::asinh(pMin);
1487 for (
unsigned long int n = 0;
n < getLocalNum();
n++) {
1490 int itsBinID =
std::floor((std::asinh(temp_betagamma) - asinh0) / eta + 1.0E-6);
1492 if (maxbinIndex < itsBinID) {
1493 maxbinIndex = itsBinID;
1496 if (itsBinID >= maxbin) {
1497 ERRORMSG(
"The bin number limit is " << maxbin <<
", please increase the energy interval and try again" <<
endl);
1500 partInBin[itsBinID]++;
1505 pbin_m->resetPartInBin_cyc(partInBin, maxbinIndex);
1515 template <
class T,
unsigned Dim>
1517 int maxbin = pbin_m->getNBins();
1518 std::size_t partInBin[maxbin];
1519 for (
int i = 0; i < maxbin; ++i) {
1523 for (std::size_t i = 0; i < getLocalNum(); ++i) {
1524 partInBin[Bin[i]]++;
1528 pbin_m->resetPartInBin_cyc(partInBin, numBunch_m - 1);
1537 template <
class T,
unsigned Dim>
1539 return reference->getQ();
1543 template <
class T,
unsigned Dim>
1545 return reference->getM();
1549 template <
class T,
unsigned Dim>
1551 return reference->getP();
1555 template <
class T,
unsigned Dim>
1557 return reference->getE();
1561 template <
class T,
unsigned Dim>
1563 return refPOrigin_m;
1566 template <
class T,
unsigned Dim>
1568 refPOrigin_m = origin;
1572 template <
class T,
unsigned Dim>
1577 template <
class T,
unsigned Dim>
1580 switch (refPType_m) {
1588 return "ANTIPROTON";
1610 INFOMSG(
"Unknown type for OPAL particles" <<
endl);
1615 template <
class T,
unsigned Dim>
1618 if (
type ==
"ELECTRON") {
1620 }
else if (
type ==
"PROTON") {
1622 }
else if (
type ==
"POSITRON") {
1624 }
else if (
type ==
"ANTIPROTON") {
1626 }
else if (
type ==
"CARBON") {
1628 }
else if (
type ==
"HMINUS") {
1630 }
else if (
type ==
"URANIUM") {
1632 }
else if (
type ==
"MUON") {
1634 }
else if (
type ==
"DEUTERON") {
1636 }
else if (
type ==
"XENON") {
1638 }
else if (
type ==
"H2P") {
1640 }
else if (
type ==
"ALPHA") {
1642 }
else if (
type ==
"HYDROGEN") {
1644 }
else if (
type ==
"H3P") {
1647 INFOMSG(
"Unknown type for OPAL particles. Default ParticleType::UNNAMED is set" <<
endl);
1653 template <
class T,
unsigned Dim>
1655 const_cast<PartData *
>(reference)->setQ(q);
1659 template <
class T,
unsigned Dim>
1661 const_cast<PartData *
>(reference)->setM(m);
1665 template <
class T,
unsigned Dim>
1667 return momentsComputer_m.getStdKineticEnergy();
1671 template <
class T,
unsigned Dim>
1673 return reference->getBeta();
1677 template <
class T,
unsigned Dim>
1679 return reference->getGamma();
1683 template <
class T,
unsigned Dim>
1689 template <
class T,
unsigned Dim>
1695 template <
class T,
unsigned Dim>
1701 template <
class T,
unsigned Dim>
1707 template <
class T,
unsigned Dim>
1709 return dist_m->getEmissionDeltaT();
1713 template <
class T,
unsigned Dim>
1715 binemitted_m[binNumber]++;
1719 template <
class T,
unsigned Dim>
1721 momentsComputer_m.computeMeanKineticEnergy(*
this);
1724 template <
class T,
unsigned Dim>
1727 if (getTotalNum() != 0) {
1730 double pathLength = get_sPos();
1732 os << std::scientific;
1734 os <<
"* ************** B U N C H ********************************************************* \n";
1735 os <<
"* NP = " << getTotalNum() <<
"\n";
1742 if (getTotalNum() >= 2) {
1744 os <<
"* rms momenta = " << std::setw(12) << std::setprecision(5) << get_prms() <<
" [beta gamma]\n";
1746 os <<
"* mean momenta = " << std::setw(12) << std::setprecision(5) << get_pmean() <<
" [beta gamma]\n";
1747 os <<
"* rms emittance = " << std::setw(12) << std::setprecision(5) << get_emit() <<
" (not normalized)\n";
1748 os <<
"* rms correlation = " << std::setw(12) << std::setprecision(5) << get_rprms() <<
"\n";
1751 os <<
"* dh = " << std::setw(13) << std::setprecision(5) << dh_m * 100 <<
" [%]\n";
1755 os <<
"* ********************************************************************************** " <<
endl;
1762 template <
class T,
unsigned Dim>
1764 double thetaXY =
atan2(y, x);
1770 template <
class T,
unsigned Dim>
1780 template <
class T,
unsigned Dim>
1782 throw OpalException(
"PartBunchBase<T, Dim>::runTests() ",
"No test supported.");
1786 template <
class T,
unsigned Dim>
1791 template <
class T,
unsigned Dim>
1793 if (i >= getLocalNum() || j >= getLocalNum() || i == j)
return;
1795 std::swap(
R[i],
R[j]);
1796 std::swap(P[i], P[j]);
1797 std::swap(Q[i], Q[j]);
1798 std::swap(M[i], M[j]);
1799 std::swap(Phi[i], Phi[j]);
1800 std::swap(Ef[i], Ef[j]);
1801 std::swap(Eftmp[i], Eftmp[j]);
1802 std::swap(Bf[i], Bf[j]);
1803 std::swap(Bin[i], Bin[j]);
1804 std::swap(dt[i], dt[j]);
1805 std::swap(PType[i], PType[j]);
1806 std::swap(POrigin[i], POrigin[j]);
1807 std::swap(TriID[i], TriID[j]);
1808 std::swap(cavityGapCrossed[i], cavityGapCrossed[j]);
1809 std::swap(bunchNum[i], bunchNum[j]);
1813 template <
class T,
unsigned Dim>
1815 throw OpalException(
"PartBunchBase<T, Dim>::setBCAllPeriodic() ",
"Not supported BC.");
1819 template <
class T,
unsigned Dim>
1821 throw OpalException(
"PartBunchBase<T, Dim>::setBCAllOpen() ",
"Not supported BC.");
1825 template <
class T,
unsigned Dim>
1827 throw OpalException(
"PartBunchBase<T, Dim>::setBCForDCBeam() ",
"Not supported BC.");
1831 template <
class T,
unsigned Dim>
1836 template <
class T,
unsigned Dim>
1865 globalPartPerNode_m = std::unique_ptr<size_t[]>(
new size_t[
Ippl::getNodes()]);
1871 template <
class T,
unsigned Dim>
1873 return pbase_m->getTotalNum();
1876 template <
class T,
unsigned Dim>
1878 return pbase_m->getLocalNum();
1882 template <
class T,
unsigned Dim>
1884 return pbase_m->getDestroyNum();
1887 template <
class T,
unsigned Dim>
1889 return pbase_m->getGhostNum();
1892 template <
class T,
unsigned Dim>
1894 pbase_m->setTotalNum(
n);
1897 template <
class T,
unsigned Dim>
1899 pbase_m->setLocalNum(
n);
1902 template <
class T,
unsigned Dim>
1904 return pbase_m->getLayout();
1907 template <
class T,
unsigned Dim>
1909 return pbase_m->getLayout();
1912 template <
class T,
unsigned Dim>
1914 return pbase_m->getUpdateFlag(f);
1917 template <
class T,
unsigned Dim>
1919 pbase_m->setUpdateFlag(f, val);
1922 template <
class T,
unsigned Dim>
1924 return pbase_m->singleInitNode();
1927 template <
class T,
unsigned Dim>
1932 template <
class T,
unsigned Dim>
1941 template <
class T,
unsigned Dim>
1944 pbase_m->update(canSwap);
1950 template <
class T,
unsigned Dim>
1952 pbase_m->createWithID(
id);
1955 template <
class T,
unsigned Dim>
1960 template <
class T,
unsigned Dim>
1962 pbase_m->globalCreate(np);
1965 template <
class T,
unsigned Dim>
1967 pbase_m->destroy(M, I, doNow);
1970 template <
class T,
unsigned Dim>
1972 pbase_m->performDestroy(updateLocalNum);
1975 template <
class T,
unsigned Dim>
1977 pbase_m->ghostDestroy(M, I);
1980 template <
class T,
unsigned Dim>
1985 template <
class T,
unsigned Dim>
1990 for (
unsigned int i = 0; i <
Dim; i++) {
1991 rpmean(2*i)= get_rmean()(i);
1992 rpmean((2*i)+1)= get_pmean()(i);
1996 for (
unsigned int i = 0; i < 2 *
Dim; i++) {
1997 for (
unsigned int j = 0; j <= i; j++) {
1998 sigmaMatrix[i][j] = moments_m(i, j) - rpmean(i) * rpmean(j);
1999 sigmaMatrix[j][i] = sigmaMatrix[i][j];
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sqrt(const Tps< T > &x)
Square root.
Inform & operator<<(Inform &os, PartBunchBase< T, Dim > &p)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
void allreduce(const T *input, T *output, int count, Op op)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
void gather(const T *input, T *output, int count, int root=0)
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_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
void bounds(const PETE_Expr< T1 > &expr, Vektor< T2, D > &minval, Vektor< T2, D > &maxval)
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Inform & level1(Inform &inf)
Inform & endl(Inform &inf)
Inform & level2(Inform &inf)
constexpr double two_pi
The value of.
constexpr double e
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
std::string getChargeString(double charge, unsigned int precision=3)
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
std::string getTimeString(double time, unsigned int precision=3)
std::string getLengthString(double spos, unsigned int precision=3)
bool eq(double x, double y)
boost::function< boost::tuple< double, bool >arguments_t)> type
ParticleLayout< T, Dim > & getLayout()
void setEnergyBins(int numberOfEnergyBins)
double get_meanKineticEnergy() const
void setDistribution(Distribution *d, std::vector< Distribution * > addedDistributions, size_t &np)
virtual void resetInterpolationCache(bool clearCache=false)
const PartData * getReference() const
ParticleOrigin getPOrigin() const
void setMass(double mass)
int getSteptoLastInj() const
void boundp_destroyCycl()
bool resetPartBinID2(const double eta)
reset Bin[] for each particle according to the method given in paper PAST-AB(064402) by G....
void setNumBunch(short n)
std::string getPTypeString()
double getMassPerParticle() const
double getQ() const
Access to reference data.
double getCouplingConstant() const
double getChargePerParticle() const
get the macro particle charge
virtual void set_meshEnlargement(double dh)
virtual double getBeta(int i)
void getLocalBounds(Vector_t &rmin, Vector_t &rmax)
virtual double getPx0(int i)
size_t getLocalNum() const
void setLocalTrackStep(long long n)
step in a TRACK command
void setLocalBinCount(size_t num, int bin)
bool getUpdateFlag(UpdateFlags_t f) const
void setParticle(FVector< double, 6 > z, int ii)
size_t emitParticles(double eZ)
Emit particles in the given bin i.e. copy the particles from the bin structure into the particle cont...
void maximumAmplitudes(const FMatrix< double, 6, 6 > &D, double &axmax, double &aymax)
Return maximum amplitudes.
void setMassZeroPart(double mass)
size_t getTotalNum() const
virtual void updateFields(const Vector_t &hr, const Vector_t &origin)
virtual void setZ(int i, double zcoo)
double calcMeanPhi()
calculate average angle of longitudinal direction of bins
Quaternion_t getGlobalToLocalQuaternion()
void setBeamFrequency(double v)
void switchToUnitlessPositions(bool use_dt_per_particle=false)
size_t calcNumPartsOutside(Vector_t x)
returns the number of particles outside of a box defined by x
Inform & print(Inform &os)
double getEmissionDeltaT()
void setLocalNumPerBunch(size_t numpart, short n)
size_t getLocalNumPerBunch(short n) const
void setGlobalToLocalQuaternion(Quaternion_t globalToLocalQuaternion)
Vector_t get_rrms() const
virtual double getPy(int i)
double getBinGamma(int bin)
Get gamma of one bin.
double getInitialBeta() const
int getLastEmittedEnergyBin()
void calcBeamParameters()
void setSteptoLastInj(int n)
virtual double getX0(int i)
double getInitialGamma() const
virtual void setBCAllPeriodic()
void setChargeZeroPart(double q)
virtual double getY0(int i)
ParticleType getPType() const
Vector_t get_origin() const
Vector_t get_prms() const
void createWithID(unsigned id)
PartBunchBase(AbstractParticle< T, Dim > *pb, const PartData *ref)
double getCharge() const
get the total charge per simulation particle
virtual double getPy0(int i)
size_t getTotalNumPerBunch(short n) const
virtual double getPx(int i)
Vector_t get_pmean_Distribution() const
size_t getNumberOfEmissionSteps()
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.
void setup(AbstractParticle< T, Dim > *pb)
virtual void setBCAllOpen()
void setTotalNum(size_t n)
long long getLocalTrackStep() const
void setGlobalMeanR(Vector_t globalMeanR)
void setCouplingConstant(double c)
short getNumBunch() const
virtual void do_binaryRepart()
Vector_t get_norm_emit() const
void calcGammas()
Compute the gammas of all bins.
int getStepsPerTurn() const
Vector_t get_rprms() const
void setPOrigin(ParticleOrigin)
Vector_t get_maxExtent() const
void gatherLoadBalanceStatistics()
void countTotalNumPerBunch()
void get_bounds(Vector_t &rmin, Vector_t &rmax)
void get_PBounds(Vector_t &min, Vector_t &max) const
virtual void setBinCharge(int bin, double q)
Set the charge of one bin to the value of q and all other to zero.
Vector_t get_halo() const
void performDestroy(bool updateLocalNum=false)
Vector_t getGlobalMeanR()
void ghostDestroy(size_t M, size_t I)
int getNumberOfEnergyBins()
void setGlobalTrackStep(long long n)
step in multiple TRACK commands
std::pair< Vector_t, double > getBoundingSphere()
Vector_t get_centroid() const
void push_back(OpalParticle const &p)
virtual double getX(int i)
virtual double getPz(int i)
void setLocalNum(size_t n)
Vector_t get_pmean() const
void setTotalNumPerBunch(size_t numpart, short n)
virtual void setBCForDCBeam()
void destroy(size_t M, size_t I, bool doNow=false)
void globalCreate(size_t np)
FMatrix< double, 2 *Dim, 2 *Dim > getSigmaMatrix()
OpalParticle getParticle(int ii)
virtual void swap(unsigned int i, unsigned int j)
void setPType(std::string type)
void setPBins(PartBins *pbin)
size_t getDestroyNum() const
virtual double getGamma(int i)
virtual void setSolver(FieldSolver *fs)
long long getGlobalTrackStep() const
size_t getGhostNum() const
void setTEmission(double t)
size_t getLoadBalance(int p) const
std::pair< Vector_t, double > getLocalBoundingSphere()
std::string getFieldSolverType() const
Return the fieldsolver type if we have a fieldsolver.
virtual Vector_t get_hr() const
Vector_t get_emit() const
double calculateAngle(double x, double y)
angle range [0~2PI) degree
void iterateEmittedBin(int binNumber)
bool singleInitNode() const
void setUpdateFlag(UpdateFlags_t f, bool val)
virtual double getY(int i)
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
void setStepsPerTurn(int n)
virtual double getZ(int i)
Vector_t get_rmean() const
static OpalData * getInstance()
double getPy() const
Get vertical momentum (no dimension).
const Vector_t & getR() const
Get position in m.
const Vector_t & getP() const
Get momentum.
double getPz() const
Get relative momentum error (no dimension).
double getY() const
Get vertical displacement in m.
double getZ() const
Get longitudinal displacement c*t in m.
double getPx() const
Get horizontal momentum (no dimension).
double getX() const
Get horizontal position in m.
A templated representation for vectors.
void createOpalT(PartBunchBase< double, 3 > *beam, std::vector< Distribution * > addedDistributions, size_t &numberOfParticles)
The FieldSolver definition.
The base class for all OPAL exceptions.
virtual void addAttribute(ParticleAttribBase &pa)=0
std::ios_base::fmtflags FmtFlags_t
virtual const std::string & where() const
virtual const char * what() const
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t