OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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 <filesystem>
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
48
50 Component(right),
51 phaseTD_m(right.phaseTD_m),
58 scale_m(right.scale_m),
60 phase_m(right.phase_m),
63 fast_m(right.fast_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),
75 pdis_m(right.pdis_m),
77 phi0_m(right.phi0_m),
78 RNormal_m(nullptr),
79 VrNormal_m(nullptr),
80 DvDr_m(nullptr),
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),
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
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 &&
134 R(2) < startField_m + getElementLength()) {
135
136 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
137
138 bool outOfBounds = fieldmap_m->getFieldstrength(R, tmpE, tmpB);
139 if (outOfBounds) return getFlagDeleteOnTransverseExit();
140
141 E += (scale_m + scaleError_m) * std::cos(frequency_m * t + phase_m + phaseError_m) * tmpE;
142 B -= (scale_m + scaleError_m) * std::sin(frequency_m * t + phase_m + phaseError_m) * tmpB;
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 &&
154 R(2) < startField_m + getElementLength()) {
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
182 fieldmap_m->getFieldDimensions(startField_m, endField);
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);
190 if (std::abs((frequency_m - fieldmap_m->getFrequency()) / frequency_m) > 0.01) {
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 }
201 frequency_m = fieldmap_m->getFrequency();
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
234 VrNormal_m[i] *= RefPartBunch_m->getQ();
235 DvDr_m[i] *= RefPartBunch_m->getQ();
236 }
237 sinAngle_m = std::sin(angle_m);
238 cosAngle_m = std::cos(angle_m);
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
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 if (rmin_m >= 0.0) {
292 return rmin_m;
293 } else {
294 throw GeneralClassicException("RFCavity::getRmin",
295 "RMIN must be positive");
296 }
297}
298
299double RFCavity::getRmax() const {
300 if (rmax_m > rmin_m) {
301 return rmax_m;
302 } else {
303 throw GeneralClassicException("RFCavity::getRmax",
304 "The attribute RMAX has to be higher than RMIN");
305 }
306}
307
308double RFCavity::getAzimuth() const {
309 return angle_m;
310}
311
313 return sinAngle_m;
314}
315
317 return cosAngle_m;
318}
319
321 return pdis_m;
322}
323
324double RFCavity::getGapWidth() const {
325 return gapwidth_m;
326}
327
328double RFCavity::getPhi0() const {
329 return phi0_m;
330}
331
332void RFCavity::setCavityType(const std::string& name) {
333 auto it = bmCavityTypeString_s.right.find(name);
334 if (it != bmCavityTypeString_s.right.end()) {
335 type_m = it->second;
336 } else {
338 }
339}
340
341std::string RFCavity::getCavityTypeString() const {
342 return bmCavityTypeString_s.left.at(type_m);
343}
344
345std::string RFCavity::getFieldMapFN() const {
346 if (filename_m.empty()) {
347 throw GeneralClassicException("RFCavity::getFieldMapFN",
348 "The attribute \"FMAPFN\" isn't set "
349 "for the \"RFCAVITY\" element!");
350 } else if (std::filesystem::exists(filename_m)) {
351 return filename_m;
352 } else {
353 throw GeneralClassicException("RFCavity::getFieldMapFN",
354 "Failed to open file '" + filename_m +
355 "', please check if it exists");
356 }
357}
358
360 return frequency_m;
361}
362
373void RFCavity::getMomentaKick(const double normalRadius,
374 double momentum[],
375 const double t,
376 const double dtCorrt,
377 const int PID,
378 const double restMass,
379 const int chargenumber) {
380
381 double derivate;
382
383 double momentum2 = momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2];
384 double betgam = std::sqrt(momentum2);
385
386 double gamma = std::sqrt(1.0 + momentum2);
387 double beta = betgam / gamma;
388
389 double Voltage = spline(normalRadius, &derivate) * scale_m * Units::MVpm2Vpm;
390
391 double Ufactor = 1.0;
392
393 double frequency = frequency_m * frequencyTD_m->getValue(t);
394
395 if (gapwidth_m > 0.0) {
396 double transit_factor = 0.5 * frequency * gapwidth_m / (Physics::c * beta);
397 Ufactor = std::sin(transit_factor) / transit_factor;
398 }
399
400 Voltage *= Ufactor;
401 // rad/s, ns --> rad
402
403 double nphase = (frequency * (t + dtCorrt)) - phi0_m;
404 double dgam = Voltage * std::cos(nphase) / (restMass);
405
406 double tempdegree = std::fmod(nphase * Units::rad2deg, 360.0);
407 if (tempdegree > 270.0) tempdegree -= 360.0;
408
409 gamma += dgam;
410
411 double newmomentum2 = std::pow(gamma, 2) - 1.0;
412
413 double pr = momentum[0] * cosAngle_m + momentum[1] * sinAngle_m;
414 double ptheta = std::sqrt(newmomentum2 - std::pow(pr, 2));
415 double px = pr * cosAngle_m - ptheta * sinAngle_m ; // x
416 double py = pr * sinAngle_m + ptheta * cosAngle_m; // y
417
418 double rotate = -derivate * (scale_m * Units::MVpm2Vpm) / (rmax_m - rmin_m) * std::sin(nphase) / (frequency * Physics::two_pi) / (betgam * restMass / Physics::c / chargenumber); // radian
419
421 momentum[0] = std::cos(rotate) * px + std::sin(rotate) * py;
422 momentum[1] = -std::sin(rotate) * px + std::cos(rotate) * py;
423
424 if (PID == 0) {
425 Inform m("OPAL", *gmsg, Ippl::myNode());
426 m << "* Cavity " << getName() << " Phase= " << tempdegree << " [deg] transit time factor= " << Ufactor
427 << " dE= " << dgam * restMass * Units::eV2MeV << " [MeV]"
428 << " E_kin= " << (gamma - 1.0) * restMass * Units::eV2MeV << " [MeV] Time dep freq = " << frequencyTD_m->getValue(t) << endl;
429 }
430}
431
432/* cubic spline subrutine */
433double RFCavity::spline(double z, double* za) {
434 double splint;
435
436 // domain-test and handling of case "1-support-point"
437 if (num_points_m < 1) {
438 throw GeneralClassicException("RFCavity::spline",
439 "no support points!");
440 }
441 if (num_points_m == 1) {
442 splint = RNormal_m[0];
443 *za = 0.0;
444 return splint;
445 }
446
447 // search the two support-points
448 int il, ih;
449 il = 0;
450 ih = num_points_m - 1;
451 while ((ih - il) > 1) {
452 int i = (int)((il + ih) / 2.0);
453 if (z < RNormal_m[i]) {
454 ih = i;
455 } else if (z > RNormal_m[i]) {
456 il = i;
457 } else if (z == RNormal_m[i]) {
458 il = i;
459 ih = i + 1;
460 break;
461 }
462 }
463
464 double x1 = RNormal_m[il];
465 double x2 = RNormal_m[ih];
466 double y1 = VrNormal_m[il];
467 double y2 = VrNormal_m[ih];
468 double y1a = DvDr_m[il];
469 double y2a = DvDr_m[ih];
470 //
471 // determination of the requested function-values and its derivatives
472 //
473 double dx = x2 - x1;
474 double dy = y2 - y1;
475 double u = (z - x1) / dx;
476 double u2 = u * u;
477 double u3 = u2 * u;
478 double dy2 = -2.0 * dy;
479 double ya2 = y2a + 2.0 * y1a;
480 double dy3 = 3.0 * dy;
481 double ya3 = y2a + y1a;
482 double yb2 = dy2 + dx * ya3;
483 double yb4 = dy3 - dx * ya2;
484 splint = y1 + u * dx * y1a + u2 * yb4 + u3 * yb2;
485 *za = y1a + 2.0 * u / dx * yb4 + 3.0 * u2 / dx * yb2;
486 // if(m>=1) za=y1a+2.0*u/dx*yb4+3.0*u2/dx*yb2;
487 // if(m>=2) za[1]=2.0/dx2*yb4+6.0*u/dx2*yb2;
488 // if(m>=3) za[2]=6.0/dx3*yb2;
489
490 return splint;
491}
492
493void RFCavity::getDimensions(double& zBegin, double& zEnd) const {
494 zBegin = startField_m;
495 zEnd = endField_m;
496}
497
498
502
503double RFCavity::getAutoPhaseEstimateFallback(double E0, double t0, double q, double mass) {
504
505 const double dt = 1e-13;
506 const double p0 = Util::getBetaGamma(E0, mass);
507 const double origPhase =getPhasem();
508 double dphi = Physics::pi / 18;
509
510 double phi = 0.0;
511 setPhasem(phi);
512 std::pair<double, double> ret = trackOnAxisParticle(p0, t0, dt, q, mass);
513 double phimax = 0.0;
514 double Emax = Util::getKineticEnergy(Vector_t(0.0, 0.0, ret.first), mass);
515 phi += dphi;
516
517 for (unsigned int j = 0; j < 2; ++ j) {
518 for (unsigned int i = 0; i < 36; ++ i, phi += dphi) {
519 setPhasem(phi);
520 ret = trackOnAxisParticle(p0, t0, dt, q, mass);
521 double Ekin = Util::getKineticEnergy(Vector_t(0.0, 0.0, ret.first), mass);
522 if (Ekin > Emax) {
523 Emax = Ekin;
524 phimax = phi;
525 }
526 }
527
528 phi = phimax - dphi;
529 dphi = dphi / 17.5;
530 }
531
532 phimax = phimax - std::round(phimax / Physics::two_pi) * Physics::two_pi;
533 phimax = std::fmod(phimax, Physics::two_pi);
534
535 const int prevPrecision = Ippl::Info->precision(8);
537 << "estimated phase= " << phimax << " rad = "
538 << phimax * Units::rad2deg << " deg \n"
539 << "Ekin= " << Emax << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
540
541 setPhasem(origPhase);
542 return phimax;
543}
544
545double RFCavity::getAutoPhaseEstimate(const double& E0, const double& t0,
546 const double& q, const double& mass) {
547 std::vector<double> t, E, t2, E2;
548 std::vector<double> F;
549 std::vector< std::pair< double, double > > G;
550 gsl_spline *onAxisInterpolants;
551 gsl_interp_accel *onAxisAccel;
552
553 double phi = 0.0, tmp_phi, dphi = 0.5 * Units::deg2rad;
554 double dz = 1.0, length = 0.0;
555 fieldmap_m->getOnaxisEz(G);
556 if (G.size() == 0) return 0.0;
557 double begin = (G.front()).first;
558 double end = (G.back()).first;
559 std::unique_ptr<double[]> zvals( new double[G.size()]);
560 std::unique_ptr<double[]> onAxisField(new double[G.size()]);
561
562 for (size_t j = 0; j < G.size(); ++ j) {
563 zvals[j] = G[j].first;
564 onAxisField[j] = G[j].second;
565 }
566 onAxisInterpolants = gsl_spline_alloc(gsl_interp_cspline, G.size());
567 onAxisAccel = gsl_interp_accel_alloc();
568 gsl_spline_init(onAxisInterpolants, zvals.get(), onAxisField.get(), G.size());
569
570 length = end - begin;
571 dz = length / G.size();
572
573 G.clear();
574
575 unsigned int N = (int)std::floor(length / dz + 1);
576 dz = length / N;
577
578 F.resize(N);
579 double z = begin;
580 for (size_t j = 0; j < N; ++ j, z += dz) {
581 F[j] = gsl_spline_eval(onAxisInterpolants, z, onAxisAccel);
582 }
583 gsl_spline_free(onAxisInterpolants);
584 gsl_interp_accel_free(onAxisAccel);
585
586 t.resize(N, t0);
587 t2.resize(N, t0);
588 E.resize(N, E0);
589 E2.resize(N, E0);
590
591 z = begin + dz;
592 for (unsigned int i = 1; i < N; ++ i, z += dz) {
593 E[i] = E[i - 1] + dz * scale_m / mass;
594 E2[i] = E[i];
595 }
596
597 for (int iter = 0; iter < 10; ++ iter) {
598 double A = 0.0;
599 double B = 0.0;
600 for (unsigned int i = 1; i < N; ++ i) {
601 t[i] = t[i - 1] + getdT(i, E, dz, mass);
602 t2[i] = t2[i - 1] + getdT(i, E2, dz, mass);
603 A += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi) * getdA(i, t, dz, frequency_m, F);
604 B += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi) * getdB(i, t, dz, frequency_m, F);
605 }
606
607 if (std::abs(B) > 0.0000001) {
608 tmp_phi = std::atan(A / B);
609 } else {
610 tmp_phi = Physics::pi / 2;
611 }
612 if (q * (A * std::sin(tmp_phi) + B * std::cos(tmp_phi)) < 0) {
613 tmp_phi += Physics::pi;
614 }
615
616 if (std::abs (phi - tmp_phi) < frequency_m * (t[N - 1] - t[0]) / (10 * N)) {
617 for (unsigned int i = 1; i < N; ++ i) {
618 E[i] = E[i - 1];
619 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
620 }
621 const int prevPrecision = Ippl::Info->precision(8);
622 INFOMSG(level2 << "estimated phase= " << tmp_phi << " rad = "
623 << tmp_phi * Units::rad2deg << " deg \n"
624 << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
625
626 return tmp_phi;
627 }
628 phi = tmp_phi - std::round(tmp_phi / Physics::two_pi) * Physics::two_pi;
629
630 for (unsigned int i = 1; i < N; ++ i) {
631 E[i] = E[i - 1];
632 E2[i] = E2[i - 1];
633 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
634 E2[i] += q * scale_m * getdE(i, t2, dz, phi + dphi, frequency_m, F);
635 double a = E[i], b = E2[i];
636 if (std::isnan(a) || std::isnan(b)) {
637 return getAutoPhaseEstimateFallback(E0, t0, q, mass);
638 }
639 t[i] = t[i - 1] + getdT(i, E, dz, mass);
640 t2[i] = t2[i - 1] + getdT(i, E2, dz, mass);
641
642 E[i] = E [i - 1];
643 E2[i] = E2[i - 1];
644 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F) ;
645 E2[i] += q * scale_m * getdE(i, t2, dz, phi + dphi, frequency_m, F);
646 }
647
648 double cosine_part = 0.0, sine_part = 0.0;
649 double p0 = Util::getBetaGamma(E0, mass);
650 cosine_part += scale_m * std::cos(frequency_m * t0) * F[0];
651 sine_part += scale_m * std::sin(frequency_m * t0) * F[0];
652
653 double totalEz0 = std::cos(phi) * cosine_part - std::sin(phi) * sine_part;
654
655 if (p0 + q * totalEz0 * (t[1] - t[0]) * Physics::c / mass < 0) {
656 // make totalEz0 = 0
657 tmp_phi = std::atan(cosine_part / sine_part);
658 if (std::abs (tmp_phi - phi) > Physics::pi) {
659 phi = tmp_phi + Physics::pi;
660 } else {
661 phi = tmp_phi;
662 }
663 }
664 }
665
666 const int prevPrecision = Ippl::Info->precision(8);
668 << "estimated phase= " << tmp_phi << " rad = "
669 << tmp_phi * Units::rad2deg << " deg \n"
670 << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n" << endl);
671
672 return phi;
673}
674
675std::pair<double, double> RFCavity::trackOnAxisParticle(const double& p0,
676 const double& t0,
677 const double& dt,
678 const double& /*q*/,
679 const double& mass,
680 std::ofstream *out) {
681 Vector_t p(0, 0, p0);
682 double t = t0;
683 BorisPusher integrator(*RefPartBunch_m->getReference());
684 const double cdt = Physics::c * dt;
685 const double zbegin = startField_m;
686 const double zend = getElementLength() + startField_m;
687
688 Vector_t z(0.0, 0.0, zbegin);
689 double dz = 0.5 * p(2) / Util::getGamma(p) * cdt;
690 Vector_t Ef(0.0), Bf(0.0);
691
692 if (out) *out << std::setw(18) << z[2]
693 << std::setw(18) << Util::getKineticEnergy(p, mass)
694 << std::endl;
695 while (z(2) + dz < zend && z(2) + dz > zbegin) {
696 z /= cdt;
697 integrator.push(z, p, dt);
698 z *= cdt;
699
700 Ef = 0.0;
701 Bf = 0.0;
702 if (z(2) >= zbegin && z(2) <= zend) {
703 applyToReferenceParticle(z, p, t + 0.5 * dt, Ef, Bf);
704 }
705 integrator.kick(z, p, Ef, Bf, dt);
706
707 dz = 0.5 * p(2) / std::sqrt(1.0 + dot(p, p)) * cdt;
708 z /= cdt;
709 integrator.push(z, p, dt);
710 z *= cdt;
711 t += dt;
712
713 if (out) *out << std::setw(18) << z[2]
714 << std::setw(18) << Util::getKineticEnergy(p, mass)
715 << std::endl;
716 }
717
718 const double beta = std::sqrt(1. - 1 / (dot(p, p) + 1.));
719 const double tErr = (z(2) - zend) / (Physics::c * beta);
720
721 return std::pair<double, double>(p(2), t - tErr);
722}
723
724bool RFCavity::isInside(const Vector_t& r) const {
725 if (isInsideTransverse(r)) {
726 return fieldmap_m->isInside(r);
727 }
728
729 return false;
730}
731
733 double length = ElementBase::getElementLength();
734 if (length < 1e-10 && fieldmap_m != nullptr) {
735 double start, end;
736 fieldmap_m->getFieldDimensions(start, end);
737 length = end - start;
738 }
739
740 return length;
741}
742
743void RFCavity::getElementDimensions(double& begin, double& end) const {
744 fieldmap_m->getFieldDimensions(begin, end);
745}
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
CavityType
Definition RFCavity.h:31
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)
Inform * gmsg
Definition Main.cpp:70
std::complex< double > a
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 c
The velocity of light in m/s.
Definition Physics.h:45
constexpr double pi
The value of.
Definition Physics.h:30
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
double getKineticEnergy(Vector_t p, double mass)
Definition Util.h:56
double getBetaGamma(double Ekin, double mass)
Definition Util.h:61
double getGamma(Vector_t p)
Definition Util.h:46
virtual void visitRFCavity(const RFCavity &)=0
Apply the algorithm to a RF cavity.
bool online_m
Definition Component.h:192
Component(const std::string &name)
Constructor with given name.
Definition Component.cpp:53
PartBunchBase< double, 3 > * RefPartBunch_m
Definition Component.h:191
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)
Definition RFCavity.h:469
virtual bool isInside(const Vector_t &r) const override
Definition RFCavity.cpp:724
virtual double getPhasem() const
Definition RFCavity.h:394
virtual bool bends() const override
Definition RFCavity.cpp:250
bool fast_m
Definition RFCavity.h:212
virtual double getRmax() const
Definition RFCavity.cpp:299
double phi0_m
Definition RFCavity.h:234
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:373
virtual double getAzimuth() const
Definition RFCavity.cpp:308
virtual ElementType getType() const override
Get element type std::string.
Definition RFCavity.cpp:499
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:270
virtual void accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
Definition RFCavity.cpp:119
double endField_m
Definition RFCavity.h:221
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:322
double designEnergy_m
Definition RFCavity.h:215
std::string filename_m
Definition RFCavity.h:204
CavityType type_m
Definition RFCavity.h:223
std::unique_ptr< double[]> DvDr_m
Definition RFCavity.h:238
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:454
virtual void getElementDimensions(double &begin, double &end) const override
Definition RFCavity.cpp:743
virtual double getCosAzimuth() const
Definition RFCavity.cpp:316
double rmin_m
Definition RFCavity.h:227
double scale_m
Definition RFCavity.h:206
double phaseError_m
Definition RFCavity.h:209
std::shared_ptr< AbstractTimeDependence > phaseTD_m
Definition RFCavity.h:197
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
Definition RFCavity.cpp:167
double cosAngle_m
Definition RFCavity.h:231
Fieldmap fieldmap_m
Definition RFCavity.h:217
std::string frequencyName_m
Definition RFCavity.h:202
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:675
std::unique_ptr< double[]> RNormal_m
Definition RFCavity.h:236
std::shared_ptr< AbstractTimeDependence > amplitudeTD_m
Definition RFCavity.h:199
double gapwidth_m
Definition RFCavity.h:233
virtual void setPhasem(double phase)
Definition RFCavity.h:389
RFCavity(const std::string &name)
Constructor with given name.
Definition RFCavity.cpp:84
double sinAngle_m
Definition RFCavity.h:230
virtual double getSinAzimuth() const
Definition RFCavity.cpp:312
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:433
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
Definition RFCavity.h:201
double frequency_m
Definition RFCavity.h:210
virtual std::string getFieldMapFN() const
Definition RFCavity.cpp:345
std::string phaseName_m
Definition RFCavity.h:198
void setAzimuth(double angle)
Definition RFCavity.cpp:274
std::unique_ptr< double[]> VrNormal_m
Definition RFCavity.h:237
virtual void goOnline(const double &kineticEnergy) override
Definition RFCavity.cpp:254
double pdis_m
Definition RFCavity.h:232
void setCavityType(const std::string &type)
Definition RFCavity.cpp:332
double startField_m
Definition RFCavity.h:218
virtual double getCycFrequency() const
Definition RFCavity.cpp:359
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:310
virtual double getGapWidth() const
Definition RFCavity.cpp:324
virtual double getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &m)
Definition RFCavity.cpp:545
double rmax_m
Definition RFCavity.h:228
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition RFCavity.cpp:493
double scaleError_m
Definition RFCavity.h:207
static const boost::bimap< CavityType, std::string > bmCavityTypeString_s
Definition RFCavity.h:225
virtual double getPerpenDistance() const
Definition RFCavity.cpp:320
std::string amplitudeName_m
Definition RFCavity.h:200
void setGapWidth(double gapwidth)
Definition RFCavity.cpp:282
virtual double getElementLength() const override
Get design length.
Definition RFCavity.cpp:732
double phase_m
Definition RFCavity.h:208
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Definition RFCavity.cpp:123
bool autophaseVeto_m
Definition RFCavity.h:213
virtual void goOffline() override
Definition RFCavity.cpp:260
double angle_m
Definition RFCavity.h:229
virtual double getPhi0() const
Definition RFCavity.cpp:328
virtual double getAutoPhaseEstimateFallback(double E0, double t0, double q, double m)
Definition RFCavity.cpp:503
std::string getCavityTypeString() const
Definition RFCavity.cpp:341
void setRmax(double rmax)
Definition RFCavity.cpp:270
void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition RFCavity.h:439
virtual double getRmin() const
Definition RFCavity.cpp:290
int num_points_m
Definition RFCavity.h:239
double getdT(const int &i, const std::vector< double > &E, const double &dz, const double mass) const
Definition RFCavity.h:282
virtual void freeMap()=0
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition Fieldmap.cpp:649
virtual void readMap()=0
static Fieldmap getFieldmap(std::string Filename, bool fast=false)
Definition Fieldmap.cpp:48
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
static Inform * Info
Definition IpplInfo.h:78
static int myNode()
Definition IpplInfo.cpp:691
Vektor< double, 3 > Vector_t