OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
RFCavity.cpp
Go to the documentation of this file.
1//
2// Class RFCavity
3// Defines the abstract interface for for RF cavities.
4//
5// Copyright (c) 200x - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
6// All rights reserved
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
19
22#include "Fields/Fieldmap.h"
23#include "Physics/Units.h"
26#include "Utilities/Util.h"
27
28#include <boost/assign.hpp>
29#include <boost/filesystem.hpp>
30
31#include "gsl/gsl_interp.h"
32#include "gsl/gsl_spline.h"
33
34#include <iostream>
35#include <fstream>
36
37extern Inform *gmsg;
38
39const boost::bimap<CavityType, std::string> RFCavity::bmCavityTypeString_s =
40 boost::assign::list_of<const boost::bimap<CavityType, std::string>::relation>
41 (CavityType::SW, "STANDING")
42 (CavityType::SGSW, "SINGLEGAP");
43
44
46 RFCavity("")
47{}
48
50 Component(right),
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),
63 fast_m(right.fast_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),
69 type_m(right.type_m),
70 rmin_m(right.rmin_m),
71 rmax_m(right.rmax_m),
72 angle_m(right.angle_m),
73 sinAngle_m(right.sinAngle_m),
74 cosAngle_m(right.cosAngle_m),
75 pdis_m(right.pdis_m),
76 gapwidth_m(right.gapwidth_m),
77 phi0_m(right.phi0_m),
78 RNormal_m(nullptr),
79 VrNormal_m(nullptr),
80 DvDr_m(nullptr),
81 num_points_m(right.num_points_m)
82{}
83
84RFCavity::RFCavity(const std::string& name):
86 phaseTD_m(nullptr),
87 amplitudeTD_m(nullptr),
88 frequencyTD_m(nullptr),
89 filename_m(""),
90 scale_m(1.0),
91 scaleError_m(0.0),
92 phase_m(0.0),
93 phaseError_m(0.0),
94 frequency_m(0.0),
95 fast_m(true),
96 autophaseVeto_m(false),
97 designEnergy_m(-1.0),
98 fieldmap_m(nullptr),
99 startField_m(0.0),
100 endField_m(0.0),
101 type_m(CavityType::SW),
102 rmin_m(0.0),
103 rmax_m(0.0),
104 angle_m(0.0),
105 sinAngle_m(0.0),
106 cosAngle_m(0.0),
107 pdis_m(0.0),
108 gapwidth_m(0.0),
109 phi0_m(0.0),
110 RNormal_m(nullptr),
111 VrNormal_m(nullptr),
112 DvDr_m(nullptr),
113 num_points_m(0)
114{}
115
117}
118
119void RFCavity::accept(BeamlineVisitor& visitor) const {
120 visitor.visitRFCavity(*this);
121}
122
123bool RFCavity::apply(const size_t& i, const double& t, Vector_t& E, Vector_t& B) {
124 return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
125}
126
128 const Vector_t& /*P*/,
129 const double& t,
130 Vector_t& E,
131 Vector_t& B) {
132
133 if (R(2) >= startField_m &&
135 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
136
137 bool outOfBounds = fieldmap_m->getFieldstrength(R, tmpE, tmpB);
138 if (outOfBounds) return getFlagDeleteOnTransverseExit();
139
140 E += (scale_m + scaleError_m) * std::cos(frequency_m * t + phase_m + phaseError_m) * tmpE;
141 B -= (scale_m + scaleError_m) * std::sin(frequency_m * t + phase_m + phaseError_m) * tmpB;
142
143 }
144 return false;
145}
146
148 const Vector_t& /*P*/,
149 const double& t,
150 Vector_t& E,
151 Vector_t& B) {
152
153 if (R(2) >= startField_m &&
155 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
156
157 bool outOfBounds = fieldmap_m->getFieldstrength(R, tmpE, tmpB);
158 if (outOfBounds) return true;
159
160 E += scale_m * std::cos(frequency_m * t + phase_m) * tmpE;
161 B -= scale_m * std::sin(frequency_m * t + phase_m) * tmpB;
162
163 }
164 return false;
165}
166
167void RFCavity::initialise(PartBunchBase<double, 3>* bunch, double& startField, double& endField) {
168
169 startField_m = endField_m = 0.0;
170 if (bunch == nullptr) {
171 startField = startField_m;
172 endField = endField_m;
173
174 return;
175 }
176
177 Inform msg("RFCavity ", *gmsg);
178 std::stringstream errormsg;
179 RefPartBunch_m = bunch;
180
183 if (endField <= startField_m) {
184 throw GeneralClassicException("RFCavity::initialise",
185 "The length of the field map '" + filename_m + "' is zero or negative");
186 }
187
188 msg << level2 << getName() << " using file ";
189 fieldmap_m->getInfo(&msg);
191 errormsg << "FREQUENCY IN INPUT FILE DIFFERENT THAN IN FIELD MAP '" << filename_m << "';\n"
192 << frequency_m / Physics::two_pi * Units::Hz2MHz << " MHz <> "
193 << fieldmap_m->getFrequency() / Physics::two_pi * Units::Hz2MHz << " MHz; TAKE ON THE LATTER";
194 std::string errormsg_str = Fieldmap::typeset_msg(errormsg.str(), "warning");
195 ERRORMSG(errormsg_str << "\n" << endl);
196 if (Ippl::myNode() == 0) {
197 std::ofstream omsg("errormsg.txt", std::ios_base::app);
198 omsg << errormsg_str << std::endl;
199 omsg.close();
200 }
202 }
203 setElementLength(endField - startField_m);
204}
205
206// In current version ,this function reads in the cavity voltage profile data from file.
208 std::shared_ptr<AbstractTimeDependence> freq_atd,
209 std::shared_ptr<AbstractTimeDependence> ampl_atd,
210 std::shared_ptr<AbstractTimeDependence> phase_atd) {
211
212 RefPartBunch_m = bunch;
213
215 setAmplitudeModel(ampl_atd);
216 setPhaseModel(phase_atd);
217 setFrequencyModel(freq_atd);
218
219 std::ifstream in(filename_m.c_str());
220 in >> num_points_m;
221
222 RNormal_m = std::unique_ptr<double[]>(new double[num_points_m]);
223 VrNormal_m = std::unique_ptr<double[]>(new double[num_points_m]);
224 DvDr_m = std::unique_ptr<double[]>(new double[num_points_m]);
225
226 for (int i = 0; i < num_points_m; i++) {
227 if (in.eof()) {
228 throw GeneralClassicException("RFCavity::initialise",
229 "Not enough data in file '" + filename_m +
230 "', please check the data format");
231 }
232 in >> RNormal_m[i] >> VrNormal_m[i] >> DvDr_m[i];
233
235 DvDr_m[i] *= RefPartBunch_m->getQ();
236 }
239
240 if (!frequencyName_m.empty()) {
241 *gmsg << "* Timedependent frequency model " << frequencyName_m << endl;
242 }
243
244 *gmsg << "* Cavity voltage data read successfully!" << endl;
245}
246
248{}
249
250bool RFCavity::bends() const {
251 return false;
252}
253
254void RFCavity::goOnline(const double&) {
256
257 online_m = true;
258}
259
262
263 online_m = false;
264}
265
266void RFCavity::setRmin(double rmin) {
267 rmin_m = rmin;
268}
269
270void RFCavity::setRmax(double rmax) {
271 rmax_m = rmax;
272}
273
274void RFCavity::setAzimuth(double angle) {
275 angle_m = angle;
276}
277
279 pdis_m = pdis;
280}
281
282void RFCavity::setGapWidth(double gapwidth) {
283 gapwidth_m = gapwidth;
284}
285
286void RFCavity::setPhi0(double phi0) {
287 phi0_m = phi0;
288}
289
290double RFCavity::getRmin() const {
291 return rmin_m;
292}
293
294double RFCavity::getRmax() const {
295 return rmax_m;
296}
297
298double RFCavity::getAzimuth() const {
299 return angle_m;
300}
301
303 return sinAngle_m;
304}
305
307 return cosAngle_m;
308}
309
311 return pdis_m;
312}
313
314double RFCavity::getGapWidth() const {
315 return gapwidth_m;
316}
317
318double RFCavity::getPhi0() const {
319 return phi0_m;
320}
321
322void RFCavity::setCavityType(const std::string& name) {
323 auto it = bmCavityTypeString_s.right.find(name);
324 if (it != bmCavityTypeString_s.right.end()) {
325 type_m = it->second;
326 } else {
328 }
329}
330
331std::string RFCavity::getCavityTypeString() const {
332 return bmCavityTypeString_s.left.at(type_m);
333}
334
335std::string RFCavity::getFieldMapFN() const {
336 if (filename_m.empty()) {
337 throw GeneralClassicException("RFCavity::getFieldMapFN",
338 "The attribute \"FMAPFN\" isn't set "
339 "for the \"RFCAVITY\" element!");
340 } else if (boost::filesystem::exists(filename_m)) {
341 return filename_m;
342 } else {
343 throw GeneralClassicException("RFCavity::getFieldMapFN",
344 "Failed to open file '" + filename_m +
345 "', please check if it exists");
346 }
347}
348
350 return frequency_m;
351}
352
363void RFCavity::getMomentaKick(const double normalRadius,
364 double momentum[],
365 const double t,
366 const double dtCorrt,
367 const int PID,
368 const double restMass,
369 const int chargenumber) {
370
371 double derivate;
372
373 double momentum2 = momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2];
374 double betgam = std::sqrt(momentum2);
375
376 double gamma = std::sqrt(1.0 + momentum2);
377 double beta = betgam / gamma;
378
379 double Voltage = spline(normalRadius, &derivate) * scale_m * Units::MVpm2Vpm;
380
381 double Ufactor = 1.0;
382
383 double frequency = frequency_m * frequencyTD_m->getValue(t);
384
385 if (gapwidth_m > 0.0) {
386 double transit_factor = 0.5 * frequency * gapwidth_m * Units::mm2m / (Physics::c * beta);
387 Ufactor = std::sin(transit_factor) / transit_factor;
388 }
389
390 Voltage *= Ufactor;
391 // rad/s, ns --> rad
392 double nphase = (frequency * (t + dtCorrt) * Units::ns2s) - phi0_m * Units::deg2rad;
393 double dgam = Voltage * std::cos(nphase) / (restMass);
394
395 double tempdegree = std::fmod(nphase * Units::rad2deg, 360.0);
396 if (tempdegree > 270.0) tempdegree -= 360.0;
397
398 gamma += dgam;
399
400 double newmomentum2 = std::pow(gamma, 2) - 1.0;
401
402 double pr = momentum[0] * cosAngle_m + momentum[1] * sinAngle_m;
403 double ptheta = std::sqrt(newmomentum2 - std::pow(pr, 2));
404 double px = pr * cosAngle_m - ptheta * sinAngle_m ; // x
405 double py = pr * sinAngle_m + ptheta * cosAngle_m; // y
406
407 double rotate = -derivate * (scale_m * Units::MVpm2Vpm) / ((rmax_m - rmin_m) * Units::mm2m) * std::sin(nphase) / (frequency * Physics::two_pi) / (betgam * restMass / Physics::c / chargenumber); // radian
408
410 momentum[0] = std::cos(rotate) * px + std::sin(rotate) * py;
411 momentum[1] = -std::sin(rotate) * px + std::cos(rotate) * py;
412
413 if (PID == 0) {
414 Inform m("OPAL", *gmsg, Ippl::myNode());
415
416 m << "* Cavity " << getName() << " Phase= " << tempdegree << " [deg] transit time factor= " << Ufactor
417 << " dE= " << dgam *restMass * Units::eV2MeV << " [MeV]"
418 << " E_kin= " << (gamma - 1.0)*restMass * Units::eV2MeV << " [MeV] Time dep freq = " << frequencyTD_m->getValue(t) << endl;
419 }
420
421}
422
423/* cubic spline subrutine */
424double 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
484void RFCavity::getDimensions(double& zBegin, double& zEnd) const {
485 zBegin = startField_m;
486 zEnd = endField_m;
487}
488
489
492}
493
494double 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 * Units::rad2deg << " deg \n"
530 << "Ekin= " << Emax << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
531
532 setPhasem(origPhase);
533 return phimax;
534}
535
536double RFCavity::getAutoPhaseEstimate(const double& E0, const double& t0,
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;
543
544 double phi = 0.0, tmp_phi, dphi = 0.5 * Units::deg2rad;
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()]);
552
553 for (size_t j = 0; j < G.size(); ++ j) {
554 zvals[j] = G[j].first;
555 onAxisField[j] = G[j].second;
556 }
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());
560
561 length = end - begin;
562 dz = length / G.size();
563
564 G.clear();
565
566 unsigned int N = (int)std::floor(length / dz + 1);
567 dz = length / N;
568
569 F.resize(N);
570 double z = begin;
571 for (size_t j = 0; j < N; ++ j, z += dz) {
572 F[j] = gsl_spline_eval(onAxisInterpolants, z, onAxisAccel);
573 }
574 gsl_spline_free(onAxisInterpolants);
575 gsl_interp_accel_free(onAxisAccel);
576
577 t.resize(N, t0);
578 t2.resize(N, t0);
579 E.resize(N, E0);
580 E2.resize(N, E0);
581
582 z = begin + dz;
583 for (unsigned int i = 1; i < N; ++ i, z += dz) {
584 E[i] = E[i - 1] + dz * scale_m / mass;
585 E2[i] = E[i];
586 }
587
588 for (int iter = 0; iter < 10; ++ iter) {
589 double A = 0.0;
590 double B = 0.0;
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);
594 A += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi) * getdA(i, t, dz, frequency_m, F);
595 B += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi) * getdB(i, t, dz, frequency_m, F);
596 }
597
598 if (std::abs(B) > 0.0000001) {
599 tmp_phi = std::atan(A / B);
600 } else {
601 tmp_phi = Physics::pi / 2;
602 }
603 if (q * (A * std::sin(tmp_phi) + B * std::cos(tmp_phi)) < 0) {
604 tmp_phi += Physics::pi;
605 }
606
607 if (std::abs (phi - tmp_phi) < frequency_m * (t[N - 1] - t[0]) / (10 * N)) {
608 for (unsigned int i = 1; i < N; ++ i) {
609 E[i] = E[i - 1];
610 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
611 }
612 const int prevPrecision = Ippl::Info->precision(8);
613 INFOMSG(level2 << "estimated phase= " << tmp_phi << " rad = "
614 << tmp_phi * Units::rad2deg << " deg \n"
615 << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
616
617 return tmp_phi;
618 }
619 phi = tmp_phi - std::round(tmp_phi / Physics::two_pi) * Physics::two_pi;
620
621 for (unsigned int i = 1; i < N; ++ i) {
622 E[i] = E[i - 1];
623 E2[i] = E2[i - 1];
624 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
625 E2[i] += q * scale_m * getdE(i, t2, dz, phi + dphi, frequency_m, F);
626 double a = E[i], b = E2[i];
627 if (std::isnan(a) || std::isnan(b)) {
628 return getAutoPhaseEstimateFallback(E0, t0, q, mass);
629 }
630 t[i] = t[i - 1] + getdT(i, E, dz, mass);
631 t2[i] = t2[i - 1] + getdT(i, E2, dz, mass);
632
633 E[i] = E [i - 1];
634 E2[i] = E2[i - 1];
635 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
636 E2[i] += q * scale_m * getdE(i, t2, dz, phi + dphi, frequency_m, F);
637 }
638
639 double cosine_part = 0.0, sine_part = 0.0;
640 double p0 = Util::getBetaGamma(E0, mass);
641 cosine_part += scale_m * std::cos(frequency_m * t0) * F[0];
642 sine_part += scale_m * std::sin(frequency_m * t0) * F[0];
643
644 double totalEz0 = std::cos(phi) * cosine_part - std::sin(phi) * sine_part;
645
646 if (p0 + q * totalEz0 * (t[1] - t[0]) * Physics::c / mass < 0) {
647 // make totalEz0 = 0
648 tmp_phi = std::atan(cosine_part / sine_part);
649 if (std::abs (tmp_phi - phi) > Physics::pi) {
650 phi = tmp_phi + Physics::pi;
651 } else {
652 phi = tmp_phi;
653 }
654 }
655 }
656
657 const int prevPrecision = Ippl::Info->precision(8);
659 << "estimated phase= " << tmp_phi << " rad = "
660 << tmp_phi * Units::rad2deg << " deg \n"
661 << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
662
663 return phi;
664}
665
666std::pair<double, double> RFCavity::trackOnAxisParticle(const double& p0,
667 const double& t0,
668 const double& dt,
669 const double& /*q*/,
670 const double& mass,
671 std::ofstream *out) {
672 Vector_t p(0, 0, p0);
673 double t = t0;
675 const double cdt = Physics::c * dt;
676 const double zbegin = startField_m;
677 const double zend = getElementLength() + startField_m;
678
679 Vector_t z(0.0, 0.0, zbegin);
680 double dz = 0.5 * p(2) / Util::getGamma(p) * cdt;
681 Vector_t Ef(0.0), Bf(0.0);
682
683 if (out) *out << std::setw(18) << z[2]
684 << std::setw(18) << Util::getKineticEnergy(p, mass)
685 << std::endl;
686 while (z(2) + dz < zend && z(2) + dz > zbegin) {
687 z /= cdt;
688 integrator.push(z, p, dt);
689 z *= cdt;
690
691 Ef = 0.0;
692 Bf = 0.0;
693 if (z(2) >= zbegin && z(2) <= zend) {
694 applyToReferenceParticle(z, p, t + 0.5 * dt, Ef, Bf);
695 }
696 integrator.kick(z, p, Ef, Bf, dt);
697
698 dz = 0.5 * p(2) / std::sqrt(1.0 + dot(p, p)) * cdt;
699 z /= cdt;
700 integrator.push(z, p, dt);
701 z *= cdt;
702 t += dt;
703
704 if (out) *out << std::setw(18) << z[2]
705 << std::setw(18) << Util::getKineticEnergy(p, mass)
706 << std::endl;
707 }
708
709 const double beta = std::sqrt(1. - 1 / (dot(p, p) + 1.));
710 const double tErr = (z(2) - zend) / (Physics::c * beta);
711
712 return std::pair<double, double>(p(2), t - tErr);
713}
714
715bool RFCavity::isInside(const Vector_t& r) const {
716 if (isInsideTransverse(r)) {
717 return fieldmap_m->isInside(r);
718 }
719
720 return false;
721}
722
724 double length = ElementBase::getElementLength();
725 if (length < 1e-10 && fieldmap_m != nullptr) {
726 double start, end;
728 length = end - start;
729 }
730
731 return length;
732}
733
734void RFCavity::getElementDimensions(double& begin, double& end) const {
736}
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
Inform * gmsg
Definition: Main.cpp:61
CavityType
Definition: RFCavity.h:32
ElementType
Definition: ElementBase.h:88
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.
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
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
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)
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#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 e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
constexpr double pi
The value of.
Definition: Physics.h:30
constexpr double mm2m
Definition: Units.h:29
constexpr double ns2s
Definition: Units.h:47
constexpr double MVpm2Vpm
Definition: Units.h:128
constexpr double eV2MeV
Definition: Units.h:77
constexpr double Hz2MHz
Definition: Units.h:116
constexpr double rad2deg
Definition: Units.h:146
constexpr double deg2rad
Definition: Units.h:143
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:66
double getKineticEnergy(Vector_t p, double mass)
Definition: Util.h:55
double getBetaGamma(double Ekin, double mass)
Definition: Util.h:60
double getGamma(Vector_t p)
Definition: Util.h:45
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:192
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
virtual const std::string & getName() const
Get element name.
bool getFlagDeleteOnTransverseExit() const
Definition: ElementBase.h:613
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:414
virtual void setElementLength(double length)
Set design length.
Definition: ElementBase.h:418
bool isInsideTransverse(const Vector_t &r) const
void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition: RFCavity.h:470
virtual bool isInside(const Vector_t &r) const override
Definition: RFCavity.cpp:715
virtual double getPhasem() const
Definition: RFCavity.h:395
virtual bool bends() const override
Definition: RFCavity.cpp:250
bool fast_m
Definition: RFCavity.h:213
virtual double getRmax() const
Definition: RFCavity.cpp:294
double phi0_m
Definition: RFCavity.h:235
void setPerpenDistance(double pdis)
Definition: RFCavity.cpp:278
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:363
virtual double getAzimuth() const
Definition: RFCavity.cpp:298
Fieldmap * fieldmap_m
Definition: RFCavity.h:218
virtual ElementType getType() const override
Get element type std::string.
Definition: RFCavity.cpp:490
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:271
virtual void accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
Definition: RFCavity.cpp:119
double endField_m
Definition: RFCavity.h:222
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:323
std::string filename_m
Definition: RFCavity.h:205
CavityType type_m
Definition: RFCavity.h:224
std::unique_ptr< double[]> DvDr_m
Definition: RFCavity.h:239
virtual void finalise() override
Definition: RFCavity.cpp:247
virtual ~RFCavity()
Definition: RFCavity.cpp:116
void setRmin(double rmin)
Definition: RFCavity.cpp:266
void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition: RFCavity.h:455
virtual void getElementDimensions(double &begin, double &end) const override
Definition: RFCavity.cpp:734
virtual double getCosAzimuth() const
Definition: RFCavity.cpp:306
double rmin_m
Definition: RFCavity.h:228
double scale_m
Definition: RFCavity.h:207
RFCavity()
Definition: RFCavity.cpp:45
double phaseError_m
Definition: RFCavity.h:210
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Definition: RFCavity.cpp:167
double cosAngle_m
Definition: RFCavity.h:232
std::string frequencyName_m
Definition: RFCavity.h:203
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)
Definition: RFCavity.cpp:666
std::unique_ptr< double[]> RNormal_m
Definition: RFCavity.h:237
double gapwidth_m
Definition: RFCavity.h:234
virtual void setPhasem(double phase)
Definition: RFCavity.h:390
double sinAngle_m
Definition: RFCavity.h:231
virtual double getSinAzimuth() const
Definition: RFCavity.cpp:302
void setPhi0(double phi0)
Definition: RFCavity.cpp:286
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Definition: RFCavity.cpp:147
double spline(double z, double *za)
Definition: RFCavity.cpp:424
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
Definition: RFCavity.h:202
double frequency_m
Definition: RFCavity.h:211
virtual std::string getFieldMapFN() const
Definition: RFCavity.cpp:335
void setAzimuth(double angle)
Definition: RFCavity.cpp:274
std::unique_ptr< double[]> VrNormal_m
Definition: RFCavity.h:238
virtual void goOnline(const double &kineticEnergy) override
Definition: RFCavity.cpp:254
double pdis_m
Definition: RFCavity.h:233
void setCavityType(const std::string &type)
Definition: RFCavity.cpp:322
double startField_m
Definition: RFCavity.h:219
virtual double getCycFrequency() const
Definition: RFCavity.cpp:349
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:311
virtual double getGapWidth() const
Definition: RFCavity.cpp:314
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:229
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition: RFCavity.cpp:484
double scaleError_m
Definition: RFCavity.h:208
static const boost::bimap< CavityType, std::string > bmCavityTypeString_s
Definition: RFCavity.h:226
virtual double getPerpenDistance() const
Definition: RFCavity.cpp:310
void setGapWidth(double gapwidth)
Definition: RFCavity.cpp:282
virtual double getElementLength() const override
Get design length.
Definition: RFCavity.cpp:723
double phase_m
Definition: RFCavity.h:209
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Definition: RFCavity.cpp:123
virtual void goOffline() override
Definition: RFCavity.cpp:260
double angle_m
Definition: RFCavity.h:230
virtual double getPhi0() const
Definition: RFCavity.cpp:318
virtual double getAutoPhaseEstimateFallback(double E0, double t0, double q, double m)
Definition: RFCavity.cpp:494
std::string getCavityTypeString() const
Definition: RFCavity.cpp:331
void setRmax(double rmax)
Definition: RFCavity.cpp:270
void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition: RFCavity.h:440
virtual double getRmin() const
Definition: RFCavity.cpp:290
int num_points_m
Definition: RFCavity.h:240
double getdT(const int &i, const std::vector< double > &E, const double &dz, const double mass) const
Definition: RFCavity.h:283
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