117 bool revBeam,
bool revTrack,
122 const double& mbPara,
123 const std::string& mbMode,
124 const std::string& mbBinning)
125 :
Tracker(beamline, bunch, reference, revBeam, revTrack)
127 , maxSteps_m(maxSTEPS)
128 , lastDumpedStep_m(0)
129 , myNode_m(
Ippl::myNode())
130 , initialLocalNum_m(bunch->getLocalNum())
131 , initialTotalNum_m(bunch->getTotalNum())
132 , opalRing_m(nullptr)
133 , itsStepper_mp(nullptr)
135 , stepper_m(timeintegrator)
141 if ( numBunch > 1 ) {
144 mbPara, mbMode, mbBinning)
177 Inform msg(
"bgf_main_collision_test ");
191 dtime, intecoords, triId);
200 <<
" lost on boundary geometry" <<
endl;
209 const short& bunchNr) {
210 if ( prevAzimuth < 0.0 ) {
215 azimuth = theta + plus;
217 double dtheta = theta - prevAzimuth;
221 if ( dtheta > 180 ) {
239 std::vector<double> dotP(dl.size());
246 allreduce(dotP.data(), dotP.size(), std::plus<double>());
249 double sum = std::accumulate(dotP.begin(), dotP.end() - 1, 0);
253 for (
short b = 0; b < (short)dotP.size() - 1; ++b) {
265 for (
size_t i = 0; i < dotP.size(); ++i) {
266 double const gamma =
std::sqrt(1.0 + dotP[i]);
267 double const beta =
std::sqrt(dotP[i]) / gamma;
280 for (
unsigned int i=0; i<numFiles; i++) {
281 std::string SfileName2 = SfileName;
283 SfileName2 += std::string(
"-Angle" + std::to_string(
int(i)) +
".dat");
287 SfileName2 += std::string(
"-afterEachTurn.dat");
290 outfTheta_m.emplace_back(
new std::ofstream(SfileName2.c_str()));
292 outfTheta_m.back()->setf(std::ios::scientific, std::ios::floatfield);
294 <<
"theta [deg] beta_theta*gamma "
317 *gmsg <<
"* ----------------------------- Cyclotron -------------------------------- *" <<
endl;
326 *gmsg << endl <<
"* This is a Spiral Inflector Simulation! This means the following:" <<
endl;
327 *gmsg <<
"* 1.) It is up to the user to provide appropriate geometry, electric and magnetic fields!" <<
endl;
328 *gmsg <<
"* (Use BANDRF type cyclotron and use RFMAPFN to load both magnetic" <<
endl;
329 *gmsg <<
"* and electric fields, setting SUPERPOSE to an array of TRUE values.)" <<
endl;
330 *gmsg <<
"* 2.) For high currents it is strongly recommended to use the SAAMG fieldsolver," <<
endl;
331 *gmsg <<
"* FFT does not give the correct results (boundary conditions are missing)." <<
endl;
332 *gmsg <<
"* 3.) The whole geometry will be meshed and used for the fieldsolver." <<
endl;
333 *gmsg <<
"* There will be no transformations of the bunch into a local frame und consequently," <<
endl;
334 *gmsg <<
"* the problem will be treated non-relativistically!" <<
endl;
335 *gmsg <<
"* (This is not an issue for spiral inflectors as they are typically < 100 keV/amu.)" <<
endl;
336 *gmsg << endl <<
"* Note: For now, multi-bunch mode (MBM) needs to be de-activated for spiral inflector" <<
endl;
337 *gmsg <<
"* and space charge needs to be solved every time-step. numBunch_m and scSolveFreq are reset." <<
endl;
359 if (insqrt > -1.0
e-10) {
362 throw OpalException(
"Error in ParallelCyclotronTracker::visitCyclotron",
381 throw OpalException(
"Error in ParallelCyclotronTracker::visitCyclotron",
382 "You are trying a local restart from a global h5 file");
388 throw OpalException(
"Error in ParallelCyclotronTracker::visitCyclotron",
389 "You are trying a global restart from a local h5 file");
408 *gmsg <<
"* Bunch global starting position:" <<
endl;
413 *gmsg <<
"* Bunch global starting momenta:" <<
endl;
416 *gmsg <<
"* Reference total momentum = " <<
referencePtot <<
" [beta gamma]" <<
endl;
417 *gmsg <<
"* Reference azimuthal momentum (Pt) = " <<
referencePt <<
" [beta gamma]" <<
endl;
418 *gmsg <<
"* Reference radial momentum (Pr) = " <<
referencePr <<
" [beta gamma]" <<
endl;
419 *gmsg <<
"* Reference axial momentum (Pz) = " <<
referencePz <<
" [beta gamma]" <<
endl;
423 *gmsg <<
"* " << sym <<
"-fold field symmetry " <<
endl;
430 *gmsg <<
"* Field map file = '" << fmfn <<
"'" <<
endl;
433 *gmsg <<
"* Type of cyclotron = " << type <<
" " <<
endl;
437 *gmsg <<
"* Radial aperture = " << rmin <<
" ... " << rmax <<
" [m]" <<
endl;
441 *gmsg <<
"* Vertical aperture = " << zmin <<
" ... " << zmax <<
" [m]" <<
endl;
445 *gmsg <<
"* Harmonic number h = " << h <<
endl;
453 for (
size_t i = 0; i < rfphi.size(); ++i) {
468 double BcParameter[8] = {};
482 *gmsg <<
"* ----------------------------- Collimator ------------------------------- *" <<
endl;
490 *gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
492 double xend = elptr->
getXEnd();
493 *gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
496 *gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
498 double yend = elptr->
getYEnd();
499 *gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
502 *gmsg <<
"* ZStart = " << zstart <<
" [m]" <<
endl;
504 double zend = elptr->
getZEnd();
505 *gmsg <<
"* ZEnd = " << zend <<
" [m]" <<
endl;
508 *gmsg <<
"* Width = " << width <<
" [m]" <<
endl;
512 double BcParameter[8] = {};
514 BcParameter[0] = xstart;
515 BcParameter[1] = xend;
516 BcParameter[2] = ystart;
517 BcParameter[3] = yend;
518 BcParameter[4] = width;
571 "ParallelCylcotronTracker::visitOffset",
572 "Attempt to place an offset when Ring not defined");
604 *gmsg <<
"In Multipole; L= " << mult.
getElementLength() <<
" however the element is missing " <<
endl;
614 *gmsg <<
"Adding MultipoleT" <<
endl;
618 throw OpalException(
"ParallelCyclotronTracker::visitMultipoleT",
619 "Need to define a RINGDEFINITION to use MultipoleT element");
630 *gmsg <<
"Adding MultipoleTStraight" <<
endl;
634 throw OpalException(
"ParallelCyclotronTracker::visitMultipoleTStraight",
635 "Need to define a RINGDEFINITION to use MultipoleTStraight element");
637 myElements.push_back(dynamic_cast<MultipoleTStraight*>(multTstraight.
clone()));
646 *gmsg <<
"Adding MultipoleTCurvedConstRadius" <<
endl;
650 throw OpalException(
"ParallelCyclotronTracker::visitMultipoleTCurvedConstRadius",
651 "Need to define a RINGDEFINITION to use MultipoleTCurvedConstRadius element");
653 myElements.push_back(dynamic_cast<MultipoleTCurvedConstRadius*>(multTccurv.
clone()));
662 *gmsg <<
"Adding MultipoleTCurvedVarRadius" <<
endl;
666 throw OpalException(
"ParallelCyclotronTracker::visitMultipoleTCurvedVarRadius",
667 "Need to define a RINGDEFINITION to use MultipoleTCurvedVarRadius element");
669 myElements.push_back(dynamic_cast<MultipoleTCurvedVarRadius*>(multTvcurv.
clone()));
680 throw OpalException(
"ParallelCylcotronTracker::visitOutputPlane",
681 "Attempt to place an OutputPlane when Ring not defined");
689 double BcParameter[8] = {};
694 BcParameter[0] = centre[0]-width*norm[1];
695 BcParameter[1] = centre[0]+width*norm[1];
696 BcParameter[2] = centre[1]-width*norm[0];
697 BcParameter[3] = centre[1]+width*norm[0];
709 *gmsg <<
"* ----------------------------- Probe ------------------------------------ *" <<
endl;
717 *gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
719 double xend = elptr->
getXEnd();
720 *gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
723 *gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
725 double yend = elptr->
getYEnd();
726 *gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
731 double BcParameter[8] = {};
733 BcParameter[0] = xstart;
734 BcParameter[1] = xend;
735 BcParameter[2] = ystart;
736 BcParameter[3] = yend;
748 *gmsg <<
"In RBend; L= " << bend.
getElementLength() <<
" however the element is missing " <<
endl;
758 *gmsg <<
"* ----------------------------- RFCavity --------------------------------- * " <<
endl;
764 throw OpalException(
"ParallelCyclotronTracker::visitRFCavity",
766 "The ParallelCyclotronTracker can only play with cyclotron type RF system currently...");
772 *gmsg <<
"* RF Field map file = '" << fmfn <<
"'" <<
endl;
774 double rmin = elptr->
getRmin();
775 *gmsg <<
"* Minimal radius of cavity = " << rmin <<
" [m]" <<
endl;
777 double rmax = elptr->
getRmax();
778 *gmsg <<
"* Maximal radius of cavity = " << rmax <<
" [m]" <<
endl;
781 *gmsg <<
"* RF frequency (2*pi*f) = " << rff <<
" [rad/s]" <<
endl;
784 *gmsg <<
"* Cavity azimuth position = " << angle *
Units::rad2deg <<
" [deg] " <<
endl;
787 *gmsg <<
"* Cavity gap width = " << gap <<
" [m] " <<
endl;
790 *gmsg <<
"* Cavity Shift distance = " << pdis <<
" [m] " <<
endl;
792 double phi0 = elptr->
getPhi0();
800 std::shared_ptr<AbstractTimeDependence> freq_atd =
nullptr;
801 std::shared_ptr<AbstractTimeDependence> ampl_atd =
nullptr;
802 std::shared_ptr<AbstractTimeDependence> phase_atd =
nullptr;
805 unityVec.push_back(1.);
806 unityVec.push_back(0.);
807 unityVec.push_back(0.);
808 unityVec.push_back(0.);
814 if (!frequencyModelName.empty()) {
816 *gmsg <<
"* Variable frequency RF Model name " << frequencyModelName <<
endl;
821 if (!amplitudeModelName.empty()) {
823 *gmsg <<
"* Variable amplitude RF Model name " << amplitudeModelName <<
endl;
828 if (!phaseModelName.empty()) {
830 *gmsg <<
"* Variable phase RF Model name " << phaseModelName <<
endl;
837 double BcParameter[8] = {};
839 BcParameter[0] = rmin;
840 BcParameter[1] = rmax;
841 BcParameter[2] = pdis;
842 BcParameter[3] =
angle;
852 *gmsg <<
"* ----------------------------- Ring ------------------------------------- *" <<
endl;
868 throw OpalException(
"Error in ParallelCyclotronTracker::visitRing",
869 "BEAM_PHIINIT is out of [-180, 180)");
884 double BcParameter[8] = {};
889 *gmsg <<
"* Initial beam radius = " <<
referenceR <<
" [m] " <<
endl;
892 *gmsg <<
"* Total reference momentum = " <<
referencePtot <<
" [beta gamma]" <<
endl;
893 *gmsg <<
"* Reference azimuthal momentum = " <<
referencePt <<
" [beta gamma]" <<
endl;
894 *gmsg <<
"* Reference radial momentum = " << referencePr <<
" [beta gamma]" <<
endl;
905 *gmsg <<
"In SBend; L = " << bend.
getElementLength() <<
" however the element is missing " <<
endl;
910 *gmsg <<
"Adding SBend3D" <<
endl;
914 throw OpalException(
"ParallelCyclotronTracker::visitSBend3D",
915 "Need to define a RINGDEFINITION to use SBend3D element");
919 *gmsg <<
"Adding ScalingFFAMagnet" <<
endl;
925 throw OpalException(
"ParallelCyclotronTracker::visitScalingFFAMagnet",
926 "Need to define a RINGDEFINITION to use ScalingFFAMagnet element");
936 *gmsg <<
"* ----------------------------- Septum ----------------------------------- *" <<
endl;
944 *gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
946 double xend = elptr->
getXEnd();
947 *gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
950 *gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
952 double yend = elptr->
getYEnd();
953 *gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
956 *gmsg <<
"* Width = " << width <<
" [m]" <<
endl;
961 double BcParameter[8] = {};
963 BcParameter[0] = xstart;
964 BcParameter[1] = xend;
965 BcParameter[2] = ystart;
966 BcParameter[3] = yend;
967 BcParameter[4] = width;
981 *gmsg <<
"Solenoid: no position of the element given" <<
endl;
992 *gmsg <<
"* ----------------------------- Stripper --------------------------------- *" <<
endl;
1000 *gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
1002 double xend = elptr->
getXEnd();
1003 *gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
1006 *gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
1008 double yend = elptr->
getYEnd();
1009 *gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
1012 *gmsg <<
"* Charge of outcoming particle = +e * " << opcharge <<
endl;
1015 *gmsg <<
"* Mass of the outcoming particle = " << opmass <<
" [GeV/c^2]" <<
endl;
1018 *gmsg << std::boolalpha
1019 <<
"* Particles stripped will be deleted after interaction -> "
1024 double BcParameter[8] = {};
1026 BcParameter[0] = xstart;
1027 BcParameter[1] = xend;
1028 BcParameter[2] = ystart;
1029 BcParameter[3] = yend;
1031 BcParameter[5] = opcharge;
1032 BcParameter[6] = opmass;
1043 *gmsg <<
"* ----------------------------- Vacuum ----------------------------------- *" <<
endl;
1048 double BcParameter[8] = {};
1051 *gmsg <<
"* Residual gas = " << gas <<
endl;
1056 *gmsg <<
"* Pressure field map file = '" << pmfn <<
"'" <<
endl;
1057 *gmsg <<
"* Default pressure = " << pressure <<
" [mbar]" <<
endl;
1059 *gmsg <<
"* Pressure = " << pressure <<
" [mbar]" <<
endl;
1064 *gmsg <<
"* Temperature = " << temperature <<
" [K]" <<
endl;
1067 *gmsg << std::boolalpha
1068 <<
"* Particles stripped will be deleted after interaction -> "
1073 BcParameter[0] = pressure;
1074 BcParameter[1] = pscale;
1075 BcParameter[2] = temperature;
1086 *gmsg <<
"Adding Variable RF Cavity" <<
endl;
1090 throw OpalException(
"ParallelCyclotronTracker::visitVariableRFCavity",
1091 "Need to define a RINGDEFINITION to use VariableRFCavity element");
1101 *gmsg <<
"Adding Variable RF Cavity with Fringe Field" <<
endl;
1102 if (opalRing_m !=
nullptr)
1103 opalRing_m->appendElement(cav);
1105 throw OpalException(
"ParallelCyclotronTracker::visitVariableRFCavityFringeField",
1106 "Need to define a RINGDEFINITION to use VariableRFCavity element");
1115 *gmsg <<
"Adding Vertical FFA Magnet" <<
endl;
1119 throw OpalException(
"ParallelCyclotronTracker::visitVerticalFFAMagnet",
1120 "Need to define a RINGDEFINITION to use VerticalFFAMagnet element");
1135 localpair->first = elementType;
1137 for (
int i = 0; i < 8; i++)
1138 *(((localpair->second).first) + i) = *(BcParameter + i);
1140 (localpair->second).second = elptr;
1164 int maxnlp = 111111;
1167 *gmsg << s <<
"min local particle number: "<< minnlp <<
endl;
1168 *gmsg <<
"* max local particle number: " << maxnlp <<
endl;
1196 *gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl;
1197 *gmsg <<
"* The selected Beam line elements are :" <<
endl;
1214 *gmsg <<
"* ------------------------------------------------------------------------ *" << endl <<
endl;
1222 for (
int k = 0; k < 2; k++) {
1232 std::placeholders::_1,
1233 std::placeholders::_2,
1234 std::placeholders::_3,
1235 std::placeholders::_4);
1239 *gmsg <<
"* 2nd order Leap-Frog integrator" <<
endl;
1244 *gmsg <<
"* Multiple time stepping (MTS) integrator" <<
endl;
1249 *gmsg <<
"* 4th order Runge-Kutta integrator" <<
endl;
1261 *gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl;
1262 *gmsg <<
"* Finalizing i.e. write data and close files :" <<
endl;
1263 for (
auto fd : FieldDimensions) {
1264 ((fd->second).second)->finalise();
1269 *gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl;
1284 double t = 0, dt = 0, oldReferenceTheta = 0;
1288 *gmsg <<
"* MTS: Number of substeps per step is " << numSubsteps <<
endl;
1290 double const dt_inner = dt / double(numSubsteps);
1291 *gmsg <<
"* MTS: The inner time step is therefore " << dt_inner *
Units::s2ns <<
" [ns]" <<
endl;
1295 bool flagTransition =
false;
1297 *gmsg <<
"* ---------------------- Start tracking ---------------------------------- *" <<
endl;
1305 bool finishedTurn =
false;
1319 for (
int n = 0;
n < numSubsteps; ++
n) {
1360 temp_meanTheta, finishedTurn);
1363 oldReferenceTheta, temp_meanTheta);
1365 oldReferenceTheta = temp_meanTheta;
1372 finishedTurn =
true;
1376 <<
", Total number of live particles: "
1392 *gmsg <<
"* ---------------------- DONE TRACKING PARTICLES ------------------------- *" <<
endl;
1422 double t = 0, dt = 0, oldReferenceTheta = 0;
1441 *gmsg <<
"* ---------------------- Start tracking ---------------------------------- *" <<
endl;
1445 bool finishedTurn =
false;
1450 seoMode_m(t, dt, finishedTurn, Ttime, Tdeltr, Tdeltz, TturnNumber);
1466 throw OpalException(
"ParallelCyclotronTracker::GenericTracker()",
1467 "No such tracking mode.");
1477 *gmsg <<
"* ---------------------- DONE TRACKING PARTICLES ------------------------- *" <<
endl;
1513 RFCavity* rfcavity,
double& Dold) {
1519 double distNew = (Rnew[0] * sinx - Rnew[1] * cosx) - PerpenDistance;
1520 double distOld = (Rold[0] * sinx - Rold[1] * cosx) - PerpenDistance;
1521 if (distOld > 0.0 && distNew <= 0.0) flag =
true;
1531 double rmin = rfcavity->
getRmin();
1532 double rmax = rfcavity->
getRmax();
1533 double nomalRadius = (radius - rmin) / (rmax - rmin);
1535 if (nomalRadius <= 1.0 && nomalRadius >= 0.0) {
1537 for (
int j = 0; j < 3; j++)
1543 for (
int j = 0; j < 3; j++)
1570 int lastTurn,
double& ,
double& ) {
1573 int Ndat = t.size();
1580 for (
int i = 0; i < Ndat; i++)
1585 for (
int i = 0; i < Ndat; i++)
1587 double ti = *(t.begin());
1588 double tf = t[t.size()-1];
1589 double T = (tf - ti);
1592 for (
int i = 0; i < Ndat; i++) {
1599 *gmsg <<
"* ************************************* nuR ******************************************* *" <<
endl;
1600 *gmsg << endl <<
"* ===> " << Ndat <<
" data points Ti=" << ti <<
" Tf= " << tf <<
" -> T= " << T <<
endl;
1606 stat = tune->
lombAnalysis(t, r, nhis_lomb, T / lastTurn);
1608 *gmsg <<
"* TUNE: Lomb analysis failed" <<
endl;
1609 *gmsg <<
"* ************************************************************************************* *" <<
endl;
1619 *gmsg <<
"* ************************************* nuZ ******************************************* *" <<
endl;
1620 *gmsg << endl <<
"* ===> " << Ndat <<
" data points Ti=" << ti <<
" Tf= " << tf <<
" -> T= " << T <<
endl;
1624 stat = tune->
lombAnalysis(t, z, nhis_lomb, T / lastTurn);
1626 *gmsg <<
"* TUNE: Lomb analysis failed" <<
endl;
1627 *gmsg <<
"* ************************************************************************************* *" <<
endl;
1640 if (elcycl !=
nullptr)
1642 throw OpalException(
"ParallelCyclotronTracker::getHarmonicNumber()",
1643 std::string(
"The first item in the FieldDimensions list does not ")
1644 +std::string(
"seem to be a Ring or a Cyclotron element"));
1656 for (
int d = 0; d < 3; ++d) {
1675 for (
int d = 0; d < 3; ++d) {
1694 double phi,
Vector_t const translationToGlobal) {
1696 particleVectors -= translationToGlobal;
1715 double phi,
Vector_t const translationToGlobal) {
1732 particleVectors += translationToGlobal;
1743 particleVectors -= meanR;
1756 reverseQuaternion(0) *= -1.0;
1762 particleVectors += meanR;
1775 particleVectors -= meanR;
1825 particleVectors += meanR;
1852 Vector_t const quaternionVectorComponent =
Vector_t(quaternion(1), quaternion(2), quaternion(3));
1853 double const quaternionScalarComponent = quaternion(0);
1857 particleVectors[i] = 2.0f *
dot(quaternionVectorComponent, particleVectors[i]) * quaternionVectorComponent +
1858 (quaternionScalarComponent * quaternionScalarComponent -
1859 dot(quaternionVectorComponent, quaternionVectorComponent)) * particleVectors[i] + 2.0f *
1860 quaternionScalarComponent *
cross(quaternionVectorComponent, particleVectors[i]);
1866 double tolerance = 1.0e-10;
1867 double length2 =
dot(quaternion, quaternion);
1869 if (
std::abs(length2) > tolerance &&
std::abs(length2 - 1.0f) > tolerance) {
1872 quaternion /= length;
1878 double tolerance = 1.0e-10;
1879 double length2 =
dot(vector, vector);
1881 if (
std::abs(length2) > tolerance &&
std::abs(length2 - 1.0f) > tolerance) {
1962 double k_cos_theta =
dot(u, v);
1964 double tolerance1 = 1.0e-5;
1965 double tolerance2 = 1.0e-8;
1968 if (
std::abs(k_cos_theta / k + 1.0) < tolerance1) {
1975 if (
dot(resultVectorComponent, resultVectorComponent) < tolerance2) {
1980 double sinHalfAngle =
std::sin(halfAngle);
1982 resultVectorComponent *= sinHalfAngle;
1988 resultVectorComponent =
cross(u, v);
1991 quaternion(0) = k_cos_theta + k;
1992 quaternion(1) = resultVectorComponent(0);
1993 quaternion(2) = resultVectorComponent(1);
1994 quaternion(3) = resultVectorComponent(2);
2004 bool flagNeedUpdate =
false;
2015 double const distNew = (
itsBunch_m->
R[i][0] * ccd.sinAzimuth -
itsBunch_m->
R[i][1] * ccd.cosAzimuth) - ccd.perpenDistance;
2016 bool tagCrossing =
false;
2018 if (distNew <= 0.0) {
2019 distOld = (oldR[0] * ccd.sinAzimuth - oldR[1] * ccd.cosAzimuth) - ccd.perpenDistance;
2020 if (distOld > 0.0) tagCrossing =
true;
2024 double const dt2 = h - dt1;
2039 return flagNeedUpdate;
2046 bool flagNeedUpdate =
false;
2059 return flagNeedUpdate;
2066 bool flagNeedUpdate =
push(0.5 * h);
2081 flagNeedUpdate |=
kick(h);
2084 flagNeedUpdate |=
push(0.5 * h);
2098 Vacuum* vac =
static_cast<Vacuum*
>(((*sindex)->second).second);
2113 *gmsg <<
"* Total number of particles after PluginElement= "
2131 allreduce(flagNeedUpdate, 1, std::logical_or<bool>());
2133 if (flagNeedUpdate) {
2135 std::vector<size_t> locLostParticleNum(bunchCount, 0);
2138 std::unique_ptr<size_t[]> localBinCount;
2141 localBinCount = std::unique_ptr<size_t[]>(
new size_t[leb]);
2142 for (
int i = 0; i < leb; ++i)
2143 localBinCount[i] = 0;
2160 for (
int i = 0; i < leb; ++i) {
2165 std::vector<size_t> localnum(bunchCount + 1);
2166 for (
size_t i = 0; i < localnum.size() - 1; ++i) {
2182 std::vector<size_t> totalnum(bunchCount + 1);
2185 allreduce(localnum.data(), totalnum.data(), localnum.size(), std::plus<size_t>());
2188 for (
short i = 0; i < bunchCount; ++i) {
2192 size_t sum = std::accumulate(totalnum.begin(),
2193 totalnum.end() - 1, 0);
2195 if ( sum != totalnum[bunchCount] ) {
2196 throw OpalException(
"ParallelCyclotronTracker::deleteParticle()",
2197 "Total number of particles " + std::to_string(totalnum[bunchCount]) +
2198 " != " + std::to_string(sum) +
" (sum over all bunches)");
2201 size_t globLostParticleNum = 0;
2202 size_t locNumLost = std::accumulate(locLostParticleNum.begin(),
2203 locLostParticleNum.end(), 0);
2205 reduce(locNumLost, globLostParticleNum, 1, std::plus<size_t>());
2207 if ( globLostParticleNum > 0 ) {
2209 <<
", lost " << globLostParticleNum <<
" particles" <<
endl;
2212 if (totalnum[bunchCount] == 0) {
2214 return flagNeedUpdate;
2247 return flagNeedUpdate;
2334 *gmsg <<
"* Restart in the local frame" <<
endl;
2351 *gmsg <<
"* Restart in the global frame" <<
endl;
2370 double radius =
std::sqrt(meanR[0] * meanR[0] + meanR[1] * meanR[1]);
2388 *gmsg <<
endl <<
"* *********************** Bunch information in local frame: ************************";
2410 *gmsg << endl <<
"* *********************** Bunch information in global frame: ***********************";
2422 double pTotalMean = 0.0;
2427 allreduce(pTotalMean, 1, std::plus<double>());
2432 if (tolerance > 0 &&
2434 throw OpalException(
"ParallelCyclotronTracker::checkFileMomentum",
2435 "The total momentum of the particle distribution\n"
2436 "in the global reference frame: " +
2437 std::to_string(pTotalMean) +
",\n"
2438 "is different from the momentum given\n"
2439 "in the \"BEAM\" command: " +
2441 "In Opal-cycl the initial distribution\n"
2442 "is specified in the local reference frame.\n"
2443 "When using a \"FROMFILE\" type distribution, the momentum \n"
2444 "must be the same as the specified in the \"BEAM\" command,\n"
2445 "which is in global reference frame.");
2464 int found[2] = {-1, -1};
2480 int numberOfPart = 0;
2482 while(notReceived > 0) {
2487 if (rmsg ==
nullptr)
2488 ERRORMSG(
"Could not receive from client nodes in main." <<
endl);
2492 rmsg->
get(&numberOfPart);
2494 for (
int i = 0; i < numberOfPart; ++i) {
2497 for (
int ii = 0; ii < 6; ii++) {
2505 for (
int i = 0; i < counter; ++i) {
2509 for (
int j = 0; j < 3; ++j) {
2517 for (
auto tmpid : tmpi) {
2529 for (
int ii = 0; ii < 6; ii++) {
2541 for (
int i = 0; i < counter; i++) {
2545 for (
int j = 0; j < 3; j++) {
2552 ERRORMSG(
"Ippl::Comm->send(smsg, 0, tag) failed " <<
endl);
2585 double phi = 0.0, psi = 0.0;
2649 (((*DumpSindex)->second).second)->apply(meanR, meanP, temp_t,
extE_m,
extB_m);
2715 double const theta =
std::atan2(meanR(1), meanR(0));
2743 (((*DumpSindex)->second).second)->apply(meanR, meanP, temp_t,
extE_m,
extB_m);
2749 bool dumpLocalFrame =
true;
2750 std::string dumpString =
"local";
2752 dumpLocalFrame =
false;
2753 dumpString =
"global";
2756 if (dumpLocalFrame ==
true) {
2780 psi * Units::rad2deg,
2784 if (dumpLocalFrame ==
true) {
2793 *gmsg <<
endl <<
"* Integration step " <<
step_m + 1
2794 <<
" (no phase space dump for <= 2 particles)" <<
endl;
2797 <<
" (" << dumpString <<
" frame) at integration step " <<
step_m + 1 <<
endl;
2802 *gmsg <<
"* T = " << temp_t <<
" s"
2804 *gmsg <<
"* E = " << E <<
" MeV"
2805 <<
", beta * gamma = " << betagamma_temp <<
endl;
2806 *gmsg <<
"* Bunch position: R = " <<
referenceR <<
" mm"
2820 const bool& finishedTurn)
2828 if (!(
step_m + 1 % 1000)) {
2913 *gmsg <<
"* Beginning of this run is at t = " << t *
Units::s2ns <<
" [ns]" <<
endl;
2914 *gmsg <<
"* The time step is set to dt = " << dt *
Units::s2ns <<
" [ns]" <<
endl;
2917 *gmsg <<
"* MBM: Time interval between neighbour bunches is set to "
2919 *gmsg <<
"* MBM: The particles energy bin reset frequency is set to "
2930 *gmsg <<
"* ------------------------- STATIC EQUILIBRIUM ORBIT MODE ----------------------------- *" << endl
2931 <<
"* Instruction: When the total particle number is equal to 2, SEO mode is triggered *" << endl
2932 <<
"* automatically. This mode does NOT include any RF cavities. The initial distribution *" << endl
2933 <<
"* file must be specified. In the file the first line is for reference particle and the *" << endl
2934 <<
"* second line is for off-center particle. The tune is calculated by FFT routines based *" << endl
2935 <<
"* on these two particles. *" << endl
2936 <<
"* ---------------- NOTE: SEO MODE ONLY WORKS SERIALLY ON SINGLE NODE ------------------ *" <<
endl;
2939 throw OpalException(
"Error in ParallelCyclotronTracker::initializeTracking_m",
2940 "SEO MODE ONLY WORKS SERIALLY ON SINGLE NODE");
2945 *gmsg <<
"* ------------------------------ SINGLE PARTICLE MODE --------------------------------- *" << endl
2946 <<
"* Instruction: When the total particle number is equal to 1, single particle mode is *" << endl
2947 <<
"* triggered automatically. The initial distribution file must be specified which should *" << endl
2948 <<
"* contain only one line for the single particle *" << endl
2949 <<
"* ---------NOTE: SINGLE PARTICLE MODE ONLY WORKS SERIALLY ON A SINGLE NODE ------------ *" <<
endl;
2952 throw OpalException(
"Error in ParallelCyclotronTracker::initializeTracking_m",
2953 "SINGLE PARTICLE MODE ONLY WORKS SERIALLY ON A SINGLE NODE");
2964 throw OpalException(
"ParallelCyclotronTracker::initializeTracking_m()",
2965 "No such tracking mode.");
2969 return std::make_tuple(t, dt, oldReferenceTheta);
2981 *gmsg <<
"* Final energy of reference particle = " << FinalEnergy <<
" [MeV]" <<
endl;
2982 *gmsg <<
"* Total phase space dump number(includes the initial distribution) = " <<
lastDumpedStep_m + 1 <<
endl;
2983 *gmsg <<
"* One can restart simulation from the last dump step (--restart " <<
lastDumpedStep_m <<
")" <<
endl;
2993 *gmsg <<
"* **************** The result for tune calculation (NO space charge) ******************* *" << endl
2994 <<
"* Number of tracked turns: " << TturnNumber.back() <<
endl;
2996 getTunes(Ttime, Tdeltr, Tdeltz, TturnNumber.back(), nur, nuz);
3007 *gmsg <<
"*" <<
endl;
3009 *gmsg <<
"* Cave: Turn number is not correct for restart mode"<<
endl;
3020 *gmsg <<
endl <<
"* *********************** Bunch information in global frame: ***********************";
3027 *gmsg << endl <<
"* No Particles left in bunch" <<
endl;
3028 *gmsg <<
"* **********************************************************************************" <<
endl;
3050 double r_tuning[2], z_tuning[2];
3085 Tdeltz.push_back(z_tuning[1]);
3086 Tdeltr.push_back(r_tuning[1] - r_tuning[0]);
3093 bool& finishedTurn,
double& oldReferenceTheta) {
3127 temp_meanTheta, finishedTurn);
3130 oldReferenceTheta, temp_meanTheta);
3132 oldReferenceTheta = temp_meanTheta;
3159 static bool flagTransition =
false;
3239 finishedTurn =
true;
3243 <<
", Total number of live particles: "
3259 bool tag_crossing =
false;
3260 double DistOld = 0.0;
3265 rfcav =
static_cast<RFCavity*
>(((*sindex)->second).second);
3269 if ( tag_crossing ) {
3273 double dt1 = DistOld / (oldBeta *
Physics::c);
3274 double dt2 = dt - dt1;
3281 if (dt / dt1 < 1.0e9) {
3285 RFkick(rfcav, t, dt1, i);
3290 if (dt / dt2 < 1.0e9) {
3301 const double& oldReferenceTheta,
3302 const double& temp_meanTheta) {
3304 for (
unsigned int i=0; i<=2; i++) {
3310 <<
" " << std::hypot(
R(0),
R(1))
3311 <<
" " << P(0) *
std::cos(temp_meanTheta) + P(1) *
std::sin(temp_meanTheta)
3313 <<
" " << - P(0) *
std::sin(temp_meanTheta) + P(1) *
std::cos(temp_meanTheta)
3323 const double& temp_meanTheta,
3324 bool& finishedTurn) {
3327 finishedTurn =
true;
3334 <<
" " << P(0) *
std::cos(temp_meanTheta) +
3337 <<
" " << - P(0) *
std::sin(temp_meanTheta) +
3426 bool outOfBound = (((*sindex)->second).second)->apply(i, t, Efield, Bfield);
3439 bool outOfBound = (((*sindex)->second).second)->apply(R, P, t, Efield, Bfield);
3466 if ( flagTransition ) {
3467 *gmsg <<
"* MBM: Saving beam distribution at turn " <<
turnnumber_m <<
endl;
3468 *gmsg <<
"* MBM: After one revolution, Multi-Bunch Mode will be invoked" <<
endl;
3478 throw OpalException(
"ParallelCyclotronTracker::injectBunch()",
3479 "Unknown return value " + std::to_string(result));
3513 std::vector<double> lpaths(1);
3546 for (
short b = 0; b <
mbHandler_m->getNumBunch(); ++b) {
virtual void visitOffset(const Offset &)
Apply the algorithm to a offset (placement).
void setOpenMode(OpenMode openMode)
virtual void visitVacuum(const Vacuum &)
Apply the algorithm to a vacuum space.
void setGlobalFieldMap(Component *field)
virtual double getCosAzimuth() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Pure virtual implementation of Component.
std::vector< double > dvector_t
static OpalData * getInstance()
Tps< T > sqrt(const Tps< T > &x)
Square root.
ParticleAttrib< short > cavityGapCrossed
void setTotalNum(size_t n)
constexpr double c
The velocity of light in m/s.
bool computeExternalFields_m(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &Efield, Vector_t &Bfield)
Calculate the field map at an arbitrary point.
void computePathLengthUpdate(std::vector< double > &dl, const double &dt)
Message & put(const T &val)
double getHarmonicNumber()
void setGlobalToLocalQuaternion(Quaternion_t globalToLocalQuaternion)
virtual void visitScalingFFAMagnet(const ScalingFFAMagnet &bend)
Apply the algorithm to a scaling FFA magnet.
std::string boolVectorToUpperString(const std::vector< bool > &b)
virtual double getRmax() const
void dumpAzimuthAngles_m(const double &t, const Vector_t &R, const Vector_t &P, const double &oldReferenceTheta, const double &temp_meanTheta)
virtual double getRmin() const
std::string getCavityTypeString() const
IpplTimings::TimerRef TransformTimer_m
unsigned int delPartFreq
The frequency to delete particles (currently: OPAL-cycl only)
virtual void do_binaryRepart()
item[EANGLE] Entrance edge angle(radians).\item[ROTATION] Rotation of the magnet about its central axis(radians
void singleParticleDump()
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
bool RFkick(RFCavity *rfcavity, const double t, const double dt, const int Pindex)
IpplTimings::TimerRef BinRepartTimer_m
bool hasMultiBunch() const
std::vector< std::unique_ptr< std::ofstream > > outfTheta_m
output coordinates at different azimuthal angles and one after every turn
virtual double getAzimuth() const
void setLocalBinCount(size_t num, int bin)
void setLocalTrackStep(long long n)
step in a TRACK command
std::unique_ptr< MultiBunchHandler > mbHandler_m
void borisExternalFields(double h)
double getSymmetry() const
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a closed orbit corrector.
virtual bool checkVacuum(PartBunchBase< double, 3 > *bunch, Cyclotron *cycl)
int lombAnalysis(double *x, double *y, int Ndat, int nhis)
double getOPCharge() const
Vector_t calcMeanP() const
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a degrader.
Message * receive_block(int &node, int &tag)
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
std::tuple< double, double, double > initializeTracking_m()
virtual void visitSBend3D(const SBend3D &)
Apply the algorithm to a sector bend with 3D field map.
int repartFreq
The frequency to do particles repartition for better load balance between nodes.
DumpFrame psDumpFrame
flag to decide in which coordinate frame the phase space will be dumped for OPAL-cycl ...
ParticleAttrib< Vector_t > P
item[EANGLE] Entrance edge counterclockwise This enables to obtain skew at each point along the its radius is computed such that the reference trajectory always remains in the centre of the magnet In the body of the magnet the radius is set from the LENGTH and ANGLE attributes It is then continuously changed to be proportional to the dipole field on the reference trajectory while entering the end fields This attribute is only to be set TRUE for a non zero dipole component(Default:FALSE)\item[VARSTEP] The step size(meters) used in calculating the reference trajectory for VARRARDIUS
static void writeFields(Component *field)
ElementBase * clone() const override
ElementBase * clone() const override
void bgf_main_collision_test()
virtual void visitMultipoleT(const MultipoleT &)
Apply the algorithm to an arbitrary multipole.
virtual std::string getFieldMapFN() const
double getHarmonicNumber() const
Vektor< double, 3 > Vector_t
double getBeamPRInit() const
unsigned int getNumberOfTrimcoils() const
bool angleBetweenAngles(const double angle, const double min, const double max)
check if angle (in rad and in range [0,2pi]) is within [min, max]
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift space.
void destroy(size_t M, size_t I, bool doNow=false)
ParticleAttrib< Vector_t > Ef
Vector_t getCentre() const
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
int scSolveFreq
The frequency to solve space charge fields.
ParticleAttrib< short > bunchNum
virtual double getPRinit() const
int next_tag(int t, int s=1000)
void rotateAroundZ(ParticleAttrib< Vector_t > &particleVectors, double const phi)
ParticleAttrib< double > M
virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet &bend)
Apply the algorithm to a vertical FFA magnet.
void update_m(double &t, const double &dt, const bool &finishedTurn)
Update time and path length, write to output files.
4-th order Runnge-Kutta stepper
long long getLocalTrackStep() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
virtual ElementBase * clone() const override
Vector_t getNormal() const
std::vector< CavityCrossData > cavCrossDatas_m
bool applyPluginElements(const double dt)
int partInside(const Vector_t &r, const Vector_t &v, const double dt, Vector_t &intecoords, int &triId)
void calcBeamParameters()
virtual void visitMultipoleTCurvedVarRadius(const MultipoleTCurvedVarRadius &)
Apply the algorithm to an arbitrary curved multipole of variable radius.
double computeRadius(const Vector_t &meanR) const
An abstract sequence of beam line components.
void bunchMode_m(double &t, const double dt, bool &finishedTurn)
double getTemperature() const
Message & get(const T &cval)
Interface for general multipole.
virtual void visitSBend(const SBend &)
Apply the algorithm to a sector bend.
BoundaryGeometry * getGlobalGeometry()
virtual void visitVariableRFCavity(const VariableRFCavity &cav)
Apply the algorithm to a variabel RF cavity.
ScalingFFAMagnet * clone() const override
virtual ElementBase * clone() const override
Interface for drift space.
virtual double getPhi0() const
std::string getTypeString() const
Interface for general corrector.
double getBeta() const
The relativistic beta per particle.
virtual double getRmax() const
virtual const std::string & getName() const
Get element name.
void rotateWithQuaternion(ParticleAttrib< Vector_t > &vectorArray, Quaternion_t const quaternion)
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
double getQ() const
Access to reference data.
constexpr double pi
The value of .
BFieldType getBFieldType() const
virtual std::vector< bool > getSuperpose() const
Inform & endl(Inform &inf)
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual double getGapWidth() const
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
void appendElement(const Component &element)
virtual double getCycFrequency() const
bool checkGapCross(Vector_t Rold, Vector_t Rnew, RFCavity *rfcavity, double &DistOld)
virtual double getRmin() const
virtual double getRinit() const
void normalizeQuaternion(Quaternion_t &quaternion)
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Pure virtual implementation of Component.
double getBeamRInit() const
void updateTime(const double &dt)
void setMultiBunchInitialPathLengh(MultiBunchHandler *mbhandler_p)
void seoMode_m(double &t, const double dt, bool &finishedTurn, dvector_t &Ttime, dvector_t &Tdeltr, dvector_t &Tdeltz, ivector_t &TturnNumber)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
void initTrackOrbitFile()
void dumpThetaEachTurn_m(const double &t, const Vector_t &R, const Vector_t &P, const double &temp_meanTheta, bool &finishedTurn)
void initDistInGlobalFrame()
ParticleAttrib< Vector_t > Bf
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
std::string getPressureMapFN() const
bool getFieldsAtPoint(const double &t, const size_t &Pindex, Vector_t &Efield, Vector_t &Bfield)
double beamInitialRotation
static void startTimer(TimerRef t)
std::string::iterator iterator
double getBeamPhiInit() const
virtual void iterate(BeamlineVisitor &, bool r2l) const
Apply visitor to all elements of the line.
std::unique_ptr< Stepper< function_t > > itsStepper_mp
T euclidean_norm(const Vector< T > &)
Euclidean norm.
std::string getFrequencyModelName()
double calculateAngle2(double x, double y)
bool isTurnDone()
Check if turn done.
virtual bool getSpiralFlag() const
virtual void visitStripper(const Stripper &)
Apply the algorithm to a particle stripper.
virtual void visitProbe(const Probe &)
Apply the algorithm to a probe.
void writeMultiBunchStatistics(PartBunchBase< double, 3 > *beam, MultiBunchHandler *mbhandler)
void setTotalNumPerBunch(size_t numpart, short n)
std::string getPhaseModelName()
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
size_t getTotalNum() const
void buildupFieldList(double BcParameter[], ElementType elementType, Component *elptr)
virtual void visitRing(const Ring &ring)
Apply the algorithm to a ring.
static Communicate * Comm
The base class for all OPAL exceptions.
CavityType getCavityType() const
void getMomentaKick(const double normalRadius, double momentum[], const double t, const double dtCorrt, const int PID, const double restMass, const int chargenumber)
used in OPAL-cycl
void rotateAroundX(ParticleAttrib< Vector_t > &particleVectors, double const psi)
virtual double getZinit() const
int getStepsPerTurn() const
virtual double getMaxZ() const
Inform & level4(Inform &inf)
std::unique_ptr< LossDataSink > lossDs_m
size_t getLocalNum() const
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
int psDumpFreq
The frequency to dump the phase space, i.e.dump data when steppsDumpFreq==0.
bool psDumpEachTurn
phase space dump flag for OPAL-cycl
void updatePathLength(const double &dt)
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
double calculateAngle(double x, double y)
bool getTunes(dvector_t &t, dvector_t &r, dvector_t &z, int lastTurn, double &nur, double &nuz)
const PartData itsReference
The reference information.
Vector_t getBeta(Vector_t p)
static Vector_t const yaxis
void injectBunch(bool &flagTransition)
virtual void visitMultipoleTCurvedConstRadius(const MultipoleTCurvedConstRadius &)
Apply the algorithm to an arbitrary curved multipole of constant radius.
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
virtual void visitVariableRFCavityFringeField(const VariableRFCavityFringeField &cav)
Apply the algorithm to a variable RF cavity with Fringe Field.
void allreduce(const T *input, T *output, int count, Op op)
void finalizeTracking_m(dvector_t &Ttime, dvector_t &Tdeltr, dvector_t &Tdeltz, ivector_t &TturnNumber)
void dumpAngle(const double &theta, double &prevAzimuth, double &azimuth, const short &bunchNr=0)
T prod_boost_vector(const boost::numeric::ublas::matrix< double > &rotation, const T &vector)
ParticleAttrib< double > Q
beamline_list FieldDimensions
virtual double getSymmetry() const
virtual double getElementLength() const
Get design length.
virtual ~ParallelCyclotronTracker()
int sptDumpFreq
The frequency to dump single particle trajectory of particles with ID = 0 & 1.
const size_t initialLocalNum_m
virtual void visitCyclotron(const Cyclotron &cycl)
Apply the algorithm to a cyclotron.
constexpr double q_e
The elementary charge in As.
const std::string & getCyclotronType() const
void computeSpaceChargeFields_m()
virtual ElementBase * clone() const override
std::vector< double > azimuth_angle_m
the different azimuthal angles for the outfTheta_m output files
double getHorizontalExtent() const
double getZStart()
Member variable access.
ParticleAttrib< double > dt
const std::string & getOpalName() const
Return object name.
Steppers::TimeIntegrator stepper_m
virtual double getMaxR() const
static void writeFields(Component *field)
double getGamma(Vector_t p)
double getChargePerParticle() const
get the macro particle charge
void updateAzimuthAndRadius()
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
IpplTimings::TimerRef PluginElemTimer_m
virtual void visitOutputPlane(const OutputPlane &)
Apply the algorithm to a outputplane.
Tps< T > cos(const Tps< T > &x)
Cosine.
std::ofstream outfTrackOrbit_m
static Vector_t const xaxis
The positive axes unit vectors.
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
virtual bool hasAttribute(const std::string &aKey) const
Test for existence of an attribute.
virtual void setBinCharge(int bin, double q)
Set the charge of one bin to the value of q and all other to zero.
std::vector< PluginElement * > pluginElements_m
void openFiles(size_t numFiles, std::string fn)
@ open / close output coordinate files
IpplTimings::TimerRef DumpTimer_m
std::function< bool(const double &, const size_t &, Vector_t &, Vector_t &)> function_t
virtual std::vector< double > getEScale() const
static Vector_t const zaxis
T deg(T x)
Convert radians to degrees.
virtual ElementBase * clone() const =0
Return clone.
void boundp_destroyCycl()
void setGlobalMeanR(Vector_t globalMeanR)
struct ParallelCyclotronTracker::settings setup_m
std::vector< int > ivector_t
IpplTimings::TimerRef IntegrationTimer_m
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
virtual std::vector< double > getRfPhi() const
virtual void computeSelfFields_cycl(double gamma)=0
void setLocalNumPerBunch(size_t numpart, short n)
int maxSteps_m
The maximal number of steps the system is integrated.
std::pair< ElementType, element_pair > type_pair
virtual double getPerpenDistance() const
virtual double getCyclHarm() const
void localToGlobal(ParticleAttrib< Vector_t > &vectorArray, double phi, Vector_t const translationToGlobal=0)
bool isMultiBunch() const
void globalToLocal(ParticleAttrib< Vector_t > &vectorArray, double phi, Vector_t const translationToGlobal=0)
std::string getInputBasename()
get input file name without extension
virtual double getMinR() const
void operator()(double x)
virtual std::string getFieldMapFN() const
void singleMode_m(double &t, const double dt, bool &finishedTurn, double &oldReferenceTheta)
std::string getAmplitudeModelName()
int rebinFreq
The frequency to reset energy bin ID for all particles.
void countTotalNumPerBunch()
virtual void visitSeptum(const Septum &)
Apply the algorithm to a septum.
Inform & level3(Inform &inf)
static TimerRef getTimer(const char *nm)
std::string doubleVectorToString(const std::vector< double > &v)
virtual double getPHIinit() const
constexpr double e
The value of .
bool deleteParticle(bool=false)
virtual double getBScale() const
void performDestroy(bool updateLocalNum=false)
double get_meanKineticEnergy() const
ParticleAttrib< int > Bin
void normalizeVector(Vector_t &vector)
Ring describes a ring type geometry for tracking.
short getNumBunch() const
void getQuaternionTwoVectors(Vector_t u, Vector_t v, Quaternion_t &quaternion)
Vector_t calcMeanR(short bunchNr=-1) const
FieldSolverType getFieldSolverType() const
Return the fieldsolver type if we have a fieldsolver.
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a solenoid.
DistributionType getDistType() const
bool for_each(const BareFieldIterator< T, D > &p, SameFieldID s, C)
Interface for a single beam element.
void gapCrossKick_m(size_t i, double t, double dt, const Vector_t &Rold, const Vector_t &Pold)
void checkInitialReferenceParticle(double refR, double refTheta, double refZ)
double getBeamThetaInit() const
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sin(const Tps< T > &x)
Sine.
double bega
The reference variables.
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a beam position monitor.
void checkNumPart(std::string s)
static void stopTimer(TimerRef t)
std::string getResidualGasName()
ParallelCyclotronTracker()
IpplTimings::TimerRef DelParticleTimer_m
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
double getXStart() const
Member variable access.
virtual double getSinAzimuth() const
virtual void execute()
Apply the algorithm to the top-level beamline.
virtual std::vector< double > getRfFrequ() const
virtual double getPZinit() const
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
double getPressure() const
size_t getTotalNumPerBunch(short n) const
std::list< Component * > myElements
int statDumpFreq
The frequency to dump statistical values, e.e. dump data when stepstatDumpFreq==0.
const size_t initialTotalNum_m
size_t getLocalNumPerBunch(short n) const
virtual ElementBase * clone() const override
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
double getMomentumTolerance() const
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
static std::shared_ptr< AbstractTimeDependence > getTimeDependence(std::string name)
virtual double getMinZ() const
void bunchDumpPhaseSpaceData()
double getGamma() const
The relativistic gamma per particle.
virtual void visitMultipoleTStraight(const MultipoleTStraight &)
Apply the algorithm to an arbitrary straight multipole.