OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 extern Inform *gmsg;
37 
38 // The attributes of class OpalTrimCoil.
39 namespace {
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 
72  itsAttr[COEFDENOMPHI] = Attributes::makeRealArray
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 
108 OpalTrimCoil::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 
124 OpalTrimCoil *OpalTrimCoil::clone(const std::string &name) {
125  return new OpalTrimCoil(name, this);
126 }
127 
128 
130  update();
131 }
132 
133 
134 OpalTrimCoil *OpalTrimCoil::find(const std::string &name) {
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 
205 void 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 }
@ SIZE
Definition: IndexMap.cpp:174
Inform * gmsg
Definition: Main.cpp:62
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:281
void setOpalName(const std::string &name)
Set object name.
Definition: Object.cpp:302
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:565
static OpalData * getInstance()
Definition: OpalData.cpp:195
void define(Object *newObject)
Define a new object.
Definition: OpalData.cpp:488
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