25#include "gsl/gsl_interp.h"
26#include "gsl/gsl_spline.h"
38 scaleCore_m(right.scaleCore_m),
39 scaleCoreError_m(right.scaleCoreError_m),
40 phaseCore1_m(right.phaseCore1_m),
41 phaseCore2_m(right.phaseCore2_m),
42 phaseExit_m(right.phaseExit_m),
43 startCoreField_m(right.startCoreField_m),
44 startExitField_m(right.startExitField_m),
45 mappedStartExitField_m(right.mappedStartExitField_m),
46 periodLength_m(right.periodLength_m),
47 numCells_m(right.numCells_m),
48 cellLength_m(right.cellLength_m),
49 mode_m(right.mode_m) {
55 scaleCoreError_m(0.0),
59 startCoreField_m(0.0),
60 startExitField_m(0.0),
61 mappedStartExitField_m(0.0),
87 double tmpcos, tmpsin;
100 const double z = tmpR(2);
149 double tmpcos, tmpsin;
161 const double z = tmpR(2);
200 if (bunch ==
nullptr) {
209 double zBegin = 0.0, zEnd = 0.0;
213 "TravelingWave::initialise",
214 "The field map of a traveling wave structure has to begin at 0.0");
239 std::shared_ptr<AbstractTimeDependence> ampl_atd,
240 std::shared_ptr<AbstractTimeDependence> phase_atd) {
276 const double& E0,
const double& t0,
const double& q,
const double& mass) {
277 std::vector<double> t, E, t2, E2;
278 std::vector<std::pair<double, double> > F;
288 int N1 =
static_cast<int>(std::floor(F.size() / 4.)) + 1;
289 int N2 = F.size() - 2 * N1 + 1;
290 int N3 = 2 * N1 +
static_cast<int>(std::floor((
numCells_m - 1) * N2 *
mode_m)) - 1;
291 int N4 =
static_cast<int>(std::round(N2 *
mode_m));
292 double Dz = F[N1 + N2].first - F[N1].first;
298 for (
int i = 1; i < N1; ++i) {
299 E[i] = E0 + (F[i].first + F[i - 1].first) / 2. *
scale_m / mass;
302 for (
int i = N1; i < N3 - N1 + 1; ++i) {
303 int I = (i - N1) % N2 + N1;
304 double Z = (F[I].first + F[I - 1].first) / 2. + std::floor((i - N1) / N2) * Dz;
308 for (
int i = N3 - N1 + 1; i < N3; ++i) {
309 int I = i - N3 - 1 + 2 * N1 + N2;
310 double Z = (F[I].first + F[I - 1].first) / 2. + ((
numCells_m - 1) *
mode_m - 1) * Dz;
311 E[i] = E0 + Z *
scale_m / mass;
315 for (
int iter = 0; iter < 10; ++iter) {
318 for (
int i = 1; i < N1; ++i) {
319 t[i] = t[i - 1] +
getdT(i, i, E, F, mass);
320 t2[i] = t2[i - 1] +
getdT(i, i, E2, F, mass);
324 for (
int i = N1; i < N3 - N1 + 1; ++i) {
325 int I = (i - N1) % N2 + N1;
326 int J = (i - N1 + N4) % N2 + N1;
327 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
328 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
330 * (
getdA(i, I, t, phaseC1, F) +
getdA(i, J, t, phaseC2, F));
332 * (
getdB(i, I, t, phaseC1, F) +
getdB(i, J, t, phaseC2, F));
334 for (
int i = N3 - N1 + 1; i < N3; ++i) {
335 int I = i - N3 - 1 + 2 * N1 + N2;
336 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
337 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
342 if (std::abs(B) > 0.0000001) {
343 tmp_phi = std::atan(A / B);
347 if (q * (A * std::sin(tmp_phi) + B * std::cos(tmp_phi)) < 0) {
351 if (std::abs(phi - tmp_phi) <
frequency_m * (t[N3 - 1] - t[0]) / N3) {
352 for (
int i = 1; i < N1; ++i) {
355 for (
int i = N1; i < N3 - N1 + 1; ++i) {
356 int I = (i - N1) % N2 + N1;
357 int J = (i - N1 + N4) % N2 + N1;
361 * (
getdE(i, I, t, phi + phaseC1, F) +
getdE(i, J, t, phi + phaseC2, F));
363 for (
int i = N3 - N1 + 1; i < N3; ++i) {
364 int I = i - N3 - 1 + 2 * N1 + N2;
365 E[i] = E[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE, F);
368 const int prevPrecision =
ippl::Info->precision(8);
371 <<
"Ekin= " << E[N3 - 1] <<
" MeV" << std::setprecision(prevPrecision)
378 for (
int i = 1; i < N1; ++i) {
382 t[i] = t[i - 1] +
getdT(i, i, E, F, mass);
383 t2[i] = t2[i - 1] +
getdT(i, i, E2, F, mass);
385 E2[i] = E2[i - 1] + q *
scale_m *
getdE(i, i, t2, phi + dphi, F);
387 for (
int i = N1; i < N3 - N1 + 1; ++i) {
388 int I = (i - N1) % N2 + N1;
389 int J = (i - N1 + N4) % N2 + N1;
392 * (
getdE(i, I, t, phi + phaseC1, F) +
getdE(i, J, t, phi + phaseC2, F));
395 * (
getdE(i, I, t, phi + phaseC1 + dphi, F)
396 +
getdE(i, J, t, phi + phaseC2 + dphi, F));
397 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
398 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
401 * (
getdE(i, I, t, phi + phaseC1, F) +
getdE(i, J, t, phi + phaseC2, F));
404 * (
getdE(i, I, t2, phi + phaseC1 + dphi, F)
405 +
getdE(i, J, t2, phi + phaseC2 + dphi, F));
407 for (
int i = N3 - N1 + 1; i < N3; ++i) {
408 int I = i - N3 - 1 + 2 * N1 + N2;
409 E[i] = E[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE, F);
413 t[i] = t[i - 1] +
getdT(i, I, E, F, mass);
414 t2[i] = t2[i - 1] +
getdT(i, I, E2, F, mass);
415 E[i] = E[i - 1] + q *
scale_m *
getdE(i, I, t, phi + phaseE, F);
416 E2[i] = E2[i - 1] + q *
scale_m *
getdE(i, I, t2, phi + phaseE + dphi, F);
421 const int prevPrecision =
ippl::Info->precision(8);
424 <<
"Ekin= " << E[N3 - 1] <<
" MeV" << std::setprecision(prevPrecision) <<
"\n"
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
PartBunch< T, Dim >::ConstIterator begin(PartBunch< T, Dim > const &bunch)
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
constexpr double two_pi
The value of.
constexpr double pi
The value of.
std::unique_ptr< Inform > Info
virtual void visitTravelingWave(const TravelingWave &)=0
Apply the algorithm to a traveling wave.
PartBunch_t * RefPartBunch_m
bool getFlagDeleteOnTransverseExit() const
virtual void setElementLength(double length)
Set design length.
bool isInsideTransverse(const Vector_t< double, 3 > &r) const
virtual void initialise(PartBunch_t *bunch, double &startField, double &endField) override
std::string filename_m
The name of the inputfile.
double scale_m
scale multiplier
double phaseError_m
phase shift error (rad)
double frequency_m
Read in frequency of time varying field(Hz)
double startField_m
starting point of field(m)
double scaleError_m
additive scale error
virtual double getElementLength() const override
Get design length.
double phase_m
phase shift of time varying field (rad)
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 ElementType getType() const override
Get element type std::string.
virtual bool bends() const override
virtual void accept(BeamlineVisitor &) const override
Apply visitor to TravelingWave.
virtual void getDimensions(double &zBegin, double &zEnd) const override
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 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 void initialise(PartBunch_t *bunch, double &startField, double &endField) override
virtual bool applyToReferenceParticle(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
virtual bool apply(const size_t &i, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
virtual void finalise() override
virtual bool isInside(const Vector_t< double, 3 > &r) const override
virtual void getElementDimensions(double &begin, double &end) const 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
double startCoreField_m
starting point of field(m)
virtual void goOnline(const double &kineticEnergy) override
Vector_t< double, Dim > R(size_t)
ParticleAttrib< Vector_t< T, Dim > > P
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const =0
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &onaxis)
virtual bool isInside(const Vector_t< double, 3 > &) const