OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
VariableRFCavityFringeField.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Chris Rogers
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice,
9  * this list of conditions and the following disclaimer in the documentation
10  * and/or other materials provided with the distribution.
11  * 3. Neither the name of STFC nor the names of its contributors may be used to
12  * endorse or promote products derived from this software without specific
13  * prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "Physics/Physics.h"
31 
34 
36  initNull(); // initialise everything to NULL
37 }
38 
40  initNull(); // initialise everything to NULL
41 }
42 
44  initNull(); // initialise everything to NULL
45  *this = var;
46 }
47 
49 
50  if (&rhs == this) {
51  return *this;
52  }
55  zCentre_m = rhs.zCentre_m;
56  f_m = rhs.f_m;
57  g_m = rhs.f_m;
58  h_m = rhs.f_m;
59  return *this;
60 }
61 
63 }
64 
66  return new VariableRFCavityFringeField(*this);
67 }
68 
71  endField_m = std::shared_ptr<endfieldmodel::EndFieldModel>();
72  zCentre_m = 0;
73  maxOrder_m = 1;
74 }
75 
79  const_cast<VariableRFCavityFringeField*>(this);
80  cavity->initialiseCoefficients();
81  visitor.visitVariableRFCavity(*this);
82 }
83 
84 bool VariableRFCavityFringeField::apply(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) {
85  if (R[2] > _length || R[2] < 0.) {
86  return true;
87  }
88  if (std::abs(R[0]) > halfWidth_m || std::abs(R[1]) > halfHeight_m) {
89  return true;
90  }
91  double z_pos = R[2]-zCentre_m;
92  double E0 = amplitudeTD_m->getValue(t);
93  double omega = Physics::two_pi*frequencyTD_m->getValue(t) * 1.0E-3; // need GHz on the element we have MHz
94  double phi = phaseTD_m->getValue(t);
95  double E_sin_t = E0*sin(omega * t + phi);
96  double B_cos_t = E0*cos(omega * t + phi); // 1/c^2 factor in the h_n coefficients
97 
98  std::vector<double> y_power(maxOrder_m+1, 0.);
99  y_power[0] = 1.;
100  for (size_t i = 1; i < y_power.size(); ++i) {
101  y_power[i] = y_power[i-1]*R[1];
102  }
103 
104  // d^i f0 dz^i
105  std::vector<double> endField(maxOrder_m/2+2, 0.);
106  for (size_t i = 0; i < endField.size(); ++i) {
107  endField[i] = endField_m->function(z_pos, i);
108  }
109 
110  // omega^i
111  std::vector<double> omegaPower(maxOrder_m+1, 1.);
112  for (size_t i = 1; i < omegaPower.size(); ++i) {
113  omegaPower[i] = omegaPower[i-1]*omega;
114  }
115 
116  E = Vector_t(0., 0., 0.);
117  B = Vector_t(0., 0., 0.);
118  // even power of y
119  //std::cerr << "EVEN POWER OF Y maxOrder: " << maxOrder_m << std::endl;
120  for (size_t n = 0; n <= maxOrder_m ; n += 2) { // power of y
121  double fCoeff = 0.;
122  size_t index = n/2;
123  //std::cerr << "Size i: " << index << " f_m[i]: " << f_m[index].size()
124  // << " endfield: " << endField.size() << std::endl;
125  for (size_t i = 0; i < f_m[index].size() && i < endField.size(); i += 2) { // derivative of f
126  fCoeff += f_m[index][i]*endField[i]*omegaPower[n-i];
127  }
128  E[2] += E_sin_t*y_power[n]*fCoeff;
129  }
130  // odd power of y
131  //std::cerr << "ODD POWER OF Y maxOrder: " << maxOrder_m << std::endl;
132  for (size_t n = 1; n <= maxOrder_m; n += 2) {
133  double gCoeff = 0.;
134  double hCoeff = 0.;
135  size_t index = (n-1)/2;
136  //std::cerr << "Size i: " << index << " g_m[i]: " << g_m[index].size() << " endfield: " << endField.size() << std::endl;
137  for (size_t j = 0; j < g_m[index].size() && j < endField.size(); ++j) {
138  //std::cerr << "g_m " << j << " " << g_m[index][j] << std::endl;
139  //std::cerr << "endfield " << j << " " << endField[j] << std::endl;
140  //std::cerr << "omegaPower " << j << " " << omegaPower[n-j] << std::endl;
141  gCoeff += g_m[index][j]*endField[j]*omegaPower[n-j];
142  }
143  for (size_t j = 0; j < h_m[index].size() && j < endField.size(); ++j) {
144  hCoeff += h_m[index][j]*endField[j]*omegaPower[n-j];
145  //std::cerr << "j: " << j << " " << hCoeff << " ";
146  }
147  //std::cerr << std::endl;
148  E[1] += E_sin_t*y_power[n]*gCoeff;
149  B[0] += B_cos_t*y_power[n]*hCoeff;
150  //std::cerr << "APPLY B " << n << " " << B[0] << " " << hCoeff << std::endl;
151  }
152  B *= 1e1; //B converted to kGauss
153  return false;
154 }
155 
156 bool VariableRFCavityFringeField::apply(const size_t &i, const double &t,
157  Vector_t &E, Vector_t &B) {
158  return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
159 }
160 
162  const Vector_t &P,
163  const double &t,
164  Vector_t &E,
165  Vector_t &B) {
166  return apply(R, P, t, E, B);
167 }
168 
170  double &startField,
171  double &endField) {
172  VariableRFCavity::initialise(bunch, startField, endField);
174 }
175 
176 void printVector(std::ostream& out, std::vector< std::vector<double> > vec) {
177  for (size_t i = 0; i < vec.size(); ++i) {
178  out << std::setw(3) << i;
179  for (size_t j = 0; j < vec[i].size(); ++j) {
180  out << " " << std::setw(14) << vec[i][j];
181  }
182  out << std::endl;
183  }
184 }
185 
187  f_m = std::vector< std::vector<double> >();
188  g_m = std::vector< std::vector<double> >();
189  h_m = std::vector< std::vector<double> >();
190  f_m.push_back(std::vector<double>(1, 1.));
191  double c_l = Physics::c*1e-6; // speed of light in mm/ns
192  // generate f_{n+2} term
193  // note frequency term has to be added at apply(time) as we have
194  // time-dependent frequency
195  for(size_t n = 0; n+2 <= maxOrder_m; n += 2) {
196  // n denotes the subscript on f_n
197  // n+2 is the subscript on g_{n+2} and terms proportional to y^{n+2}
198  std::vector<double> f_n = f_m.back(); // f_n
199  std::vector<double> f_np2 = std::vector<double>(f_n.size()+2, 0.); // f_{n+2}
200  double n_const = 1./(n+1.)/(n+2.);
201  for (size_t j = 0; j < f_n.size(); ++j) {
202  f_np2[j] -= f_n[j]*n_const/c_l/c_l;
203  }
204  for (size_t j = 0; j < f_n.size(); ++j) {
205  f_np2[j+2] -= f_n[j]*n_const;
206  }
207  f_m.push_back(f_np2);
208  }
209  // generate g_{n+2} and h_{n+2} term
210  for(size_t n = 0; n+1 <= maxOrder_m; n += 2) {
211  // n denotes the subscript on f_n
212  // n+1 is the subscript on g_{n+1} and terms proportional to y^{n+1}
213  size_t f_index = n/2;
214  std::vector<double> f_n = f_m[f_index];
215  std::vector<double> g_np1 = std::vector<double>(f_n.size()+1, 0.);
216  std::vector<double> h_np1 = std::vector<double>(f_n.size(), 0.);
217  for (size_t j = 0; j < f_n.size(); ++j) {
218  g_np1[j+1] = -1./(n+1.)*f_n[j];
219  h_np1[j] = -1./c_l/c_l/(n+1.)*f_n[j];
220  }
221  g_m.push_back(g_np1);
222  h_m.push_back(h_np1);
223  }
224 }
225 
226 void VariableRFCavityFringeField::printCoefficients(std::ostream& out) const {
227  out << "f_m" << std::endl;
228  printVector(out, f_m);
229  out << "g_m" << std::endl;
230  printVector(out, g_m);
231  out << "h_m" << std::endl;
232  printVector(out, h_m);
233  out << std::endl;
234 }
235 
237  std::shared_ptr<endfieldmodel::EndFieldModel> end) {
238  endField_m = end;
239 }
std::vector< std::vector< double > > g_m
ParticleAttrib< Vector_t > P
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
constexpr double e
The value of .
Definition: Physics.h:40
Interface for basic beam line object.
Definition: ElementBase.h:128
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
constexpr double two_pi
The value of .
Definition: Physics.h:34
std::shared_ptr< AbstractTimeDependence > phaseTD_m
std::vector< std::vector< double > > h_m
VariableRFCavityFringeField & operator=(const VariableRFCavityFringeField &)
std::vector< std::vector< double > > f_m
VariableRFCavity & operator=(const VariableRFCavity &)
void printCoefficients(std::ostream &out) const
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:200
virtual void setEndField(std::shared_ptr< endfieldmodel::EndFieldModel > endField)
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
void initialise() const
std::shared_ptr< AbstractTimeDependence > frequencyTD_m
void printVector(std::ostream &out, std::vector< std::vector< double > > vec)
virtual void visitVariableRFCavity(const VariableRFCavity &)=0
Apply the algorithm to a variable RF cavity.
virtual void accept(BeamlineVisitor &) const override
virtual ElementBase * clone() const override
Definition: Vec.h:21
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
const std::string name
std::shared_ptr< endfieldmodel::EndFieldModel > endField_m
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
ParticlePos_t & R
std::shared_ptr< AbstractTimeDependence > amplitudeTD_m
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Abstract algorithm.
Inform & endl(Inform &inf)
Definition: Inform.cpp:42