OPAL (Object Oriented Parallel Accelerator Library)  2024.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 //
26 #include "TrimCoils/OpalTrimCoil.h"
27 
29 #include "Attributes/Attributes.h"
30 #include "TrimCoils/TrimCoilBFit.h"
34 #include "Utility/Inform.h"
35 
36 #include <map>
37 
38 extern Inform *gmsg;
39 
40 // The attributes of class OpalTrimCoil.
41 namespace {
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 
69  itsAttr[COEFDENOM] = Attributes::makeRealArray
70  ("COEFDENOM", "Radial profile: list of polynomial coefficients for the denominator (not for PSI-BFIELD-MIRRORED)");
71 
72  itsAttr[COEFNUMPHI] = Attributes::makeRealArray
73  ("COEFNUMPHI", "Angular profile: list of polynomial coefficients for the numerator (not for PSI-BFIELD-MIRRORED)");
74 
75  itsAttr[COEFDENOMPHI] = Attributes::makeRealArray
76  ("COEFDENOMPHI", "Angular profile: list of polynomial coefficients for the denominator (not for PSI-BFIELD-MIRRORED)");
77 
78  itsAttr[BMAX] = Attributes::makeReal
79  ("BMAX", "Maximum magnetic field [T]");
80 
81  itsAttr[PHIMIN] = Attributes::makeReal
82  ("PHIMIN", "Minimal azimuth [deg] (default 0)", 0.0);
83 
84  itsAttr[PHIMAX] = Attributes::makeReal
85  ("PHIMAX", "Maximal azimuth [deg] (default 360)", 360.0);
86 
87  itsAttr[RMIN] = Attributes::makeReal
88  ("RMIN", "Minimum radius [mm]");
89 
90  itsAttr[RMAX] = Attributes::makeReal
91  ("RMAX", "Maximum radius [mm]");
92 
93  itsAttr[SLPTC] = Attributes::makeReal
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 
109 OpalTrimCoil::OpalTrimCoil(const std::string& name, OpalTrimCoil* parent):
110  Definition(name, parent),
111  trimcoil_m(nullptr)
112 {}
113 
114 
116 }
117 
118 
120  // Can replace only by another trim coil.
121  return dynamic_cast<OpalTrimCoil*>(object) != nullptr;
122 }
123 
124 
125 OpalTrimCoil* OpalTrimCoil::clone(const std::string& name) {
126  return new OpalTrimCoil(name, this);
127 }
128 
129 
131  update();
132 }
133 
134 
135 OpalTrimCoil* OpalTrimCoil::find(const std::string& name) {
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 
178  if (type == TrimCoilType::BFIELD || type == TrimCoilType::PHASE) {
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 
205  if (type == TrimCoilType::BFIELD || type == TrimCoilType::PHASE) {
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';
216  if (type == TrimCoilType::BFIELDMIRRORED) {
217  os << "* SLPTC " << Attributes::getReal(itsAttr[SLPTC]) << '\n';
218  }
219  os << "* *********************************************************************************" << endl;
220  return os;
221 }
222 
223 void 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 }
std::unique_ptr< TrimCoil > trimcoil_m
Actual implementation.
Definition: OpalTrimCoil.h:70
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:240
static OpalData * getInstance()
Definition: OpalData.cpp:196
bool builtin
Built-in flag.
Definition: Object.h:233
TrimCoilType getTrimCoilType() const
void setOpalName(const std::string &name)
Set object name.
Definition: Object.cpp:331
The base class for all OPAL objects.
Definition: Object.h:48
virtual void execute()
Check the OpalTrimCoil data.
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
void define(Object *newObject)
Define a new object.
Definition: OpalData.cpp:489
void initOpalTrimCoil()
Initialise implementation.
const std::string & getName() const
Return the attribute name.
Definition: Attribute.cpp:92
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Definition: Attributes.cpp:294
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
Definition: Attributes.cpp:289
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
virtual ~OpalTrimCoil()
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:191
The base class for all OPAL exceptions.
Definition: OpalException.h:28
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
virtual void update()
Update the OpalTrimCoil data.
void printPolynom(Inform &os, const Attribute &attr) const
Helper method for printing.
Definition: Inform.h:42
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:310
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
OpalTrimCoil()
Exemplar constructor.
const std::string name
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
The base class for all OPAL definitions.
Definition: Definition.h:30
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:571
static OpalTrimCoil * find(const std::string &name)
Find named trim coil.
virtual OpalTrimCoil * clone(const std::string &name)
Make clone.
SDDS1 &description type
Definition: test.stat:4
Inform * gmsg
Definition: Main.cpp:70
Inform & print(Inform &os) const
A representation of an Object attribute.
Definition: Attribute.h:52