OPALX (Object Oriented Parallel Accelerator Library for Exascale) MINIorX
OPALX
MultipoleTBase.h
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#ifndef CLASSIC_MULTIPOLETBASE_H
30#define CLASSIC_MULTIPOLETBASE_H
31
77#include <vector>
81
83
84class MultipoleTBase : public Component {
85public:
91 explicit MultipoleTBase(const std::string& name);
93 MultipoleTBase(const MultipoleTBase& right);
99 const EMField& getField() const;
109 bool apply(
110 const Vector_t<double, 3>& R, const Vector_t<double, 3>& P, const double& t,
121 bool apply(const size_t& i, const double& t, Vector_t<double, 3>& E, Vector_t<double, 3>& B);
127 void initialise(PartBunch_t*, double& startField, double& endField);
129 void finalise();
131 bool bends() const;
133 double getDipoleConstant() const;
135 void setDipoleConstant(const double& B0);
137 std::size_t getMaxOrder() const;
142 virtual void setMaxOrder(const std::size_t& maxOrder);
144 std::size_t getTransMaxOrder() const;
148 void setTransMaxOrder(const std::size_t& transMaxOrder);
154 void setTransProfile(const std::size_t& n, const double& Bn);
158 double getTransProfile(const std::size_t& n) const;
160 std::vector<double> getTransProfile() const;
169 bool setFringeField(const double& s0, const double& lambda_left, const double& lambda_right);
173 std::vector<double> getFringeLength() const;
177 void setEntranceAngle(const double& entranceAngle);
179 virtual void setBendAngle(const double& angle);
181 virtual double getBendAngle() const;
183 double getEntranceAngle() const;
188 void setLength(const double& length);
190 double getLength() const;
196 void setAperture(const double& vertAp, const double& horizAp);
200 std::vector<double> getAperture() const;
205 void setRotation(const double& rot);
207 double getRotation() const;
209 double getBoundingBoxLength() const;
213 void setBoundingBoxLength(const double& boundingBoxLength);
215 virtual void getDimensions(double& zBegin, double& zEnd) const;
216
217protected:
222 double getFringeDeriv(const std::size_t& n, const double& s);
229 double getTransDeriv(const std::size_t& n, const double& x);
230
231private:
232 // MultipoleTBase operator=(const MultipoleTBase &rhs);
233 // End fields
237 std::size_t maxOrder_m;
239 std::size_t transMaxOrder_m = 0;
241 std::vector<double> transProfile_m;
258 double length_m;
267 virtual double getBx(const Vector_t<double, 3>& R);
272 double getBz(const Vector_t<double, 3>& R);
277 virtual double getBs(const Vector_t<double, 3>& R);
286 bool insideAperture(const Vector_t<double, 3>& R);
290 virtual double getRadius(const double& s) = 0;
295 virtual double getScaleFactor(const double& x, const double& s) = 0;
303 double getFnDerivX(const std::size_t& n, const double& x, const double& s);
311 double getFnDerivS(const std::size_t& n, const double& x, const double& s);
318 virtual double getFn(const std::size_t& n, const double& x, const double& s) = 0;
319};
320
322 RefPartBunch_m = nullptr;
323}
325 const size_t& i, const double& t, Vector_t<double, 3>& E, Vector_t<double, 3>& B) {
326 std::shared_ptr<ParticleContainer_t> pc = RefPartBunch_m->getParticleContainer();
327 auto Rview = pc->R.getView();
328 auto Pview = pc->P.getView();
329
330 const Vector_t<double, 3> R = Rview(i);
331 const Vector_t<double, 3> P = Pview(i);
332
333 return apply(R(i), P(i), t, E, B);
334}
335inline void MultipoleTBase::setBendAngle(const double& /*angle*/) {
336}
337inline double MultipoleTBase::getBendAngle() const {
338 return 0.0;
339}
340inline void MultipoleTBase::setEntranceAngle(const double& entranceAngle) {
341 entranceAngle_m = entranceAngle;
342}
344 return (
345 std::abs(R[1]) <= (verticalApert_m / 2.0) && std::abs(R[0]) <= (horizontalApert_m / 2.0));
346}
347inline double MultipoleTBase::getEntranceAngle() const {
348 return entranceAngle_m;
349}
350inline double MultipoleTBase::getTransProfile(const std::size_t& n) const {
351 return transProfile_m[n];
352}
353inline std::vector<double> MultipoleTBase::getTransProfile() const {
354 return transProfile_m;
355}
357 return transProfile_m[0];
358}
359inline void MultipoleTBase::setMaxOrder(const std::size_t& maxOrder) {
360 maxOrder_m = maxOrder;
361}
362inline std::size_t MultipoleTBase::getMaxOrder() const {
363 return maxOrder_m;
364}
365inline std::size_t MultipoleTBase::getTransMaxOrder() const {
366 return transMaxOrder_m;
367}
368inline void MultipoleTBase::setTransMaxOrder(const std::size_t& transMaxOrder) {
369 transMaxOrder_m = transMaxOrder;
370 transProfile_m.resize(transMaxOrder + 1, 0.);
371}
372inline double MultipoleTBase::getRotation() const {
373 return rotation_m;
374}
375inline void MultipoleTBase::setRotation(const double& rot) {
376 rotation_m = rot;
377}
378inline void MultipoleTBase::setLength(const double& length) {
379 length_m = std::abs(length);
380}
381inline double MultipoleTBase::getLength() const {
382 return length_m;
383}
385 return boundingBoxLength_m;
386}
387inline void MultipoleTBase::setBoundingBoxLength(const double& boundingBoxLength) {
388 boundingBoxLength_m = boundingBoxLength;
389}
390inline void MultipoleTBase::setTransProfile(const std::size_t& n, const double& dTn) {
391 if (n > transMaxOrder_m) {
392 transMaxOrder_m = n;
393 transProfile_m.resize(n + 1, 0.0);
394 }
395 transProfile_m[n] = dTn;
396}
397inline void MultipoleTBase::setDipoleConstant(const double& B0) {
398 if (transMaxOrder_m < 1) {
399 transProfile_m.resize(1, 0.);
400 }
401 transProfile_m[0] = B0;
402}
403inline void MultipoleTBase::setAperture(const double& vertAp, const double& horizAp) {
404 verticalApert_m = vertAp;
405 horizontalApert_m = horizAp;
406}
407inline std::vector<double> MultipoleTBase::getAperture() const {
408 std::vector<double> temp(2, 0.0);
409 temp[0] = verticalApert_m;
410 temp[1] = horizontalApert_m;
411 return temp;
412}
413inline std::vector<double> MultipoleTBase::getFringeLength() const {
414 std::vector<double> temp(2, 0.0);
415 temp[0] = fringeField_l.getLambda();
416 temp[1] = fringeField_r.getLambda();
417 return temp;
418}
420 PartBunch_t* /*bunch*/, double& /*startField*/, double& /*endField*/) {
421}
422inline bool MultipoleTBase::bends() const {
423 return transProfile_m[0] != 0;
424}
426 return dummy;
427}
428inline const EMField& MultipoleTBase::getField() const {
429 return dummy;
430}
431inline void MultipoleTBase::getDimensions(double& /*zBegin*/, double& /*zEnd*/) const {
432}
433
434#endif
Interface for a single beam element.
Definition: Component.h:50
PartBunch_t * RefPartBunch_m
Definition: Component.h:185
Calculate the Tanh function (e.g.
Definition: Tanh.h:48
double getLambda() const
Return lambda (end length)
Definition: Tanh.h:101
~MultipoleTBase()
Destructor.
virtual double getRadius(const double &s)=0
Radius of curvature.
BMultipoleField dummy
Not implemented.
double getBoundingBoxLength() const
Get distance between centre of magnet and entrance.
std::size_t getTransMaxOrder() const
Get the maximum order in the given transverse profile.
virtual void setBendAngle(const double &angle)
Set the bending angle of the magnet.
bool insideAperture(const Vector_t< double, 3 > &R)
Tests if inside the magnet.
virtual double getFn(const std::size_t &n, const double &x, const double &s)=0
Calculate fn(x, s) by expanding the differential operator (from Laplacian and scalar potential) in te...
double boundingBoxLength_m
Distance between centre of magnet and entrance.
std::vector< double > getFringeLength() const
Return vector of 2 doubles [left fringe length, right fringelength].
virtual void transformCoords(Vector_t< double, 3 > &R)=0
Transform to Frenet-Serret coordinates for sector magnets.
void setRotation(const double &rot)
Set the angle of rotation of the magnet around its axis To make skew components.
virtual void transformBField(Vector_t< double, 3 > &B, const Vector_t< double, 3 > &R)=0
Transform B-field from Frenet-Serret coordinates to lab coordinates.
void setLength(const double &length)
Set the length of the magnet If straight-> Actual length If curved -> Arc length.
double getDipoleConstant() const
Get the dipole constant B_0.
endfieldmodel::Tanh fringeField_l
virtual void setMaxOrder(const std::size_t &maxOrder)
Set the number of terms used in calculation of field components Maximum power of z in Bz is 2 * maxO...
double verticalApert_m
Assume rectangular aperture with these dimensions.
double getRotation() const
Get the angle of rotation of the magnet around its axis.
std::vector< double > getAperture() const
Get the aperture dimensions Returns a vector of 2 doubles.
double getLength() const
Get the length of the magnet.
bool bends() const
Return true if dipole component not zero.
std::vector< double > transProfile_m
List of transverse profile coefficients.
std::size_t maxOrder_m
Number of terms in z expansion used in calculating field components.
double getEntranceAngle() const
Get the entrance angle.
virtual double getBx(const Vector_t< double, 3 > &R)
Returns the radial component of the field Returns zero far outside fringe field .
std::size_t getMaxOrder() const
Get the number of terms used in calculation of field components.
void initialise(PartBunch_t *, double &startField, double &endField)
Initialise the MultipoleT.
virtual double getBs(const Vector_t< double, 3 > &R)
Returns the component of the field along the central axis Returns zero far outside fringe field .
void finalise()
Finalise the MultipoleT - sets bunch to nullptr.
endfieldmodel::Tanh fringeField_r
std::vector< double > getTransProfile() const
Get all terms of transverse profile.
Vector_t< double, 3 > rotateFrame(const Vector_t< double, 3 > &R)
Rotate frame for skew elements Consecutive rotations: 1st -> about central axis 2nd -> azimuthal rot...
double getTransDeriv(const std::size_t &n, const double &x)
Returns the value of the transverse field n-th derivative at x Transverse field is a polynomial in x...
double getBz(const Vector_t< double, 3 > &R)
Returns the vertical field component Returns zero far outside fringe field .
MultipoleTBase()
Default constructor.
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)
Calculate the field at some arbitrary position If particle is outside field map true is returned,...
double entranceAngle_m
virtual double getScaleFactor(const double &x, const double &s)=0
Returns the scale factor .
void setEntranceAngle(const double &entranceAngle)
Set the entrance angle.
std::size_t transMaxOrder_m
Highest power in given mid-plane field.
double horizontalApert_m
void setTransProfile(const std::size_t &n, const double &Bn)
Set transverse profile T(x) T(x) = B_0 + B1 x + B2 x^2 + B3 x^3 + ...
double getFnDerivX(const std::size_t &n, const double &x, const double &s)
Calculate partial derivative of fn wrt x using a 5-point finite difference formula Error of order ste...
EMField & getField()
Return a dummy field value.
bool setFringeField(const double &s0, const double &lambda_left, const double &lambda_right)
Set fringe field model Tanh model used here .
void setDipoleConstant(const double &B0)
Set the dipole constant B_0.
double getFringeDeriv(const std::size_t &n, const double &s)
Returns the value of the fringe field n-th derivative at s.
virtual void getDimensions(double &zBegin, double &zEnd) const
Not implemented.
void setBoundingBoxLength(const double &boundingBoxLength)
Set distance between centre of magnet and enctrance.
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...
double getFnDerivS(const std::size_t &n, const double &x, const double &s)
Calculate partial derivative of fn wrt s using a 5-point finite difference formula Error of order ste...
void setAperture(const double &vertAp, const double &horizAp)
Set the aperture dimensions This element only supports a rectangular aperture.
double length_m
Magnet parameters.
void setTransMaxOrder(const std::size_t &transMaxOrder)
Set the maximum order in the given transverse profile.
virtual double getBendAngle() const
Get the bending angle of the magnet.
std::shared_ptr< ParticleContainer_t > getParticleContainer()
Definition: PartBunch.h:221
The magnetic field of a multipole.
Abstract base class for electromagnetic fields.
Definition: EMField.h:188