OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
36extern Inform *gmsg;
37
38// The attributes of class OpalTrimCoil.
39namespace {
40 enum {
41 TYPE, // The type of trim coil
42 COEFNUM, //
43 COEFDENOM, //
44 COEFNUMPHI,
45 COEFDENOMPHI,
46 BMAX, //
47 PHIMIN,
48 PHIMAX,
49 RMIN, //
50 RMAX, //
51 SLPTC,
52 SIZE
53 };
54}
55
57 Definition(SIZE, "TRIMCOIL",
58 "The \"TRIMCOIL\" statement defines a trim coil."),
59 trimcoil_m(nullptr) {
61 ("TYPE", "Specifies the type of trim coil.", {"PSI-BFIELD", "PSI-PHASE", "PSI-BFIELD-MIRRORED"});
62
64 ("COEFNUM", "Radial profile: list of polynomial coefficients for the numerator (not for PSI-BFIELD-MIRRORED)");
65
67 ("COEFDENOM", "Radial profile: list of polynomial coefficients for the denominator (not for PSI-BFIELD-MIRRORED)");
68
70 ("COEFNUMPHI", "Angular profile: list of polynomial coefficients for the numerator (not for PSI-BFIELD-MIRRORED)");
71
73 ("COEFDENOMPHI", "Angular profile: list of polynomial coefficients for the denominator (not for PSI-BFIELD-MIRRORED)");
74
76 ("BMAX", "Maximum magnetic field in Tesla.");
77
79 ("PHIMIN", "Minimal azimuth [deg] (default 0)");
80
82 ("PHIMAX", "Maximal azimuth [deg] (default 360)");
83
85 ("RMIN", "Minimum radius [mm].");
86
88 ("RMAX", "Maximum radius [mm].");
89
91 ("SLPTC", "Slopes of the rising edge [1/mm] (for PSI-BFIELD-MIRRORED)");
92
93
95
96 OpalTrimCoil *defTrimCoil = clone("UNNAMED_TRIMCOIL");
97 defTrimCoil->builtin = true;
98
99 try {
100 defTrimCoil->update();
101 OpalData::getInstance()->define(defTrimCoil);
102 } catch(...) {
103 delete defTrimCoil;
104 }
105}
106
107
108OpalTrimCoil::OpalTrimCoil(const std::string &name, OpalTrimCoil *parent):
109 Definition(name, parent),
110 trimcoil_m(nullptr)
111{}
112
113
115}
116
117
119 // Can replace only by another trim coil.
120 return dynamic_cast<OpalTrimCoil *>(object) != nullptr;
121}
122
123
125 return new OpalTrimCoil(name, this);
126}
127
128
130 update();
131}
132
133
135 OpalTrimCoil *trimcoil = dynamic_cast<OpalTrimCoil *>(OpalData::getInstance()->find(name));
136
137 if (trimcoil == nullptr) {
138 throw OpalException("OpalTrimCoil::find()", "OpalTrimCoil \"" + name + "\" not found.");
139 }
140 return trimcoil;
141}
142
143
145 // Set default name.
146 if (getOpalName().empty()) setOpalName("UNNAMED_TRIMCOIL");
147}
148
149
151 if (trimcoil_m != nullptr) return;
152
153 std::string type = Attributes::getString(itsAttr[TYPE]);
154
155 double bmax = Attributes::getReal(itsAttr[BMAX]);
156 double phimin = Attributes::getReal(itsAttr[PHIMIN]);
157 double phimax = Attributes::getReal(itsAttr[PHIMAX]);
158 double rmin = Attributes::getReal(itsAttr[RMIN]);
159 double rmax = Attributes::getReal(itsAttr[RMAX]);
160
161 if (type == "PSI-BFIELD" || type == "PSI-PHASE") {
162 std::vector<double> coefnum = Attributes::getRealArray(itsAttr[COEFNUM]);
163 std::vector<double> coefdenom = Attributes::getRealArray(itsAttr[COEFDENOM]);
164 std::vector<double> coefnumphi = Attributes::getRealArray(itsAttr[COEFNUMPHI]);
165 std::vector<double> coefdenomphi = Attributes::getRealArray(itsAttr[COEFDENOMPHI]);
166 if (type == "PSI-BFIELD")
167 trimcoil_m = std::unique_ptr<TrimCoilBFit> (new TrimCoilBFit (bmax, rmin, rmax, coefnum, coefdenom, coefnumphi, coefdenomphi));
168 else // type == "PSI-PHASE"
169 trimcoil_m = std::unique_ptr<TrimCoilPhaseFit> (new TrimCoilPhaseFit(bmax, rmin, rmax, coefnum, coefdenom, coefnumphi, coefdenomphi));
170
171 } else if (type == "PSI-BFIELD-MIRRORED") {
172 double slope = Attributes::getReal(itsAttr[SLPTC]);
173 trimcoil_m = std::unique_ptr<TrimCoilMirrored> (new TrimCoilMirrored(bmax, rmin, rmax, slope));
174 }
175
176 trimcoil_m->setAzimuth(phimin, phimax);
177
178 *gmsg << level3 << *this << endl;
179}
180
182 os << "* ******************************** T R I M C O I L ********************************\n"
183 << "* TRIMCOIL " << getOpalName() << '\n'
184 << "* TYPE " << Attributes::getString(itsAttr[TYPE]) << '\n';
185
186 std::string type = Attributes::getString(itsAttr[TYPE]);
187 if (type == "PSI-BFIELD" || type == "PSI-PHASE") {
188 printPolynom(os,itsAttr[COEFNUM]);
189 printPolynom(os,itsAttr[COEFDENOM]);
190 printPolynom(os,itsAttr[COEFNUMPHI]);
191 printPolynom(os,itsAttr[COEFDENOMPHI]);
192 }
193
194 os << "* BMAX " << Attributes::getReal(itsAttr[BMAX]) << '\n'
195 << "* RMIN " << Attributes::getReal(itsAttr[RMIN]) << '\n'
196 << "* RMAX " << Attributes::getReal(itsAttr[RMAX]) << '\n';
197
198 if (Attributes::getString(itsAttr[TYPE]) == "PSI-BFIELD-MIRRORED") {
199 os << "* SLPTC " << Attributes::getReal(itsAttr[SLPTC]) << '\n';
200 }
201 os << "* *********************************************************************************" << endl;
202 return os;
203}
204
205void OpalTrimCoil::printPolynom(Inform& os, const Attribute& attr) const {
206 std::stringstream ss;
207 std::vector<double> coef = Attributes::getRealArray(attr);
208 for (std::size_t i = 0; i < coef.size(); ++i) {
209 ss << ((i > 0) ? "+ " : "") << coef[i]
210 << ((i > 0) ? (" * x^" + std::to_string(i)) : "") << ' ';
211 }
212 os << "* POLYNOM " << attr.getName() << " " << ss.str() << '\n';
213}
Inform * gmsg
Definition: Main.cpp:61
@ SIZE
Definition: IndexMap.cpp:174
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.
Definition: Attributes.cpp:252
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Definition: Attributes.cpp:409
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:240
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
boost::function< boost::tuple< double, bool >(arguments_t)> type
Definition: function.hpp:21
A representation of an Object attribute.
Definition: Attribute.h:52
const std::string & getName() const
Return the attribute name.
Definition: Attribute.cpp:92
The base class for all OPAL definitions.
Definition: Definition.h:30
The base class for all OPAL objects.
Definition: Object.h:48
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:191
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:310
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:566
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.
Definition: OpalTrimCoil.h:69
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.
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.
Definition: OpalException.h:28
Definition: Inform.h:42