28#include <boost/assign.hpp>
29#include <boost/filesystem.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),
135 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
155 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
158 if (outOfBounds)
return true;
170 if (bunch ==
nullptr) {
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");
244 *
gmsg <<
"* Cavity voltage data read successfully!" <<
endl;
338 "The attribute \"FMAPFN\" isn't set "
339 "for the \"RFCAVITY\" element!");
340 }
else if (boost::filesystem::exists(
filename_m)) {
345 "', please check if it exists");
366 const double dtCorrt,
368 const double restMass,
369 const int chargenumber) {
373 double momentum2 = momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2];
376 double gamma =
std::sqrt(1.0 + momentum2);
377 double beta = betgam / gamma;
381 double Ufactor = 1.0;
387 Ufactor =
std::sin(transit_factor) / transit_factor;
393 double dgam = Voltage *
std::cos(nphase) / (restMass);
396 if (tempdegree > 270.0) tempdegree -= 360.0;
400 double newmomentum2 =
std::pow(gamma, 2) - 1.0;
416 m <<
"* Cavity " <<
getName() <<
" Phase= " << tempdegree <<
" [deg] transit time factor= " << Ufactor
430 "no support points!");
442 while ((ih - il) > 1) {
443 int i = (int)((il + ih) / 2.0);
466 double u = (z - x1) / dx;
469 double dy2 = -2.0 * dy;
470 double ya2 = y2a + 2.0 * y1a;
471 double dy3 = 3.0 * dy;
472 double ya3 = y2a + y1a;
473 double yb2 = dy2 + dx * ya3;
474 double yb4 = dy3 - dx * ya2;
475 splint = y1 + u * dx * y1a + u2 * yb4 + u3 * yb2;
476 *za = y1a + 2.0 * u / dx * yb4 + 3.0 * u2 / dx * yb2;
496 const double dt = 1
e-13;
508 for (
unsigned int j = 0; j < 2; ++ j) {
509 for (
unsigned int i = 0; i < 36; ++ i, phi += dphi) {
528 <<
"estimated phase= " << phimax <<
" rad = "
530 <<
"Ekin= " << Emax <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
537 const double& q,
const double& mass) {
538 std::vector<double> t, E, t2, E2;
539 std::vector<double> F;
540 std::vector< std::pair< double, double > > G;
541 gsl_spline *onAxisInterpolants;
542 gsl_interp_accel *onAxisAccel;
545 double dz = 1.0, length = 0.0;
547 if (G.size() == 0)
return 0.0;
548 double begin = (G.front()).first;
549 double end = (G.back()).first;
550 std::unique_ptr<double[]> zvals(
new double[G.size()]);
551 std::unique_ptr<double[]> onAxisField(
new double[G.size()]);
553 for (
size_t j = 0; j < G.size(); ++ j) {
554 zvals[j] = G[j].first;
555 onAxisField[j] = G[j].second;
557 onAxisInterpolants = gsl_spline_alloc(gsl_interp_cspline, G.size());
558 onAxisAccel = gsl_interp_accel_alloc();
559 gsl_spline_init(onAxisInterpolants, zvals.get(), onAxisField.get(), G.size());
562 dz = length / G.size();
566 unsigned int N = (int)
std::floor(length / dz + 1);
571 for (
size_t j = 0; j < N; ++ j, z += dz) {
572 F[j] = gsl_spline_eval(onAxisInterpolants, z, onAxisAccel);
574 gsl_spline_free(onAxisInterpolants);
575 gsl_interp_accel_free(onAxisAccel);
583 for (
unsigned int i = 1; i < N; ++ i, z += dz) {
584 E[i] = E[i - 1] + dz *
scale_m / mass;
588 for (
int iter = 0; iter < 10; ++ iter) {
591 for (
unsigned int i = 1; i < N; ++ i) {
592 t[i] = t[i - 1] +
getdT(i, E, dz, mass);
593 t2[i] = t2[i - 1] +
getdT(i, E2, dz, mass);
608 for (
unsigned int i = 1; i < N; ++ i) {
613 INFOMSG(
level2 <<
"estimated phase= " << tmp_phi <<
" rad = "
615 <<
"Ekin= " << E[N - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
621 for (
unsigned int i = 1; i < N; ++ i) {
626 double a = E[i], b = E2[i];
630 t[i] = t[i - 1] +
getdT(i, E, dz, mass);
631 t2[i] = t2[i - 1] +
getdT(i, E2, dz, mass);
639 double cosine_part = 0.0, sine_part = 0.0;
646 if (p0 + q * totalEz0 * (t[1] - t[0]) *
Physics::c / mass < 0) {
648 tmp_phi =
std::atan(cosine_part / sine_part);
659 <<
"estimated phase= " << tmp_phi <<
" rad = "
661 <<
"Ekin= " << E[N - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
671 std::ofstream *out) {
683 if (out) *out << std::setw(18) << z[2]
686 while (z(2) + dz < zend && z(2) + dz > zbegin) {
688 integrator.
push(z, p, dt);
693 if (z(2) >= zbegin && z(2) <= zend) {
696 integrator.
kick(z, p, Ef, Bf, dt);
700 integrator.
push(z, p, dt);
704 if (out) *out << std::setw(18) << z[2]
709 const double beta =
std::sqrt(1. - 1 / (
dot(p, p) + 1.));
710 const double tErr = (z(2) - zend) / (
Physics::c * beta);
712 return std::pair<double, double>(p(2), t - tErr);
728 length =
end - start;
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
Tps< T > cos(const Tps< T > &x)
Cosine.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sin(const Tps< T > &x)
Sine.
Tps< T > sqrt(const Tps< T > &x)
Square root.
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
constexpr double two_pi
The value of.
constexpr double e
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
constexpr double MVpm2Vpm
T isnan(T x)
isnan function with adjusted return type
double getKineticEnergy(Vector_t p, double mass)
double getBetaGamma(double Ekin, double mass)
double getGamma(Vector_t p)
const PartData * getReference() const
double getQ() const
Access to reference data.
ParticleAttrib< Vector_t > P
virtual void visitRFCavity(const RFCavity &)=0
Apply the algorithm to a RF cavity.
Interface for a single beam element.
PartBunchBase< double, 3 > * RefPartBunch_m
virtual const std::string & getName() const
Get element name.
bool getFlagDeleteOnTransverseExit() const
virtual double getElementLength() const
Get design length.
virtual void setElementLength(double length)
Set design length.
bool isInsideTransverse(const Vector_t &r) const
void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
virtual bool isInside(const Vector_t &r) const override
virtual double getPhasem() const
virtual bool bends() const override
virtual double getRmax() const
void setPerpenDistance(double pdis)
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
virtual ElementType getType() const override
Get element type std::string.
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 accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
double getdB(const int &i, const std::vector< double > &t, const double &dz, const double &frequency, const std::vector< double > &F) const
std::unique_ptr< double[]> DvDr_m
virtual void finalise() override
void setRmin(double rmin)
void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
virtual void getElementDimensions(double &begin, double &end) const override
virtual double getCosAzimuth() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
std::string frequencyName_m
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)
std::unique_ptr< double[]> RNormal_m
virtual void setPhasem(double phase)
virtual double getSinAzimuth() const
void setPhi0(double phi0)
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
double spline(double z, double *za)
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
virtual std::string getFieldMapFN() const
void setAzimuth(double angle)
std::unique_ptr< double[]> VrNormal_m
virtual void goOnline(const double &kineticEnergy) override
void setCavityType(const std::string &type)
virtual double getCycFrequency() const
double getdA(const int &i, const std::vector< double > &t, const double &dz, const double &frequency, const std::vector< double > &F) const
virtual double getGapWidth() const
virtual double getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &m)
virtual void getDimensions(double &zBegin, double &zEnd) const override
static const boost::bimap< CavityType, std::string > bmCavityTypeString_s
virtual double getPerpenDistance() const
void setGapWidth(double gapwidth)
virtual double getElementLength() const override
Get design length.
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
virtual void goOffline() override
virtual double getPhi0() const
virtual double getAutoPhaseEstimateFallback(double E0, double t0, double q, double m)
std::string getCavityTypeString() const
void setRmax(double rmax)
void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
virtual double getRmin() const
double getdT(const int &i, const std::vector< double > &E, const double &dz, const double mass) const
virtual void getInfo(Inform *msg)=0
virtual void getFieldDimensions(double &zBegin, double &zEnd) const =0
static Fieldmap * getFieldmap(std::string Filename, bool fast=false)
virtual bool isInside(const Vector_t &) const
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &onaxis)
virtual bool getFieldstrength(const Vector_t &R, Vector_t &E, Vector_t &B) const =0
virtual double getFrequency() const =0
static std::string typeset_msg(const std::string &msg, const std::string &title)
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
void push(Vector_t &R, const Vector_t &P, const double &dt) const
Vektor< double, 3 > Vector_t