OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
RFCavity.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: RFCavity.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: RFCavity
10 // Defines the abstract interface for an accelerating structure.
11 //
12 // ------------------------------------------------------------------------
13 // Class category: AbsBeamline
14 // ------------------------------------------------------------------------
15 //
16 // $Date: 2000/03/27 09:32:31 $
17 // $Author: andreas adelmann $
18 //
19 // ------------------------------------------------------------------------
20 
21 #include "AbsBeamline/RFCavity.h"
24 #include "Steppers/BorisPusher.h"
25 #include "Fields/Fieldmap.h"
27 #include "Utilities/Util.h"
28 
29 #include "gsl/gsl_interp.h"
30 #include "gsl/gsl_spline.h"
31 
32 #include <cmath>
33 #include <iostream>
34 #include <fstream>
35 
36 extern Inform *gmsg;
37 
38 // Class RFCavity
39 // ------------------------------------------------------------------------
40 
42  RFCavity("")
43 {}
44 
45 
47  Component(right),
48  phase_td_m(right.phase_td_m),
49  phase_name_m(right.phase_name_m),
50  amplitude_td_m(right.amplitude_td_m),
51  amplitude_name_m(right.amplitude_name_m),
52  frequency_td_m(right.frequency_td_m),
53  frequency_name_m(right.frequency_name_m),
54  filename_m(right.filename_m),
55  scale_m(right.scale_m),
56  scaleError_m(right.scaleError_m),
57  phase_m(right.phase_m),
58  phaseError_m(right.phaseError_m),
59  frequency_m(right.frequency_m),
60  fast_m(right.fast_m),
61  autophaseVeto_m(right.autophaseVeto_m),
62  designEnergy_m(right.designEnergy_m),
63  fieldmap_m(right.fieldmap_m),
64  startField_m(right.startField_m),
65  endField_m(right.endField_m),
66  type_m(right.type_m),
67  rmin_m(right.rmin_m),
68  rmax_m(right.rmax_m),
69  angle_m(right.angle_m),
70  sinAngle_m(right.sinAngle_m),
71  cosAngle_m(right.cosAngle_m),
72  pdis_m(right.pdis_m),
73  gapwidth_m(right.gapwidth_m),
74  phi0_m(right.phi0_m),
75  RNormal_m(nullptr),
76  VrNormal_m(nullptr),
77  DvDr_m(nullptr),
78  num_points_m(right.num_points_m)
79 {}
80 
81 
82 RFCavity::RFCavity(const std::string &name):
83  Component(name),
84  phase_td_m(nullptr),
85  amplitude_td_m(nullptr),
86  frequency_td_m(nullptr),
87  filename_m(""),
88  scale_m(1.0),
89  scaleError_m(0.0),
90  phase_m(0.0),
91  phaseError_m(0.0),
92  frequency_m(0.0),
93  fast_m(true),
94  autophaseVeto_m(false),
95  designEnergy_m(-1.0),
96  fieldmap_m(nullptr),
97  startField_m(0.0),
98  endField_m(0.0),
99  type_m(SW),
100  rmin_m(0.0),
101  rmax_m(0.0),
102  angle_m(0.0),
103  sinAngle_m(0.0),
104  cosAngle_m(0.0),
105  pdis_m(0.0),
106  gapwidth_m(0.0),
107  phi0_m(0.0),
108  RNormal_m(nullptr),
109  VrNormal_m(nullptr),
110  DvDr_m(nullptr),
111  num_points_m(0)
112 {}
113 
114 
116 }
117 
118 void RFCavity::accept(BeamlineVisitor &visitor) const {
119  visitor.visitRFCavity(*this);
120 }
121 
122 bool RFCavity::apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) {
123  return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
124 }
125 
127  const Vector_t &/*P*/,
128  const double &t,
129  Vector_t &E,
130  Vector_t &B) {
131  if (R(2) >= startField_m &&
132  R(2) < startField_m + getElementLength()) {
133  Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
134 
135  bool outOfBounds = fieldmap_m->getFieldstrength(R, tmpE, tmpB);
136  if (outOfBounds) return true;
137 
138  E += (scale_m + scaleError_m) * std::cos(frequency_m * t + phase_m + phaseError_m) * tmpE;
139  B -= (scale_m + scaleError_m) * std::sin(frequency_m * t + phase_m + phaseError_m) * tmpB;
140 
141  }
142  return false;
143 }
144 
146  const Vector_t &/*P*/,
147  const double &t,
148  Vector_t &E,
149  Vector_t &B) {
150 
151  if (R(2) >= startField_m &&
152  R(2) < startField_m + getElementLength()) {
153  Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
154 
155  bool outOfBounds = fieldmap_m->getFieldstrength(R, tmpE, tmpB);
156  if (outOfBounds) return true;
157 
158  E += scale_m * std::cos(frequency_m * t + phase_m) * tmpE;
159  B -= scale_m * std::sin(frequency_m * t + phase_m) * tmpB;
160 
161  }
162  return false;
163 }
164 
165 void RFCavity::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
166 
167  startField_m = endField_m = 0.0;
168  if (bunch == NULL) {
169  startField = startField_m;
170  endField = endField_m;
171 
172  return;
173  }
174 
175  Inform msg("RFCavity ", *gmsg);
176  std::stringstream errormsg;
177  RefPartBunch_m = bunch;
178 
181  if (endField <= startField_m) {
182  throw GeneralClassicException("RFCavity::initialise",
183  "The length of the field map '" + filename_m + "' is zero or negative");
184  }
185 
186  msg << level2 << getName() << " using file ";
187  fieldmap_m->getInfo(&msg);
188  if (std::abs((frequency_m - fieldmap_m->getFrequency()) / frequency_m) > 0.01) {
189  errormsg << "FREQUENCY IN INPUT FILE DIFFERENT THAN IN FIELD MAP '" << filename_m << "';\n"
190  << frequency_m / Physics::two_pi * 1e-6 << " MHz <> "
191  << fieldmap_m->getFrequency() / Physics::two_pi * 1e-6 << " MHz; TAKE ON THE LATTER";
192  std::string errormsg_str = Fieldmap::typeset_msg(errormsg.str(), "warning");
193  ERRORMSG(errormsg_str << "\n" << endl);
194  if (Ippl::myNode() == 0) {
195  std::ofstream omsg("errormsg.txt", std::ios_base::app);
196  omsg << errormsg_str << std::endl;
197  omsg.close();
198  }
200  }
201  setElementLength(endField - startField_m);
202 }
203 
204 // In current version ,this function reads in the cavity voltage profile data from file.
206  std::shared_ptr<AbstractTimeDependence> freq_atd,
207  std::shared_ptr<AbstractTimeDependence> ampl_atd,
208  std::shared_ptr<AbstractTimeDependence> phase_atd) {
209 
210  RefPartBunch_m = bunch;
211 
213  setAmplitudeModel(ampl_atd);
214  setPhaseModel(phase_atd);
215  setFrequencyModel(freq_atd);
216 
217  std::ifstream in(filename_m.c_str());
218  if (!in.good()) {
219  throw GeneralClassicException("RFCavity::initialise",
220  "failed to open file '" + filename_m + "', please check if it exists");
221  }
222  *gmsg << "* Read cavity voltage profile data" << endl;
223 
224  in >> num_points_m;
225 
226  RNormal_m = std::unique_ptr<double[]>(new double[num_points_m]);
227  VrNormal_m = std::unique_ptr<double[]>(new double[num_points_m]);
228  DvDr_m = std::unique_ptr<double[]>(new double[num_points_m]);
229 
230  for (int i = 0; i < num_points_m; i++) {
231  if (in.eof()) {
232  throw GeneralClassicException("RFCavity::initialise",
233  "not enough data in file '" + filename_m + "', please check the data format");
234  }
235  in >> RNormal_m[i] >> VrNormal_m[i] >> DvDr_m[i];
236 
237  VrNormal_m[i] *= RefPartBunch_m->getQ();
238  DvDr_m[i] *= RefPartBunch_m->getQ();
239  }
242 
243  if (frequency_name_m != "")
244  *gmsg << "* Timedependent frequency model " << frequency_name_m << endl;
245 
246  *gmsg << "* Cavity voltage data read successfully!" << endl;
247 }
248 
250 {}
251 
252 bool RFCavity::bends() const {
253  return false;
254 }
255 
256 
257 void RFCavity::goOnline(const double &) {
259 
260  online_m = true;
261 }
262 
265 
266  online_m = false;
267 }
268 
269 void RFCavity::setRmin(double rmin) {
270  rmin_m = rmin;
271 }
272 
273 void RFCavity::setRmax(double rmax) {
274  rmax_m = rmax;
275 }
276 
277 void RFCavity::setAzimuth(double angle) {
278  angle_m = angle;
279 }
280 
281 void RFCavity::setPerpenDistance(double pdis) {
282  pdis_m = pdis;
283 }
284 
285 void RFCavity::setGapWidth(double gapwidth) {
286  gapwidth_m = gapwidth;
287 }
288 
289 void RFCavity::setPhi0(double phi0) {
290  phi0_m = phi0;
291 }
292 
293 double RFCavity::getRmin() const {
294  return rmin_m;
295 }
296 
297 double RFCavity::getRmax() const {
298  return rmax_m;
299 }
300 
301 double RFCavity::getAzimuth() const {
302  return angle_m;
303 }
304 
305 double RFCavity::getSinAzimuth() const {
306  return sinAngle_m;
307 }
308 
309 double RFCavity::getCosAzimuth() const {
310  return cosAngle_m;
311 }
312 
314  return pdis_m;
315 }
316 
317 double RFCavity::getGapWidth() const {
318  return gapwidth_m;
319 }
320 
321 double RFCavity::getPhi0() const {
322  return phi0_m;
323 }
324 
325 void RFCavity::setComponentType(std::string name) {
326  if (name == "STANDING") {
327  type_m = SW;
328  } else if (name == "SINGLEGAP") {
329  type_m = SGSW;
330  } else if (name != "") {
331  std::stringstream errormsg;
332  errormsg << getName() << ": CAVITY TYPE " << name << " DOES NOT EXIST;";
333  std::string errormsg_str = Fieldmap::typeset_msg(errormsg.str(), "warning");
334  ERRORMSG(errormsg_str << "\n" << endl);
335  if (Ippl::myNode() == 0) {
336  std::ofstream omsg("errormsg.txt", std::ios_base::app);
337  omsg << errormsg_str << std::endl;
338  omsg.close();
339  }
340  throw GeneralClassicException("RFCavity::setComponentType", errormsg_str);
341  } else {
342  type_m = SW;
343  }
344 
345 }
346 
347 std::string RFCavity::getComponentType()const {
348  if (type_m == SGSW)
349  return std::string("SINGLEGAP");
350  else
351  return std::string("STANDING");
352 }
353 
355  return frequency_m;
356 }
357 
368 void RFCavity::getMomentaKick(const double normalRadius, double momentum[], const double t, const double dtCorrt, const int PID, const double restMass, const int chargenumber) {
369 
370  double derivate;
371 
372  double momentum2 = momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2];
373  double betgam = std::sqrt(momentum2);
374 
375  double gamma = std::sqrt(1.0 + momentum2);
376  double beta = betgam / gamma;
377 
378  double Voltage = spline(normalRadius, &derivate) * scale_m * 1.0e6; // V
379 
380  double Ufactor = 1.0;
381 
382  double frequency = frequency_m * frequency_td_m->getValue(t);
383 
384  if (gapwidth_m > 0.0) {
385  double transit_factor = 0.5 * frequency * gapwidth_m * 1.0e-3 / (Physics::c * beta);
386  Ufactor = std::sin(transit_factor) / transit_factor;
387  }
388 
389  Voltage *= Ufactor;
390  // rad/s, ns --> rad
391  double nphase = (frequency * (t + dtCorrt) * 1.0e-9) - phi0_m / 180.0 * Physics::pi ;
392  double dgam = Voltage * std::cos(nphase) / (restMass);
393 
394  double tempdegree = std::fmod(nphase * 360.0 / Physics::two_pi, 360.0);
395  if (tempdegree > 270.0) tempdegree -= 360.0;
396 
397  gamma += dgam;
398 
399  double newmomentum2 = std::pow(gamma, 2) - 1.0;
400 
401  double pr = momentum[0] * cosAngle_m + momentum[1] * sinAngle_m;
402  double ptheta = std::sqrt(newmomentum2 - std::pow(pr, 2));
403  double px = pr * cosAngle_m - ptheta * sinAngle_m ; // x
404  double py = pr * sinAngle_m + ptheta * cosAngle_m; // y
405 
406  double rotate = -derivate * (scale_m * 1.0e6) / ((rmax_m - rmin_m) / 1000.0) * std::sin(nphase) / (frequency * Physics::two_pi) / (betgam * restMass / Physics::c / chargenumber); // radian
407 
409  momentum[0] = std::cos(rotate) * px + std::sin(rotate) * py;
410  momentum[1] = -std::sin(rotate) * px + std::cos(rotate) * py;
411 
412  if (PID == 0) {
413 
414  Inform m("OPAL", *gmsg, Ippl::myNode());
415 
416  m << "* Cavity " << getName() << " Phase= " << tempdegree << " [deg] transit time factor= " << Ufactor
417  << " dE= " << dgam *restMass * 1.0e-6 << " [MeV]"
418  << " E_kin= " << (gamma - 1.0)*restMass * 1.0e-6 << " [MeV] Time dep freq = " << frequency_td_m->getValue(t) << endl;
419  }
420 
421 }
422 
423 /* cubic spline subrutine */
424 double RFCavity::spline(double z, double *za) {
425  double splint;
426 
427  // domain-test and handling of case "1-support-point"
428  if (num_points_m < 1) {
429  throw GeneralClassicException("RFCavity::spline",
430  "no support points!");
431  }
432  if (num_points_m == 1) {
433  splint = RNormal_m[0];
434  *za = 0.0;
435  return splint;
436  }
437 
438  // search the two support-points
439  int il, ih;
440  il = 0;
441  ih = num_points_m - 1;
442  while ((ih - il) > 1) {
443  int i = (int)((il + ih) / 2.0);
444  if (z < RNormal_m[i]) {
445  ih = i;
446  } else if (z > RNormal_m[i]) {
447  il = i;
448  } else if (z == RNormal_m[i]) {
449  il = i;
450  ih = i + 1;
451  break;
452  }
453  }
454 
455  double x1 = RNormal_m[il];
456  double x2 = RNormal_m[ih];
457  double y1 = VrNormal_m[il];
458  double y2 = VrNormal_m[ih];
459  double y1a = DvDr_m[il];
460  double y2a = DvDr_m[ih];
461  //
462  // determination of the requested function-values and its derivatives
463  //
464  double dx = x2 - x1;
465  double dy = y2 - y1;
466  double u = (z - x1) / dx;
467  double u2 = u * u;
468  double u3 = u2 * u;
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;
477  // if(m>=1) za=y1a+2.0*u/dx*yb4+3.0*u2/dx*yb2;
478  // if(m>=2) za[1]=2.0/dx2*yb4+6.0*u/dx2*yb2;
479  // if(m>=3) za[2]=6.0/dx3*yb2;
480 
481  return splint;
482 }
483 
484 void RFCavity::getDimensions(double &zBegin, double &zEnd) const {
485  zBegin = startField_m;
486  zEnd = endField_m;
487 }
488 
489 
491  return RFCAVITY;
492 }
493 
494 double RFCavity::getAutoPhaseEstimateFallback(double E0, double t0, double q, double mass) {
495 
496  const double dt = 1e-13;
497  const double p0 = Util::getBetaGamma(E0, mass);
498  const double origPhase =getPhasem();
499  double dphi = Physics::pi / 18;
500 
501  double phi = 0.0;
502  setPhasem(phi);
503  std::pair<double, double> ret = trackOnAxisParticle(p0, t0, dt, q, mass);
504  double phimax = 0.0;
505  double Emax = Util::getKineticEnergy(Vector_t(0.0, 0.0, ret.first), mass);
506  phi += dphi;
507 
508  for (unsigned int j = 0; j < 2; ++ j) {
509  for (unsigned int i = 0; i < 36; ++ i, phi += dphi) {
510  setPhasem(phi);
511  ret = trackOnAxisParticle(p0, t0, dt, q, mass);
512  double Ekin = Util::getKineticEnergy(Vector_t(0.0, 0.0, ret.first), mass);
513  if (Ekin > Emax) {
514  Emax = Ekin;
515  phimax = phi;
516  }
517  }
518 
519  phi = phimax - dphi;
520  dphi = dphi / 17.5;
521  }
522 
523  phimax = phimax - std::round(phimax / Physics::two_pi) * Physics::two_pi;
524  phimax = std::fmod(phimax, Physics::two_pi);
525 
526  const int prevPrecision = Ippl::Info->precision(8);
528  << "estimated phase= " << phimax << " rad = "
529  << phimax * Physics::rad2deg << " deg \n"
530  << "Ekin= " << Emax << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
531 
532  setPhasem(origPhase);
533  return phimax;
534 }
535 
536 double RFCavity::getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &mass) {
537  std::vector<double> t, E, t2, E2;
538  std::vector<double> F;
539  std::vector< std::pair< double, double > > G;
540  gsl_spline *onAxisInterpolants;
541  gsl_interp_accel *onAxisAccel;
542 
543  double phi = 0.0, tmp_phi, dphi = 0.5 * Physics::pi / 180.;
544  double dz = 1.0, length = 0.0;
546  if (G.size() == 0) return 0.0;
547  double begin = (G.front()).first;
548  double end = (G.back()).first;
549  std::unique_ptr<double[]> zvals( new double[G.size()]);
550  std::unique_ptr<double[]> onAxisField(new double[G.size()]);
551 
552  for (size_t j = 0; j < G.size(); ++ j) {
553  zvals[j] = G[j].first;
554  onAxisField[j] = G[j].second;
555  }
556  onAxisInterpolants = gsl_spline_alloc(gsl_interp_cspline, G.size());
557  onAxisAccel = gsl_interp_accel_alloc();
558  gsl_spline_init(onAxisInterpolants, zvals.get(), onAxisField.get(), G.size());
559 
560  length = end - begin;
561  dz = length / G.size();
562 
563  G.clear();
564 
565  unsigned int N = (int)floor(length / dz + 1);
566  dz = length / N;
567 
568  F.resize(N);
569  double z = begin;
570  for (size_t j = 0; j < N; ++ j, z += dz) {
571  F[j] = gsl_spline_eval(onAxisInterpolants, z, onAxisAccel);
572  }
573  gsl_spline_free(onAxisInterpolants);
574  gsl_interp_accel_free(onAxisAccel);
575 
576  t.resize(N, t0);
577  t2.resize(N, t0);
578  E.resize(N, E0);
579  E2.resize(N, E0);
580 
581  z = begin + dz;
582  for (unsigned int i = 1; i < N; ++ i, z += dz) {
583  E[i] = E[i - 1] + dz * scale_m / mass;
584  E2[i] = E[i];
585  }
586 
587  for (int iter = 0; iter < 10; ++ iter) {
588  double A = 0.0;
589  double B = 0.0;
590  for (unsigned int i = 1; i < N; ++ i) {
591  t[i] = t[i - 1] + getdT(i, E, dz, mass);
592  t2[i] = t2[i - 1] + getdT(i, E2, dz, mass);
593  A += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi) * getdA(i, t, dz, frequency_m, F);
594  B += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi) * getdB(i, t, dz, frequency_m, F);
595  }
596 
597  if (std::abs(B) > 0.0000001) {
598  tmp_phi = atan(A / B);
599  } else {
600  tmp_phi = Physics::pi / 2;
601  }
602  if (q * (A * sin(tmp_phi) + B * cos(tmp_phi)) < 0) {
603  tmp_phi += Physics::pi;
604  }
605 
606  if (std::abs (phi - tmp_phi) < frequency_m * (t[N - 1] - t[0]) / (10 * N)) {
607  for (unsigned int i = 1; i < N; ++ i) {
608  E[i] = E[i - 1];
609  E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
610  }
611  const int prevPrecision = Ippl::Info->precision(8);
612  INFOMSG(level2 << "estimated phase= " << tmp_phi << " rad = "
613  << tmp_phi * Physics::rad2deg << " deg \n"
614  << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
615 
616  return tmp_phi;
617  }
618  phi = tmp_phi - std::round(tmp_phi / Physics::two_pi) * Physics::two_pi;
619 
620  for (unsigned int i = 1; i < N; ++ i) {
621  E[i] = E[i - 1];
622  E2[i] = E2[i - 1];
623  E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
624  E2[i] += q * scale_m * getdE(i, t2, dz, phi + dphi, frequency_m, F);
625  double a = E[i], b = E2[i];
626  if (std::isnan(a) || std::isnan(b)) {
627  return getAutoPhaseEstimateFallback(E0, t0, q, mass);
628  }
629  t[i] = t[i - 1] + getdT(i, E, dz, mass);
630  t2[i] = t2[i - 1] + getdT(i, E2, dz, mass);
631 
632  E[i] = E [i - 1];
633  E2[i] = E2[i - 1];
634  E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
635  E2[i] += q * scale_m * getdE(i, t2, dz, phi + dphi, frequency_m, F);
636  }
637 
638  double cosine_part = 0.0, sine_part = 0.0;
639  double p0 = Util::getBetaGamma(E0, mass);
640  cosine_part += scale_m * std::cos(frequency_m * t0) * F[0];
641  sine_part += scale_m * std::sin(frequency_m * t0) * F[0];
642 
643  double totalEz0 = std::cos(phi) * cosine_part - sin(phi) * sine_part;
644 
645  if (p0 + q * totalEz0 * (t[1] - t[0]) * Physics::c / mass < 0) {
646  // make totalEz0 = 0
647  tmp_phi = std::atan(cosine_part / sine_part);
648  if (std::abs (tmp_phi - phi) > Physics::pi) {
649  phi = tmp_phi + Physics::pi;
650  } else {
651  phi = tmp_phi;
652  }
653  }
654  }
655 
656  const int prevPrecision = Ippl::Info->precision(8);
658  << "estimated phase= " << tmp_phi << " rad = "
659  << tmp_phi * Physics::rad2deg << " deg \n"
660  << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
661 
662  return phi;
663 }
664 
665 std::pair<double, double> RFCavity::trackOnAxisParticle(const double &p0,
666  const double &t0,
667  const double &dt,
668  const double &/*q*/,
669  const double &mass,
670  std::ofstream *out) {
671  Vector_t p(0, 0, p0);
672  double t = t0;
673  BorisPusher integrator(*RefPartBunch_m->getReference());
674  const double cdt = Physics::c * dt;
675  const double zbegin = startField_m;
676  const double zend = getElementLength() + startField_m;
677 
678  Vector_t z(0.0, 0.0, zbegin);
679  double dz = 0.5 * p(2) / Util::getGamma(p) * cdt;
680  Vector_t Ef(0.0), Bf(0.0);
681 
682  if (out) *out << std::setw(18) << z[2]
683  << std::setw(18) << Util::getKineticEnergy(p, mass)
684  << std::endl;
685  while (z(2) + dz < zend && z(2) + dz > zbegin) {
686  z /= cdt;
687  integrator.push(z, p, dt);
688  z *= cdt;
689 
690  Ef = 0.0;
691  Bf = 0.0;
692  if (z(2) >= zbegin && z(2) <= zend) {
693  applyToReferenceParticle(z, p, t + 0.5 * dt, Ef, Bf);
694  }
695  integrator.kick(z, p, Ef, Bf, dt);
696 
697  dz = 0.5 * p(2) / std::sqrt(1.0 + dot(p, p)) * cdt;
698  z /= cdt;
699  integrator.push(z, p, dt);
700  z *= cdt;
701  t += dt;
702 
703  if (out) *out << std::setw(18) << z[2]
704  << std::setw(18) << Util::getKineticEnergy(p, mass)
705  << std::endl;
706  }
707 
708  const double beta = std::sqrt(1. - 1 / (dot(p, p) + 1.));
709  const double tErr = (z(2) - zend) / (Physics::c * beta);
710 
711  return std::pair<double, double>(p(2), t - tErr);
712 }
713 
714 bool RFCavity::isInside(const Vector_t &r) const {
715  if (isInsideTransverse(r)) {
716  return fieldmap_m->isInside(r);
717  }
718 
719  return false;
720 }
721 
723  double length = ElementBase::getElementLength();
724  if (length < 1e-10 && fieldmap_m != NULL) {
725  double start, end;
727  length = end - start;
728  }
729 
730  return length;
731 }
732 
734  double &end) const {
736 }
Inform * gmsg
Definition: Main.cpp:62
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
std::complex< double > a
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)
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:727
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
#define INFOMSG(msg)
Definition: IpplInfo.h:348
const std::string name
constexpr double two_pi
The value of.
Definition: Physics.h:33
constexpr double deg2rad
The conversion factor from degrees to radians.
Definition: Physics.h:48
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
constexpr double pi
The value of.
Definition: Physics.h:30
constexpr double rad2deg
The conversion factor from radians to degrees.
Definition: Physics.h:45
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:66
double getKineticEnergy(Vector_t p, double mass)
Definition: Util.h:37
double getBetaGamma(double Ekin, double mass)
Definition: Util.h:42
double getGamma(Vector_t p)
Definition: Util.h:27
ParticlePos_t & R
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.
Definition: Component.h:50
bool online_m
Definition: Component.h:195
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:194
virtual const std::string & getName() const
Get element name.
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:432
virtual void setElementLength(double length)
Set design length.
Definition: ElementBase.h:436
bool isInsideTransverse(const Vector_t &r) const
Interface for RF cavity.
Definition: RFCavity.h:37
virtual std::string getComponentType() const override
Definition: RFCavity.cpp:347
void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition: RFCavity.h:488
virtual bool isInside(const Vector_t &r) const override
Definition: RFCavity.cpp:714
virtual double getPhasem() const
Definition: RFCavity.h:408
virtual bool bends() const override
Definition: RFCavity.cpp:252
bool fast_m
Definition: RFCavity.h:223
virtual double getRmax() const
Definition: RFCavity.cpp:297
double phi0_m
Definition: RFCavity.h:243
void setPerpenDistance(double pdis)
Definition: RFCavity.cpp:281
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
Definition: RFCavity.cpp:368
virtual double getAzimuth() const
Definition: RFCavity.cpp:301
Fieldmap * fieldmap_m
Definition: RFCavity.h:228
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
Definition: RFCavity.h:279
virtual void accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
Definition: RFCavity.cpp:118
double endField_m
Definition: RFCavity.h:232
double getdB(const int &i, const std::vector< double > &t, const double &dz, const double &frequency, const std::vector< double > &F) const
Definition: RFCavity.h:331
std::string filename_m
Definition: RFCavity.h:215
CavityType type_m
Definition: RFCavity.h:234
std::unique_ptr< double[]> DvDr_m
Definition: RFCavity.h:247
virtual void finalise() override
Definition: RFCavity.cpp:249
virtual ~RFCavity()
Definition: RFCavity.cpp:115
void setRmin(double rmin)
Definition: RFCavity.cpp:269
void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition: RFCavity.h:473
@ SGSW
Definition: RFCavity.h:41
virtual std::pair< double, double > trackOnAxisParticle(const double &p0, const double &t0, const double &dt, const double &q, const double &mass, std::ofstream *out=NULL)
Definition: RFCavity.cpp:665
virtual void getElementDimensions(double &begin, double &end) const override
Definition: RFCavity.cpp:733
virtual double getCosAzimuth() const
Definition: RFCavity.cpp:309
double rmin_m
Definition: RFCavity.h:236
double scale_m
Definition: RFCavity.h:217
RFCavity()
Definition: RFCavity.cpp:41
double phaseError_m
Definition: RFCavity.h:220
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Definition: RFCavity.cpp:165
double cosAngle_m
Definition: RFCavity.h:240
std::shared_ptr< AbstractTimeDependence > frequency_td_m
Definition: RFCavity.h:212
std::unique_ptr< double[]> RNormal_m
Definition: RFCavity.h:245
double gapwidth_m
Definition: RFCavity.h:242
virtual void setPhasem(double phase)
Definition: RFCavity.h:403
double sinAngle_m
Definition: RFCavity.h:239
virtual void setComponentType(std::string name) override
Definition: RFCavity.cpp:325
virtual double getSinAzimuth() const
Definition: RFCavity.cpp:305
void setPhi0(double phi0)
Definition: RFCavity.cpp:289
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Definition: RFCavity.cpp:145
double spline(double z, double *za)
Definition: RFCavity.cpp:424
double frequency_m
Definition: RFCavity.h:221
void setAzimuth(double angle)
Definition: RFCavity.cpp:277
std::unique_ptr< double[]> VrNormal_m
Definition: RFCavity.h:246
virtual void goOnline(const double &kineticEnergy) override
Definition: RFCavity.cpp:257
double pdis_m
Definition: RFCavity.h:241
double startField_m
Definition: RFCavity.h:229
virtual double getCycFrequency() const
Definition: RFCavity.cpp:354
double getdA(const int &i, const std::vector< double > &t, const double &dz, const double &frequency, const std::vector< double > &F) const
Definition: RFCavity.h:319
virtual double getGapWidth() const
Definition: RFCavity.cpp:317
virtual double getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &m)
Definition: RFCavity.cpp:536
double rmax_m
Definition: RFCavity.h:237
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition: RFCavity.cpp:484
double scaleError_m
Definition: RFCavity.h:218
virtual double getPerpenDistance() const
Definition: RFCavity.cpp:313
virtual ElementBase::ElementType getType() const override
Get element type std::string.
Definition: RFCavity.cpp:490
void setGapWidth(double gapwidth)
Definition: RFCavity.cpp:285
virtual double getElementLength() const override
Get design length.
Definition: RFCavity.cpp:722
double phase_m
Definition: RFCavity.h:219
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Definition: RFCavity.cpp:122
virtual void goOffline() override
Definition: RFCavity.cpp:263
double angle_m
Definition: RFCavity.h:238
virtual double getPhi0() const
Definition: RFCavity.cpp:321
virtual double getAutoPhaseEstimateFallback(double E0, double t0, double q, double m)
Definition: RFCavity.cpp:494
std::string frequency_name_m
Definition: RFCavity.h:213
void setRmax(double rmax)
Definition: RFCavity.cpp:273
void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition: RFCavity.h:458
virtual double getRmin() const
Definition: RFCavity.cpp:293
int num_points_m
Definition: RFCavity.h:248
double getdT(const int &i, const std::vector< double > &E, const double &dz, const double mass) const
Definition: RFCavity.h:291
virtual void getInfo(Inform *msg)=0
virtual void getFieldDimensions(double &zBegin, double &zEnd) const =0
static Fieldmap * getFieldmap(std::string Filename, bool fast=false)
Definition: Fieldmap.cpp:50
virtual bool isInside(const Vector_t &) const
Definition: Fieldmap.h:101
virtual void freeMap()=0
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &onaxis)
Definition: Fieldmap.cpp:709
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)
Definition: Fieldmap.cpp:652
virtual void readMap()=0
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
Definition: BorisPusher.h:65
void push(Vector_t &R, const Vector_t &P, const double &dt) const
Definition: BorisPusher.h:131
Definition: Inform.h:42
int precision() const
Definition: Inform.h:112
static Inform * Info
Definition: IpplInfo.h:78
static int myNode()
Definition: IpplInfo.cpp:691
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6