OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
VariableRFCavity.cpp
Go to the documentation of this file.
1//
2// Class VariableRFCavity
3// Defines the abstract interface for a RF Cavity
4// with Time Dependent Parameters.
5//
6// Copyright (c) 2014 - 2023, Chris Rogers, STFC Rutherford Appleton Laboratory, Didcot, UK
7// All rights reserved
8//
9// This file is part of OPAL.
10//
11// OPAL is free software: you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation, either version 3 of the License, or
14// (at your option) any later version.
15//
16// You should have received a copy of the GNU General Public License
17// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
18//
20
23#include "Physics/Physics.h"
24#include "Physics/Units.h"
26#include <boost/algorithm/string/case_conv.hpp>
27
28#include <cmath>
29
31 initNull(); // initialise everything to nullptr
32}
33
35 initNull(); // initialise everything to nullptr
36}
37
39 initNull(); // initialise everything to nullptr
40 *this = var;
41}
42
44 if (&rhs == this) {
45 return *this;
46 }
47 setName(rhs.getName());
48 setPhaseModel(nullptr);
49 setAmplitudeModel(nullptr);
50 setFrequencyModel(nullptr);
51 if (rhs.phaseTD_m != nullptr) {
52 setPhaseModel(std::shared_ptr<AbstractTimeDependence>(rhs.phaseTD_m->clone()));
53 }
54 if (rhs.amplitudeTD_m != nullptr) {
55 setAmplitudeModel(std::shared_ptr<AbstractTimeDependence>(rhs.amplitudeTD_m->clone()));
56 }
57 if (rhs.frequencyTD_m != nullptr) {
58 setFrequencyModel(std::shared_ptr<AbstractTimeDependence>(rhs.frequencyTD_m->clone()));
59 }
66 return *this;
67}
68
70 // shared_ptr should self-destruct when they are ready
71}
72
74 length_m = 0.;
75 phaseName_m = "";
76 amplitudeName_m = "";
77 frequencyName_m = "";
78 halfHeight_m = 0.;
79 halfWidth_m = 0;
80 RefPartBunch_m = nullptr;
81}
82
83std::shared_ptr<AbstractTimeDependence> VariableRFCavity::getAmplitudeModel() const {
84 return amplitudeTD_m;
85}
86
87std::shared_ptr<AbstractTimeDependence> VariableRFCavity::getPhaseModel() const {
88 return phaseTD_m;
89}
90
91std::shared_ptr<AbstractTimeDependence> VariableRFCavity::getFrequencyModel() const {
92 return frequencyTD_m;
93}
94
95void VariableRFCavity::setAmplitudeModel(std::shared_ptr<AbstractTimeDependence> amplitude_td) {
96 amplitudeTD_m = amplitude_td;
97}
98
99void VariableRFCavity::setPhaseModel(std::shared_ptr<AbstractTimeDependence> phase_td) {
100 phaseTD_m = phase_td;
101}
102
103void VariableRFCavity::setFrequencyModel(std::shared_ptr<AbstractTimeDependence> frequency_td) {
104 frequencyTD_m = frequency_td;
106}
107
109 return geometry;
110}
111
113 return geometry;
114}
115
117 throw GeneralClassicException("VariableRFCavity",
118 "No field defined for VariableRFCavity");
119}
120
122 throw GeneralClassicException("VariableRFCavity::getField",
123 "No field defined for VariableRFCavity");
124}
125
126
127bool VariableRFCavity::apply(const size_t& i, const double& t,
128 Vector_t& E, Vector_t& B) {
129 return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
130}
131
132// If this is too slow: a quicker implementation would be to use templates not
133// inheritance (vtable lookup is removed). This is in the inner
134// tracking loop, so low level optimisation is possibly worthwhile.
135//
136// Do I need bound checking here? I have no "radius" parameter, but I do have a
137// "length".
138bool VariableRFCavity::apply(const Vector_t& R, const Vector_t& /*P*/,
139 const double& t, Vector_t& E, Vector_t& /*B*/) {
140 if (R[2] >= 0. && R[2] < length_m) {
141 if (std::abs(R[0]) > halfWidth_m || std::abs(R[1]) > halfHeight_m) {
142 return true;
143 }
144 const double E0 = amplitudeTD_m->getValue(t);
145 const double integralF = frequencyCache_m.getIntegral(t) * Units::MHz2Hz;
146 const double phi = phaseTD_m->getValue(t);
147 E = Vector_t(0., 0., E0 * std::sin(Physics::two_pi * integralF + phi));
148 return false;
149 }
150 return true;
151}
152
154 const double& t, Vector_t& E, Vector_t& B) {
155 return apply(R, P, t, E, B);
156}
157
158void VariableRFCavity::initialise(PartBunchBase<double, 3>* bunch, double& /*startField*/,
159 double& /*endField*/) {
160 RefPartBunch_m = bunch;
161}
162
164 RefPartBunch_m = nullptr;
165}
166
168 return new VariableRFCavity(*this);
169}
170
172 initialise();
173 visitor.visitVariableRFCavity(*this);
174}
175
177 VariableRFCavity* cavity = const_cast<VariableRFCavity*>(this);
178 std::shared_ptr<AbstractTimeDependence> phaseTD =
179 AbstractTimeDependence::getTimeDependence(boost::to_upper_copy<std::string>(phaseName_m));
180 cavity->setPhaseModel(std::shared_ptr<AbstractTimeDependence>(phaseTD->clone()));
181 std::shared_ptr<AbstractTimeDependence> frequencyTD =
182 AbstractTimeDependence::getTimeDependence(boost::to_upper_copy<std::string>(frequencyName_m));
183 cavity->setFrequencyModel(std::shared_ptr<AbstractTimeDependence>(frequencyTD->clone()));
184 std::shared_ptr<AbstractTimeDependence> amplitudeTD =
185 AbstractTimeDependence::getTimeDependence(boost::to_upper_copy<std::string>(amplitudeName_m));
186 cavity->setAmplitudeModel(std::shared_ptr<AbstractTimeDependence>(amplitudeTD->clone()));
187
188 if (halfHeight_m < 1e-9 || halfWidth_m < 1e-9)
189 throw GeneralClassicException("VariableRFCavity::initialise",
190 "Height or width was not set on VariableRFCavity");
191}
192
193void VariableRFCavity::setLength(double length) {
194 length_m = length;
196}
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
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 MHz2Hz
Definition: Units.h:113
ParticlePos_t & R
ParticleAttrib< Vector_t > P
virtual void visitVariableRFCavity(const VariableRFCavity &)=0
Apply the algorithm to a variable RF cavity.
Interface for a single beam element.
Definition: Component.h:50
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
virtual void setName(const std::string &name)
Set element name.
virtual const std::string & getName() const
Get element name.
Generates a field like E = a(t) * sin{2*pi * integral(f(tau),0,t) + q(t)} B = 0 where E0,...
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
void initialise() const
Lookup the time dependencies and update.
StraightGeometry geometry
The cavity's geometry.
virtual void finalise() override
Finalise following tracking.
std::string amplitudeName_m
std::string phaseName_m
std::string frequencyName_m
virtual std::shared_ptr< AbstractTimeDependence > getFrequencyModel() const
VariableRFCavity()
Default constructor.
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Calculate the field at the position of the i^th particle.
virtual void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Set the phase time dependence.
virtual ~VariableRFCavity()
Destructor does nothing.
virtual std::shared_ptr< AbstractTimeDependence > getAmplitudeModel() const
TimeDependenceCache frequencyCache_m
virtual void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Set the frequency time dependence.
virtual void setLength(double length)
Set the length of the cavity.
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Calculate the field at a given position.
std::shared_ptr< AbstractTimeDependence > amplitudeTD_m
virtual void accept(BeamlineVisitor &) const override
Apply visitor to RFCavity.
virtual std::shared_ptr< AbstractTimeDependence > getPhaseModel() const
virtual ElementBase * clone() const override
Inheritable deepcopy method.
virtual EMField & getField() override
Not implemented.
std::shared_ptr< AbstractTimeDependence > phaseTD_m
virtual StraightGeometry & getGeometry() override
Set the cavity geometry.
VariableRFCavity & operator=(const VariableRFCavity &)
Assignment operator; performs deepcopy on time-dependence models.
virtual void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
Set the amplitude (field gradient) time dependence.
static std::shared_ptr< AbstractTimeDependence > getTimeDependence(std::string name)
Look up the time dependence that has a given name.
double getIntegral(double time)
void setTimeDependence(AbstractTimeDependence *timeDependence)
A geometry representing a straight line.
virtual void setElementLength(double length)
Set design length.
Abstract base class for electromagnetic fields.
Definition: EMField.h:188
Vektor< double, 3 > Vector_t