OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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].");
67  registerRealAttribute("FIELD_INDEX");
68  registerRealAttribute("TAN_DELTA");
69  registerRealAttribute("MAX_Y_POWER");
70  registerRealAttribute("END_LENGTH");
71  registerRealAttribute("CENTRE_LENGTH");
72  registerRealAttribute("RADIAL_NEG_EXTENT");
73  registerRealAttribute("RADIAL_POS_EXTENT");
74  registerRealAttribute("HEIGHT");
75  registerRealAttribute("MAGNET_START");
76  registerRealAttribute("MAGNET_END");
77  registerRealAttribute("AZIMUTHAL_EXTENT");
79 
80  ScalingFFAMagnet* magnet = new ScalingFFAMagnet("ScalingFFAMagnet");
81  magnet->setEndField(new endfieldmodel::Tanh(1., 1., 1));
82  setElement(magnet->makeAlignWrapper());
83 }
84 
85 
87  OpalScalingFFAMagnet *parent) :
88  OpalElement(name, parent) {
89  ScalingFFAMagnet* magnet = new ScalingFFAMagnet(name);
90  magnet->setEndField(new endfieldmodel::Tanh(1., 1., 1));
91  setElement(magnet->makeAlignWrapper());
92 }
93 
94 
96 }
97 
98 
100  return new OpalScalingFFAMagnet(name, this);
101 }
102 
103 
107 }
108 
109 
111  ScalingFFAMagnet *magnet = dynamic_cast<ScalingFFAMagnet*>(getElement()->removeWrappers());
112 
113  // use L = r0*theta; we define the magnet ito length for UI but ito angles
114  // internally; and use m as external default unit and mm internally
115  double metres = 1e3;
116  // get r0 in m
117  double r0 = Attributes::getReal(itsAttr[R0]);
118  magnet->setR0(r0*metres);
119  // get B0 in T
121 
122  // dimensionless quantities
125  int maxOrder = floor(Attributes::getReal(itsAttr[MAX_Y_POWER]));
126  magnet->setMaxOrder(maxOrder);
127 
128  // get centre length and end length in radians
129  endfieldmodel::Tanh* endField = dynamic_cast<endfieldmodel::Tanh*>(magnet->getEndField());
130  double end_length = Attributes::getReal(itsAttr[END_LENGTH])/r0;
131  double centre_length = Attributes::getReal(itsAttr[CENTRE_LENGTH])/2./r0;
132  endField->setLambda(end_length);
133  // x0 is the distance between B=0.5*B0 and B=B0 i.e. half the centre length
134  endField->setX0(centre_length);
135  endField->setTanhDiffIndices(maxOrder+2);
136 
137  // get rmin and rmax bounding box edge in mm
138  double rmin = r0-Attributes::getReal(itsAttr[RADIAL_NEG_EXTENT]);
139  double rmax = r0+Attributes::getReal(itsAttr[RADIAL_POS_EXTENT]);
140  magnet->setRMin(rmin*metres);
141  magnet->setRMax(rmax*metres);
142  Vector_t centre(-r0*metres, 0, 0);
143  magnet->setCentre(centre);
144 
145  // we store maximum vertical displacement (which is half the height)
146  double height = Attributes::getReal(itsAttr[HEIGHT])*metres;
147  magnet->setVerticalExtent(height/2.);
148 
149  // get default length of the magnet element in radians
150  // total length is two end field lengths (e-folds) at each end plus a
151  // centre length
152  double defaultLength = (endField->getLambda()*4.+2.*endField->getX0());
153 
154  // get end of the magnet element in radians
155  if (itsAttr[MAGNET_END]) {
156  double phi_end = Attributes::getReal(itsAttr[MAGNET_END])/r0;
157  magnet->setPhiEnd(phi_end);
158  } else {
159  magnet->setPhiEnd(defaultLength);
160  }
161 
162  // get start of the magnet element in radians
163  // setPhiStart sets the position of the magnet centre relative to start (!)
164  if (itsAttr[MAGNET_START]) {
165  double phi_start = Attributes::getReal(itsAttr[MAGNET_START])/r0;
166  magnet->setPhiStart(phi_start+centre_length);
167  } else {
168  magnet->setPhiStart(defaultLength/2.);
169  }
170  // get azimuthal extent in radians; this is just the bounding box
171  double defaultExtent = (endField->getLambda()*5.+endField->getX0());
172  if (itsAttr[AZIMUTHAL_EXTENT]) {
173  magnet->setAzimuthalExtent(Attributes::getReal(itsAttr[AZIMUTHAL_EXTENT])/r0);
174  } else {
175  magnet->setAzimuthalExtent(defaultExtent);
176  }
177  magnet->initialise();
178  setElement(magnet->makeAlignWrapper());
179 
180 }
static void setTanhDiffIndices(size_t n)
Definition: Tanh.cpp:76
void setMaxOrder(size_t maxOrder)
Interface for basic beam line object.
Definition: ElementBase.h:128
virtual void fillRegisteredAttributes(const ElementBase &, ValueFlag)
Fill in all registered attributes.
void setPhiStart(double phiStart)
void setEndField(endfieldmodel::EndFieldModel *endField)
ValueFlag
Switch for value desired on ATTLIST command.
Definition: OpalElement.h:71
void setFieldIndex(double k)
virtual ElementBase * removeWrappers()
Return the design element.
Inform * gmsg
Definition: Main.cpp:21
void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
endfieldmodel::EndFieldModel * getEndField() const
void setRMax(double rMax)
void setLambda(double lambda)
Definition: Tanh.h:98
Base class for all beam line elements.
Definition: OpalElement.h:41
void setPhiEnd(double phiEnd)
void setTanDelta(double tanDelta)
void setRMin(double rMin)
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:133
void registerOwnership() const
void setAzimuthalExtent(double azimuthalExtent)
void setX0(double x0)
Definition: Tanh.h:101
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:128
virtual OpalScalingFFAMagnet * clone(const std::string &name)
const std::string name
virtual ElementBase * makeAlignWrapper()
Allow misalignment.
double getX0() const
Definition: Tanh.h:95
void setCentre(Vector_t centre)
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:217
double getLambda() const
Definition: Tanh.h:92
Definition: Inform.h:41
void setR0(double r0)
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:205
void setDipoleConstant(double Bz)
static AttCell * registerRealAttribute(const std::string &name)
Register a ``real&#39;&#39; element attribute.
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:816
void setVerticalExtent(double verticalExtent)
virtual void fillRegisteredAttributes(const ElementBase &, ValueFlag)