OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
Beam.cpp
Go to the documentation of this file.
1//
2// Class Beam
3// The class for the OPAL BEAM command.
4// A BEAM definition is used by most physics commands to define the
5// particle charge and the reference momentum, together with some other data.
6//
7// Copyright (c) 200x - 2023, Paul Scherrer Institut, Villigen PSI, Switzerland
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//
20#include "Structure/Beam.h"
21
28#include "Physics/Physics.h"
29#include "Physics/Units.h"
31
32#include <cmath>
33#include <iterator>
34
35using namespace Expressions;
36
37// The attributes of class Beam.
38namespace {
39 enum {
40 PARTICLE, // The particle name
41 MASS, // The particle rest mass in GeV
42 CHARGE, // The particle charge in proton charges
43 ENERGY, // The particle energy in GeV
44 PC, // The particle momentum in GeV/c
45 GAMMA, // ENERGY / MASS
46 BCURRENT, // Beam current in A
47 BFREQ, // Beam frequency in MHz
48 NPART, // Number of particles per bunch
49 MOMENTUMTOLERANCE, // Fractional tolerance to momentum deviations
50 SIZE
51 };
52}
53
54
56 Definition(SIZE, "BEAM",
57 "The \"BEAM\" statement defines data for the particles "
58 "in a beam."),
59 reference(1.0, Physics::m_p * Units::GeV2eV, 1.0 * Units::GeV2eV) {
60
62 ("PARTICLE", "Name of particle to be used",
63 {"ELECTRON",
64 "POSITRON",
65 "MUON",
66 "PROTON",
67 "ANTIPROTON",
68 "DEUTERON",
69 "HMINUS",
70 "H2P",
71 "ALPHA",
72 "CARBON",
73 "XENON",
74 "URANIUM"});
75
77 ("MASS", "Particle rest mass [GeV]");
78
80 ("CHARGE", "Particle charge in proton charges");
81
83 ("ENERGY", "Particle energy [GeV]");
84
86 ("PC", "Particle momentum [GeV/c]");
87
89 ("GAMMA", "ENERGY / MASS");
90
92 ("BCURRENT", "Beam current [A] (all bunches)");
93
95 ("BFREQ", "Beam frequency [MHz] (all bunches)");
96
98 ("NPART", "Number of particles in bunch");
99
100 itsAttr[MOMENTUMTOLERANCE] = Attributes::makeReal
101 ("MOMENTUMTOLERANCE",
102 "Fractional tolerance to deviations in the distribution "
103 "compared to the reference data at initialisation (default=1e-2). "
104 "If MOMENTUMTOLERANCE<=0, no tolerance checking is done.", 1e-2);
105
106 // Set up default beam.
107 Beam* defBeam = clone("UNNAMED_BEAM");
108 defBeam->builtin = true;
109
110 try {
111 defBeam->update();
112 OpalData::getInstance()->define(defBeam);
113 } catch(...) {
114 delete defBeam;
115 }
116
118}
119
120
121Beam::Beam(const std::string& name, Beam* parent):
122 Definition(name, parent),
123 reference(parent->reference)
124{}
125
126
129
130
132 // Can replace only by another BEAM.
133 return dynamic_cast<Beam*>(object) != 0;
134}
135
136
137Beam* Beam::clone(const std::string& name) {
138 return new Beam(name, this);
139}
140
141
143 update();
144 // Check if energy explicitly has been set with the BEAM command
145 if (!itsAttr[GAMMA] && !(itsAttr[ENERGY]) && !(itsAttr[PC])) {
146 throw OpalException("Beam::execute()",
147 "The energy hasn't been set. "
148 "Set either \"GAMMA\", \"ENERGY\" or \"PC\".");
149 }
150
151 if ( !(itsAttr[PARTICLE]) && (!itsAttr[MASS] || !(itsAttr[CHARGE])) ) {
152 throw OpalException("Beam::execute()",
153 "The beam particle hasn't been set. "
154 "Set either \"PARTICLE\" or \"MASS\" and \"CHARGE\".");
155 }
156
157 if (!(itsAttr[NPART])) {
158 throw OpalException("Beam::execute()", "\"NPART\" must be set.");
159 }
160}
161
162
163Beam* Beam::find(const std::string& name) {
164 Beam* beam = dynamic_cast<Beam*>(OpalData::getInstance()->find(name));
165
166 if (beam == 0) {
167 throw OpalException("Beam::find()", "Beam \"" + name + "\" not found.");
168 }
169
170 return beam;
171}
172
174 if (Attributes::getReal(itsAttr[NPART]) > 0) {
175 return (size_t)Attributes::getReal(itsAttr[NPART]);
176 } else {
177 throw OpalException("Beam::getNumberOfParticles()",
178 "Wrong number of particles in beam!. \"NPART\" must be positive");
179 }
180}
181
183 // Cast away const, to allow logically constant Beam to update.
184 const_cast<Beam*>(this)->update();
185 return reference;
186}
187
188double Beam::getCurrent() const {
189 return Attributes::getReal(itsAttr[BCURRENT]);
190}
191
192double Beam::getCharge() const {
193 return Attributes::getReal(itsAttr[CHARGE]);
194}
195
196double Beam::getMass() const {
197 return Attributes::getReal(itsAttr[MASS]);
198}
199
200std::string Beam::getParticleName() const {
201 return Attributes::getString(itsAttr[PARTICLE]);
202}
203
204double Beam::getFrequency() const {
205 return Attributes::getReal(itsAttr[BFREQ]);
206}
207
209 return std::copysign(1.0, getCharge()) * getCurrent()
212}
213
216}
217
219
220 if (itsAttr[PARTICLE]) {
221 std::string pName = getParticleName();
225 }
226
227 // Set up particle reference; convert all to eV for CLASSIC.
228 double mass = (itsAttr[MASS] ? getMass() : Physics::m_p) * Units::GeV2eV;
229 double charge = itsAttr[CHARGE] ? getCharge() : 1.0;
230
231 reference = PartData(charge, mass, 1.0);
232
233 if (itsAttr[GAMMA]) {
234 double gamma = Attributes::getReal(itsAttr[GAMMA]);
235 if (gamma > 1.0) {
236 reference.setGamma(gamma);
237 } else {
238 throw OpalException("Beam::update()",
239 "\"GAMMA\" should be greater than 1.");
240 }
241 } else if (itsAttr[ENERGY]) {
242 double energy = Attributes::getReal(itsAttr[ENERGY]) * Units::GeV2eV;
243 if (energy > reference.getM()) {
244 reference.setE(energy);
245 } else {
246 throw OpalException("Beam::update()",
247 "\"ENERGY\" should be greater than \"MASS\".");
248 }
249 } else if (itsAttr[PC]) {
250 double pc = Attributes::getReal(itsAttr[PC]) * Units::GeV2eV;
251 if (pc > 0.0) {
252 reference.setP(pc);
253 } else {
254 throw OpalException("Beam::update()",
255 "\"PC\" should be greater than 0.");
256 }
257 }
258
259 double momentumTol = Attributes::getReal(itsAttr[MOMENTUMTOLERANCE]);
260 reference.setMomentumTolerance(momentumTol);
261
262 // Set default name.
263 if (getOpalName().empty()) setOpalName("UNNAMED_BEAM");
264}
265
266
267void Beam::print(std::ostream& os) const {
268 double charge = Attributes::getReal(itsAttr[CHARGE]);
269 os << "* ************* B E A M ************************************************************ " << std::endl;
270 os << "* BEAM " << getOpalName() << '\n'
271 << "* PARTICLE " << Attributes::getString(itsAttr[PARTICLE]) << '\n'
272 << "* REST MASS " << Attributes::getReal(itsAttr[MASS]) << " [GeV]\n"
273 << "* CHARGE " << (charge > 0 ? '+' : '-') << "e * " << std::abs(charge) << " \n"
274 << "* MOMENTUM " << reference.getP() << " [eV/c]\n";
275 if (Attributes::getReal(itsAttr[MOMENTUMTOLERANCE]) > 0) {
276 os << "* MOMENTUM TOLERANCE " << Attributes::getReal(itsAttr[MOMENTUMTOLERANCE]) << '\n';
277 }
278 os << "* CURRENT " << Attributes::getReal(itsAttr[BCURRENT]) << " [A]\n"
279 << "* FREQUENCY " << Attributes::getReal(itsAttr[BFREQ]) << " [MHz]\n"
280 << "* NPART " << Attributes::getReal(itsAttr[NPART]) << '\n';
281 os << "* ********************************************************************************** " << std::endl;
282}
@ SIZE
Definition IndexMap.cpp:174
const std::string name
Representation objects and parsers for attribute expressions.
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.
void setReal(Attribute &attr, double val)
Set real value.
std::string getString(const Attribute &attr)
Get string value.
Definition Air.h:27
constexpr double m_p
The proton rest mass in GeV.
Definition Physics.h:90
constexpr double q_e
The elementary charge in As.
Definition Physics.h:69
Definition Units.h:23
constexpr double MHz2Hz
Definition Units.h:113
constexpr double GeV2eV
Definition Units.h:68
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
static double getParticleMass(const ParticleType &type)
static double getParticleCharge(const ParticleType &type)
static ParticleType getParticleType(const std::string &str)
std::string getParticleName() const
Return Particle's name.
Definition Beam.cpp:200
double getCurrent() const
Return the beam current in A.
Definition Beam.cpp:188
double getChargePerParticle() const
Charge per macro particle in C.
Definition Beam.cpp:208
virtual void execute()
Check the BEAM data.
Definition Beam.cpp:142
static Beam * find(const std::string &name)
Find named BEAM.
Definition Beam.cpp:163
double getCharge() const
Return the charge number in elementary charge.
Definition Beam.cpp:192
virtual Beam * clone(const std::string &name)
Make clone.
Definition Beam.cpp:137
PartData reference
Definition Beam.h:93
double getFrequency() const
Return the beam frequency in MHz.
Definition Beam.cpp:204
size_t getNumberOfParticles() const
Return the number of (macro)particles.
Definition Beam.cpp:173
double getMassPerParticle() const
Mass per macro particle in GeV/c^2.
Definition Beam.cpp:214
double getMass() const
Return Particle's rest mass in GeV.
Definition Beam.cpp:196
virtual void update()
Update the BEAM data.
Definition Beam.cpp:218
void print(std::ostream &os) const
Print the object.
Definition Beam.cpp:267
Beam()
Exemplar constructor.
Definition Beam.cpp:55
const PartData & getReference() const
Return the embedded CLASSIC PartData.
Definition Beam.cpp:182
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
Definition Beam.cpp:131
virtual ~Beam()
Definition Beam.cpp:127
The base class for all OPAL exceptions.