OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
OpalMultipoleT.cpp
Go to the documentation of this file.
1//
2// Class OpalMultipoleT
3// The Opal MultipoleT element.
4//
5// Copyright (c) 2017 - 2023, Titus Dascalu
6// Chris Rogers, STFC Rutherford Appleton Laboratory, Didcot, UK
7// Copyright (c) 2025, Jon Thompson
8// All rights reserved
9//
10// This file is part of OPAL.
11//
12// OPAL is free software: you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// You should have received a copy of the GNU General Public License
18// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
19//
21#include <iostream>
22#include <vector>
25
28 SIZE, "MULTIPOLET", "The \"MULTIPOLET\" element defines a combined function multipole.") {
29 // Attributes for a straight multipole
31 "TP",
32 "Array of multipolar field strengths b_k. The field generated in the "
33 "flat top is B = b_k x^k [T m^(-k)]");
34 itsAttr[LFRINGE] = Attributes::makeReal("LFRINGE", "The length of the left end field [m]");
35 itsAttr[RFRINGE] = Attributes::makeReal("RFRINGE", "The length of the right end field [m]");
36 itsAttr[HAPERT] = Attributes::makeReal("HAPERT", "The aperture width [m]");
37 itsAttr[VAPERT] = Attributes::makeReal("VAPERT", "The aperture height [m]");
39 "MAXFORDER", "Number of terms used in each fringe component", DefaultMAXFORDER);
41 "ROTATION", "Rotation angle about its axis for skew elements [rad]");
42 itsAttr[EANGLE] = Attributes::makeReal("EANGLE", "The entrance angle [rad]");
44 "BBLENGTH", "Distance between centre of magnet and entrance [m]");
45
46 // Further attributes for a constant radius curved multipole
48 "ANGLE", "The azimuthal angle of the magnet in ring [rad]", 0.0);
50 "MAXXORDER", "Number of terms used in polynomial expansions", DefaultMAXXORDER);
51
52 // Further attributes for a variable radius multipole
54 "VARRADIUS", "Set true if radius of magnet is variable", false);
56 "ENTRYOFFSET", "Longitudinal offset from standard entrance point [m]", 0.0);
57
58 // Time dependence attributes
60 ("SCALING_MODEL",
61 "The name of the time dependence model, which should give a scaling factor.");
62
64 setElement(new MultipoleT("MULTIPOLET"));
65}
66
68 : OpalElement(name, parent) {
70}
71
73 return new OpalMultipoleT(name, this);
74}
75
76void OpalMultipoleT::print(std::ostream& os) const {
78}
79
81 // Base class first
83 // Make some sanity checks
84 const auto maxFOrder = Attributes::getReal(itsAttr[MAXFORDER]);
85 if(maxFOrder < MinimumMAXFORDER) {
86 throw OpalException("OpalMultipoleT::Update",
87 "Attribute MAXFORDER must be >= 1.0");
88 }
89 if(maxFOrder > MaximumMAXFORDER) {
90 WARNMSG("OpalMultipoleT::Update, a value of "
91 << maxFOrder << " for MAXFORDER may lead to excessive run time");
92 }
93 const double rotation = Attributes::getReal(itsAttr[ROTATION]);
94 const double bendAngle = Attributes::getReal(itsAttr[ANGLE]);
95 if(bendAngle != 0.0 && rotation != 0.0) {
96 throw OpalException("OpalMultipoleT::Update",
97 "Non-zero ROTATION (a skew multipole) is only supported for straight magnets");
98 }
99 const bool varRadius = Attributes::getBool(itsAttr[VARRADIUS]);
100 if(varRadius && bendAngle != 0.0) {
101 WARNMSG("OpalMultipoleT::Update, the variable radius multipole magnet implementation is very slow");
102 }
103 const double entryOffset = Attributes::getReal(itsAttr[ENTRYOFFSET]);
104 if((!varRadius || bendAngle == 0.0) && entryOffset != 0.0) {
105 throw OpalException("OpalMultipoleT::Update",
106 "The ENTRYOFFSET is only supported for variable radius curved magnets");
107 }
108 // Convert pole strengths from Tesla to internal units which are kGauss
110 for(auto& i : tp) {
111 i *= Units::T2kG;
112 }
113 // Set the attributes
114 const auto length = Attributes::getReal(itsAttr[LENGTH]);
115 auto* multT = dynamic_cast<MultipoleT*>(getElement());
116 multT->setElementLength(length);
117 multT->setBendAngle(bendAngle, varRadius);
119 multT->setFringeField(
121 multT->setBoundingBoxLength(Attributes::getReal(itsAttr[BBLENGTH]));
122 multT->setTransProfile(tp);
123 multT->setMaxOrder(static_cast<size_t>(maxFOrder),
124 static_cast<size_t>(Attributes::getReal(itsAttr[MAXXORDER])));
125 multT->setRotation(rotation);
126 multT->setEntranceAngle(Attributes::getReal(itsAttr[EANGLE]));
127 multT->setEntryOffset(entryOffset);
128 multT->setScalingName(Attributes::getString(itsAttr[SCALING_MODEL]));
129 // Transmit "unknown" attributes.
131}
@ SIZE
Definition: IndexMap.cpp:174
#define WARNMSG(msg)
Definition: IpplInfo.h:349
const std::string name
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
Definition: Attributes.cpp:90
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
bool getBool(const Attribute &attr)
Return logical value.
Definition: Attributes.cpp:100
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
Definition: Attributes.cpp:289
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Definition: Attributes.cpp:294
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 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
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
void setElementLength(double length) override
Set the length of the magnet If straight-> Actual length If curved -> Arc length.
Definition: MultipoleT.cpp:232
virtual void updateUnknown(ElementBase *)
Transmit the `‘unknown’' (not known to OPAL) attributes to CLASSIC.
virtual void print(std::ostream &) const
Print the object.
virtual void update()
Update the embedded CLASSIC element.
void registerOwnership() const
OpalMultipoleT * clone(const std::string &name) override
Inherited copy constructor.
static constexpr double MaximumMAXFORDER
static constexpr double DefaultMAXXORDER
void update() override
Update the MultipoleT with new parameters from UI parser.
void print(std::ostream &os) const override
Print the object.
static constexpr double DefaultMAXFORDER
Default value for maximum series expansion order.
static constexpr double MinimumMAXFORDER
OpalMultipoleT()
Default constructor initialises UI parameters.
The base class for all OPAL exceptions.
Definition: OpalException.h:28