114 bool revBeam,
bool revTrack,
119 const double& mbPara,
120 const std::string& mbMode,
121 const std::string& mbBinning)
122 :
Tracker(beamline, bunch, reference, revBeam, revTrack)
138 if ( numBunch > 1 ) {
141 mbPara, mbMode, mbBinning)
174 Inform msg(
"bgf_main_collision_test ");
186 for (
size_t i = 0; i <
itsBunch_m->getLocalNum(); i++) {
188 dtime, intecoords, triId);
197 <<
" lost on boundary geometry" <<
endl;
206 const short& bunchNr) {
207 if ( prevAzimuth < 0.0 ) {
212 azimuth = theta + plus;
214 double dtheta = theta - prevAzimuth;
218 if ( dtheta > 180 ) {
228 return Units::m2mm * std::sqrt(meanR(0) * meanR(0) + meanR(1) * meanR(1));
236 std::vector<double> dotP(dl.size());
239 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
243 allreduce(dotP.data(), dotP.size(), std::plus<double>());
246 double sum = std::accumulate(dotP.begin(), dotP.end() - 1, 0);
250 for (
short b = 0; b < (short)dotP.size() - 1; ++b) {
251 dotP[b] /= double(
itsBunch_m->getTotalNumPerBunch(b));
254 }
else if (
itsBunch_m->getLocalNum() == 0 ) {
262 for (
size_t i = 0; i < dotP.size(); ++i) {
263 double const gamma = std::sqrt(1.0 + dotP[i]);
264 double const beta = std::sqrt(dotP[i]) / gamma;
277 for (
unsigned int i=0; i<numFiles; i++) {
278 std::string SfileName2 = SfileName;
280 SfileName2 += std::string(
"-Angle" + std::to_string(
int(i)) +
".dat");
284 SfileName2 += std::string(
"-afterEachTurn.dat");
287 outfTheta_m.emplace_back(
new std::ofstream(SfileName2.c_str()));
289 outfTheta_m.back()->setf(std::ios::scientific, std::ios::floatfield);
291 <<
"theta [deg] beta_theta*gamma "
292 <<
"z [mm] beta_z*gamma" << std::endl;
314 *
gmsg <<
"* ----------------------------- Cyclotron -------------------------------- *" <<
endl;
323 *
gmsg <<
endl <<
"* This is a Spiral Inflector Simulation! This means the following:" <<
endl;
324 *
gmsg <<
"* 1.) It is up to the user to provide appropriate geometry, electric and magnetic fields!" <<
endl;
325 *
gmsg <<
"* (Use BANDRF type cyclotron and use RFMAPFN to load both magnetic" <<
endl;
326 *
gmsg <<
"* and electric fields, setting SUPERPOSE to an array of TRUE values.)" <<
endl;
327 *
gmsg <<
"* 2.) For high currents it is strongly recommended to use the SAAMG fieldsolver," <<
endl;
328 *
gmsg <<
"* FFT does not give the correct results (boundary conditions are missing)." <<
endl;
329 *
gmsg <<
"* 3.) The whole geometry will be meshed and used for the fieldsolver." <<
endl;
330 *
gmsg <<
"* There will be no transformations of the bunch into a local frame und consequently," <<
endl;
331 *
gmsg <<
"* the problem will be treated non-relativistically!" <<
endl;
332 *
gmsg <<
"* (This is not an issue for spiral inflectors as they are typically < 100 keV/amu.)" <<
endl;
333 *
gmsg <<
endl <<
"* Note: For now, multi-bunch mode (MBM) needs to be de-activated for spiral inflector" <<
endl;
334 *
gmsg <<
"* and space charge needs to be solved every time-step. numBunch_m and scSolveFreq are reset." <<
endl;
356 if (insqrt > -1.0e-10) {
359 throw OpalException(
"Error in ParallelCyclotronTracker::visitCyclotron",
378 throw OpalException(
"Error in ParallelCyclotronTracker::visitCyclotron",
379 "You are trying a local restart from a global h5 file");
385 throw OpalException(
"Error in ParallelCyclotronTracker::visitCyclotron",
386 "You are trying a global restart from a local h5 file");
405 *
gmsg <<
"* Bunch global starting position:" <<
endl;
410 *
gmsg <<
"* Bunch global starting momenta:" <<
endl;
414 *
gmsg <<
"* Reference azimuthal momentum (Pt) = " <<
referencePt <<
" [beta gamma]" <<
endl;
419 double sym =
cycl_m->getSymmetry();
420 *
gmsg <<
"* " << sym <<
"-fold field symmetry " <<
endl;
426 std::string fmfn =
cycl_m->getFieldMapFN();
427 *
gmsg <<
"* Field map file = '" << fmfn <<
"'" <<
endl;
429 std::string
type =
cycl_m->getCyclotronType();
430 *
gmsg <<
"* Type of cyclotron = " <<
type <<
" " <<
endl;
432 double rmin =
cycl_m->getMinR();
433 double rmax =
cycl_m->getMaxR();
434 *
gmsg <<
"* Radial aperture = " << rmin <<
" ... " << rmax <<
" [m]" <<
endl;
436 double zmin =
cycl_m->getMinZ();
437 double zmax =
cycl_m->getMaxZ();
438 *
gmsg <<
"* Vertical aperture = " << zmin <<
" ... " << zmax <<
" [m]" <<
endl;
440 double h =
cycl_m->getCyclHarm();
441 *
gmsg <<
"* Number of trimcoils = " <<
cycl_m->getNumberOfTrimcoils() <<
endl;
442 *
gmsg <<
"* Harmonic number h = " << h <<
endl;
444 std::vector<double> rffrequ =
cycl_m->getRfFrequ();
448 std::vector<double> rfphi =
cycl_m->getRfPhi();
449 for (
size_t i = 0; i < rfphi.size(); ++i) {
454 std::vector<double> escale =
cycl_m->getEScale();
457 std::vector<bool> superpose =
cycl_m->getSuperpose();
464 double BcParameter[8] = {};
465 BcParameter[0] =
cycl_m->getRmin();
466 BcParameter[1] =
cycl_m->getRmax();
478 *
gmsg <<
"* ----------------------------- Collimator ------------------------------- *" <<
endl;
486 *
gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
488 double xend = elptr->
getXEnd();
489 *
gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
492 *
gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
494 double yend = elptr->
getYEnd();
495 *
gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
498 *
gmsg <<
"* ZStart = " << zstart <<
" [m]" <<
endl;
500 double zend = elptr->
getZEnd();
501 *
gmsg <<
"* ZEnd = " << zend <<
" [m]" <<
endl;
504 *
gmsg <<
"* Width = " << width <<
" [m]" <<
endl;
508 double BcParameter[8] = {};
510 BcParameter[0] = xstart;
511 BcParameter[1] = xend;
512 BcParameter[2] = ystart;
513 BcParameter[3] = yend;
514 BcParameter[4] = width;
535 *
gmsg <<
"In Degrader; L= " << deg.getElementLength() <<
endl;
567 "ParallelCylcotronTracker::visitOffset",
568 "Attempt to place an offset when Ring not defined");
610 *
gmsg <<
"Adding MultipoleT" <<
endl;
614 throw OpalException(
"ParallelCyclotronTracker::visitMultipoleT",
615 "Need to define a RINGDEFINITION to use MultipoleT element");
627 throw OpalException(
"ParallelCylcotronTracker::visitOutputPlane",
628 "Attempt to place an OutputPlane when Ring not defined");
636 double BcParameter[8] = {};
641 BcParameter[0] = centre[0]-width*norm[1];
642 BcParameter[1] = centre[0]+width*norm[1];
643 BcParameter[2] = centre[1]-width*norm[0];
644 BcParameter[3] = centre[1]+width*norm[0];
656 *
gmsg <<
"* ----------------------------- Probe ------------------------------------ *" <<
endl;
664 *
gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
666 double xend = elptr->
getXEnd();
667 *
gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
670 *
gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
672 double yend = elptr->
getYEnd();
673 *
gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
678 double BcParameter[8] = {};
680 BcParameter[0] = xstart;
681 BcParameter[1] = xend;
682 BcParameter[2] = ystart;
683 BcParameter[3] = yend;
705 *
gmsg <<
"* ----------------------------- RFCavity --------------------------------- * " <<
endl;
711 throw OpalException(
"ParallelCyclotronTracker::visitRFCavity",
713 "The ParallelCyclotronTracker can only play with cyclotron type RF system currently...");
719 *
gmsg <<
"* RF Field map file = '" << fmfn <<
"'" <<
endl;
721 double rmin = elptr->
getRmin();
722 *
gmsg <<
"* Minimal radius of cavity = " << rmin <<
" [m]" <<
endl;
724 double rmax = elptr->
getRmax();
725 *
gmsg <<
"* Maximal radius of cavity = " << rmax <<
" [m]" <<
endl;
728 *
gmsg <<
"* RF frequency (2*pi*f) = " << rff <<
" [rad/s]" <<
endl;
734 *
gmsg <<
"* Cavity gap width = " << gap <<
" [m] " <<
endl;
737 *
gmsg <<
"* Cavity Shift distance = " << pdis <<
" [m] " <<
endl;
739 double phi0 = elptr->
getPhi0();
747 std::shared_ptr<AbstractTimeDependence> freq_atd =
nullptr;
748 std::shared_ptr<AbstractTimeDependence> ampl_atd =
nullptr;
749 std::shared_ptr<AbstractTimeDependence> phase_atd =
nullptr;
752 unityVec.push_back(1.);
753 unityVec.push_back(0.);
754 unityVec.push_back(0.);
755 unityVec.push_back(0.);
761 if (!frequencyModelName.empty()) {
763 *
gmsg <<
"* Variable frequency RF Model name " << frequencyModelName <<
endl;
768 if (!amplitudeModelName.empty()) {
770 *
gmsg <<
"* Variable amplitude RF Model name " << amplitudeModelName <<
endl;
775 if (!phaseModelName.empty()) {
777 *
gmsg <<
"* Variable phase RF Model name " << phaseModelName <<
endl;
784 double BcParameter[8] = {};
786 BcParameter[0] = rmin;
787 BcParameter[1] = rmax;
788 BcParameter[2] = pdis;
789 BcParameter[3] = angle;
799 *
gmsg <<
"* ----------------------------- Ring ------------------------------------- *" <<
endl;
815 throw OpalException(
"Error in ParallelCyclotronTracker::visitRing",
816 "BEAM_PHIINIT is out of [-180, 180)");
831 double BcParameter[8] = {};
861 throw OpalException(
"ParallelCyclotronTracker::visitSBend3D",
862 "Need to define a RINGDEFINITION to use SBend3D element");
866 *
gmsg <<
"Adding ScalingFFAMagnet" <<
endl;
872 throw OpalException(
"ParallelCyclotronTracker::visitScalingFFAMagnet",
873 "Need to define a RINGDEFINITION to use ScalingFFAMagnet element");
883 *
gmsg <<
"* ----------------------------- Septum ----------------------------------- *" <<
endl;
891 *
gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
893 double xend = elptr->
getXEnd();
894 *
gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
897 *
gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
899 double yend = elptr->
getYEnd();
900 *
gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
903 *
gmsg <<
"* Width = " << width <<
" [m]" <<
endl;
908 double BcParameter[8] = {};
910 BcParameter[0] = xstart;
911 BcParameter[1] = xend;
912 BcParameter[2] = ystart;
913 BcParameter[3] = yend;
914 BcParameter[4] = width;
928 *
gmsg <<
"Solenoid: no position of the element given" <<
endl;
939 *
gmsg <<
"* ----------------------------- Stripper --------------------------------- *" <<
endl;
947 *
gmsg <<
"* XStart = " << xstart <<
" [m]" <<
endl;
949 double xend = elptr->
getXEnd();
950 *
gmsg <<
"* XEnd = " << xend <<
" [m]" <<
endl;
953 *
gmsg <<
"* YStart = " << ystart <<
" [m]" <<
endl;
955 double yend = elptr->
getYEnd();
956 *
gmsg <<
"* YEnd = " << yend <<
" [m]" <<
endl;
959 *
gmsg <<
"* Charge of outcoming particle = +e * " << opcharge <<
endl;
962 *
gmsg <<
"* Mass of the outcoming particle = " << opmass <<
" [GeV/c^2]" <<
endl;
965 *
gmsg << std::boolalpha
966 <<
"* Particles stripped will be deleted after interaction -> "
971 double BcParameter[8] = {};
973 BcParameter[0] = xstart;
974 BcParameter[1] = xend;
975 BcParameter[2] = ystart;
976 BcParameter[3] = yend;
978 BcParameter[5] = opcharge;
979 BcParameter[6] = opmass;
990 *
gmsg <<
"* ----------------------------- Vacuum ----------------------------------- *" <<
endl;
995 double BcParameter[8] = {};
998 *
gmsg <<
"* Residual gas = " << gas <<
endl;
1003 *
gmsg <<
"* Pressure field map file = '" << pmfn <<
"'" <<
endl;
1004 *
gmsg <<
"* Default pressure = " << pressure <<
" [mbar]" <<
endl;
1006 *
gmsg <<
"* Pressure = " << pressure <<
" [mbar]" <<
endl;
1011 *
gmsg <<
"* Temperature = " << temperature <<
" [K]" <<
endl;
1014 *
gmsg << std::boolalpha
1015 <<
"* Particles stripped will be deleted after interaction -> "
1020 BcParameter[0] = pressure;
1021 BcParameter[1] = pscale;
1022 BcParameter[2] = temperature;
1033 *
gmsg <<
"Adding Variable RF Cavity" <<
endl;
1037 throw OpalException(
"ParallelCyclotronTracker::visitVariableRFCavity",
1038 "Need to define a RINGDEFINITION to use VariableRFCavity element");
1048 *
gmsg <<
"Adding Variable RF Cavity with Fringe Field" <<
endl;
1052 throw OpalException(
"ParallelCyclotronTracker::visitVariableRFCavityFringeField",
1053 "Need to define a RINGDEFINITION to use VariableRFCavity element");
1062 *
gmsg <<
"Adding Vertical FFA Magnet" <<
endl;
1066 throw OpalException(
"ParallelCyclotronTracker::visitVerticalFFAMagnet",
1067 "Need to define a RINGDEFINITION to use VerticalFFAMagnet element");
1079 beamline_list::iterator sindex;
1082 localpair->first = elementType;
1084 for (
int i = 0; i < 8; i++)
1085 *(((localpair->second).first) + i) = *(BcParameter + i);
1087 (localpair->second).second = elptr;
1111 int maxnlp = 111111;
1114 *
gmsg << s <<
"min local particle number: "<< minnlp <<
endl;
1115 *
gmsg <<
"* max local particle number: " << maxnlp <<
endl;
1143 *
gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl;
1144 *
gmsg <<
"* The selected Beam line elements are :" <<
endl;
1161 *
gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl <<
endl;
1169 for (
int k = 0; k < 2; k++) {
1179 std::placeholders::_1,
1180 std::placeholders::_2,
1181 std::placeholders::_3,
1182 std::placeholders::_4);
1186 *
gmsg <<
"* 2nd order Leap-Frog integrator" <<
endl;
1191 *
gmsg <<
"* Multiple time stepping (MTS) integrator" <<
endl;
1196 *
gmsg <<
"* 4th order Runge-Kutta integrator" <<
endl;
1208 *
gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl;
1209 *
gmsg <<
"* Finalizing i.e. write data and close files :" <<
endl;
1211 ((fd->second).second)->finalise();
1216 *
gmsg <<
"* ------------------------------------------------------------------------ *" <<
endl;
1231 double t = 0, dt = 0, oldReferenceTheta = 0;
1235 *
gmsg <<
"* MTS: Number of substeps per step is " << numSubsteps <<
endl;
1237 double const dt_inner = dt / double(numSubsteps);
1238 *
gmsg <<
"* MTS: The inner time step is therefore " << dt_inner *
Units::s2ns <<
" [ns]" <<
endl;
1242 bool flagTransition =
false;
1244 *
gmsg <<
"* ---------------------- Start tracking ---------------------------------- *" <<
endl;
1252 bool finishedTurn =
false;
1266 for (
int n = 0; n < numSubsteps; ++n) {
1307 temp_meanTheta, finishedTurn);
1310 oldReferenceTheta, temp_meanTheta);
1312 oldReferenceTheta = temp_meanTheta;
1319 finishedTurn =
true;
1323 <<
", Total number of live particles: "
1339 *
gmsg <<
"* ---------------------- DONE TRACKING PARTICLES ------------------------- *" <<
endl;
1369 double t = 0, dt = 0, oldReferenceTheta = 0;
1388 *
gmsg <<
"* ---------------------- Start tracking ---------------------------------- *" <<
endl;
1392 bool finishedTurn =
false;
1397 seoMode_m(t, dt, finishedTurn, Ttime, Tdeltr, Tdeltz, TturnNumber);
1413 throw OpalException(
"ParallelCyclotronTracker::GenericTracker()",
1414 "No such tracking mode.");
1424 *
gmsg <<
"* ---------------------- DONE TRACKING PARTICLES ------------------------- *" <<
endl;
1460 RFCavity* rfcavity,
double& Dold) {
1466 double distNew = (Rnew[0] * sinx - Rnew[1] * cosx) - PerpenDistance;
1467 double distOld = (Rold[0] * sinx - Rold[1] * cosx) - PerpenDistance;
1468 if (distOld > 0.0 && distNew <= 0.0) flag =
true;
1476 double radius = std::sqrt(std::pow(
itsBunch_m->R[Pindex](0), 2.0) + std::pow(
itsBunch_m->R[Pindex](1), 2.0)
1478 double rmin = rfcavity->
getRmin();
1479 double rmax = rfcavity->
getRmax();
1480 double nomalRadius = (radius - rmin) / (rmax - rmin);
1482 if (nomalRadius <= 1.0 && nomalRadius >= 0.0) {
1484 for (
int j = 0; j < 3; j++)
1490 for (
int j = 0; j < 3; j++)
1517 int lastTurn,
double& ,
double& ) {
1520 int Ndat = t.size();
1527 for (
int i = 0; i < Ndat; i++)
1532 for (
int i = 0; i < Ndat; i++)
1534 double ti = *(t.begin());
1535 double tf = t[t.size()-1];
1536 double T = (tf - ti);
1539 for (
int i = 0; i < Ndat; i++) {
1546 *
gmsg <<
"* ************************************* nuR ******************************************* *" <<
endl;
1547 *
gmsg <<
endl <<
"* ===> " << Ndat <<
" data points Ti=" << ti <<
" Tf= " << tf <<
" -> T= " <<
T <<
endl;
1555 *
gmsg <<
"* TUNE: Lomb analysis failed" <<
endl;
1556 *
gmsg <<
"* ************************************************************************************* *" <<
endl;
1566 *
gmsg <<
"* ************************************* nuZ ******************************************* *" <<
endl;
1567 *
gmsg <<
endl <<
"* ===> " << Ndat <<
" data points Ti=" << ti <<
" Tf= " << tf <<
" -> T= " <<
T <<
endl;
1573 *
gmsg <<
"* TUNE: Lomb analysis failed" <<
endl;
1574 *
gmsg <<
"* ************************************************************************************* *" <<
endl;
1587 if (elcycl !=
nullptr)
1589 throw OpalException(
"ParallelCyclotronTracker::getHarmonicNumber()",
1590 std::string(
"The first item in the FieldDimensions list does not ")
1591 +std::string(
"seem to be a Ring or a Cyclotron element"));
1598 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1600 if ( bunchNr > -1 &&
itsBunch_m->bunchNum[i] != bunchNr)
1603 for (
int d = 0; d < 3; ++d) {
1613 n =
itsBunch_m->getTotalNumPerBunch(bunchNr);
1621 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1622 for (
int d = 0; d < 3; ++d) {
1641 double phi,
Vector_t const translationToGlobal) {
1643 particleVectors -= translationToGlobal;
1655 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1662 double phi,
Vector_t const translationToGlobal) {
1675 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1679 particleVectors += translationToGlobal;
1690 particleVectors -= meanR;
1703 reverseQuaternion(0) *= -1.0;
1709 particleVectors += meanR;
1722 particleVectors -= meanR;
1772 particleVectors += meanR;
1799 Vector_t const quaternionVectorComponent =
Vector_t(quaternion(1), quaternion(2), quaternion(3));
1800 double const quaternionScalarComponent = quaternion(0);
1802 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1804 particleVectors[i] = 2.0f *
dot(quaternionVectorComponent, particleVectors[i]) * quaternionVectorComponent +
1805 (quaternionScalarComponent * quaternionScalarComponent -
1806 dot(quaternionVectorComponent, quaternionVectorComponent)) * particleVectors[i] + 2.0f *
1807 quaternionScalarComponent *
cross(quaternionVectorComponent, particleVectors[i]);
1813 double tolerance = 1.0e-10;
1814 double length2 =
dot(quaternion, quaternion);
1816 if (std::abs(length2) > tolerance && std::abs(length2 - 1.0f) > tolerance) {
1818 double length = std::sqrt(length2);
1819 quaternion /= length;
1825 double tolerance = 1.0e-10;
1826 double length2 =
dot(vector, vector);
1828 if (std::abs(length2) > tolerance && std::abs(length2 - 1.0f) > tolerance) {
1830 double length = std::sqrt(length2);
1848 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1882 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1909 double k_cos_theta =
dot(u, v);
1910 double k = std::sqrt(
dot(u, u) *
dot(v, v));
1911 double tolerance1 = 1.0e-5;
1912 double tolerance2 = 1.0e-8;
1915 if (std::abs(k_cos_theta / k + 1.0) < tolerance1) {
1922 if (
dot(resultVectorComponent, resultVectorComponent) < tolerance2) {
1927 double sinHalfAngle = std::sin(halfAngle);
1929 resultVectorComponent *= sinHalfAngle;
1932 k_cos_theta = std::cos(halfAngle);
1935 resultVectorComponent =
cross(u, v);
1938 quaternion(0) = k_cos_theta + k;
1939 quaternion(1) = resultVectorComponent(0);
1940 quaternion(2) = resultVectorComponent(1);
1941 quaternion(3) = resultVectorComponent(2);
1951 bool flagNeedUpdate =
false;
1952 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
1962 double const distNew = (
itsBunch_m->R[i][0] * ccd.sinAzimuth -
itsBunch_m->R[i][1] * ccd.cosAzimuth) - ccd.perpenDistance;
1963 bool tagCrossing =
false;
1965 if (distNew <= 0.0) {
1966 distOld = (oldR[0] * ccd.sinAzimuth - oldR[1] * ccd.cosAzimuth) - ccd.perpenDistance;
1967 if (distOld > 0.0) tagCrossing =
true;
1971 double const dt2 = h - dt1;
1986 return flagNeedUpdate;
1993 bool flagNeedUpdate =
false;
1998 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
2006 return flagNeedUpdate;
2013 bool flagNeedUpdate =
push(0.5 * h);
2017 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
2028 flagNeedUpdate |=
kick(h);
2031 flagNeedUpdate |=
push(0.5 * h);
2045 Vacuum* vac =
static_cast<Vacuum*
>(((*sindex)->second).second);
2060 *
gmsg <<
"* Total number of particles after PluginElement= "
2078 allreduce(flagNeedUpdate, 1, std::logical_or<bool>());
2080 if (flagNeedUpdate) {
2081 short bunchCount =
itsBunch_m->getNumBunch();
2082 std::vector<size_t> locLostParticleNum(bunchCount, 0);
2084 const int leb =
itsBunch_m->getLastemittedBin();
2085 std::unique_ptr<size_t[]> localBinCount;
2088 localBinCount = std::unique_ptr<size_t[]>(
new size_t[leb]);
2089 for (
int i = 0; i < leb; ++i)
2090 localBinCount[i] = 0;
2093 for (
unsigned int i = 0; i <
itsBunch_m->getLocalNum(); i++) {
2095 ++locLostParticleNum[
itsBunch_m->bunchNum[i]];
2107 for (
int i = 0; i < leb; ++i) {
2108 itsBunch_m->setLocalBinCount(localBinCount[i], i);
2112 std::vector<size_t> localnum(bunchCount + 1);
2113 for (
size_t i = 0; i < localnum.size() - 1; ++i) {
2114 localnum[i] =
itsBunch_m->getLocalNumPerBunch(i) - locLostParticleNum[i];
2115 itsBunch_m->setLocalNumPerBunch(localnum[i], i);
2129 std::vector<size_t> totalnum(bunchCount + 1);
2130 localnum[bunchCount] =
itsBunch_m->getLocalNum();
2132 allreduce(localnum.data(), totalnum.data(), localnum.size(), std::plus<size_t>());
2133 itsBunch_m->setTotalNum(totalnum[bunchCount]);
2135 for (
short i = 0; i < bunchCount; ++i) {
2136 itsBunch_m->setTotalNumPerBunch(totalnum[i], i);
2139 size_t sum = std::accumulate(totalnum.begin(),
2140 totalnum.end() - 1, 0);
2142 if (
sum != totalnum[bunchCount] ) {
2143 throw OpalException(
"ParallelCyclotronTracker::deleteParticle()",
2144 "Total number of particles " + std::to_string(totalnum[bunchCount]) +
2145 " != " + std::to_string(
sum) +
" (sum over all bunches)");
2148 size_t globLostParticleNum = 0;
2149 size_t locNumLost = std::accumulate(locLostParticleNum.begin(),
2150 locLostParticleNum.end(), 0);
2152 reduce(locNumLost, globLostParticleNum, 1, std::plus<size_t>());
2154 if ( globLostParticleNum > 0 ) {
2156 <<
", lost " << globLostParticleNum <<
" particles" <<
endl;
2159 if (totalnum[bunchCount] == 0) {
2161 return flagNeedUpdate;
2194 return flagNeedUpdate;
2210 outfTrackOrbit_m <<
"# The six-dimensional phase space data in the global Cartesian coordinates" << std::endl;
2211 outfTrackOrbit_m <<
"# Part. ID x [m] beta_x*gamma y [m] beta_y*gamma z [m] beta_z*gamma" << std::endl;
2281 *
gmsg <<
"* Restart in the local frame" <<
endl;
2298 *
gmsg <<
"* Restart in the global frame" <<
endl;
2317 double radius = std::sqrt(meanR[0] * meanR[0] + meanR[1] * meanR[1]);
2335 *
gmsg <<
endl <<
"* *********************** Bunch information in local frame: ************************";
2357 *
gmsg <<
endl <<
"* *********************** Bunch information in global frame: ***********************";
2369 double pTotalMean = 0.0;
2374 allreduce(pTotalMean, 1, std::plus<double>());
2378 double tolerance =
itsBunch_m->getMomentumTolerance();
2379 if (tolerance > 0 &&
2380 std::abs(pTotalMean -
referencePtot) / pTotalMean > tolerance) {
2381 throw OpalException(
"ParallelCyclotronTracker::checkFileMomentum",
2382 "The total momentum of the particle distribution\n"
2383 "in the global reference frame: " +
2384 std::to_string(pTotalMean) +
",\n"
2385 "is different from the momentum given\n"
2386 "in the \"BEAM\" command: " +
2388 "In Opal-cycl the initial distribution\n"
2389 "is specified in the local reference frame.\n"
2390 "When using a \"FROMFILE\" type distribution, the momentum \n"
2391 "must be the same as the specified in the \"BEAM\" command,\n"
2392 "which is in global reference frame.");
2411 int found[2] = {-1, -1};
2414 for (
size_t i = 0; i <
itsBunch_m->getLocalNum(); ++i) {
2427 int numberOfPart = 0;
2429 while(notReceived > 0) {
2434 if (rmsg ==
nullptr)
2435 ERRORMSG(
"Could not receive from client nodes in main." <<
endl);
2439 rmsg->
get(&numberOfPart);
2441 for (
int i = 0; i < numberOfPart; ++i) {
2444 for (
int ii = 0; ii < 6; ii++) {
2452 for (
int i = 0; i < counter; ++i) {
2456 for (
int j = 0; j < 3; ++j) {
2462 dvector_t::iterator itParameter = tmpr.begin();
2464 for (
auto tmpid : tmpi) {
2470 itsBunch_m->RefPartR_m[1] = *(itParameter + 2);
2471 itsBunch_m->RefPartR_m[2] = *(itParameter + 4);
2472 itsBunch_m->RefPartP_m[0] = *(itParameter + 1);
2473 itsBunch_m->RefPartP_m[1] = *(itParameter + 3);
2474 itsBunch_m->RefPartP_m[2] = *(itParameter + 5);
2476 for (
int ii = 0; ii < 6; ii++) {
2488 for (
int i = 0; i < counter; i++) {
2492 for (
int j = 0; j < 3; j++) {
2499 ERRORMSG(
"Ippl::Comm->send(smsg, 0, tag) failed " <<
endl);
2507 for (
size_t i = 0; i <
itsBunch_m->getLocalNum(); i++) {
2532 double phi = 0.0, psi = 0.0;
2596 (((*DumpSindex)->second).second)->apply(meanR, meanP, temp_t,
extE_m,
extB_m);
2659 double const E =
itsBunch_m->get_meanKineticEnergy();
2662 double const theta = std::atan2(meanR(1), meanR(0));
2668 double const psi = 0.5 *
Physics::pi - std::acos(meanP(2) / betagamma_temp);
2680 referencePr = meanP(0) * std::cos(theta) + meanP(1) * std::sin(theta);
2690 (((*DumpSindex)->second).second)->apply(meanR, meanP, temp_t,
extE_m,
extB_m);
2696 bool dumpLocalFrame =
true;
2697 std::string dumpString =
"local";
2699 dumpLocalFrame =
false;
2700 dumpString =
"global";
2703 if (dumpLocalFrame ==
true) {
2731 if (dumpLocalFrame ==
true) {
2741 <<
" (no phase space dump for <= 2 particles)" <<
endl;
2744 <<
" (" << dumpString <<
" frame) at integration step " <<
step_m + 1 <<
endl;
2749 *
gmsg <<
"* T = " << temp_t <<
" s"
2751 *
gmsg <<
"* E = " << E <<
" MeV"
2752 <<
", beta * gamma = " << betagamma_temp <<
endl;
2767 const bool& finishedTurn)
2775 if (!(
step_m + 1 % 1000)) {
2864 *
gmsg <<
"* MBM: Time interval between neighbour bunches is set to "
2866 *
gmsg <<
"* MBM: The particles energy bin reset frequency is set to "
2871 *
gmsg <<
"* The frequency to solve space charge fields is set to " <<
setup_m.scSolveFreq <<
endl;
2877 *
gmsg <<
"* ------------------------- STATIC EQUILIBRIUM ORBIT MODE ----------------------------- *" <<
endl
2878 <<
"* Instruction: When the total particle number is equal to 2, SEO mode is triggered *" <<
endl
2879 <<
"* automatically. This mode does NOT include any RF cavities. The initial distribution *" <<
endl
2880 <<
"* file must be specified. In the file the first line is for reference particle and the *" <<
endl
2881 <<
"* second line is for off-center particle. The tune is calculated by FFT routines based *" <<
endl
2882 <<
"* on these two particles. *" <<
endl
2883 <<
"* ---------------- NOTE: SEO MODE ONLY WORKS SERIALLY ON SINGLE NODE ------------------ *" <<
endl;
2886 throw OpalException(
"Error in ParallelCyclotronTracker::initializeTracking_m",
2887 "SEO MODE ONLY WORKS SERIALLY ON SINGLE NODE");
2892 *
gmsg <<
"* ------------------------------ SINGLE PARTICLE MODE --------------------------------- *" <<
endl
2893 <<
"* Instruction: When the total particle number is equal to 1, single particle mode is *" <<
endl
2894 <<
"* triggered automatically. The initial distribution file must be specified which should *" <<
endl
2895 <<
"* contain only one line for the single particle *" <<
endl
2896 <<
"* ---------NOTE: SINGLE PARTICLE MODE ONLY WORKS SERIALLY ON A SINGLE NODE ------------ *" <<
endl;
2899 throw OpalException(
"Error in ParallelCyclotronTracker::initializeTracking_m",
2900 "SINGLE PARTICLE MODE ONLY WORKS SERIALLY ON A SINGLE NODE");
2911 throw OpalException(
"ParallelCyclotronTracker::initializeTracking_m()",
2912 "No such tracking mode.");
2916 return std::make_tuple(t, dt, oldReferenceTheta);
2924 for (
size_t ii = 0; ii < (
itsBunch_m->getLocalNum()); ii++) {
2928 *
gmsg <<
"* Final energy of reference particle = " << FinalEnergy <<
" [MeV]" <<
endl;
2940 *
gmsg <<
"* **************** The result for tune calculation (NO space charge) ******************* *" <<
endl
2941 <<
"* Number of tracked turns: " << TturnNumber.back() <<
endl;
2943 getTunes(Ttime, Tdeltr, Tdeltz, TturnNumber.back(), nur, nuz);
2956 *
gmsg <<
"* Cave: Turn number is not correct for restart mode"<<
endl;
2967 *
gmsg <<
endl <<
"* *********************** Bunch information in global frame: ***********************";
2974 *
gmsg <<
endl <<
"* No Particles left in bunch" <<
endl;
2975 *
gmsg <<
"* **********************************************************************************" <<
endl;
2997 double r_tuning[2], z_tuning[2];
3000 for (
size_t i = 0; i < (
itsBunch_m->getLocalNum()); i++) {
3014 r_tuning[i] =
itsBunch_m->R[i](0) * std::cos(OldTheta) +
3032 Tdeltz.push_back(z_tuning[1]);
3033 Tdeltr.push_back(r_tuning[1] - r_tuning[0]);
3040 bool& finishedTurn,
double& oldReferenceTheta) {
3074 temp_meanTheta, finishedTurn);
3077 oldReferenceTheta, temp_meanTheta);
3079 oldReferenceTheta = temp_meanTheta;
3089 if (
itsBunch_m->cavityGapCrossed[i] ==
true) {
3106 static bool flagTransition =
false;
3154 for (
size_t i = 0; i <
itsBunch_m->getLocalNum(); i++) {
3164 if (
itsBunch_m->cavityGapCrossed[i] ==
true) {
3186 finishedTurn =
true;
3190 <<
", Total number of live particles: "
3206 bool tag_crossing =
false;
3207 double DistOld = 0.0;
3212 rfcav =
static_cast<RFCavity*
>(((*sindex)->second).second);
3216 if ( tag_crossing ) {
3220 double dt1 = DistOld / (oldBeta *
Physics::c);
3221 double dt2 = dt - dt1;
3228 if (dt / dt1 < 1.0e9) {
3232 RFkick(rfcav, t, dt1, i);
3237 if (dt / dt2 < 1.0e9) {
3248 const double& oldReferenceTheta,
3249 const double& temp_meanTheta) {
3251 for (
unsigned int i=0; i<=2; i++) {
3256 <<
", Time = " << t *
Units::s2ns <<
" [ns]" << std::endl
3257 <<
" " << std::hypot(R(0), R(1))
3258 <<
" " << P(0) * std::cos(temp_meanTheta) + P(1) * std::sin(temp_meanTheta)
3260 <<
" " << - P(0) * std::sin(temp_meanTheta) + P(1) * std::cos(temp_meanTheta)
3262 <<
" " << P(2) << std::endl;
3270 const double& temp_meanTheta,
3271 bool& finishedTurn) {
3274 finishedTurn =
true;
3279 <<
", Time = " << t *
Units::s2ns <<
" [ns]" << std::endl
3280 <<
" " << std::sqrt(R(0) * R(0) + R(1) * R(1))
3281 <<
" " << P(0) * std::cos(temp_meanTheta) +
3282 P(1) * std::sin(temp_meanTheta)
3284 <<
" " << - P(0) * std::sin(temp_meanTheta) +
3285 P(1) * std::cos(temp_meanTheta)
3287 <<
" " << P(2) << std::endl;
3337 for (
int b = 0; b <
itsBunch_m->getLastemittedBin(); b++) {
3340 itsBunch_m->setGlobalToLocalQuaternion(quaternionToYAxis);
3353 itsBunch_m->setGlobalToLocalQuaternion(quaternionToYAxis);
3354 itsBunch_m->computeSelfFields_cycl(temp_meangamma);
3373 bool outOfBound = (((*sindex)->second).second)->apply(i, t, Efield, Bfield);
3386 bool outOfBound = (((*sindex)->second).second)->apply(R, P, t, Efield, Bfield);
3413 if ( flagTransition ) {
3415 *
gmsg <<
"* MBM: After one revolution, Multi-Bunch Mode will be invoked" <<
endl;
3425 throw OpalException(
"ParallelCyclotronTracker::injectBunch()",
3426 "Unknown return value " + std::to_string(result));
3460 std::vector<double> lpaths(1);
3493 for (
short b = 0; b <
mbHandler_m->getNumBunch(); ++b) {
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
TBeamline< FlaggedElmPtr > FlaggedBeamline
A beam line with flagged elements.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
T prod_boost_vector(const boost::numeric::ublas::matrix< double > &rotation, const T &vector)
void allreduce(const T *input, T *output, int count, Op op)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
bool for_each(const BareFieldIterator< T, D > &p, SameFieldID s, C)
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Inform & level4(Inform &inf)
Inform & endl(Inform &inf)
Inform & level3(Inform &inf)
constexpr double q_e
The elementary charge in As.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
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
int sptDumpFreq
The frequency to dump single particle trajectory of particles with ID = 0 & 1.
unsigned int delPartFreq
The frequency to delete particles (currently: OPAL-cycl only).
int scSolveFreq
The frequency to solve space charge fields.
int repartFreq
The frequency to do particles repartition for better load balance between nodes.
int rebinFreq
The frequency to reset energy bin ID for all particles.
DumpFrame psDumpFrame
flag to decide in which coordinate frame the phase space will be dumped for OPAL-cycl
int statDumpFreq
The frequency to dump statistical values, e.e. dump data when stepstatDumpFreq==0.
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]
std::string doubleVectorToString(const std::vector< double > &v)
std::string boolVectorToUpperString(const std::vector< bool > &b)
Vector_t getBeta(Vector_t p)
double getGamma(Vector_t p)
std::string getInputBasename()
get input file name without extension
static OpalData * getInstance()
BoundaryGeometry * getGlobalGeometry()
void setOpenMode(OpenMode openMode)
int lombAnalysis(double *x, double *y, int Ndat, int nhis)
void operator()(double x)
void computePathLengthUpdate(std::vector< double > &dl, const double &dt)
std::vector< PluginElement * > pluginElements_m
void dumpAzimuthAngles_m(const double &t, const Vector_t &R, const Vector_t &P, const double &oldReferenceTheta, const double &temp_meanTheta)
IpplTimings::TimerRef IntegrationTimer_m
IpplTimings::TimerRef PluginElemTimer_m
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a degrader.
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
static Vector_t const xaxis
The positive axes unit vectors.
Vector_t calcMeanP() const
virtual void visitProbe(const Probe &)
Apply the algorithm to a probe.
virtual void visitVacuum(const Vacuum &)
Apply the algorithm to a vacuum space.
std::function< bool(const double &, const size_t &, Vector_t &, Vector_t &)> function_t
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.
std::vector< double > azimuth_angle_m
the different azimuthal angles for the outfTheta_m output files
std::unique_ptr< MultiBunchHandler > mbHandler_m
void injectBunch(bool &flagTransition)
void rotateAroundZ(ParticleAttrib< Vector_t > &particleVectors, double const phi)
virtual void visitStripper(const Stripper &)
Apply the algorithm to a particle stripper.
void normalizeQuaternion(Quaternion_t &quaternion)
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
void singleMode_m(double &t, const double dt, bool &finishedTurn, double &oldReferenceTheta)
void update_m(double &t, const double &dt, const bool &finishedTurn)
Update time and path length, write to output files.
ParallelCyclotronTracker()
virtual ~ParallelCyclotronTracker()
std::vector< std::unique_ptr< std::ofstream > > outfTheta_m
output coordinates at different azimuthal angles and one after every turn
void computeSpaceChargeFields_m()
bool hasMultiBunch() const
double getHarmonicNumber() const
void rotateAroundX(ParticleAttrib< Vector_t > &particleVectors, double const psi)
double calculateAngle(double x, double y)
bool isTurnDone()
Check if turn done.
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
bool checkGapCross(Vector_t Rold, Vector_t Rnew, RFCavity *rfcavity, double &DistOld)
virtual void visitOffset(const Offset &)
Apply the algorithm to a offset (placement).
IpplTimings::TimerRef DelParticleTimer_m
void normalizeVector(Vector_t &vector)
bool RFkick(RFCavity *rfcavity, const double t, const double dt, const int Pindex)
virtual void visitScalingFFAMagnet(const ScalingFFAMagnet &bend)
Apply the algorithm to a scaling FFA magnet.
double computeRadius(const Vector_t &meanR) const
void updatePathLength(const double &dt)
void updateTime(const double &dt)
void openFiles(size_t numFiles, std::string fn)
@ open / close output coordinate files
virtual void visitSBend3D(const SBend3D &)
Apply the algorithm to a sector bend with 3D field map.
void borisExternalFields(double h)
double bega
The reference variables.
void dumpAngle(const double &theta, double &prevAzimuth, double &azimuth, const short &bunchNr=0)
bool applyPluginElements(const double dt)
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a closed orbit corrector.
static Vector_t const yaxis
std::tuple< double, double, double > initializeTracking_m()
std::pair< ElementType, element_pair > type_pair
virtual void visitRing(const Ring &ring)
Apply the algorithm to a ring.
IpplTimings::TimerRef BinRepartTimer_m
void globalToLocal(ParticleAttrib< Vector_t > &vectorArray, double phi, Vector_t const translationToGlobal=0)
static Vector_t const zaxis
void updateAzimuthAndRadius()
const size_t initialLocalNum_m
bool getFieldsAtPoint(const double &t, const size_t &Pindex, Vector_t &Efield, Vector_t &Bfield)
std::vector< CavityCrossData > cavCrossDatas_m
beamline_list FieldDimensions
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift space.
std::unique_ptr< Stepper< function_t > > itsStepper_mp
struct ParallelCyclotronTracker::settings setup_m
std::ofstream outfTrackOrbit_m
void finalizeTracking_m(dvector_t &Ttime, dvector_t &Tdeltr, dvector_t &Tdeltz, ivector_t &TturnNumber)
virtual void visitVariableRFCavityFringeField(const VariableRFCavityFringeField &cav)
Apply the algorithm to a variable RF cavity with Fringe Field.
void gapCrossKick_m(size_t i, double t, double dt, const Vector_t &Rold, const Vector_t &Pold)
void getQuaternionTwoVectors(Vector_t u, Vector_t v, Quaternion_t &quaternion)
virtual void visitSBend(const SBend &)
Apply the algorithm to a sector bend.
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
virtual void execute()
Apply the algorithm to the top-level beamline.
void dumpThetaEachTurn_m(const double &t, const Vector_t &R, const Vector_t &P, const double &temp_meanTheta, bool &finishedTurn)
void bunchMode_m(double &t, const double dt, bool &finishedTurn)
void initTrackOrbitFile()
std::list< Component * > myElements
std::unique_ptr< LossDataSink > lossDs_m
virtual void visitMultipoleT(const MultipoleT &)
Apply the algorithm to an arbitrary multipole.
virtual void visitVariableRFCavity(const VariableRFCavity &cav)
Apply the algorithm to a variabel RF cavity.
const size_t initialTotalNum_m
void bgf_main_collision_test()
double beamInitialRotation
void buildupFieldList(double BcParameter[], ElementType elementType, Component *elptr)
void rotateWithQuaternion(ParticleAttrib< Vector_t > &vectorArray, Quaternion_t const quaternion)
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a solenoid.
Steppers::TimeIntegrator stepper_m
std::vector< double > dvector_t
void bunchDumpPhaseSpaceData()
IpplTimings::TimerRef TransformTimer_m
Vector_t calcMeanR(short bunchNr=-1) const
double calculateAngle2(double x, double y)
virtual void visitCyclotron(const Cyclotron &cycl)
Apply the algorithm to a cyclotron.
bool deleteParticle(bool=false)
void localToGlobal(ParticleAttrib< Vector_t > &vectorArray, double phi, Vector_t const translationToGlobal=0)
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
bool getTunes(dvector_t &t, dvector_t &r, dvector_t &z, int lastTurn, double &nur, double &nuz)
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
void checkNumPart(std::string s)
void singleParticleDump()
virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet &bend)
Apply the algorithm to a vertical FFA magnet.
virtual void visitSeptum(const Septum &)
Apply the algorithm to a septum.
IpplTimings::TimerRef DumpTimer_m
bool isMultiBunch() const
void seoMode_m(double &t, const double dt, bool &finishedTurn, dvector_t &Ttime, dvector_t &Tdeltr, dvector_t &Tdeltz, ivector_t &TturnNumber)
int maxSteps_m
The maximal number of steps the system is integrated.
virtual void visitOutputPlane(const OutputPlane &)
Apply the algorithm to a outputplane.
void initDistInGlobalFrame()
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a beam position monitor.
std::vector< int > ivector_t
static void writeFields(Component *field)
static void writeFields(Component *field)
double getZStart()
Member variable access.
Interface for a single beam element.
Interface for general corrector.
virtual double getCyclHarm() const
Interface for drift space.
virtual const std::string & getName() const
Get element name.
virtual double getElementLength() const
Get design length.
virtual ElementBase * clone() const =0
Return clone.
virtual bool hasAttribute(const std::string &aKey) const
Test for existence of an attribute.
std::string getTypeString() const
Interface for general multipole.
ElementBase * clone() const override
Vector_t getCentre() const
ElementBase * clone() const override
double getHorizontalExtent() const
void setGlobalFieldMap(Component *field)
Vector_t getNormal() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Pure virtual implementation of Component.
double getXStart() const
Member variable access.
std::string getPhaseModelName()
virtual double getRmax() 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
virtual double getAzimuth() const
std::string getAmplitudeModelName()
virtual double getCosAzimuth() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual double getSinAzimuth() const
virtual std::string getFieldMapFN() const
virtual double getCycFrequency() const
virtual double getGapWidth() const
std::string getFrequencyModelName()
virtual double getPerpenDistance() const
CavityType getCavityType() const
virtual double getPhi0() const
std::string getCavityTypeString() const
virtual double getRmin() const
Ring describes a ring type geometry for tracking.
virtual ElementBase * clone() const override
ScalingFFAMagnet * clone() const override
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Pure virtual implementation of Component.
double getOPCharge() const
double getPressure() const
std::string getPressureMapFN() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual bool checkVacuum(PartBunchBase< double, 3 > *bunch, Cyclotron *cycl)
double getTemperature() const
std::string getResidualGasName()
static std::shared_ptr< AbstractTimeDependence > getTimeDependence(std::string name)
const PartData itsReference
The reference information.
Tracker(const Beamline &, const PartData &, bool backBeam, bool backTrack)
Constructor.
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
An abstract sequence of beam line components.
virtual void iterate(BeamlineVisitor &, bool r2l) const
Apply visitor to all elements of the line.
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
4-th order Runnge-Kutta stepper
The base class for all OPAL exceptions.
Message & put(const T &val)
Message & get(const T &cval)
static Communicate * Comm
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t