OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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 - 2021, 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 SIZE
50 };
51}
52
53
55 Definition(SIZE, "BEAM",
56 "The \"BEAM\" statement defines data for the particles "
57 "in a beam."),
58 reference(1.0, Physics::m_p * Units::GeV2eV, 1.0 * Units::GeV2eV) {
59
61 ("PARTICLE", "Name of particle to be used",
62 {"ELECTRON",
63 "POSITRON",
64 "MUON",
65 "PROTON",
66 "ANTIPROTON",
67 "DEUTERON",
68 "HMINUS",
69 "H2P",
70 "ALPHA",
71 "CARBON",
72 "XENON",
73 "URANIUM"});
74
76 ("MASS", "Particle rest mass [GeV]");
77
79 ("CHARGE", "Particle charge in proton charges");
80
82 ("ENERGY", "Particle energy [GeV]");
83
85 ("PC", "Particle momentum [GeV/c]");
86
88 ("GAMMA", "ENERGY / MASS");
89
91 ("BCURRENT", "Beam current [A] (all bunches)");
92
94 ("BFREQ", "Beam frequency [MHz] (all bunches)");
95
97 ("NPART", "Number of particles in bunch");
98
99 // Set up default beam.
100 Beam* defBeam = clone("UNNAMED_BEAM");
101 defBeam->builtin = true;
102
103 try {
104 defBeam->update();
105 OpalData::getInstance()->define(defBeam);
106 } catch(...) {
107 delete defBeam;
108 }
109
111}
112
113
114Beam::Beam(const std::string& name, Beam* parent):
115 Definition(name, parent),
116 reference(parent->reference)
117{}
118
119
121{}
122
123
125 // Can replace only by another BEAM.
126 return dynamic_cast<Beam*>(object) != 0;
127}
128
129
130Beam* Beam::clone(const std::string& name) {
131 return new Beam(name, this);
132}
133
134
136 update();
137 // Check if energy explicitly has been set with the BEAM command
138 if (!itsAttr[GAMMA] && !(itsAttr[ENERGY]) && !(itsAttr[PC])) {
139 throw OpalException("Beam::execute()",
140 "The energy hasn't been set. "
141 "Set either \"GAMMA\", \"ENERGY\" or \"PC\".");
142 }
143
144 if ( !(itsAttr[PARTICLE]) && (!itsAttr[MASS] || !(itsAttr[CHARGE])) ) {
145 throw OpalException("Beam::execute()",
146 "The beam particle hasn't been set. "
147 "Set either \"PARTICLE\" or \"MASS\" and \"CHARGE\".");
148 }
149
150 if (!(itsAttr[NPART])) {
151 throw OpalException("Beam::execute()", "\"NPART\" must be set.");
152 }
153}
154
155
156Beam* Beam::find(const std::string& name) {
157 Beam* beam = dynamic_cast<Beam*>(OpalData::getInstance()->find(name));
158
159 if (beam == 0) {
160 throw OpalException("Beam::find()", "Beam \"" + name + "\" not found.");
161 }
162
163 return beam;
164}
165
167 if (Attributes::getReal(itsAttr[NPART]) > 0) {
168 return (size_t)Attributes::getReal(itsAttr[NPART]);
169 } else {
170 throw OpalException("Beam::getNumberOfParticles()",
171 "Wrong number of particles in beam!. \"NPART\" must be positive");
172 }
173}
174
176 // Cast away const, to allow logically constant Beam to update.
177 const_cast<Beam*>(this)->update();
178 return reference;
179}
180
181double Beam::getCurrent() const {
182 return Attributes::getReal(itsAttr[BCURRENT]);
183}
184
185double Beam::getCharge() const {
186 return Attributes::getReal(itsAttr[CHARGE]);
187}
188
189double Beam::getMass() const {
190 return Attributes::getReal(itsAttr[MASS]);
191}
192
193std::string Beam::getParticleName() const {
194 return Attributes::getString(itsAttr[PARTICLE]);
195}
196
197double Beam::getFrequency() const {
198 return Attributes::getReal(itsAttr[BFREQ]);
199}
200
202 return std::copysign(1.0, getCharge()) * getCurrent()
205}
206
209}
210
212
213 if (itsAttr[PARTICLE]) {
214 std::string pName = getParticleName();
218 }
219
220 // Set up particle reference; convert all to eV for CLASSIC.
221 double mass = (itsAttr[MASS] ? getMass() : Physics::m_p) * Units::GeV2eV;
222 double charge = itsAttr[CHARGE] ? getCharge() : 1.0;
223
224 reference = PartData(charge, mass, 1.0);
225
226 if (itsAttr[GAMMA]) {
227 double gamma = Attributes::getReal(itsAttr[GAMMA]);
228 if (gamma > 1.0) {
229 reference.setGamma(gamma);
230 } else {
231 throw OpalException("Beam::update()",
232 "\"GAMMA\" should be greater than 1.");
233 }
234 } else if (itsAttr[ENERGY]) {
235 double energy = Attributes::getReal(itsAttr[ENERGY]) * Units::GeV2eV;
236 if (energy > reference.getM()) {
237 reference.setE(energy);
238 } else {
239 throw OpalException("Beam::update()",
240 "\"ENERGY\" should be greater than \"MASS\".");
241 }
242 } else if (itsAttr[PC]) {
243 double pc = Attributes::getReal(itsAttr[PC]) * Units::GeV2eV;
244 if (pc > 0.0) {
245 reference.setP(pc);
246 } else {
247 throw OpalException("Beam::update()",
248 "\"PC\" should be greater than 0.");
249 }
250 }
251
252 // Set default name.
253 if (getOpalName().empty()) setOpalName("UNNAMED_BEAM");
254}
255
256
257void Beam::print(std::ostream& os) const {
258 double charge = Attributes::getReal(itsAttr[CHARGE]);
259 os << "* ************* B E A M ************************************************************ " << std::endl;
260 os << "* BEAM " << getOpalName() << '\n'
261 << "* PARTICLE " << Attributes::getString(itsAttr[PARTICLE]) << '\n'
262 << "* REST MASS " << Attributes::getReal(itsAttr[MASS]) << " [GeV]\n"
263 << "* CHARGE " << (charge > 0 ? '+' : '-') << "e * " << std::abs(charge) << " \n"
264 << "* MOMENTUM " << reference.getP() << " [eV/c]\n"
265 << "* CURRENT " << Attributes::getReal(itsAttr[BCURRENT]) << " [A]\n"
266 << "* FREQUENCY " << Attributes::getReal(itsAttr[BFREQ]) << " [MHz]\n"
267 << "* NPART " << Attributes::getReal(itsAttr[NPART]) << '\n';
268 os << "* ********************************************************************************** " << std::endl;
269}
ParticleType
@ SIZE
Definition: IndexMap.cpp:174
PETE_TBTree< FnCopysign, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > copysign(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
const std::string name
Representation objects and parsers for attribute expressions.
Definition: Expressions.h:64
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
void setReal(Attribute &attr, double val)
Set real value.
Definition: Attributes.cpp:271
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
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
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
Particle reference data.
Definition: PartData.h:35
void setGamma(double gamma)
Set gamma.
Definition: PartData.cpp:83
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:114
void setP(double p)
Set reference momentum.
Definition: PartData.cpp:44
void setE(double E)
Set reference energy.
Definition: PartData.cpp:61
double getM() const
The constant mass per particle.
Definition: PartData.h:109
static double getParticleMass(const ParticleType &type)
static double getParticleCharge(const ParticleType &type)
static ParticleType getParticleType(const std::string &str)
Definition: Beam.h:31
std::string getParticleName() const
Return Particle's name.
Definition: Beam.cpp:193
double getCurrent() const
Return the beam current in A.
Definition: Beam.cpp:181
double getChargePerParticle() const
Charge per macro particle in C.
Definition: Beam.cpp:201
virtual void execute()
Check the BEAM data.
Definition: Beam.cpp:135
static Beam * find(const std::string &name)
Find named BEAM.
Definition: Beam.cpp:156
double getCharge() const
Return the charge number in elementary charge.
Definition: Beam.cpp:185
virtual Beam * clone(const std::string &name)
Make clone.
Definition: Beam.cpp:130
PartData reference
Definition: Beam.h:93
double getFrequency() const
Return the beam frequency in MHz.
Definition: Beam.cpp:197
size_t getNumberOfParticles() const
Return the number of (macro)particles.
Definition: Beam.cpp:166
double getMassPerParticle() const
Mass per macro particle in GeV/c^2.
Definition: Beam.cpp:207
double getMass() const
Return Particle's rest mass in GeV.
Definition: Beam.cpp:189
virtual void update()
Update the BEAM data.
Definition: Beam.cpp:211
void print(std::ostream &os) const
Print the object.
Definition: Beam.cpp:257
Beam()
Exemplar constructor.
Definition: Beam.cpp:54
const PartData & getReference() const
Return the embedded CLASSIC PartData.
Definition: Beam.cpp:175
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
Definition: Beam.cpp:124
virtual ~Beam()
Definition: Beam.cpp:120
The base class for all OPAL exceptions.
Definition: OpalException.h:28