26 #include "gsl/gsl_interp.h"
27 #include "gsl/gsl_spline.h"
45 scaleCore_m(right.scaleCore_m),
46 scaleCoreError_m(right.scaleCoreError_m),
47 phaseCore1_m(right.phaseCore1_m),
48 phaseCore2_m(right.phaseCore2_m),
49 phaseExit_m(right.phaseExit_m),
50 startCoreField_m(right.startCoreField_m),
51 startExitField_m(right.startExitField_m),
52 mappedStartExitField_m(right.mappedStartExitField_m),
53 PeriodLength_m(right.PeriodLength_m),
54 NumCells_m(right.NumCells_m),
55 CellLength_m(right.CellLength_m),
63 scaleCoreError_m(0.0),
67 startCoreField_m(0.0),
68 startExitField_m(0.0),
69 mappedStartExitField_m(0.0),
93 double tmpcos, tmpsin;
94 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
103 Vector_t tmpE2(0.0, 0.0, 0.0), tmpB2(0.0, 0.0, 0.0);
105 const double z = tmpR(2);
146 double tmpcos, tmpsin;
147 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
155 Vector_t tmpE2(0.0, 0.0, 0.0), tmpB2(0.0, 0.0, 0.0);
157 const double z = tmpR(2);
204 double zBegin = 0.0, zEnd = 0.0;
208 "The field map of a traveling wave structure has to begin at 0.0");
264 std::vector<double> t, E, t2, E2;
265 std::vector<std::pair<double, double> > F;
266 double phi = 0.0, tmp_phi, dphi = 0.5 *
Physics::pi / 180.;
272 if (F.size() == 0)
return 0.0;
274 int N1 =
static_cast<int>(
std::floor(F.size() / 4.)) + 1;
275 int N2 = F.size() - 2 * N1 + 1;
277 int N4 =
static_cast<int>(std::round(N2 *
Mode_m));
278 double Dz = F[N1 + N2].first - F[N1].first;
284 for (
int i = 1; i < N1; ++ i) {
285 E[i] = E0 + (F[i].first + F[i - 1].first) / 2. *
scale_m / mass;
288 for (
int i = N1; i < N3 - N1 + 1; ++ i) {
289 int I = (i - N1) % N2 + N1;
290 double Z = (F[I].first + F[I - 1].first) / 2. +
std::floor((i - N1) / N2) * Dz;
294 for (
int i = N3 - N1 + 1; i < N3; ++ i) {
295 int I = i - N3 - 1 + 2 * N1 + N2;
296 double Z = (F[I].first + F[I - 1].first) / 2. + ((
NumCells_m - 1) *
Mode_m - 1) * Dz;
297 E[i] = E0 + Z *
scale_m / mass;
301 for (
int iter = 0; iter < 10; ++ iter) {
304 for (
int i = 1; i < N1; ++ i) {
305 t[i] = t[i - 1] +
getdT(i, i, E, F, mass);
306 t2[i] = t2[i - 1] +
getdT(i, i, E2, F, mass);
310 for (
int i = N1; i < N3 - N1 + 1; ++ i) {
311 int I = (i - N1) % N2 + N1;
312 int J = (i - N1 + N4) % N2 + N1;
313 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
314 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
318 for (
int i = N3 - N1 + 1; i < N3; ++ i) {
319 int I = i - N3 - 1 + 2 * N1 + N2;
320 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
321 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
336 for (
int i = 1; i < N1; ++ i) {
339 for (
int i = N1; i < N3 - N1 + 1; ++ i) {
340 int I = (i - N1) % N2 + N1;
341 int J = (i - N1 + N4) % N2 + N1;
342 E[i] = E[i - 1] + q *
scaleCore_m * (
getdE(i, I, t, phi + phaseC1, F) +
getdE(i, J, t, phi + phaseC2, F));
344 for (
int i = N3 - N1 + 1; i < N3; ++ i) {
345 int I = i - N3 - 1 + 2 * N1 + N2;
346 E[i] = E[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE, F);
350 INFOMSG(
level2 <<
"estimated phase= " << tmp_phi <<
" rad = "
352 <<
"Ekin= " << E[N3 - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
358 for (
int i = 1; i < N1; ++ i) {
360 E2[i] = E2[i - 1] + q *
scale_m *
getdE(i, i, t, phi + dphi, F);
361 t[i] = t[i - 1] +
getdT(i, i, E, F, mass);
362 t2[i] = t2[i - 1] +
getdT(i, i, E2, F, mass);
364 E2[i] = E2[i - 1] + q *
scale_m *
getdE(i, i, t2, phi + dphi, F);
366 for (
int i = N1; i < N3 - N1 + 1; ++ i) {
367 int I = (i - N1) % N2 + N1;
368 int J = (i - N1 + N4) % N2 + N1;
369 E[i] = E[i - 1] + q *
scaleCore_m * (
getdE(i, I, t, phi + phaseC1, F) +
getdE(i, J, t, phi + phaseC2, F));
370 E2[i] = E2[i - 1] + q *
scaleCore_m * (
getdE(i, I, t, phi + phaseC1 + dphi, F) +
getdE(i, J, t, phi + phaseC2 + dphi, F));
371 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
372 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
373 E[i] = E[i - 1] + q *
scaleCore_m * (
getdE(i, I, t, phi + phaseC1, F) +
getdE(i, J, t, phi + phaseC2, F));
374 E2[i] = E2[i - 1] + q *
scaleCore_m * (
getdE(i, I, t2, phi + phaseC1 + dphi, F) +
getdE(i, J, t2, phi + phaseC2 + dphi, F));
376 for (
int i = N3 - N1 + 1; i < N3; ++ i) {
377 int I = i - N3 - 1 + 2 * N1 + N2;
378 E[i] = E[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE, F);
379 E2[i] = E2[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE + dphi, F);
380 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
381 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
382 E[i] = E[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE, F);
383 E2[i] = E2[i - 1] + q *
scale_m *
getdE(i, I, t2, phi + phaseE + dphi, F);
390 INFOMSG(
level2 <<
"estimated phase= " << tmp_phi <<
" rad = "
392 <<
"Ekin= " << E[N3 - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n" <<
endl);
Tps< T > cos(const Tps< T > &x)
Cosine.
Tps< T > sin(const Tps< T > &x)
Sine.
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
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)
Inform & endl(Inform &inf)
Inform & level2(Inform &inf)
constexpr double two_pi
The value of.
constexpr double pi
The value of.
constexpr double rad2deg
The conversion factor from radians to degrees.
ParticleAttrib< Vector_t > P
virtual void visitTravelingWave(const TravelingWave &)=0
Apply the algorithm to a traveling wave.
PartBunchBase< double, 3 > * RefPartBunch_m
virtual void setElementLength(double length)
Set design length.
bool isInsideTransverse(const Vector_t &r) const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual double getElementLength() const override
Get design length.
Interface for Traveling Wave.
double mappedStartExitField_m
double getdA(const int &i, const int &I, const std::vector< double > &t, const double &phi, const std::vector< std::pair< double, double > > &F) const
virtual bool bends() const override
virtual void accept(BeamlineVisitor &) const override
Apply visitor to TravelingWave.
virtual void getDimensions(double &zBegin, double &zEnd) const override
virtual ElementBase::ElementType getType() const override
Get element type std::string.
double getdB(const int &i, const int &I, const std::vector< double > &t, const double &phi, const std::vector< std::pair< double, double > > &F) const
virtual double getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &m) override
virtual bool isInside(const Vector_t &r) const override
virtual void goOffline() override
double getdE(const int &i, const int &I, const std::vector< double > &t, const double &phi, const std::vector< std::pair< double, double > > &F) const
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
virtual void finalise() override
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual void getElementDimensions(double &begin, double &end) const override
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
double getdT(const int &i, const int &I, const std::vector< double > &E, const std::vector< std::pair< double, double > > &F, const double mass) const
virtual void goOnline(const double &kineticEnergy) override
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
Vektor< double, 3 > Vector_t