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
27#include <cmath>
28
30 initNull(); // initialise everything to nullptr
31}
32
34 initNull(); // initialise everything to nullptr
35}
36
38 initNull(); // initialise everything to nullptr
39 *this = var;
40}
41
43 if (&rhs == this) {
44 return *this;
45 }
46 setName(rhs.getName());
47 setPhaseModel(nullptr);
48 setAmplitudeModel(nullptr);
49 setFrequencyModel(nullptr);
50 if (rhs.phaseTD_m != nullptr) {
51 setPhaseModel(std::shared_ptr<AbstractTimeDependence>(rhs.phaseTD_m->clone()));
52 }
53 if (rhs.amplitudeTD_m != nullptr) {
54 setAmplitudeModel(std::shared_ptr<AbstractTimeDependence>(rhs.amplitudeTD_m->clone()));
55 }
56 if (rhs.frequencyTD_m != nullptr) {
57 setFrequencyModel(std::shared_ptr<AbstractTimeDependence>(rhs.frequencyTD_m->clone()));
58 }
65 return *this;
66}
67
69 // shared_ptr should self-destruct when they are ready
70}
71
73 length_m = 0.;
74 phaseName_m = "";
75 amplitudeName_m = "";
76 frequencyName_m = "";
77 halfHeight_m = 0.;
78 halfWidth_m = 0;
79 RefPartBunch_m = nullptr;
80}
81
82std::shared_ptr<AbstractTimeDependence> VariableRFCavity::getAmplitudeModel() const {
83 return amplitudeTD_m;
84}
85
86std::shared_ptr<AbstractTimeDependence> VariableRFCavity::getPhaseModel() const {
87 return phaseTD_m;
88}
89
90std::shared_ptr<AbstractTimeDependence> VariableRFCavity::getFrequencyModel() const {
91 return frequencyTD_m;
92}
93
94void VariableRFCavity::setAmplitudeModel(std::shared_ptr<AbstractTimeDependence> amplitude_td) {
95 amplitudeTD_m = amplitude_td;
96}
97
98void VariableRFCavity::setPhaseModel(std::shared_ptr<AbstractTimeDependence> phase_td) {
99 phaseTD_m = phase_td;
100}
101
102void VariableRFCavity::setFrequencyModel(std::shared_ptr<AbstractTimeDependence> frequency_td) {
103 frequencyTD_m = frequency_td;
104}
105
109
113
115 throw GeneralClassicException("VariableRFCavity",
116 "No field defined for VariableRFCavity");
117}
118
120 throw GeneralClassicException("VariableRFCavity::getField",
121 "No field defined for VariableRFCavity");
122}
123
124
125bool VariableRFCavity::apply(const size_t& i, const double& t,
126 Vector_t& E, Vector_t& B) {
127 return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
128}
129
130// If this is too slow: a quicker implementation would be to use templates not
131// inheritance (vtable lookup is removed). This is in the inner
132// tracking loop, so low level optimisation is possibly worthwhile.
133//
134// Do I need bound checking here? I have no "radius" parameter, but I do have a
135// "length".
136bool VariableRFCavity::apply(const Vector_t& R, const Vector_t& /*P*/,
137 const double& t, Vector_t& E, Vector_t& /*B*/) {
138 if (R[2] >= 0. && R[2] < length_m) {
139 if (std::abs(R[0]) > halfWidth_m || std::abs(R[1]) > halfHeight_m) {
140 return true;
141 }
142 double E0 = amplitudeTD_m->getValue(t);
143 double f = frequencyTD_m->getValue(t) * Units::MHz2Hz * Units::Hz2GHz; // need GHz on the element we have MHz
144 double phi = phaseTD_m->getValue(t);
145 E = Vector_t(0., 0., E0 * std::sin(Physics::two_pi * f * t + phi));
146 return false;
147 }
148 return true;
149}
150
152 const double& t, Vector_t& E, Vector_t& B) {
153 return apply(R, P, t, E, B);
154}
155
156void VariableRFCavity::initialise(PartBunchBase<double, 3>* bunch, double& /*startField*/, double& /*endField*/) {
157 RefPartBunch_m = bunch;
158}
159
161 RefPartBunch_m = nullptr;
162}
163
165 return new VariableRFCavity(*this);
166}
167
169 initialise();
170 visitor.visitVariableRFCavity(*this);
171}
172
174 VariableRFCavity* cavity = const_cast<VariableRFCavity*>(this);
175 std::shared_ptr<AbstractTimeDependence> phaseTD =
177 cavity->setPhaseModel(std::shared_ptr<AbstractTimeDependence>(phaseTD->clone()));
178 std::shared_ptr<AbstractTimeDependence> frequencyTD =
180 cavity->setFrequencyModel(std::shared_ptr<AbstractTimeDependence>(frequencyTD->clone()));
181 std::shared_ptr<AbstractTimeDependence> amplitudeTD =
183 cavity->setAmplitudeModel(std::shared_ptr<AbstractTimeDependence>(amplitudeTD->clone()));
184
185 if (halfHeight_m < 1e-9 || halfWidth_m < 1e-9)
186 throw GeneralClassicException("VariableRFCavity::initialise",
187 "Height or width was not set on VariableRFCavity");
188}
189
190void VariableRFCavity::setLength(double length) {
191 length_m = length;
192 geometry.setElementLength(length_m);
193}
const std::string name
constexpr double two_pi
The value of.
Definition Physics.h:33
constexpr double MHz2Hz
Definition Units.h:113
constexpr double Hz2GHz
Definition Units.h:122
virtual void visitVariableRFCavity(const VariableRFCavity &)=0
Apply the algorithm to a variable RF cavity.
Component(const std::string &name)
Constructor with given name.
Definition Component.cpp:53
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.
ElementBase(const std::string &name)
Constructor with given name.
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
StraightGeometry geometry
The cavity's geometry.
virtual void finalise() override
std::string amplitudeName_m
std::string phaseName_m
std::string frequencyName_m
virtual std::shared_ptr< AbstractTimeDependence > getFrequencyModel() const
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
virtual void setPhaseModel(std::shared_ptr< AbstractTimeDependence > time_dep)
virtual std::shared_ptr< AbstractTimeDependence > getAmplitudeModel() const
virtual void setFrequencyModel(std::shared_ptr< AbstractTimeDependence > time_dep)
virtual void setLength(double length)
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
std::shared_ptr< AbstractTimeDependence > amplitudeTD_m
virtual void accept(BeamlineVisitor &) const override
virtual std::shared_ptr< AbstractTimeDependence > getPhaseModel() const
virtual ElementBase * clone() const override
virtual EMField & getField() override
Not implemented.
std::shared_ptr< AbstractTimeDependence > phaseTD_m
virtual StraightGeometry & getGeometry() override
VariableRFCavity(const std::string &name)
Constructor with given name.
VariableRFCavity & operator=(const VariableRFCavity &)
virtual void setAmplitudeModel(std::shared_ptr< AbstractTimeDependence > time_dep)
static std::shared_ptr< AbstractTimeDependence > getTimeDependence(std::string name)
virtual AbstractTimeDependence * clone()=0
A geometry representing a straight line.
Abstract base class for electromagnetic fields.
Definition EMField.h:188
Vektor< double, 3 > Vector_t