28 #include <boost/assign.hpp>
31 #include "gsl/gsl_interp.h"
32 #include "gsl/gsl_spline.h"
40 boost::assign::list_of<const boost::bimap<CavityType, std::string>::relation>
51 phaseTD_m(right.phaseTD_m),
52 phaseName_m(right.phaseName_m),
53 amplitudeTD_m(right.amplitudeTD_m),
54 amplitudeName_m(right.amplitudeName_m),
55 frequencyTD_m(right.frequencyTD_m),
56 frequencyName_m(right.frequencyName_m),
57 filename_m(right.filename_m),
58 scale_m(right.scale_m),
59 scaleError_m(right.scaleError_m),
60 phase_m(right.phase_m),
61 phaseError_m(right.phaseError_m),
62 frequency_m(right.frequency_m),
64 autophaseVeto_m(right.autophaseVeto_m),
65 designEnergy_m(right.designEnergy_m),
66 fieldmap_m(right.fieldmap_m),
67 startField_m(right.startField_m),
68 endField_m(right.endField_m),
72 angle_m(right.angle_m),
73 sinAngle_m(right.sinAngle_m),
74 cosAngle_m(right.cosAngle_m),
76 gapwidth_m(right.gapwidth_m),
81 num_points_m(right.num_points_m)
87 amplitudeTD_m(nullptr),
88 frequencyTD_m(nullptr),
96 autophaseVeto_m(false),
136 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
138 bool outOfBounds =
fieldmap_m->getFieldstrength(R, tmpE, tmpB);
155 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
157 bool outOfBounds =
fieldmap_m->getFieldstrength(R, tmpE, tmpB);
158 if (outOfBounds)
return true;
170 if (bunch ==
nullptr) {
177 Inform msg(
"RFCavity ", *gmsg);
178 std::stringstream errormsg;
185 "The length of the field map '" +
filename_m +
"' is zero or negative");
191 errormsg <<
"FREQUENCY IN INPUT FILE DIFFERENT THAN IN FIELD MAP '" <<
filename_m <<
"';\n"
197 std::ofstream omsg(
"errormsg.txt", std::ios_base::app);
208 std::shared_ptr<AbstractTimeDependence> freq_atd,
209 std::shared_ptr<AbstractTimeDependence> ampl_atd,
210 std::shared_ptr<AbstractTimeDependence> phase_atd) {
230 "', please check the data format");
232 in >>
RNormal_m[i] >> VrNormal_m[i] >> DvDr_m[i];
244 *gmsg <<
"* Cavity voltage data read successfully!" <<
endl;
295 "RMIN must be positive");
304 "The attribute RMAX has to be higher than RMIN");
348 "The attribute \"FMAPFN\" isn't set "
349 "for the \"RFCAVITY\" element!");
350 }
else if (std::filesystem::exists(
filename_m)) {
355 "', please check if it exists");
376 const double dtCorrt,
378 const double restMass,
379 const int chargenumber) {
383 double momentum2 = momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2];
386 double gamma =
std::sqrt(1.0 + momentum2);
387 double beta = betgam / gamma;
391 double Ufactor = 1.0;
397 Ufactor =
std::sin(transit_factor) / transit_factor;
403 double nphase = (frequency * (t + dtCorrt)) -
phi0_m;
404 double dgam = Voltage *
std::cos(nphase) / (restMass);
407 if (tempdegree > 270.0) tempdegree -= 360.0;
411 double newmomentum2 =
std::pow(gamma, 2) - 1.0;
416 double py = pr * sinAngle_m + ptheta *
cosAngle_m;
426 m <<
"* Cavity " <<
getName() <<
" Phase= " << tempdegree <<
" [deg] transit time factor= " << Ufactor
439 "no support points!");
451 while ((ih - il) > 1) {
452 int i = (int)((il + ih) / 2.0);
475 double u = (z - x1) / dx;
478 double dy2 = -2.0 * dy;
479 double ya2 = y2a + 2.0 * y1a;
480 double dy3 = 3.0 * dy;
481 double ya3 = y2a + y1a;
482 double yb2 = dy2 + dx * ya3;
483 double yb4 = dy3 - dx * ya2;
484 splint = y1 + u * dx * y1a + u2 * yb4 + u3 * yb2;
485 *za = y1a + 2.0 * u / dx * yb4 + 3.0 * u2 / dx * yb2;
505 const double dt = 1
e-13;
517 for (
unsigned int j = 0; j < 2; ++ j) {
518 for (
unsigned int i = 0; i < 36; ++ i, phi += dphi) {
533 phimax =
std::fmod(phimax, Physics::two_pi);
537 <<
"estimated phase= " << phimax <<
" rad = "
539 <<
"Ekin= " << Emax <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
546 const double& q,
const double& mass) {
547 std::vector<double> t, E, t2, E2;
548 std::vector<double> F;
549 std::vector< std::pair< double, double > > G;
550 gsl_spline *onAxisInterpolants;
551 gsl_interp_accel *onAxisAccel;
554 double dz = 1.0, length = 0.0;
556 if (G.size() == 0)
return 0.0;
557 double begin = (G.front()).first;
558 double end = (G.back()).first;
559 std::unique_ptr<double[]> zvals(
new double[G.size()]);
560 std::unique_ptr<double[]> onAxisField(
new double[G.size()]);
562 for (
size_t j = 0; j < G.size(); ++ j) {
563 zvals[j] = G[j].first;
564 onAxisField[j] = G[j].second;
566 onAxisInterpolants = gsl_spline_alloc(gsl_interp_cspline, G.size());
567 onAxisAccel = gsl_interp_accel_alloc();
568 gsl_spline_init(onAxisInterpolants, zvals.get(), onAxisField.get(), G.size());
570 length = end -
begin;
571 dz = length / G.size();
575 unsigned int N = (int)
std::floor(length / dz + 1);
580 for (
size_t j = 0; j < N; ++ j, z += dz) {
581 F[j] = gsl_spline_eval(onAxisInterpolants, z, onAxisAccel);
583 gsl_spline_free(onAxisInterpolants);
584 gsl_interp_accel_free(onAxisAccel);
592 for (
unsigned int i = 1; i < N; ++ i, z += dz) {
593 E[i] = E[i - 1] + dz *
scale_m / mass;
597 for (
int iter = 0; iter < 10; ++ iter) {
600 for (
unsigned int i = 1; i < N; ++ i) {
601 t[i] = t[i - 1] +
getdT(i, E, dz, mass);
602 t2[i] = t2[i - 1] +
getdT(i, E2, dz, mass);
617 for (
unsigned int i = 1; i < N; ++ i) {
622 INFOMSG(
level2 <<
"estimated phase= " << tmp_phi <<
" rad = "
624 <<
"Ekin= " << E[N - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
630 for (
unsigned int i = 1; i < N; ++ i) {
635 double a = E[i], b = E2[i];
639 t[i] = t[i - 1] +
getdT(i, E, dz, mass);
640 t2[i] = t2[i - 1] +
getdT(i, E2, dz, mass);
648 double cosine_part = 0.0, sine_part = 0.0;
655 if (p0 + q * totalEz0 * (t[1] - t[0]) *
Physics::c / mass < 0) {
657 tmp_phi =
std::atan(cosine_part / sine_part);
668 <<
"estimated phase= " << tmp_phi <<
" rad = "
670 <<
"Ekin= " << E[N - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
680 std::ofstream *out) {
692 if (out) *out << std::setw(18) << z[2]
695 while (z(2) + dz < zend && z(2) + dz > zbegin) {
697 integrator.push(z, p, dt);
702 if (z(2) >= zbegin && z(2) <= zend) {
705 integrator.kick(z, p, Ef, Bf, dt);
709 integrator.push(z, p, dt);
713 if (out) *out << std::setw(18) << z[2]
718 const double beta =
std::sqrt(1. - 1 / (
dot(p, p) + 1.));
719 const double tErr = (z(2) - zend) / (
Physics::c * beta);
721 return std::pair<double, double>(p(2), t - tErr);
737 length = end - start;
virtual double getCosAzimuth() const
std::unique_ptr< double[]> RNormal_m
Tps< T > sqrt(const Tps< T > &x)
Square root.
constexpr double c
The velocity of light in m/s.
virtual double getRmax() const
virtual double getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &m)
virtual double getRmin() const
std::string getCavityTypeString() const
item[EANGLE] Entrance edge angle(radians).\item[ROTATION] Rotation of the magnet about its central axis(radians
double getdB(const int &i, const std::vector< double > &t, const double &dz, const double &frequency, const std::vector< double > &F) const
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
constexpr double MVpm2Vpm
virtual double getAzimuth() const
virtual double getAutoPhaseEstimateFallback(double E0, double t0, double q, double m)
constexpr double two_pi
The value of .
virtual bool bends() const override
static const boost::bimap< CavityType, std::string > bmCavityTypeString_s
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void visitRFCavity(const RFCavity &)=0
Apply the algorithm to a RF cavity.
ParticleAttrib< Vector_t > P
void setCavityType(const std::string &type)
void setRmax(double rmax)
Vektor< double, 3 > Vector_t
virtual void goOnline(const double &kineticEnergy) override
void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
PartBunchBase< double, 3 > * RefPartBunch_m
static std::string typeset_msg(const std::string &msg, const std::string &title)
virtual double getPhi0() const
std::unique_ptr< double[]> VrNormal_m
void setAzimuth(double angle)
virtual ElementType getType() const override
Get element type std::string.
virtual const std::string & getName() const
Get element name.
clearpage the user may choose between constant or variable radius This model includes fringe fields begin
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 .
Inform & endl(Inform &inf)
virtual double getGapWidth() const
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
virtual double getCycFrequency() const
virtual void getElementDimensions(double &begin, double &end) const override
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
virtual double getPhasem() const
bool getFlagDeleteOnTransverseExit() 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
std::string frequencyName_m
virtual void accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
virtual std::pair< double, double > trackOnAxisParticle(const double &p0, const double &t0, const double &dt, const double &q, const double &mass, std::ofstream *out=nullptr)
void setGapWidth(double gapwidth)
std::unique_ptr< double[]> DvDr_m
void setRmin(double rmin)
double getKineticEnergy(Vector_t p, double mass)
virtual double getElementLength() const
Get design length.
virtual void goOffline() override
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
virtual void finalise() override
double getGamma(Vector_t p)
void setPerpenDistance(double pdis)
Tps< T > cos(const Tps< T > &x)
Cosine.
void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
bool isInsideTransverse(const Vector_t &r) const
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
virtual double getElementLength() const override
Get design length.
double getdA(const int &i, const std::vector< double > &t, const double &dz, const double &frequency, const std::vector< double > &F) const
virtual double getPerpenDistance() const
double getdE(const int &i, const std::vector< double > &t, const double &dz, const double &phi, const double &frequency, const std::vector< double > &F) const
virtual void setElementLength(double length)
Set design length.
virtual std::string getFieldMapFN() const
T isnan(T x)
isnan function with adjusted return type
constexpr double e
The value of .
Inform & level2(Inform &inf)
const PartData * getReference() const
void setPhi0(double phi0)
double spline(double z, double *za)
virtual void getDimensions(double &zBegin, double &zEnd) const override
Interface for a single beam element.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sin(const Tps< T > &x)
Sine.
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
virtual bool isInside(const Vector_t &r) const override
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
double getdT(const int &i, const std::vector< double > &E, const double &dz, const double mass) const
virtual double getSinAzimuth() const
static Fieldmap getFieldmap(std::string Filename, bool fast=false)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
double getBetaGamma(double Ekin, double mass)
virtual void setPhasem(double phase)