OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
29
34#include "Physics/Units.h"
35
36extern Inform *gmsg;
37
39 OpalElement(SIZE, "SCALINGFFAMAGNET",
40 "The \"ScalingFFAMagnet\" element defines a FFA scaling magnet with zero or non-zero spiral angle.") {
42 ("B0", "The nominal dipole field of the magnet [T].");
43 itsAttr[R0] = Attributes::makeReal("R0", "Radial scale [m].");
45 "The scaling magnet field index.");
47 "Tangent of the spiral angle; set to 0 to make a radial sector magnet.");
49 "The maximum power in y that will be considered in the field expansion.");
51 "Names the end field model of the ring, giving dipole field along a line of "
52 "constant radius. If blank, uses the default 'END_LENGTH' and 'CENTRE_LENGTH' "
53 "parameters and a tanh model. If 'END_FIELD_MODEL' is not blank, Opal will seek "
54 "an END_FIELD_MODEL corresponding to the name defined in this string.");
56 "The end length of the spiral FFA [m].");
58 "Full height of the magnet. Particles moving more than height/2. off the midplane (either above or below) are out of the aperture [m].");
60 "The centre length of the spiral FFA [m].");
61 itsAttr[RADIAL_NEG_EXTENT] = Attributes::makeReal("RADIAL_NEG_EXTENT",
62 "Particles are considered outside the tracking region if radius is greater than R0-RADIAL_NEG_EXTENT [m].");
63 itsAttr[RADIAL_POS_EXTENT] = Attributes::makeReal("RADIAL_POS_EXTENT",
64 "Particles are considered outside the tracking region if radius is greater than R0+RADIAL_POS_EXTENT [m].");
66 "Determines the position of the central portion of the magnet field relative to the element start (default is 2*end_length). [m]");
68 "Offset to the end of the magnet, i.e. placement of the next element. Default is centre_length + 4*end_length.");
69 itsAttr[AZIMUTHAL_EXTENT] = Attributes::makeReal("AZIMUTHAL_EXTENT",
70 "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].");
72
73 ScalingFFAMagnet* magnet = new ScalingFFAMagnet("ScalingFFAMagnet");
74 magnet->setEndField(new endfieldmodel::Tanh(1., 1., 1));
75 setElement(magnet);
76}
77
78
80 OpalScalingFFAMagnet *parent) :
81 OpalElement(name, parent) {
83 magnet->setEndField(new endfieldmodel::Tanh(1., 1., 1));
84 setElement(magnet);
85}
86
87
89}
90
91
93 return new OpalScalingFFAMagnet(name, this);
94}
95
97 ScalingFFAMagnet *magnet = dynamic_cast<ScalingFFAMagnet*>(getElement());
98 // get centre length and end length in metres
100 double end_length = Attributes::getReal(itsAttr[END_LENGTH]);
101 double centre_length = Attributes::getReal(itsAttr[CENTRE_LENGTH])/2.;
102 endField->setLambda(end_length);
103 // x0 is the distance between B=0.5*B0 and B=B0 i.e. half the centre length
104 endField->setX0(centre_length);
105 std::shared_ptr<endfieldmodel::EndFieldModel> efm(endField);
106 std::string endName = "__opal_internal__"+getOpalName();
108 magnet->setEndFieldName(endName);
109}
110
112 if (!itsAttr[END_FIELD_MODEL]) {
113 return;
114 }
116 ScalingFFAMagnet *magnet = dynamic_cast<ScalingFFAMagnet*>(getElement());
117 magnet->setEndFieldName(name);
118}
119
121 ScalingFFAMagnet *magnet = dynamic_cast<ScalingFFAMagnet*>(getElement());
122
123 // use L = r0*theta; we define the magnet ito length for UI but ito angles
124 // internally; and use m as external default unit and mm internally
125 // get r0 in m
126 double r0 = Attributes::getReal(itsAttr[R0]);
127 magnet->setR0(r0*Units::m2mm);
128 // get B0 in T
130
131 // dimensionless quantities
135 magnet->setMaxOrder(maxOrder);
136
139 } else {
141 }
142 magnet->getEndField()->setMaximumDerivative(maxOrder+2);
143 // internally OpalScalingFFAMagnet uses radians, so we scale all lengths to
144 // radians.
145 magnet->getEndField()->rescale(1/r0);
146
147 // get rmin and rmax bounding box edge in mm
150 magnet->setRMin(rmin*Units::m2mm);
151 magnet->setRMax(rmax*Units::m2mm);
152 Vector_t centre(-r0*Units::m2mm, 0, 0);
153 magnet->setCentre(centre);
154
155 // we store maximum vertical displacement (which is half the height)
157 magnet->setVerticalExtent(height/2.);
158 // end of the magnet marks the point at which the next element starts
159 if (itsAttr[MAGNET_END]) {
161 throw OpalException("OpalScalingFFAMagnet::update()",
162 "MAGNET_END must be > 0.0");
163 }
164 double phi_end = Attributes::getReal(itsAttr[MAGNET_END])/r0;
165 magnet->setPhiEnd(phi_end);
166 } else {
167 magnet->setPhiEnd(-1); // flag for setupEndField
168 }
169
170 // get start of the magnet element in radians
171 // setPhiStart sets the position of the 0 point of the endFieldModel, which
172 // is typically the magnet centre
173 if (itsAttr[MAGNET_START]) {
175 throw OpalException("OpalScalingFFAMagnet::update()",
176 "MAGNET_START must be > 0.0");
177 }
178 double phi_start = Attributes::getReal(itsAttr[MAGNET_START])/r0;
179 magnet->setPhiStart(phi_start);
180 } else {
181 magnet->setPhiStart(-1); // flag for setupEndField
182 }
183 // get azimuthal extent in radians; this is just the bounding box
186 throw OpalException("OpalScalingFFAMagnet::update()",
187 "AZIMUTHAL_EXTENT must be > 0.0");
188 }
190 } else {
191 magnet->setAzimuthalExtent(-1); // flag for setupEndField
192 }
193 magnet->initialise();
194 setElement(magnet);
195
196}
@ SIZE
Definition: IndexMap.cpp:174
Inform * gmsg
Definition: Main.cpp:61
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
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:332
constexpr double m2mm
Definition: Units.h:26
constexpr double T2kG
Definition: Units.h:56
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:120
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:125
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:310
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
virtual void rescale(double scaleFactor)=0
static void setEndFieldModel(std::string name, std::shared_ptr< EndFieldModel > efm)
virtual void setMaximumDerivative(size_t n)=0
void setX0(double x0)
Definition: Tanh.h:110
void setLambda(double lambda)
Definition: Tanh.h:107
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)
void setEndField(endfieldmodel::EndFieldModel *endField)
void setMaxOrder(size_t maxOrder)
void setFieldIndex(double k)
void setRMax(double rMax)
void setEndFieldName(std::string name)
void setPhiEnd(double phiEnd)
endfieldmodel::EndFieldModel * getEndField() const
void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
void registerOwnership() const
virtual OpalScalingFFAMagnet * clone(const std::string &name)
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Definition: Inform.h:42