OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
MultipoleT.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, Titus Dascalu
3  * Copyright (c) 2018, Martin Duy Tat
4  * All rights reserved.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * 3. Neither the name of STFC nor the names of its contributors may be used to
13  * endorse or promote products derived from this software without specific
14  * prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 #include "Algorithms/PartBunch.h"
31 #include "MultipoleT.h"
32 #include <gsl/gsl_math.h>
37 
38 using namespace endfieldmodel;
39 
40 MultipoleT::MultipoleT(const std::string &name):
41  Component(name),
42  fringeField_l(endfieldmodel::Tanh()),
43  fringeField_r(endfieldmodel::Tanh()),
44  maxOrder_m(5),
45  maxOrderX_m(10),
46  transMaxOrder_m(0),
47  planarArcGeometry_m(1., 1.),
48  length_m(1.0),
49  angle_m(0.0),
50  entranceAngle_m(0.0),
51  rotation_m(0.0),
52  variableRadius_m(false),
53  boundingBoxLength_m(0.0),
54  verticalApert_m(0.5),
55  horizApert_m(0.5) {
56 }
57 
59  Component(right),
60  fringeField_l(right.fringeField_l),
61  fringeField_r(right.fringeField_r),
62  maxOrder_m(right.maxOrder_m),
63  maxOrderX_m(right.maxOrderX_m),
64  recursion_VarRadius_m(right.recursion_VarRadius_m),
65  recursion_ConstRadius_m(right.recursion_ConstRadius_m),
66  transMaxOrder_m(right.transMaxOrder_m),
67  transProfile_m(right.transProfile_m),
68  planarArcGeometry_m(right.planarArcGeometry_m),
69  length_m(right.length_m),
70  angle_m(right.angle_m),
71  entranceAngle_m(right.entranceAngle_m),
72  rotation_m(right.rotation_m),
73  variableRadius_m(right.variableRadius_m),
74  boundingBoxLength_m(right.boundingBoxLength_m),
75  verticalApert_m(right.verticalApert_m),
76  horizApert_m(right.horizApert_m),
77  dummy() {
79 }
80 
82 }
83 
85  MultipoleT* newMultipole = new MultipoleT(*this);
86  newMultipole->initialise();
87  return newMultipole;
88 }
89 
91  RefPartBunch_m = NULL;
92 }
93 
94 bool MultipoleT::apply(const Vector_t &R, const Vector_t &P,
95  const double &t,Vector_t &E, Vector_t &B) {
97  Vector_t R_prime = rotateFrame(R);
99  //R_prime[2] *= -1; //OPAL uses different sign convention...
100  Vector_t X = R_prime;
101  R_prime = transformCoords(X);
102  if (insideAperture(R_prime)) {
104  double theta;
105  double prefactor = (length_m / angle_m) * (tanh((fringeField_l.getX0())
106  / fringeField_l.getLambda()) +
108  / fringeField_r.getLambda()));
109  if (angle_m == 0.0) {
110  theta = 0.0;
111  } else if (!variableRadius_m) {
112  theta = R_prime[2] * angle_m / length_m;
113  } else { // variableRadius_m == true
114  theta = fringeField_l.getLambda() * log(cosh((R_prime[2] +
116  fringeField_r.getLambda() * log(cosh((R_prime[2] -
118  theta /= prefactor;
119  }
120  double Bx = getBx(R_prime);
121  double Bs = getBs(R_prime);
122  B[0] = Bx * cos(theta) - Bs * sin(theta);
123  B[2] = Bx * sin(theta) + Bs * cos(theta);
124  B[1] = getBz(R_prime);
125  // B[2] *= -1; //OPAL uses different sign convention
126  return false;
127  } else {
128  for(int i = 0; i < 3; i++) {
129  B[i] = 0.0;
130  }
131  return true;
132  }
133 }
134 
135 bool MultipoleT::apply(const size_t &i, const double &t,
136  Vector_t &E, Vector_t &B) {
137  return apply(RefPartBunch_m->R[i], RefPartBunch_m->P[i], t, E, B);
138 }
139 
141  Vector_t R_prime(3), R_pprime(3);
146  // 1st rotation
147  R_prime[0] = R[0] * cos(rotation_m) + R[1] * sin(rotation_m);
148  R_prime[1] = - R[0] * sin(rotation_m) + R[1] * cos(rotation_m);
149  R_prime[2] = R[2];
150  // 2nd rotation
151  R_pprime[0] = R_prime[2] * sin(entranceAngle_m) +
152  R_prime[0] * cos(entranceAngle_m);
153  R_pprime[1] = R_prime[1];
154  R_pprime[2] = R_prime[2] * cos(entranceAngle_m) -
155  R_prime[0] * sin(entranceAngle_m);
156  return R_pprime;
157 
158 }
159 
165  Vector_t B_prime(3);
166  B_prime[0] = B[0] * cos(rotation_m) + B[1] * sin(rotation_m);
167  B_prime[1] = - B[0] * sin(rotation_m) + B[1] * cos(rotation_m);
168  B_prime[2] = B[2];
169  return B_prime;
170 }
171 
173  if (std::abs(R[1]) <= verticalApert_m / 2. && std::abs(R[0]) <= horizApert_m / 2.) {
174  return true;
175  }
176  else {
177  return false;
178  }
179 }
180 
182  Vector_t X(3);
183  // If radius is constant
184  if (!variableRadius_m) {
185  double radius = length_m / angle_m;
186  // Transform from Cartesian to Frenet-Serret along the magnet
187  double alpha = atan(R[2] / (R[0] + radius ));
188  if (alpha != 0.0 && angle_m != 0.0) {
189  X[0] = R[2] / sin(alpha) - radius;
190  X[1] = R[1];
191  X[2] = radius * alpha;// + boundingBoxLength_m;
192  } else {
193  X[0] = R[0];
194  X[1] = R[1];
195  X[2] = R[2];// + boundingBoxLength_m;
196  }
197  } else {
198  // If radius is variable
199  coordinatetransform::CoordinateTransform t(R[0], R[1], R[2],
203  (length_m / angle_m));
204  std::vector<double> r = t.getTransformation();
205  X[0] = r[0];
206  X[1] = r[1];
207  X[2] = r[2];
208  }
209  return X;
210 }
211 
212 void MultipoleT::setMaxOrder(std::size_t maxOrder) {
213  if (variableRadius_m && angle_m != 0.0) {
214  std::size_t N = recursion_VarRadius_m.size();
215  while (maxOrder >= N) {
216  polynomial::RecursionRelationTwo r(N, 2 * (N + maxOrderX_m + 1));
219  recursion_VarRadius_m.push_back(r);
220  N = recursion_VarRadius_m.size();
221  }
222  } else if (!variableRadius_m && angle_m != 0.0) {
223  std::size_t N = recursion_ConstRadius_m.size();
224  while (maxOrder >= N) {
225  polynomial::RecursionRelation r(N, 2 * (N + maxOrderX_m + 1));
228  recursion_ConstRadius_m.push_back(r);
229  N = recursion_ConstRadius_m.size();
230  }
231  }
232  maxOrder_m = maxOrder;
233 }
234 
235 void MultipoleT::setTransProfile(std::size_t n, double dTn) {
236  if (n > transMaxOrder_m) {
237  transMaxOrder_m = n;
238  transProfile_m.resize(n+1, 0.0);
239  }
240  transProfile_m[n] = dTn;
241 }
242 
243 bool MultipoleT::setFringeField(double s0, double lambda_l, double lambda_r) {
244  fringeField_l.Tanh::setLambda(lambda_l);
245  fringeField_l.Tanh::setX0(s0);
246  fringeField_l.Tanh::setTanhDiffIndices(2 * maxOrder_m + 1);
247 
248  fringeField_r.Tanh::setLambda(lambda_r);
249  fringeField_r.Tanh::setX0(s0);
250  fringeField_r.Tanh::setTanhDiffIndices(2 * maxOrder_m + 1);
251 
252  return true;
253 }
254 
255 double MultipoleT::getBz(const Vector_t &R) {
259  double Bz = 0.0;
260  if (angle_m == 0.0) {
261  // Straight geometry -> Use corresponding field expansion directly
262  for(std::size_t n = 0; n <= maxOrder_m; n++) {
263  double f_n = 0.0;
264  for(std::size_t i = 0; i <= n; i++) {
265  f_n += gsl_sf_choose(n, i) * getTransDeriv(2 * i, R[0]) *
266  getFringeDeriv(2 * n - 2 * i, R[2]);
267  }
268  f_n *= gsl_sf_pow_int(-1.0, n);
269  Bz += gsl_sf_pow_int(R[1], 2 * n) / gsl_sf_fact(2 * n) * f_n;
270  }
271  } else {
272  if (variableRadius_m == true and getFringeDeriv(0, R[2]) < 1.0e-12) {
273  // Return 0 if end of fringe field is reached
274  // This is to avoid functions being called at infinite radius
275  return 0.0;
276  }
277  // Curved geometry -> Use full machinery of differential operators
278  for(std::size_t n = 0; n <= maxOrder_m; n++) {
279  double f_n = getFn(n, R[0], R[2]);
280  Bz += gsl_sf_pow_int(R[1], 2 * n) / gsl_sf_fact(2 * n) * f_n;
281  }
282  }
283  return Bz;
284 }
285 
286 double MultipoleT::getBx(const Vector_t &R) {
290  double Bx = 0.0;
291  if (angle_m == 0.0) {
292  // Straight geometry -> Use corresponding field expansion directly
293  for(std::size_t n = 0; n <= maxOrder_m; n++) {
294  double f_n = 0.0;
295  for(std::size_t i = 0; i <= n; i++) {
296  f_n += gsl_sf_choose(n, i) * getTransDeriv(2 * i + 1, R[0]) *
297  getFringeDeriv(2 * n - 2 * i, R[2]);
298  }
299  f_n *= gsl_sf_pow_int(-1.0, n);
300  Bx += gsl_sf_pow_int(R[1], 2 * n + 1) /
301  gsl_sf_fact(2 * n + 1) * f_n;
302  }
303  } else {
304  if (variableRadius_m == true and getFringeDeriv(0, R[2]) < 1.0e-12) {
305  // Return 0 if end of fringe field is reached
306  // This is to avoid functions being called at infinite radius
307  return 0.0;
308  }
309  // Curved geometry -> Use full machinery of differential operators
310  for(std::size_t n = 0; n <= maxOrder_m; n++) {
311  double partialX_fn = getFnDerivX(n, R[0], R[2]);
312  Bx += partialX_fn * gsl_sf_pow_int(R[1], 2 * n + 1)
313  / gsl_sf_fact(2 * n + 1);
314  }
315  }
316  return Bx;
317 }
318 
319 double MultipoleT::getBs(const Vector_t &R) {
323  double Bs = 0.0;
324  if (angle_m == 0.0) {
325  // Straight geometry -> Use corresponding field expansion directly
326  for(std::size_t n = 0; n <= maxOrder_m; n++) {
327  double f_n = 0.0;
328  for(std::size_t i = 0; i <= n; i++) {
329  f_n += gsl_sf_choose(n, i) * getTransDeriv(2 * i, R[0]) *
330  getFringeDeriv(2 * n - 2 * i + 1, R[2]);
331  }
332  f_n *= gsl_sf_pow_int(-1.0, n);
333  Bs += gsl_sf_pow_int(R[1], 2 * n + 1) /
334  gsl_sf_fact(2 * n + 1) * f_n;
335  }
336  } else {
337  if (variableRadius_m == true and getFringeDeriv(0, R[2]) < 1.0e-12) {
338  // Return 0 if end of fringe field is reached
339  // This is to avoid functions being called at infinite radius
340  return 0.0;
341  }
342  // Curved geometry -> Use full machinery of differential operators
343  for(std::size_t n = 0; n <= maxOrder_m; n++) {
344  double partialS_fn = getFnDerivS(n, R[0], R[2]);
345  Bs += partialS_fn * gsl_sf_pow_int(R[1], 2 * n + 1)
346  / gsl_sf_fact(2 * n + 1);
347  }
348  Bs /= getScaleFactor(R[0], R[2]);
349  }
350  return Bs;
351 }
352 
353 double MultipoleT::getFringeDeriv(int n, double s) {
354  if (n <= 10) {
355  return (fringeField_l.getTanh(s, n) - fringeField_r.getNegTanh(s, n))
356  / 2;
357  } else {
358  return tanhderiv::integrate(s,
359  fringeField_l.Tanh::getX0(),
360  fringeField_l.Tanh::getLambda(),
361  fringeField_r.Tanh::getLambda(),
362  n);
363  }
364 }
365 
366 double MultipoleT::getTransDeriv(std::size_t n, double x) {
372  double func = 0;
373  std::vector<double> temp = transProfile_m;
374  if (n <= transMaxOrder_m) {
375  if (n != 0) {
376  for(std::size_t i = 1; i <= n; i++) {
377  for(std::size_t j = 0; j <= transMaxOrder_m; j++) {
378  if (j <= transMaxOrder_m - i) {
379  // Move terms to the left and multiply by power
380  temp[j] = temp[j + 1] * (j + 1);
381  } else {
382  // Put 0 at the end for missing higher powers
383  temp[j] = 0.0;
384  }
385  }
386  }
387  }
388  // Now use the vector to calculate value of the function
389  for(std::size_t k = 0; k <= transMaxOrder_m; k++) {
390  func += temp[k] * gsl_sf_pow_int(x, k);
391  }
392  }
393  return func;
394 }
395 
397  if (transMaxOrder_m < 1) {
398  transProfile_m.resize(1, 0.);
399  }
400  transProfile_m[0] = B0;
401 }
402 
403 void MultipoleT::accept(BeamlineVisitor& visitor) const {
404  visitor.visitMultipoleT(*this);
405 }
406 
407 void MultipoleT::getDimensions(double &zBegin, double &zEnd) const {
408 }
409 
410 void MultipoleT::setAperture(double vertAp, double horizAp) {
411  verticalApert_m = vertAp;
412  horizApert_m = horizAp;
413 }
414 
415 std::vector<double> MultipoleT::getAperture() const {
416  std::vector<double> temp(2, 0.0);
417  temp[0] = verticalApert_m;
418  temp[1] = horizApert_m;
419  return temp;
420 }
421 
422 std::vector<double> MultipoleT::getFringeLength() const {
423  std::vector<double> temp(2, 0.0);
424  temp[0] = fringeField_l.getLambda();
425  temp[1] = fringeField_r.getLambda();
426  return temp;
427 }
428 
429 double MultipoleT::getRadius(double s) {
430  double centralRadius = length_m / angle_m;
431  if (!variableRadius_m) {
432  return centralRadius;
433  }
434  if (getFringeDeriv(0, s) != 0.0) {
435  return centralRadius * getFringeDeriv(0, 0) / getFringeDeriv(0, s);
436  } else {
437  return -1; // Return -1 if radius is infinite
438  }
439 }
440 
441 double MultipoleT::getScaleFactor(double x, double s) {
442  if (!variableRadius_m) {
443  return 1 + x * angle_m/ length_m;
444  } else {
445  return 1 + x / getRadius(s);
446  }
447 }
448 
449 double MultipoleT::getFnDerivX(std::size_t n, double x, double s) {
450  if (n == 0) {
451  return getTransDeriv(1, x) * getFringeDeriv(0, s);
452  }
453  double deriv = 0.0;
454  double stepSize = 1e-3;
455  deriv += 1. * getFn(n, x - 2. * stepSize, s);
456  deriv += -8. * getFn(n, x - stepSize, s);
457  deriv += 8. * getFn(n, x + stepSize, s);
458  deriv += -1. * getFn(n, x + 2. * stepSize, s);
459  deriv /= 12 * stepSize;
460  return deriv;
461 }
462 
463 double MultipoleT::getFnDerivS(std::size_t n, double x, double s) {
464  if (n == 0) {
465  return getTransDeriv(0, x) * getFringeDeriv(1, s);
466  }
467  double deriv = 0.0;
468  double stepSize = 1e-3;
469  deriv += 1. * getFn(n, x, s - 2. * stepSize);
470  deriv += -8. * getFn(n, x, s - stepSize);
471  deriv += 8. * getFn(n, x, s + stepSize);
472  deriv += -1. * getFn(n, x, s + 2. * stepSize);
473  deriv /= 12 * stepSize;
474  return deriv;
475 }
476 
477 double MultipoleT::getFn(std::size_t n, double x, double s) {
478  if (n == 0) {
479  return getTransDeriv(0, x) * getFringeDeriv(0, s);
480  }
481  if (!variableRadius_m) {
482  double rho = length_m / angle_m;
483  double func = 0.0;
484 
485  for (std::size_t j = 0;
486  j <= recursion_ConstRadius_m.at(n).getMaxSDerivatives();
487  j++) {
488  double FringeDerivj = getFringeDeriv(2 * j, s);
489  for (std::size_t i = 0;
490  i <= recursion_ConstRadius_m.at(n).getMaxXDerivatives();
491  i++) {
492  if (recursion_ConstRadius_m.at(n).isPolynomialZero(i, j)) {
493  continue;
494  }
495  func += (recursion_ConstRadius_m.at(n)
496  .evaluatePolynomial(x / rho, i, j) *
497  getTransDeriv(i, x) * FringeDerivj) /
498  gsl_sf_pow_int(rho, 2 * n - i - 2 * j);
499  }
500  }
501  func *= gsl_sf_pow_int(-1.0, n);
502  return func;
503  } else {
504  double rho = length_m / angle_m;
505  double S_0 = getFringeDeriv(0, 0);
506  double y = getFringeDeriv(0, s) / (S_0 * rho);
507  double func = 0.0;
508  std::vector<double> fringeDerivatives;
509  for (std::size_t j = 0;
510  j <= recursion_VarRadius_m.at(n).getMaxSDerivatives();
511  j++) {
512  fringeDerivatives.push_back(getFringeDeriv(j, s) / (S_0 * rho));
513  }
514  for (std::size_t i = 0;
515  i <= recursion_VarRadius_m.at(n).getMaxXDerivatives();
516  i++) {
517  double temp = 0.0;
518  for (std::size_t j = 0;
519  j <= recursion_VarRadius_m.at(n).getMaxSDerivatives();
520  j++) {
521  temp += recursion_VarRadius_m.at(n)
522  .evaluatePolynomial(x, y, i, j, fringeDerivatives)
523  * fringeDerivatives.at(j);
524  }
525  func += temp * getTransDeriv(i, x);
526  }
527  func *= gsl_sf_pow_int(-1.0, n) * S_0 * rho;
528  return func;
529  }
530 }
531 
535 }
536 
538  double &startField,
539  double &endField) {
540  RefPartBunch_m = bunch;
541  initialise();
542 }
543 
544 bool MultipoleT::bends() const {
545  return (transProfile_m[0] != 0);
546 }
547 
549  return planarArcGeometry_m;
550 }
551 
553  return planarArcGeometry_m;
554 }
555 
557  return dummy;
558 }
559 
561  return dummy;
562 }
double getBx(const Vector_t &R)
Definition: MultipoleT.cpp:286
double boundingBoxLength_m
Definition: MultipoleT.h:289
double rotation_m
Definition: MultipoleT.h:285
ParticleAttrib< Vector_t > P
void setDipoleConstant(double B0)
Definition: MultipoleT.cpp:396
double verticalApert_m
Definition: MultipoleT.h:296
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
constexpr double e
The value of .
Definition: Physics.h:40
double getScaleFactor(double x, double s)
Definition: MultipoleT.cpp:441
std::size_t maxOrder_m
Definition: MultipoleT.h:256
std::vector< double > transProfile_m
Definition: MultipoleT.h:265
Interface for basic beam line object.
Definition: ElementBase.h:128
PlanarArcGeometry & getGeometry() override
Definition: MultipoleT.cpp:548
void setCurvature(double)
Set curvature.
void truncate(std::size_t highestXorder)
A simple arc in the XZ plane.
Definition: rbendmap.h:8
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
void truncate(std::size_t highestXorder)
double getFn(std::size_t n, double x, double s)
Definition: MultipoleT.cpp:477
double horizApert_m
Definition: MultipoleT.h:297
bool setFringeField(double s0, double lambda_left, double lambda_right)
Definition: MultipoleT.cpp:243
double getBs(const Vector_t &R)
Definition: MultipoleT.cpp:319
Vector_t rotateFrameInverse(Vector_t &B)
Definition: MultipoleT.cpp:160
double entranceAngle_m
Definition: MultipoleT.h:284
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
void finalise() override
Definition: MultipoleT.cpp:90
double getRadius(double s)
Definition: MultipoleT.cpp:429
EMField & getField() override
Definition: MultipoleT.cpp:556
void initialise()
Definition: MultipoleT.cpp:532
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:79
PlanarArcGeometry planarArcGeometry_m
Definition: MultipoleT.h:267
MultipoleT(const std::string &name)
Definition: MultipoleT.cpp:40
BMultipoleField dummy
Definition: MultipoleT.h:299
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:810
void setMaxOrder(std::size_t maxOrder)
Definition: MultipoleT.cpp:212
double getFnDerivX(std::size_t n, double x, double s)
Definition: MultipoleT.cpp:449
double getFringeDeriv(int n, double s)
Definition: MultipoleT.cpp:353
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:200
double angle_m
Definition: MultipoleT.h:283
Vector_t transformCoords(const Vector_t &R)
Definition: MultipoleT.cpp:181
Vector_t rotateFrame(const Vector_t &R)
Definition: MultipoleT.cpp:140
double length_m
Definition: MultipoleT.h:282
void initialise(PartBunchBase< double, 3 > *, double &startField, double &endField) override
Definition: MultipoleT.cpp:537
double getNegTanh(double x, int n) const
Definition: Tanh.cpp:61
void setAperture(double vertAp, double horizAp)
Definition: MultipoleT.cpp:410
std::vector< double > getAperture() const
Definition: MultipoleT.cpp:415
double getTanh(double x, int n) const
Definition: Tanh.cpp:50
Abstract base class for electromagnetic fields.
Definition: EMField.h:188
bool variableRadius_m
Definition: MultipoleT.h:287
double getBz(const Vector_t &R)
Definition: MultipoleT.cpp:255
std::vector< double > getTransformation() const
std::vector< polynomial::RecursionRelationTwo > recursion_VarRadius_m
Definition: MultipoleT.h:260
virtual void visitMultipoleT(const MultipoleT &)=0
Apply the algorithm to an arbitrary Multipole.
void resizeX(const std::size_t &xDerivatives)
bool insideAperture(const Vector_t &R)
Definition: MultipoleT.cpp:172
void setTransProfile(std::size_t n, double Bn)
Definition: MultipoleT.cpp:235
endfieldmodel::Tanh fringeField_r
Definition: MultipoleT.h:252
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
std::size_t maxOrderX_m
Definition: MultipoleT.h:258
bool bends() const override
Definition: MultipoleT.cpp:544
const std::string name
double integrate(const double &a, const double &s0, const double &lambdaleft, const double &lambdaright, const int &n)
Definition: tanhDeriv.cpp:66
void getDimensions(double &zBegin, double &zEnd) const override
Definition: MultipoleT.cpp:407
void accept(BeamlineVisitor &visitor) const override
Definition: MultipoleT.cpp:403
bool apply(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
Definition: MultipoleT.cpp:94
double getFnDerivS(std::size_t n, double x, double s)
Definition: MultipoleT.cpp:463
ParticlePos_t & R
double getX0() const
Definition: Tanh.h:95
void resizeX(const std::size_t &xDerivatives)
ElementBase * clone() const override
Definition: MultipoleT.cpp:84
Interface for a single beam element.
Definition: Component.h:51
double getLambda() const
Definition: Tanh.h:92
virtual void setElementLength(double)
Set length.
Abstract algorithm.
Tps< T > tanh(const Tps< T > &x)
Hyperbolic tangent.
Definition: TpsMath.h:240
std::vector< double > getFringeLength() const
Definition: MultipoleT.cpp:422
double getTransDeriv(std::size_t n, double x)
Definition: MultipoleT.cpp:366
endfieldmodel::Tanh fringeField_l
Definition: MultipoleT.h:251
std::vector< polynomial::RecursionRelation > recursion_ConstRadius_m
Definition: MultipoleT.h:261
std::size_t transMaxOrder_m
Definition: MultipoleT.h:263