33#include <gsl/gsl_math.h>
49 planarArcGeometry_m(1., 1.),
54 variableRadius_m(false),
55 boundingBoxLength_m(0.0),
62 fringeField_l(right.fringeField_l),
63 fringeField_r(right.fringeField_r),
64 maxOrder_m(right.maxOrder_m),
65 maxOrderX_m(right.maxOrderX_m),
66 recursion_VarRadius_m(right.recursion_VarRadius_m),
67 recursion_ConstRadius_m(right.recursion_ConstRadius_m),
68 transMaxOrder_m(right.transMaxOrder_m),
69 transProfile_m(right.transProfile_m),
70 planarArcGeometry_m(right.planarArcGeometry_m),
71 length_m(right.length_m),
72 angle_m(right.angle_m),
73 entranceAngle_m(right.entranceAngle_m),
74 rotation_m(right.rotation_m),
75 variableRadius_m(right.variableRadius_m),
76 boundingBoxLength_m(right.boundingBoxLength_m),
77 verticalApert_m(right.verticalApert_m),
78 horizApert_m(right.horizApert_m),
123 double Bx =
getBx(R_prime);
124 double Bs =
getBs(R_prime);
125 B[0] = Bx * cos(theta) - Bs * sin(theta);
126 B[2] = Bx * sin(theta) + Bs * cos(theta);
127 B[1] =
getBz(R_prime);
131 for (
int i = 0; i < 3; i++) {
140 std::shared_ptr<ParticleContainer_t> pc =
RefPartBunch_m->getParticleContainer();
141 auto Rview = pc->R.getView();
142 auto Pview = pc->P.getView();
147 return apply(R(i), P(i), t, E, B);
162 R_pprime[1] = R_prime[1];
193 double alpha = atan(R[2] / (R[0] + radius));
195 X[0] = R[2] / sin(
alpha) - radius;
197 X[2] = radius *
alpha;
219 while (maxOrder >= N) {
228 while (maxOrder >= N) {
266 for (std::size_t n = 0; n <=
maxOrder_m; n++) {
268 for (std::size_t i = 0; i <= n; i++) {
272 f_n *= gsl_sf_pow_int(-1.0, n);
273 Bz += gsl_sf_pow_int(R[1], 2 * n) / gsl_sf_fact(2 * n) * f_n;
282 for (std::size_t n = 0; n <=
maxOrder_m; n++) {
283 double f_n =
getFn(n, R[0], R[2]);
284 Bz += gsl_sf_pow_int(R[1], 2 * n) / gsl_sf_fact(2 * n) * f_n;
297 for (std::size_t n = 0; n <=
maxOrder_m; n++) {
299 for (std::size_t i = 0; i <= n; i++) {
303 f_n *= gsl_sf_pow_int(-1.0, n);
304 Bx += gsl_sf_pow_int(R[1], 2 * n + 1) / gsl_sf_fact(2 * n + 1) * f_n;
313 for (std::size_t n = 0; n <=
maxOrder_m; n++) {
315 Bx += partialX_fn * gsl_sf_pow_int(R[1], 2 * n + 1) / gsl_sf_fact(2 * n + 1);
328 for (std::size_t n = 0; n <=
maxOrder_m; n++) {
330 for (std::size_t i = 0; i <= n; i++) {
334 f_n *= gsl_sf_pow_int(-1.0, n);
335 Bs += gsl_sf_pow_int(R[1], 2 * n + 1) / gsl_sf_fact(2 * n + 1) * f_n;
344 for (std::size_t n = 0; n <=
maxOrder_m; n++) {
346 Bs += partialS_fn * gsl_sf_pow_int(R[1], 2 * n + 1) / gsl_sf_fact(2 * n + 1);
373 for (std::size_t i = 1; i <= n; i++) {
377 temp[j] = temp[j + 1] * (j + 1);
387 func += temp[k] * gsl_sf_pow_int(x, k);
413 std::vector<double> temp(2, 0.0);
420 std::vector<double> temp(2, 0.0);
429 return centralRadius;
451 double stepSize = 1
e-3;
452 deriv += 1. *
getFn(n, x - 2. * stepSize, s);
453 deriv += -8. *
getFn(n, x - stepSize, s);
454 deriv += 8. *
getFn(n, x + stepSize, s);
455 deriv += -1. *
getFn(n, x + 2. * stepSize, s);
456 deriv /= 12 * stepSize;
465 double stepSize = 1
e-3;
466 deriv += 1. *
getFn(n, x, s - 2. * stepSize);
467 deriv += -8. *
getFn(n, x, s - stepSize);
468 deriv += 8. *
getFn(n, x, s + stepSize);
469 deriv += -1. *
getFn(n, x, s + 2. * stepSize);
470 deriv /= 12 * stepSize;
490 / gsl_sf_pow_int(rho, 2 * n - i - 2 * j);
493 func *= gsl_sf_pow_int(-1.0, n);
500 std::vector<double> fringeDerivatives;
509 * fringeDerivatives.at(j);
513 func *= gsl_sf_pow_int(-1.0, n) * S_0 * rho;
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
double integrate(const double &a, const double &s0, const double &lambdaleft, const double &lambdaright, const int &n)
Perform Cauchy's integral to find derivative.
constexpr double alpha
The fine structure constant, no dimension.
constexpr double e
The value of.
virtual void visitMultipoleT(const MultipoleT &)=0
Apply the algorithm to an arbitrary multipole.
Interface for a single beam element.
PartBunch_t * RefPartBunch_m
bool getFlagDeleteOnTransverseExit() const
Calculate the Tanh function (e.g.
double getNegTanh(double x, int n) const
Returns the value of tanh((x-x0)/lambda) or its derivative.
double getX0() const
Return x0 (flat top length)
double getLambda() const
Return lambda (end length)
double getTanh(double x, int n) const
Returns the value of tanh((x+x0)/lambda) or its derivative.
std::vector< double > transProfile_m
List of transverse profile coefficients.
void setDipoleConstant(double B0)
Set the dipole constant B_0.
std::size_t transMaxOrder_m
Highest power in given mid-plane field.
void setAperture(double vertAp, double horizAp)
Set the aperture dimensions This element only supports a rectangular aperture.
BMultipoleField dummy
Not implemented.
Vector_t< double, 3 > rotateFrameInverse(Vector_t< double, 3 > &B)
Inverse of the 1st rotation in rotateFrame() method Used to rotate B field back to global coordinate...
Vector_t< double, 3 > transformCoords(const Vector_t< double, 3 > &R)
Transform to Frenet-Serret coordinates for sector magnets.
double getTransDeriv(std::size_t n, double x)
Returns the value of the transverse field n-th derivative at x.
void setMaxOrder(std::size_t maxOrder)
Set the number of terms used in calculation of field components Maximum power of z in Bz is 2 * maxO...
std::vector< polynomial::RecursionRelationTwo > recursion_VarRadius_m
Objects for storing differential operator acting on Fn.
void initialise()
Initialises the geometry.
bool apply(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
Calculate the field at some arbitrary position If particle is outside field map true is returned,...
endfieldmodel::Tanh fringeField_r
endfieldmodel::Tanh fringeField_l
double getBz(const Vector_t< double, 3 > &R)
ElementBase * clone() const override
Inheritable copy constructor.
bool insideAperture(const Vector_t< double, 3 > &R)
Tests if inside the magnet.
EMField & getField() override
Return a dummy field value.
double getScaleFactor(double x, double s)
Returns the scale factor .
double getFnDerivX(std::size_t n, double x, double s)
Calculate partial derivative of fn wrt x using a 5-point finite difference formula Error of order st...
void accept(BeamlineVisitor &visitor) const override
Accept a beamline visitor.
double verticalApert_m
Assume rectangular aperture with these dimensions.
void getDimensions(double &zBegin, double &zEnd) const override
Not implemented.
double getFnDerivS(std::size_t n, double x, double s)
Calculate partial derivative of fn wrt s using a 5-point finite difference formuln Error of order ste...
std::size_t maxOrderX_m
Highest order of polynomial expansions in x.
double getRadius(double s)
Radius of curvature If radius of curvature is infinite, -1 is returned If radius is constant,...
std::vector< polynomial::RecursionRelation > recursion_ConstRadius_m
double getBx(const Vector_t< double, 3 > &R)
Get field component methods.
double length_m
Magnet parameters.
double getFn(std::size_t n, double x, double s)
Calculate fn(x, s) by expanding the differential operator (from Laplacian and scalar potential) in te...
bool setFringeField(double s0, double lambda_left, double lambda_right)
Set fringe field model Tanh model used here .
void initialise(PartBunch_t *, double &startField, double &endField) override
Initialise the MultipoleT.
void finalise() override
Finalise the MultipoleT - sets bunch to nullptr.
double getFringeDeriv(int n, double s)
Returns the value of the fringe field n-th derivative at s.
PlanarArcGeometry planarArcGeometry_m
Geometry.
bool bends() const override
Return true if dipole component not zero.
std::vector< double > getAperture() const
Get the aperture dimensions Returns a vector of 2 doubles.
void setTransProfile(std::size_t n, double Bn)
Set transverse profile T(x) T(x) = B_0 + B1 x + B2 x^2 + B3 x^3 + ...
std::size_t maxOrder_m
Field expansion parameters Number of terms in z expansion used in calculating field components.
bool variableRadius_m
Variable radius flag.
double boundingBoxLength_m
Distance between centre of magnet and entrance.
MultipoleT(const std::string &name)
Constructor.
Vector_t< double, 3 > rotateFrame(const Vector_t< double, 3 > &R)
Rotate frame for skew elements Consecutive rotations: 1st -> about central axis 2nd -> azimuthal rota...
double getBs(const Vector_t< double, 3 > &R)
PlanarArcGeometry & getGeometry() override
Return the cell geometry.
std::vector< double > getFringeLength() const
Return vector of 2 doubles [left fringe length, right fringelength].
std::vector< double > getTransformation() const
Returns a list of transformed coordinates.
void resizeX(const std::size_t &xDerivatives)
Change number of x-derivatives to xDerivatives.
void truncate(std::size_t highestXorder)
Truncate series in x at highestXorder.
void truncate(std::size_t highestXorder)
Truncate series in x at highestXorder.
void resizeX(const std::size_t &xDerivatives)
Change number of x-derivatives to xDerivatives.
A simple arc in the XZ plane.
void setCurvature(double)
Set curvature.
virtual void setElementLength(double)
Set length.
Abstract base class for electromagnetic fields.