OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
20#include <boost/assign.hpp>
21#include <boost/filesystem.hpp>
23#include "Fields/Fieldmap.h"
24#include "PartBunch/PartBunch.h"
25#include "Physics/Units.h"
28#include "Utilities/Util.h"
29#include "Utility/IpplInfo.h"
30
31#include "gsl/gsl_interp.h"
32#include "gsl/gsl_spline.h"
33
34#include <fstream>
35#include <iostream>
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")(CavityType::SGSW, "SINGLEGAP");
42
45
47 : Component(right),
48 phaseTD_m(right.phaseTD_m),
55 scale_m(right.scale_m),
57 phase_m(right.phase_m),
60 fast_m(right.fast_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),
72 pdis_m(right.pdis_m),
74 phi0_m(right.phi0_m),
75 RNormal_m(nullptr),
76 VrNormal_m(nullptr),
77 DvDr_m(nullptr),
79}
80
81RFCavity::RFCavity(const std::string& name)
82 : Component(name),
83 phaseTD_m(nullptr),
84 amplitudeTD_m(nullptr),
85 frequencyTD_m(nullptr),
86 filename_m(""),
87 scale_m(1.0),
88 scaleError_m(0.0),
89 phase_m(0.0),
90 phaseError_m(0.0),
91 frequency_m(0.0),
92 fast_m(true),
93 autophaseVeto_m(false),
94 designEnergy_m(-1.0),
95 fieldmap_m(nullptr),
96 startField_m(0.0),
97 endField_m(0.0),
99 rmin_m(0.0),
100 rmax_m(0.0),
101 angle_m(0.0),
102 sinAngle_m(0.0),
103 cosAngle_m(0.0),
104 pdis_m(0.0),
105 gapwidth_m(0.0),
106 phi0_m(0.0),
107 RNormal_m(nullptr),
108 VrNormal_m(nullptr),
109 DvDr_m(nullptr),
110 num_points_m(0) {
111}
112
115
116void RFCavity::accept(BeamlineVisitor& visitor) const {
117 visitor.visitRFCavity(*this);
118}
119
121 const size_t& i, const double& t, Vector_t<double, 3>& E, Vector_t<double, 3>& B) {
122 std::shared_ptr<ParticleContainer_t> pc = RefPartBunch_m->getParticleContainer();
123 auto Rview = pc->R.getView();
124 auto Pview = pc->P.getView();
125
126 const Vector_t<double, 3> R = Rview(i);
127 const Vector_t<double, 3> P = Pview(i);
128
129 return apply(R(i), P(i), t, E, B);
130}
131
133 const Vector_t<double, 3>& R, const Vector_t<double, 3>& /*P*/, const double& t,
135 if (R(2) >= startField_m && R(2) < startField_m + getElementLength()) {
136 Vector_t<double, 3> 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)
141
142 E += (scale_m + scaleError_m) * std::cos(frequency_m * t + phase_m + phaseError_m) * tmpE;
143 B -= (scale_m + scaleError_m) * std::sin(frequency_m * t + phase_m + phaseError_m) * tmpB;
144 }
145 return false;
146}
147
149 const Vector_t<double, 3>& R, const Vector_t<double, 3>& /*P*/, const double& t,
151 if (R(2) >= startField_m && R(2) < startField_m + getElementLength()) {
152 Vector_t<double, 3> tmpE({0.0, 0.0, 0.0}), tmpB({0.0, 0.0, 0.0});
153
154 bool outOfBounds = fieldmap_m->getFieldstrength(R, tmpE, tmpB);
155 if (outOfBounds)
156 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 return false;
162}
163
164void RFCavity::initialise(PartBunch_t* bunch, double& startField, double& endField) {
165 startField_m = endField_m = 0.0;
166 if (bunch == nullptr) {
167 startField = startField_m;
168 endField = endField_m;
169 return;
170 }
171
172 Inform msg("RFCavity ", *gmsg);
173 std::stringstream errormsg;
174 RefPartBunch_m = bunch;
175
176 fieldmap_m = Fieldmap::getFieldmap(filename_m, fast_m);
177 fieldmap_m->getFieldDimensions(startField_m, endField);
178 if (endField <= startField_m) {
180 "RFCavity::initialise",
181 "The length of the field map '" + filename_m + "' is zero or negative");
182 }
183
184 msg << level2 << getName() << " using file ";
185 fieldmap_m->getInfo(&msg);
186 if (std::abs((frequency_m - fieldmap_m->getFrequency()) / frequency_m) > 0.01) {
187 errormsg << "FREQUENCY IN INPUT FILE DIFFERENT THAN IN FIELD MAP '" << filename_m << "';\n"
188 << frequency_m / Physics::two_pi * Units::Hz2MHz << " MHz <> "
189 << fieldmap_m->getFrequency() / Physics::two_pi * Units::Hz2MHz
190 << " MHz; TAKE ON THE LATTER";
191 std::string errormsg_str = Fieldmap::typeset_msg(errormsg.str(), "warning\n");
192 *ippl::Error << errormsg_str << endl;
193 if (ippl::Comm->rank() == 0) {
194 std::ofstream omsg("errormsg.txt", std::ios_base::app);
195 omsg << errormsg_str << std::endl;
196 omsg.close();
197 }
198 frequency_m = fieldmap_m->getFrequency();
199 }
200 setElementLength(endField - startField_m);
201}
202
203// In current version ,this function reads in the cavity voltage profile data from file.
205 PartBunch_t* bunch, std::shared_ptr<AbstractTimeDependence> freq_atd,
206 std::shared_ptr<AbstractTimeDependence> ampl_atd,
207 std::shared_ptr<AbstractTimeDependence> phase_atd) {
208 RefPartBunch_m = bunch;
209
211 setAmplitudeModel(ampl_atd);
212 setPhaseModel(phase_atd);
213 setFrequencyModel(freq_atd);
214
215 std::ifstream in(filename_m.c_str());
216 in >> num_points_m;
217
218 RNormal_m = std::unique_ptr<double[]>(new double[num_points_m]);
219 VrNormal_m = std::unique_ptr<double[]>(new double[num_points_m]);
220 DvDr_m = std::unique_ptr<double[]>(new double[num_points_m]);
221
222 for (int i = 0; i < num_points_m; i++) {
223 if (in.eof()) {
225 "RFCavity::initialise",
226 "Not enough data in file '" + filename_m + "', please check the data format");
227 }
228 in >> RNormal_m[i] >> VrNormal_m[i] >> DvDr_m[i];
229
230 VrNormal_m[i] *= RefPartBunch_m->getQ();
231 DvDr_m[i] *= RefPartBunch_m->getQ();
232 }
233 sinAngle_m = std::sin(angle_m * Units::deg2rad);
234 cosAngle_m = std::cos(angle_m * Units::deg2rad);
235
236 if (!frequencyName_m.empty()) {
237 *gmsg << "* Timedependent frequency model " << frequencyName_m << endl;
238 }
239
240 *gmsg << "* Cavity voltage data read successfully!" << endl;
241}
242
244}
245
246bool RFCavity::bends() const {
247 return false;
248}
249
250void RFCavity::goOnline(const double&) {
251 Fieldmap::readMap(filename_m);
252
253 online_m = true;
254}
255
257 Fieldmap::freeMap(filename_m);
258
259 online_m = false;
260}
261
262void RFCavity::setRmin(double rmin) {
263 rmin_m = rmin;
264}
265
266void RFCavity::setRmax(double rmax) {
267 rmax_m = rmax;
268}
269
270void RFCavity::setAzimuth(double angle) {
271 angle_m = angle;
272}
273
275 pdis_m = pdis;
276}
277
278void RFCavity::setGapWidth(double gapwidth) {
279 gapwidth_m = gapwidth;
280}
281
282void RFCavity::setPhi0(double phi0) {
283 phi0_m = phi0;
284}
285
286double RFCavity::getRmin() const {
287 return rmin_m;
288}
289
290double RFCavity::getRmax() const {
291 return rmax_m;
292}
293
294double RFCavity::getAzimuth() const {
295 return angle_m;
296}
297
299 return sinAngle_m;
300}
301
303 return cosAngle_m;
304}
305
307 return pdis_m;
308}
309
310double RFCavity::getGapWidth() const {
311 return gapwidth_m;
312}
313
314double RFCavity::getPhi0() const {
315 return phi0_m;
316}
317
318void RFCavity::setCavityType(const std::string& name) {
319 auto it = bmCavityTypeString_s.right.find(name);
320 if (it != bmCavityTypeString_s.right.end()) {
321 type_m = it->second;
322 } else {
324 }
325}
326
327std::string RFCavity::getCavityTypeString() const {
328 return bmCavityTypeString_s.left.at(type_m);
329}
330
331std::string RFCavity::getFieldMapFN() const {
332 if (filename_m.empty()) {
334 "RFCavity::getFieldMapFN",
335 "The attribute \"FMAPFN\" isn't set "
336 "for the \"RFCAVITY\" element!");
337 } else if (boost::filesystem::exists(filename_m)) {
338 return filename_m;
339 } else {
341 "RFCavity::getFieldMapFN",
342 "Failed to open file '" + filename_m + "', please check if it exists");
343 }
344}
345
347 return frequency_m;
348}
349
361 const double normalRadius, double momentum[], const double t, const double dtCorrt,
362 const int PID, const double restMass, const int chargenumber) {
363 double derivate;
364
365 double momentum2 =
366 momentum[0] * momentum[0] + momentum[1] * momentum[1] + momentum[2] * momentum[2];
367 double betgam = std::sqrt(momentum2);
368
369 double gamma = std::sqrt(1.0 + momentum2);
370 double beta = betgam / gamma;
371
372 double Voltage = spline(normalRadius, &derivate) * scale_m * Units::MVpm2Vpm;
373
374 double Ufactor = 1.0;
375
376 double frequency = frequency_m * frequencyTD_m->getValue(t);
377
378 if (gapwidth_m > 0.0) {
379 double transit_factor = 0.5 * frequency * gapwidth_m * Units::mm2m / (Physics::c * beta);
380 Ufactor = std::sin(transit_factor) / transit_factor;
381 }
382
383 Voltage *= Ufactor;
384 // rad/s, ns --> rad
385 double nphase = (frequency * (t + dtCorrt) * Units::ns2s) - phi0_m * Units::deg2rad;
386 double dgam = Voltage * std::cos(nphase) / (restMass);
387
388 double tempdegree = std::fmod(nphase * Units::rad2deg, 360.0);
389 if (tempdegree > 270.0)
390 tempdegree -= 360.0;
391
392 gamma += dgam;
393
394 double newmomentum2 = std::pow(gamma, 2) - 1.0;
395
396 double pr = momentum[0] * cosAngle_m + momentum[1] * sinAngle_m;
397 double ptheta = std::sqrt(newmomentum2 - std::pow(pr, 2));
398 double px = pr * cosAngle_m - ptheta * sinAngle_m; // x
399 double py = pr * sinAngle_m + ptheta * cosAngle_m; // y
400
401 double rotate = -derivate * (scale_m * Units::MVpm2Vpm) / ((rmax_m - rmin_m) * Units::mm2m)
402 * std::sin(nphase) / (frequency * Physics::two_pi)
403 / (betgam * restMass / Physics::c / chargenumber); // radian
404
406 momentum[0] = std::cos(rotate) * px + std::sin(rotate) * py;
407 momentum[1] = -std::sin(rotate) * px + std::cos(rotate) * py;
408
409 if (PID == 0) {
410 Inform m("OPAL", *gmsg, ippl::Comm->rank());
411
412 m << "* Cavity " << getName() << " Phase= " << tempdegree
413 << " [deg] transit time factor= " << Ufactor
414 << " dE= " << dgam * restMass * Units::eV2MeV << " [MeV]"
415 << " E_kin= " << (gamma - 1.0) * restMass * Units::eV2MeV
416 << " [MeV] Time dep freq = " << frequencyTD_m->getValue(t) << endl;
417 }
418}
419
420/* cubic spline subrutine */
421double RFCavity::spline(double z, double* za) {
422 double splint;
423
424 // domain-test and handling of case "1-support-point"
425 if (num_points_m < 1) {
426 throw GeneralClassicException("RFCavity::spline", "no support points!");
427 }
428 if (num_points_m == 1) {
429 splint = RNormal_m[0];
430 *za = 0.0;
431 return splint;
432 }
433
434 // search the two support-points
435 int il, ih;
436 il = 0;
437 ih = num_points_m - 1;
438 while ((ih - il) > 1) {
439 int i = (int)((il + ih) / 2.0);
440 if (z < RNormal_m[i]) {
441 ih = i;
442 } else if (z > RNormal_m[i]) {
443 il = i;
444 } else if (z == RNormal_m[i]) {
445 il = i;
446 ih = i + 1;
447 break;
448 }
449 }
450
451 double x1 = RNormal_m[il];
452 double x2 = RNormal_m[ih];
453 double y1 = VrNormal_m[il];
454 double y2 = VrNormal_m[ih];
455 double y1a = DvDr_m[il];
456 double y2a = DvDr_m[ih];
457 //
458 // determination of the requested function-values and its derivatives
459 //
460 double dx = x2 - x1;
461 double dy = y2 - y1;
462 double u = (z - x1) / dx;
463 double u2 = u * u;
464 double u3 = u2 * u;
465 double dy2 = -2.0 * dy;
466 double ya2 = y2a + 2.0 * y1a;
467 double dy3 = 3.0 * dy;
468 double ya3 = y2a + y1a;
469 double yb2 = dy2 + dx * ya3;
470 double yb4 = dy3 - dx * ya2;
471 splint = y1 + u * dx * y1a + u2 * yb4 + u3 * yb2;
472 *za = y1a + 2.0 * u / dx * yb4 + 3.0 * u2 / dx * yb2;
473 // if(m>=1) za=y1a+2.0*u/dx*yb4+3.0*u2/dx*yb2;
474 // if(m>=2) za[1]=2.0/dx2*yb4+6.0*u/dx2*yb2;
475 // if(m>=3) za[2]=6.0/dx3*yb2;
476
477 return splint;
478}
479
480void RFCavity::getDimensions(double& zBegin, double& zEnd) const {
481 zBegin = startField_m;
482 zEnd = endField_m;
483}
484
488
489double RFCavity::getAutoPhaseEstimateFallback(double E0, double t0, double q, double mass) {
490 const double dt = 1e-13;
491 const double p0 = Util::getBetaGamma(E0, mass);
492 const double origPhase = getPhasem();
493 double dphi = Physics::pi / 18;
494
495 double phi = 0.0;
496 setPhasem(phi);
497 std::pair<double, double> ret = trackOnAxisParticle(p0, t0, dt, q, mass);
498 double phimax = 0.0;
499 double Emax = Util::getKineticEnergy(Vector_t<double, 3>({0.0, 0.0, ret.first}), mass);
500 phi += dphi;
501
502 for (unsigned int j = 0; j < 2; ++j) {
503 for (unsigned int i = 0; i < 36; ++i, phi += dphi) {
504 setPhasem(phi);
505 ret = trackOnAxisParticle(p0, t0, dt, q, mass);
506 double Ekin = Util::getKineticEnergy(Vector_t<double, 3>({0.0, 0.0, ret.first}), mass);
507 if (Ekin > Emax) {
508 Emax = Ekin;
509 phimax = phi;
510 }
511 }
512
513 phi = phimax - dphi;
514 dphi = dphi / 17.5;
515 }
516
517 phimax = phimax - std::round(phimax / Physics::two_pi) * Physics::two_pi;
518 phimax = std::fmod(phimax, Physics::two_pi);
519
520 const int prevPrecision = ippl::Info->precision(8);
521 *ippl::Info << level2 << "estimated phase= " << phimax << " rad = " << phimax * Units::rad2deg
522 << " deg \n"
523 << "Ekin= " << Emax << " MeV" << std::setprecision(prevPrecision) << "\n"
524 << endl;
525
526 setPhasem(origPhase);
527 return phimax;
528}
529
531 const double& E0, const double& t0, const double& q, const double& mass) {
532 std::vector<double> t, E, t2, E2;
533 std::vector<double> F;
534 std::vector<std::pair<double, double> > G;
535 gsl_spline* onAxisInterpolants;
536 gsl_interp_accel* onAxisAccel;
537
538 double phi = 0.0, tmp_phi, dphi = 0.5 * Units::deg2rad;
539 double dz = 1.0, length = 0.0;
540 fieldmap_m->getOnaxisEz(G);
541 if (G.size() == 0)
542 return 0.0;
543 double begin = (G.front()).first;
544 double end = (G.back()).first;
545 std::unique_ptr<double[]> zvals(new double[G.size()]);
546 std::unique_ptr<double[]> onAxisField(new double[G.size()]);
547
548 for (size_t j = 0; j < G.size(); ++j) {
549 zvals[j] = G[j].first;
550 onAxisField[j] = G[j].second;
551 }
552 onAxisInterpolants = gsl_spline_alloc(gsl_interp_cspline, G.size());
553 onAxisAccel = gsl_interp_accel_alloc();
554 gsl_spline_init(onAxisInterpolants, zvals.get(), onAxisField.get(), G.size());
555
556 length = end - begin;
557 dz = length / G.size();
558
559 G.clear();
560
561 unsigned int N = (int)std::floor(length / dz + 1);
562 dz = length / N;
563
564 F.resize(N);
565 double z = begin;
566 for (size_t j = 0; j < N; ++j, z += dz) {
567 F[j] = gsl_spline_eval(onAxisInterpolants, z, onAxisAccel);
568 }
569 gsl_spline_free(onAxisInterpolants);
570 gsl_interp_accel_free(onAxisAccel);
571
572 t.resize(N, t0);
573 t2.resize(N, t0);
574 E.resize(N, E0);
575 E2.resize(N, E0);
576
577 z = begin + dz;
578 for (unsigned int i = 1; i < N; ++i, z += dz) {
579 E[i] = E[i - 1] + dz * scale_m / mass;
580 E2[i] = E[i];
581 }
582
583 for (int iter = 0; iter < 10; ++iter) {
584 double A = 0.0;
585 double B = 0.0;
586 for (unsigned int i = 1; i < N; ++i) {
587 t[i] = t[i - 1] + getdT(i, E, dz, mass);
588 t2[i] = t2[i - 1] + getdT(i, E2, dz, mass);
589 A += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi)
590 * getdA(i, t, dz, frequency_m, F);
591 B += scale_m * (1. + frequency_m * (t2[i] - t[i]) / dphi)
592 * getdB(i, t, dz, frequency_m, F);
593 }
594
595 if (std::abs(B) > 0.0000001) {
596 tmp_phi = std::atan(A / B);
597 } else {
598 tmp_phi = Physics::pi / 2;
599 }
600 if (q * (A * std::sin(tmp_phi) + B * std::cos(tmp_phi)) < 0) {
601 tmp_phi += Physics::pi;
602 }
603
604 if (std::abs(phi - tmp_phi) < frequency_m * (t[N - 1] - t[0]) / (10 * N)) {
605 for (unsigned int i = 1; i < N; ++i) {
606 E[i] = E[i - 1];
607 E[i] += q * scale_m * getdE(i, t, dz, phi, frequency_m, F);
608 }
609 const int prevPrecision = ippl::Info->precision(8);
610 *ippl::Info << level2 << "estimated phase= " << tmp_phi
611 << " rad = " << tmp_phi * Units::rad2deg << " deg \n"
612 << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision)
613 << "\n"
614 << 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 - std::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);
657 *ippl::Info << level2 << "estimated phase= " << tmp_phi << " rad = " << tmp_phi * Units::rad2deg
658 << " deg \n"
659 << "Ekin= " << E[N - 1] << " MeV" << std::setprecision(prevPrecision) << "\n"
660 << endl;
661
662 return phi;
663}
664
665std::pair<double, double> RFCavity::trackOnAxisParticle(
666 const double& p0, const double& t0, const double& dt, const double& /*q*/, const double& mass,
667 std::ofstream* out) {
668 Vector_t<double, 3> p({0, 0, p0});
669 double t = t0;
670
671 BorisPusher integrator(*RefPartBunch_m->getReference());
672 const double cdt = Physics::c * dt;
673 const double zbegin = startField_m;
674 const double zend = getElementLength() + startField_m;
675
676 Vector_t<double, 3> z({0.0, 0.0, zbegin});
677 double dz = 0.5 * p(2) / Util::getGamma(p) * cdt;
678 Vector_t<double, 3> Ef(0.0), Bf(0.0);
679
680 if (out)
681 *out << std::setw(18) << z[2] << std::setw(18) << Util::getKineticEnergy(p, mass)
682 << std::endl;
683 while (z(2) + dz < zend && z(2) + dz > zbegin) {
684 z /= cdt;
685 integrator.push(z, p, dt);
686 z *= cdt;
687
688 Ef = 0.0;
689 Bf = 0.0;
690 if (z(2) >= zbegin && z(2) <= zend) {
691 applyToReferenceParticle(z, p, t + 0.5 * dt, Ef, Bf);
692 }
693
694 integrator.kick(z, p, Ef, Bf, dt);
695
696 dz = 0.5 * p(2) / std::sqrt(1.0 + dot(p, p)) * cdt;
697 z /= cdt;
698
699 integrator.push(z, p, dt);
700 z *= cdt;
701 t += dt;
702
703 if (out)
704 *out << std::setw(18) << z[2] << 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 return std::pair<double, double>(p(2), t - tErr);
711}
712
714 if (isInsideTransverse(r)) {
715 return fieldmap_m->isInside(r);
716 }
717
718 return false;
719}
720
722 double length = ElementBase::getElementLength();
723 if (length < 1e-10 && fieldmap_m != nullptr) {
724 double start, end;
725 fieldmap_m->getFieldDimensions(start, end);
726 length = end - start;
727 }
728
729 return length;
730}
731
732void RFCavity::getElementDimensions(double& begin, double& end) const {
733 fieldmap_m->getFieldDimensions(begin, end);
734}
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
CavityType
Definition RFCavity.h:32
Inform * gmsg
Definition changes.cpp:7
ElementType
Definition ElementBase.h:88
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
ippl::Vector< T, Dim > Vector_t
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
PartBunch< T, Dim >::ConstIterator begin(PartBunch< T, Dim > const &bunch)
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 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
double getBetaGamma(double Ekin, double mass)
Definition Util.h:59
double getGamma(ippl::Vector< double, 3 > p)
Definition Util.h:44
double getKineticEnergy(ippl::Vector< double, 3 > p, double mass)
Definition Util.h:55
virtual void visitRFCavity(const RFCavity &)=0
Apply the algorithm to a RF cavity.
bool online_m
Definition Component.h:186
Component(const std::string &name)
Constructor with given name.
Definition Component.cpp:44
PartBunch_t * RefPartBunch_m
Definition Component.h:185
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< double, 3 > &r) const
void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition RFCavity.h:408
virtual double getPhasem() const
Definition RFCavity.h:348
virtual bool bends() const override
Definition RFCavity.cpp:246
bool fast_m
Definition RFCavity.h:195
virtual double getRmax() const
Definition RFCavity.cpp:290
double phi0_m
Definition RFCavity.h:217
void setPerpenDistance(double pdis)
Definition RFCavity.cpp:274
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:360
virtual double getAzimuth() const
Definition RFCavity.cpp:294
Fieldmap * fieldmap_m
Definition RFCavity.h:200
virtual void initialise(PartBunch_t *bunch, double &startField, double &endField) override
Definition RFCavity.cpp:164
virtual ElementType getType() const override
Get element type std::string.
Definition RFCavity.cpp:485
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:243
virtual void accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
Definition RFCavity.cpp:116
double endField_m
Definition RFCavity.h:204
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:290
double designEnergy_m
Definition RFCavity.h:198
std::string filename_m
Definition RFCavity.h:187
CavityType type_m
Definition RFCavity.h:206
std::unique_ptr< double[]> DvDr_m
Definition RFCavity.h:221
virtual void finalise() override
Definition RFCavity.cpp:243
virtual ~RFCavity()
Definition RFCavity.cpp:113
void setRmin(double rmin)
Definition RFCavity.cpp:262
void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition RFCavity.h:396
virtual bool apply(const size_t &i, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
Definition RFCavity.cpp:120
virtual void getElementDimensions(double &begin, double &end) const override
Definition RFCavity.cpp:732
virtual double getCosAzimuth() const
Definition RFCavity.cpp:302
double rmin_m
Definition RFCavity.h:210
double scale_m
Definition RFCavity.h:189
double phaseError_m
Definition RFCavity.h:192
std::shared_ptr< AbstractTimeDependence > phaseTD_m
Definition RFCavity.h:180
double cosAngle_m
Definition RFCavity.h:214
std::string frequencyName_m
Definition RFCavity.h:185
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:665
std::unique_ptr< double[]> RNormal_m
Definition RFCavity.h:219
std::shared_ptr< AbstractTimeDependence > amplitudeTD_m
Definition RFCavity.h:182
double gapwidth_m
Definition RFCavity.h:216
virtual void setPhasem(double phase)
Definition RFCavity.h:344
RFCavity(const std::string &name)
Constructor with given name.
Definition RFCavity.cpp:81
double sinAngle_m
Definition RFCavity.h:213
virtual double getSinAzimuth() const
Definition RFCavity.cpp:298
void setPhi0(double phi0)
Definition RFCavity.cpp:282
double spline(double z, double *za)
Definition RFCavity.cpp:421
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
Definition RFCavity.h:184
double frequency_m
Definition RFCavity.h:193
virtual std::string getFieldMapFN() const
Definition RFCavity.cpp:331
std::string phaseName_m
Definition RFCavity.h:181
void setAzimuth(double angle)
Definition RFCavity.cpp:270
std::unique_ptr< double[]> VrNormal_m
Definition RFCavity.h:220
virtual void goOnline(const double &kineticEnergy) override
Definition RFCavity.cpp:250
double pdis_m
Definition RFCavity.h:215
void setCavityType(const std::string &type)
Definition RFCavity.cpp:318
double startField_m
Definition RFCavity.h:201
virtual bool isInside(const Vector_t< double, 3 > &r) const override
Definition RFCavity.cpp:713
virtual double getCycFrequency() const
Definition RFCavity.cpp:346
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:280
virtual double getGapWidth() const
Definition RFCavity.cpp:310
virtual double getAutoPhaseEstimate(const double &E0, const double &t0, const double &q, const double &m)
Definition RFCavity.cpp:530
double rmax_m
Definition RFCavity.h:211
virtual void getDimensions(double &zBegin, double &zEnd) const override
Definition RFCavity.cpp:480
double scaleError_m
Definition RFCavity.h:190
static const boost::bimap< CavityType, std::string > bmCavityTypeString_s
Definition RFCavity.h:208
virtual double getPerpenDistance() const
Definition RFCavity.cpp:306
std::string amplitudeName_m
Definition RFCavity.h:183
void setGapWidth(double gapwidth)
Definition RFCavity.cpp:278
virtual double getElementLength() const override
Get design length.
Definition RFCavity.cpp:721
double phase_m
Definition RFCavity.h:191
bool autophaseVeto_m
Definition RFCavity.h:196
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
Definition RFCavity.cpp:148
virtual void goOffline() override
Definition RFCavity.cpp:256
double angle_m
Definition RFCavity.h:212
virtual double getPhi0() const
Definition RFCavity.cpp:314
virtual double getAutoPhaseEstimateFallback(double E0, double t0, double q, double m)
Definition RFCavity.cpp:489
std::string getCavityTypeString() const
Definition RFCavity.cpp:327
void setRmax(double rmax)
Definition RFCavity.cpp:266
void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Definition RFCavity.h:384
virtual double getRmin() const
Definition RFCavity.cpp:286
int num_points_m
Definition RFCavity.h:222
double getdT(const int &i, const std::vector< double > &E, const double &dz, const double mass) const
Definition RFCavity.h:254
KOKKOS_INLINE_FUNCTION void kick(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &P, const Vector_t< double, 3 > &Ef, const Vector_t< double, 3 > &Bf, const double &dt) const
Definition BorisPusher.h:67
KOKKOS_INLINE_FUNCTION void push(Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &dt) const