OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
OpalTrimCoil.cpp
Go to the documentation of this file.
1//
2// Class OpalTrimCoil
3// A TRIMCOIL definition is used to define a trim coil which can be applied
4// to a Cyclotron.
5//
6// Copyright (c) 2018 - 2019, Matthias Frey and Jochem Snuverink,
7// Paul Scherrer Institut, Villigen PSI, Switzerland
8// All rights reserved
9//
10// Implemented as part of the PhD thesis
11// "Precise Simulations of Multibunches in High Intensity Cyclotrons"
12// and the paper
13// "Matching of turn pattern measurements for cyclotrons using multiobjective optimization"
14// (https://doi.org/10.1103/PhysRevAccelBeams.22.064602)
15//
16// This file is part of OPAL.
17//
18// OPAL is free software: you can redistribute it and/or modify
19// it under the terms of the GNU General Public License as published by
20// the Free Software Foundation, either version 3 of the License, or
21// (at your option) any later version.
22//
23// You should have received a copy of the GNU General Public License
24// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
25//
27
34#include "Utility/Inform.h"
35
36#include <map>
37
38extern Inform *gmsg;
39
40// The attributes of class OpalTrimCoil.
41namespace {
42 enum {
43 TYPE, // The type of trim coil
44 COEFNUM,
45 COEFDENOM,
46 COEFNUMPHI,
47 COEFDENOMPHI,
48 BMAX,
49 PHIMIN,
50 PHIMAX,
51 RMIN,
52 RMAX,
53 SLPTC,
54 SIZE
55 };
56}
57
59 Definition(SIZE, "TRIMCOIL",
60 "The \"TRIMCOIL\" statement defines a trim coil."),
61 trimcoil_m(nullptr) {
63 ("TYPE", "Specifies the type of trim coil.",
64 {"PSI-BFIELD", "PSI-PHASE", "PSI-BFIELD-MIRRORED"});
65
67 ("COEFNUM", "Radial profile: list of polynomial coefficients for the numerator (not for PSI-BFIELD-MIRRORED)");
68
70 ("COEFDENOM", "Radial profile: list of polynomial coefficients for the denominator (not for PSI-BFIELD-MIRRORED)");
71
73 ("COEFNUMPHI", "Angular profile: list of polynomial coefficients for the numerator (not for PSI-BFIELD-MIRRORED)");
74
76 ("COEFDENOMPHI", "Angular profile: list of polynomial coefficients for the denominator (not for PSI-BFIELD-MIRRORED)");
77
79 ("BMAX", "Maximum magnetic field [T]");
80
82 ("PHIMIN", "Minimal azimuth [deg] (default 0)", 0.0);
83
85 ("PHIMAX", "Maximal azimuth [deg] (default 360)", 360.0);
86
88 ("RMIN", "Minimum radius [mm]");
89
91 ("RMAX", "Maximum radius [mm]");
92
94 ("SLPTC", "Slopes of the rising edge [1/mm] (for PSI-BFIELD-MIRRORED)");
95
97
98 OpalTrimCoil* defTrimCoil = clone("UNNAMED_TRIMCOIL");
99 defTrimCoil->builtin = true;
100 try {
101 defTrimCoil->update();
102 OpalData::getInstance()->define(defTrimCoil);
103 } catch(...) {
104 delete defTrimCoil;
105 }
106}
107
108
109OpalTrimCoil::OpalTrimCoil(const std::string& name, OpalTrimCoil* parent):
110 Definition(name, parent),
111 trimcoil_m(nullptr)
112{}
113
114
117
118
120 // Can replace only by another trim coil.
121 return dynamic_cast<OpalTrimCoil*>(object) != nullptr;
122}
123
124
126 return new OpalTrimCoil(name, this);
127}
128
129
131 update();
132}
133
134
136 OpalTrimCoil* trimcoil = dynamic_cast<OpalTrimCoil*>(OpalData::getInstance()->find(name));
137
138 if (trimcoil == nullptr) {
139 throw OpalException("OpalTrimCoil::find()", "OpalTrimCoil \"" + name + "\" not found.");
140 }
141 return trimcoil;
142}
143
144
146 // Set default name.
147 if (getOpalName().empty()) setOpalName("UNNAMED_TRIMCOIL");
148}
149
150
152 static const std::map<std::string, TrimCoilType> stringTrimCoilType_s = {
153 {"PSI-BFIELD", TrimCoilType::BFIELD},
154 {"PSI-PHASE", TrimCoilType::PHASE},
155 {"PSI-BFIELD-MIRRORED", TrimCoilType::BFIELDMIRRORED},
156 };
157
158 if (!itsAttr[TYPE]) {
159 throw OpalException("OpalTrimCoil::getTrimCoilType",
160 "The attribute \"TYPE\" isn't set for the \"TRIMCOIL\" statement");
161 } else {
162 return stringTrimCoilType_s.at(Attributes::getString(itsAttr[TYPE]));
163 }
164}
165
166
168 if (trimcoil_m != nullptr) return;
169
171
172 double bmax = Attributes::getReal(itsAttr[BMAX]);
173 double phimin = Attributes::getReal(itsAttr[PHIMIN]);
174 double phimax = Attributes::getReal(itsAttr[PHIMAX]);
175 double rmin = Attributes::getReal(itsAttr[RMIN]);
176 double rmax = Attributes::getReal(itsAttr[RMAX]);
177
179 std::vector<double> coefnum = Attributes::getRealArray(itsAttr[COEFNUM]);
180 std::vector<double> coefdenom = Attributes::getRealArray(itsAttr[COEFDENOM]);
181 std::vector<double> coefnumphi = Attributes::getRealArray(itsAttr[COEFNUMPHI]);
182 std::vector<double> coefdenomphi = Attributes::getRealArray(itsAttr[COEFDENOMPHI]);
183 if (type == TrimCoilType::BFIELD) {
184 trimcoil_m = std::unique_ptr<TrimCoilBFit> (new TrimCoilBFit (bmax, rmin, rmax, coefnum, coefdenom, coefnumphi, coefdenomphi));
185 } else { // TrimCoilType::PHASE
186 trimcoil_m = std::unique_ptr<TrimCoilPhaseFit> (new TrimCoilPhaseFit(bmax, rmin, rmax, coefnum, coefdenom, coefnumphi, coefdenomphi));
187 }
188 } else if (type == TrimCoilType::BFIELDMIRRORED) {
189 double slope = Attributes::getReal(itsAttr[SLPTC]);
190 trimcoil_m = std::unique_ptr<TrimCoilMirrored> (new TrimCoilMirrored(bmax, rmin, rmax, slope));
191 }
192
193 trimcoil_m->setAzimuth(phimin, phimax);
194
195 *gmsg << level3 << *this << endl;
196}
197
198
200 os << "* ******************************** T R I M C O I L ********************************\n"
201 << "* TRIMCOIL " << getOpalName() << '\n'
202 << "* TYPE " << Attributes::getString(itsAttr[TYPE]) << '\n';
203
206 printPolynom(os,itsAttr[COEFNUM]);
207 printPolynom(os,itsAttr[COEFDENOM]);
208 printPolynom(os,itsAttr[COEFNUMPHI]);
209 printPolynom(os,itsAttr[COEFDENOMPHI]);
210 }
211 os << "* BMAX " << Attributes::getReal(itsAttr[BMAX]) << '\n'
212 << "* RMIN " << Attributes::getReal(itsAttr[RMIN]) << '\n'
213 << "* RMAX " << Attributes::getReal(itsAttr[RMAX]) << '\n'
214 << "* PHIMIN " << Attributes::getReal(itsAttr[PHIMIN]) << '\n'
215 << "* PHIMAX " << Attributes::getReal(itsAttr[PHIMAX]) << '\n';
217 os << "* SLPTC " << Attributes::getReal(itsAttr[SLPTC]) << '\n';
218 }
219 os << "* *********************************************************************************" << endl;
220 return os;
221}
222
223void OpalTrimCoil::printPolynom(Inform& os, const Attribute& attr) const {
224 std::stringstream ss;
225 std::vector<double> coef = Attributes::getRealArray(attr);
226 for (std::size_t i = 0; i < coef.size(); ++i) {
227 ss << ((i > 0) ? "+ " : "") << coef[i]
228 << ((i > 0) ? (" * x^" + std::to_string(i)) : "") << ' ';
229 }
230 os << "* POLYNOM " << attr.getName() << " " << ss.str() << '\n';
231}
@ SIZE
Definition IndexMap.cpp:174
Inform * gmsg
Definition Main.cpp:70
Inform & endl(Inform &inf)
Definition Inform.cpp:42
Inform & level3(Inform &inf)
Definition Inform.cpp:47
const std::string name
double getReal(const Attribute &attr)
Return real value.
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
std::string getString(const Attribute &attr)
Get string value.
A representation of an Object attribute.
Definition Attribute.h:52
const std::string & getName() const
Return the attribute name.
Definition Attribute.cpp:92
Definition(int size, const char *name, const char *help)
Constructor for exemplars.
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition Object.cpp:191
const std::string & getOpalName() const
Return object name.
Definition Object.cpp:310
Object(int size, const char *name, const char *help)
Constructor for exemplars.
Definition Object.cpp:356
void setOpalName(const std::string &name)
Set object name.
Definition Object.cpp:331
std::vector< Attribute > itsAttr
The object attributes.
Definition Object.h:216
bool builtin
Built-in flag.
Definition Object.h:233
Object * find(const std::string &name)
Find entry.
Definition OpalData.cpp:571
static OpalData * getInstance()
Definition OpalData.cpp:196
void define(Object *newObject)
Define a new object.
Definition OpalData.cpp:489
Inform & print(Inform &os) const
OpalTrimCoil()
Exemplar constructor.
static OpalTrimCoil * find(const std::string &name)
Find named trim coil.
std::unique_ptr< TrimCoil > trimcoil_m
Actual implementation.
virtual ~OpalTrimCoil()
virtual void update()
Update the OpalTrimCoil data.
void initOpalTrimCoil()
Initialise implementation.
void printPolynom(Inform &os, const Attribute &attr) const
Helper method for printing.
virtual void execute()
Check the OpalTrimCoil data.
TrimCoilType getTrimCoilType() const
virtual OpalTrimCoil * clone(const std::string &name)
Make clone.
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
The base class for all OPAL exceptions.