OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
VariableRFCavityFringeField.cpp
Go to the documentation of this file.
1 //
2 // Class VariableRFCavityFringeField
3 // Defines the abstract interface for a soft-edged 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 
24 #include "Physics/Physics.h"
25 #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  }
48  zCentre_m = rhs.zCentre_m;
49  f_m = rhs.f_m;
50  g_m = rhs.f_m;
51  h_m = rhs.f_m;
52  return *this;
53 }
54 
56 }
57 
59  return new VariableRFCavityFringeField(*this);
60 }
61 
64  endField_m = std::shared_ptr<endfieldmodel::EndFieldModel>();
65  zCentre_m = 0;
66  maxOrder_m = 1;
67 }
68 
70  initialise();
72  const_cast<VariableRFCavityFringeField*>(this);
73  cavity->initialiseCoefficients();
74  visitor.visitVariableRFCavity(*this);
75 }
76 
78  const double& t, Vector_t& E, Vector_t& B) {
79  if (R[2] > length_m || R[2] < 0.) {
80  return true;
81  }
82  if (std::abs(R[0]) > halfWidth_m || std::abs(R[1]) > halfHeight_m) {
83  return true;
84  }
85  double z_pos = R[2] - zCentre_m;
86  double E0 = amplitudeTD_m->getValue(t);
87  double omega = Physics::two_pi * frequencyTD_m->getValue(t) * Units::MHz2Hz * Units::Hz2GHz; // need GHz on the element we have MHz
88  double phi = phaseTD_m->getValue(t);
89  double E_sin_t = E0 * std::sin(omega * t + phi);
90  double B_cos_t = E0 * std::cos(omega * t + phi); // 1/c^2 factor in the h_n coefficients
91 
92  std::vector<double> y_power(maxOrder_m+1, 0.);
93  y_power[0] = 1.;
94  for (size_t i = 1; i < y_power.size(); ++i) {
95  y_power[i] = y_power[i-1] * R[1];
96  }
97 
98  // d^i f0 dz^i
99  std::vector<double> endField(maxOrder_m/2+2, 0.);
100  for (size_t i = 0; i < endField.size(); ++i) {
101  endField[i] = endField_m->function(z_pos, i);
102  }
103 
104  // omega^i
105  std::vector<double> omegaPower(maxOrder_m+1, 1.);
106  for (size_t i = 1; i < omegaPower.size(); ++i) {
107  omegaPower[i] = omegaPower[i-1] * omega;
108  }
109 
110  E = Vector_t(0., 0., 0.);
111  B = Vector_t(0., 0., 0.);
112  // even power of y
113  for (size_t n = 0; n <= maxOrder_m ; n += 2) { // power of y
114  double fCoeff = 0.;
115  size_t index = n/2;
116  for (size_t i = 0; i < f_m[index].size() && i < endField.size(); i += 2) { // derivative of f
117  fCoeff += f_m[index][i] * endField[i] * omegaPower[n-i];
118  }
119  E[2] += E_sin_t * y_power[n] * fCoeff;
120  }
121  // odd power of y
122  for (size_t n = 1; n <= maxOrder_m; n += 2) {
123  double gCoeff = 0.;
124  double hCoeff = 0.;
125  size_t index = (n-1)/2;
126  for (size_t j = 0; j < g_m[index].size() && j < endField.size(); ++j) {
127  gCoeff += g_m[index][j] * endField[j] * omegaPower[n-j];
128  }
129  for (size_t j = 0; j < h_m[index].size() && j < endField.size(); ++j) {
130  hCoeff += h_m[index][j] * endField[j] * omegaPower[n-j];
131  }
132  E[1] += E_sin_t * y_power[n] * gCoeff;
133  B[0] += B_cos_t * y_power[n] * hCoeff;
134  }
135  B *= Units::T2kG;
136  return false;
137 }
138 
139 bool VariableRFCavityFringeField::apply(const size_t& i, const double& t,
140  Vector_t& E, Vector_t& B) {
141  return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
142 }
143 
145  const Vector_t& P,
146  const double& t,
147  Vector_t& E,
148  Vector_t& B) {
149  return apply(R, P, t, E, B);
150 }
151 
153  double& startField,
154  double& endField) {
155  VariableRFCavity::initialise(bunch, startField, endField);
157 }
158 
159 void printVector(std::ostream& out, std::vector< std::vector<double> > vec) {
160  for (size_t i = 0; i < vec.size(); ++i) {
161  out << std::setw(3) << i;
162  for (size_t j = 0; j < vec[i].size(); ++j) {
163  out << " " << std::setw(14) << vec[i][j];
164  }
165  out << std::endl;
166  }
167 }
168 
170  f_m = std::vector< std::vector<double> >();
171  g_m = std::vector< std::vector<double> >();
172  h_m = std::vector< std::vector<double> >();
173  f_m.push_back(std::vector<double>(1, 1.));
174  double c_l = Physics::c * Units::m2mm / Units::s2ns;
175  // generate f_{n+2} term
176  // note frequency term has to be added at apply(time) as we have
177  // time-dependent frequency
178  for (size_t n = 0; n+2 <= maxOrder_m; n += 2) {
179  // n denotes the subscript on f_n
180  // n+2 is the subscript on g_{n+2} and terms proportional to y^{n+2}
181  std::vector<double> f_n = f_m.back(); // f_n
182  std::vector<double> f_np2 = std::vector<double>(f_n.size()+2, 0.); // f_{n+2}
183  double n_const = 1./(n+1.)/(n+2.);
184  for (size_t j = 0; j < f_n.size(); ++j) {
185  f_np2[j] -= f_n[j]*n_const/c_l/c_l;
186  }
187  for (size_t j = 0; j < f_n.size(); ++j) {
188  f_np2[j+2] -= f_n[j]*n_const;
189  }
190  f_m.push_back(f_np2);
191  }
192  // generate g_{n+2} and h_{n+2} term
193  for (size_t n = 0; n+1 <= maxOrder_m; n += 2) {
194  // n denotes the subscript on f_n
195  // n+1 is the subscript on g_{n+1} and terms proportional to y^{n+1}
196  size_t f_index = n/2;
197  std::vector<double> f_n = f_m[f_index];
198  std::vector<double> g_np1 = std::vector<double>(f_n.size()+1, 0.);
199  std::vector<double> h_np1 = std::vector<double>(f_n.size(), 0.);
200  for (size_t j = 0; j < f_n.size(); ++j) {
201  g_np1[j+1] = -1./(n+1.)*f_n[j];
202  h_np1[j] = -1./c_l/c_l/(n+1.)*f_n[j];
203  }
204  g_m.push_back(g_np1);
205  h_m.push_back(h_np1);
206  }
207 }
208 
209 void VariableRFCavityFringeField::printCoefficients(std::ostream& out) const {
210  out << "f_m" << std::endl;
211  printVector(out, f_m);
212  out << "g_m" << std::endl;
213  printVector(out, g_m);
214  out << "h_m" << std::endl;
215  printVector(out, h_m);
216  out << std::endl;
217 }
218 
219 void VariableRFCavityFringeField::setEndField(std::shared_ptr<endfieldmodel::EndFieldModel> end) {
220  endField_m = end;
221 }
constexpr double Hz2GHz
Definition: Units.h:122
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
virtual void setEndField(std::shared_ptr< endfieldmodel::EndFieldModel > endField)
std::vector< std::vector< double > > h_m
constexpr double two_pi
The value of .
Definition: Physics.h:33
constexpr double m2mm
Definition: Units.h:26
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
VariableRFCavity & operator=(const VariableRFCavity &)
ParticleAttrib< Vector_t > P
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
std::shared_ptr< AbstractTimeDependence > phaseTD_m
constexpr double T2kG
Definition: Units.h:56
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::vector< std::vector< double > > f_m
std::vector< std::vector< double > > g_m
std::shared_ptr< endfieldmodel::EndFieldModel > endField_m
Definition: Vec.h:21
void printCoefficients(std::ostream &out) const
virtual void accept(BeamlineVisitor &) const override
void printVector(std::ostream &out, std::vector< std::vector< double > > vec)
constexpr double s2ns
Definition: Units.h:44
void initialise() const
std::shared_ptr< AbstractTimeDependence > amplitudeTD_m
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
const std::string name
VariableRFCavityFringeField & operator=(const VariableRFCavityFringeField &)
constexpr double MHz2Hz
Definition: Units.h:113
ParticlePos_t & R
virtual void visitVariableRFCavity(const VariableRFCavity &)=0
Apply the algorithm to a variable RF cavity.
virtual ElementBase * clone() const override
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
end
Definition: multipole_t.tex:9