OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
OpalScalingFFAMagnet.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, 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 "Attributes/Attributes.h" // used?
29 #include "Utilities/OpalException.h" // used?
30 
31 #include "AbsBeamline/EndFieldModel/Tanh.h" // classic
32 #include "AbsBeamline/ScalingFFAMagnet.h" // classic
34 
35 extern Inform *gmsg;
36 
38  OpalElement(SIZE, "SCALINGFFAMAGNET",
39  "The \"ScalingFFAMagnet\" element defines a FFA scaling magnet with zero or non-zero spiral angle.") {
41  ("B0", "The nominal dipole field of the magnet [T].");
42  itsAttr[R0] = Attributes::makeReal("R0", "Radial scale [m].");
43  itsAttr[FIELD_INDEX] = Attributes::makeReal("FIELD_INDEX",
44  "The scaling magnet field index.");
45  itsAttr[TAN_DELTA] = Attributes::makeReal("TAN_DELTA",
46  "Tangent of the spiral angle; set to 0 to make a radial sector magnet.");
47  itsAttr[MAX_Y_POWER] = Attributes::makeReal("MAX_Y_POWER",
48  "The maximum power in y that will be considered in the field expansion.");
49  itsAttr[END_LENGTH] = Attributes::makeReal("END_LENGTH",
50  "The end length of the spiral FFA [m].");
52  "Full height of the magnet. Particles moving more than height/2. off the midplane (either above or below) are out of the aperture [m].");
53  itsAttr[CENTRE_LENGTH] = Attributes::makeReal("CENTRE_LENGTH",
54  "The centre length of the spiral FFA [m].");
55  itsAttr[RADIAL_NEG_EXTENT] = Attributes::makeReal("RADIAL_NEG_EXTENT",
56  "Particles are considered outside the tracking region if radius is greater than R0-RADIAL_NEG_EXTENT [m].");
57  itsAttr[RADIAL_POS_EXTENT] = Attributes::makeReal("RADIAL_POS_EXTENT",
58  "Particles are considered outside the tracking region if radius is greater than R0+RADIAL_POS_EXTENT [m].");
59  itsAttr[MAGNET_START] = Attributes::makeReal("MAGNET_START",
60  "Determines the position of the central portion of the magnet field relative to the element start (default is 2*end_length). [m]");
61  itsAttr[MAGNET_END] = Attributes::makeReal("MAGNET_END",
62  "Offset to the end of the magnet, i.e. placement of the next element. Default is centre_length + 4*end_length.");
63  itsAttr[AZIMUTHAL_EXTENT] = Attributes::makeReal("AZIMUTHAL_EXTENT",
64  "The field will be assumed zero if particles are more than AZIMUTHAL_EXTENT from the magnet centre (psi=0). Default is CENTRE_LENGTH/2.+5.*END_LENGTH [m].");
66 
67  ScalingFFAMagnet* magnet = new ScalingFFAMagnet("ScalingFFAMagnet");
68  magnet->setEndField(new endfieldmodel::Tanh(1., 1., 1));
69  setElement(magnet);
70 }
71 
72 
74  OpalScalingFFAMagnet *parent) :
75  OpalElement(name, parent) {
76  ScalingFFAMagnet* magnet = new ScalingFFAMagnet(name);
77  magnet->setEndField(new endfieldmodel::Tanh(1., 1., 1));
78  setElement(magnet);
79 }
80 
81 
83 }
84 
85 
87  return new OpalScalingFFAMagnet(name, this);
88 }
89 
90 
92  ScalingFFAMagnet *magnet = dynamic_cast<ScalingFFAMagnet*>(getElement());
93 
94  // use L = r0*theta; we define the magnet ito length for UI but ito angles
95  // internally; and use m as external default unit and mm internally
96  double metres = 1e3;
97  // get r0 in m
98  double r0 = Attributes::getReal(itsAttr[R0]);
99  magnet->setR0(r0*metres);
100  // get B0 in T
102 
103  // dimensionless quantities
106  int maxOrder = floor(Attributes::getReal(itsAttr[MAX_Y_POWER]));
107  magnet->setMaxOrder(maxOrder);
108 
109  // get centre length and end length in radians
110  endfieldmodel::Tanh* endField = dynamic_cast<endfieldmodel::Tanh*>(magnet->getEndField());
111  double end_length = Attributes::getReal(itsAttr[END_LENGTH])/r0;
112  double centre_length = Attributes::getReal(itsAttr[CENTRE_LENGTH])/2./r0;
113  endField->setLambda(end_length);
114  // x0 is the distance between B=0.5*B0 and B=B0 i.e. half the centre length
115  endField->setX0(centre_length);
116  endField->setTanhDiffIndices(maxOrder+2);
117 
118  // get rmin and rmax bounding box edge in mm
119  double rmin = r0-Attributes::getReal(itsAttr[RADIAL_NEG_EXTENT]);
120  double rmax = r0+Attributes::getReal(itsAttr[RADIAL_POS_EXTENT]);
121  magnet->setRMin(rmin*metres);
122  magnet->setRMax(rmax*metres);
123  Vector_t centre(-r0*metres, 0, 0);
124  magnet->setCentre(centre);
125 
126  // we store maximum vertical displacement (which is half the height)
127  double height = Attributes::getReal(itsAttr[HEIGHT])*metres;
128  magnet->setVerticalExtent(height/2.);
129 
130  // get default length of the magnet element in radians
131  // total length is two end field lengths (e-folds) at each end plus a
132  // centre length
133  double defaultLength = (endField->getLambda()*4.+2.*endField->getX0());
134 
135  // get end of the magnet element in radians
136  if (itsAttr[MAGNET_END]) {
137  double phi_end = Attributes::getReal(itsAttr[MAGNET_END])/r0;
138  magnet->setPhiEnd(phi_end);
139  } else {
140  magnet->setPhiEnd(defaultLength);
141  }
142 
143  // get start of the magnet element in radians
144  // setPhiStart sets the position of the magnet centre relative to start (!)
145  if (itsAttr[MAGNET_START]) {
146  double phi_start = Attributes::getReal(itsAttr[MAGNET_START])/r0;
147  magnet->setPhiStart(phi_start+centre_length);
148  } else {
149  magnet->setPhiStart(defaultLength/2.);
150  }
151  // get azimuthal extent in radians; this is just the bounding box
152  double defaultExtent = (endField->getLambda()*5.+endField->getX0());
153  if (itsAttr[AZIMUTHAL_EXTENT]) {
155  } else {
156  magnet->setAzimuthalExtent(defaultExtent);
157  }
158  magnet->initialise();
159  setElement(magnet);
160 
161 }
@ SIZE
Definition: IndexMap.cpp:174
Inform * gmsg
Definition: Main.cpp:62
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
const std::string name
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:240
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:120
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:125
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
static void setTanhDiffIndices(size_t n)
Definition: Tanh.cpp:76
void setX0(double x0)
Definition: Tanh.h:101
double getX0() const
Definition: Tanh.h:95
void setLambda(double lambda)
Definition: Tanh.h:98
double getLambda() const
Definition: Tanh.h:92
void setAzimuthalExtent(double azimuthalExtent)
void setRMin(double rMin)
void setCentre(Vector_t centre)
void setR0(double r0)
void setVerticalExtent(double verticalExtent)
void setTanDelta(double tanDelta)
void setDipoleConstant(double Bz)
void setPhiStart(double phiStart)
endfieldmodel::EndFieldModel * getEndField() const
void setEndField(endfieldmodel::EndFieldModel *endField)
void setMaxOrder(size_t maxOrder)
void setFieldIndex(double k)
void setRMax(double rMax)
void setPhiEnd(double phiEnd)
void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
void registerOwnership() const
virtual OpalScalingFFAMagnet * clone(const std::string &name)
Definition: Inform.h:42