OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
54 : Definition(
55 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) {
60 "PARTICLE", "Name of particle to be used",
61 {"ELECTRON", "POSITRON", "MUON", "PROTON", "ANTIPROTON", "DEUTERON", "HMINUS", "H2P",
62 "ALPHA", "CARBON", "XENON", "URANIUM"});
63
64 itsAttr[MASS] = Attributes::makeReal("MASS", "Particle rest mass [GeV]");
65
66 itsAttr[CHARGE] = Attributes::makeReal("CHARGE", "Particle charge in proton charges");
67
68 itsAttr[ENERGY] = Attributes::makeReal("ENERGY", "Particle energy [GeV]");
69
70 itsAttr[PC] = Attributes::makeReal("PC", "Particle momentum [GeV/c]");
71
72 itsAttr[GAMMA] = Attributes::makeReal("GAMMA", "ENERGY / MASS");
73
74 itsAttr[BCURRENT] = Attributes::makeReal("BCURRENT", "Beam current [A] (all bunches)");
75
76 itsAttr[BFREQ] = Attributes::makeReal("BFREQ", "Beam frequency [MHz] (all bunches)");
77
78 itsAttr[NPART] = Attributes::makeReal("NPART", "Number of particles in bunch");
79
80 // Set up default beam.
81 Beam* defBeam = clone("UNNAMED_BEAM");
82 defBeam->builtin = true;
83
84 try {
85 defBeam->update();
86 OpalData::getInstance()->define(defBeam);
87 } catch (...) {
88 delete defBeam;
89 }
90
92}
93
94Beam::Beam(const std::string& name, Beam* parent)
95 : Definition(name, parent), reference(parent->reference) {
96}
97
100
102 // Can replace only by another BEAM.
103 return dynamic_cast<Beam*>(object) != 0;
104}
105
106Beam* Beam::clone(const std::string& name) {
107 return new Beam(name, this);
108}
109
111 update();
112 // Check if energy explicitly has been set with the BEAM command
113 if (!itsAttr[GAMMA] && !(itsAttr[ENERGY]) && !(itsAttr[PC])) {
114 throw OpalException(
115 "Beam::execute()",
116 "The energy hasn't been set. "
117 "Set either \"GAMMA\", \"ENERGY\" or \"PC\".");
118 }
119
120 if (!(itsAttr[PARTICLE]) && (!itsAttr[MASS] || !(itsAttr[CHARGE]))) {
121 throw OpalException(
122 "Beam::execute()",
123 "The beam particle hasn't been set. "
124 "Set either \"PARTICLE\" or \"MASS\" and \"CHARGE\".");
125 }
126
127 if (!(itsAttr[NPART])) {
128 throw OpalException("Beam::execute()", "\"NPART\" must be set.");
129 }
130}
131
132Beam* Beam::find(const std::string& name) {
133 Beam* beam = dynamic_cast<Beam*>(OpalData::getInstance()->find(name));
134
135 if (beam == 0) {
136 throw OpalException("Beam::find()", "Beam \"" + name + "\" not found.");
137 }
138
139 return beam;
140}
141
143 if (Attributes::getReal(itsAttr[NPART]) > 0) {
144 return (size_t)Attributes::getReal(itsAttr[NPART]);
145 } else {
146 throw OpalException(
147 "Beam::getNumberOfParticles()",
148 "Wrong number of particles in beam!. \"NPART\" must be positive");
149 }
150}
151
153 // Cast away const, to allow logically constant Beam to update.
154 const_cast<Beam*>(this)->update();
155 return reference;
156}
157
158double Beam::getCurrent() const {
159 return Attributes::getReal(itsAttr[BCURRENT]);
160}
161
162double Beam::getCharge() const {
163 return Attributes::getReal(itsAttr[CHARGE]);
164}
165
166double Beam::getMass() const {
167 return Attributes::getReal(itsAttr[MASS]);
168}
169
170double Beam::getMomentum() const {
171 return reference.getP()/1.e9;
172}
173
174std::string Beam::getParticleName() const {
175 return Attributes::getString(itsAttr[PARTICLE]);
176}
177
178double Beam::getFrequency() const {
179 return Attributes::getReal(itsAttr[BFREQ]);
180}
181
183 return std::copysign(1.0, getCharge()) * getCurrent() / (getFrequency() * Units::MHz2Hz)
185}
186
189}
190
192 if (itsAttr[PARTICLE]) {
193 std::string pName = getParticleName();
197 }
198
199 // Set up particle reference; convert all to eV for CLASSIC.
200 double mass = (itsAttr[MASS] ? getMass() : Physics::m_p) * Units::GeV2eV;
201 double charge = itsAttr[CHARGE] ? getCharge() : 1.0;
202
203 reference = PartData(charge, mass, 1.0);
204
205 if (itsAttr[GAMMA]) {
206 double gamma = Attributes::getReal(itsAttr[GAMMA]);
207 if (gamma > 1.0) {
208 reference.setGamma(gamma);
209 } else {
210 throw OpalException("Beam::update()", "\"GAMMA\" should be greater than 1.");
211 }
212 } else if (itsAttr[ENERGY]) {
213 double energy = Attributes::getReal(itsAttr[ENERGY]) * Units::GeV2eV;
214 if (energy > reference.getM()) {
215 reference.setE(energy);
216 } else {
217 throw OpalException("Beam::update()", "\"ENERGY\" should be greater than \"MASS\".");
218 }
219 } else if (itsAttr[PC]) {
220 double pc = Attributes::getReal(itsAttr[PC]) * Units::GeV2eV;
221 if (pc > 0.0) {
222 reference.setP(pc);
223 } else {
224 throw OpalException("Beam::update()", "\"PC\" should be greater than 0.");
225 }
226 }
227
228 // Set default name.
229 if (getOpalName().empty())
230 setOpalName("UNNAMED_BEAM");
231}
232
233void Beam::print(std::ostream& os) const {
234 double charge = Attributes::getReal(itsAttr[CHARGE]);
235 os << "* ************* B E A M ************************************************************ "
236 << std::endl;
237 os << "* BEAM " << getOpalName() << '\n'
238 << "* PARTICLE " << Attributes::getString(itsAttr[PARTICLE]) << '\n'
239 << "* REST MASS " << Attributes::getReal(itsAttr[MASS]) << " [GeV]\n"
240 << "* CHARGE " << (charge > 0 ? '+' : '-') << "e * " << std::abs(charge) << " \n"
241 << "* MOMENTUM " << reference.getP() << " [eV/c]\n"
242 << "* MOMENTUM " << Attributes::getReal(itsAttr[PC]) << " [GeV/c]\n"
243 << "* CURRENT " << Attributes::getReal(itsAttr[BCURRENT]) << " [A]\n"
244 << "* FREQUENCY " << Attributes::getReal(itsAttr[BFREQ]) << " [MHz]\n"
245 << "* NPART " << Attributes::getReal(itsAttr[NPART]) << '\n';
246 os << "* ********************************************************************************** "
247 << std::endl;
248}
@ SIZE
Definition IndexMap.cpp:173
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:189
const std::string & getOpalName() const
Return object name.
Definition Object.cpp:308
Object(int size, const char *name, const char *help)
Constructor for exemplars.
Definition Object.cpp:354
void setOpalName(const std::string &name)
Set object name.
Definition Object.cpp:329
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:563
static OpalData * getInstance()
Definition OpalData.cpp:195
void define(Object *newObject)
Define a new object.
Definition OpalData.cpp:486
Particle reference data.
Definition PartData.h:37
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:174
double getCurrent() const
Return the beam current in A.
Definition Beam.cpp:158
double getChargePerParticle() const
Charge per macro particle in C.
Definition Beam.cpp:182
virtual void execute()
Check the BEAM data.
Definition Beam.cpp:110
double getMomentum() const
Definition Beam.cpp:170
static Beam * find(const std::string &name)
Find named BEAM.
Definition Beam.cpp:132
double getCharge() const
Return the charge number in elementary charge.
Definition Beam.cpp:162
virtual Beam * clone(const std::string &name)
Make clone.
Definition Beam.cpp:106
PartData reference
Definition Beam.h:96
double getFrequency() const
Return the beam frequency in MHz.
Definition Beam.cpp:178
size_t getNumberOfParticles() const
Return the number of (macro)particles.
Definition Beam.cpp:142
double getMassPerParticle() const
Mass per macro particle in GeV/c^2.
Definition Beam.cpp:187
double getMass() const
Return Particle's rest mass in GeV.
Definition Beam.cpp:166
virtual void update()
Update the BEAM data.
Definition Beam.cpp:191
void print(std::ostream &os) const
Print the object.
Definition Beam.cpp:233
Beam()
Exemplar constructor.
Definition Beam.cpp:53
const PartData & getReference() const
Return the embedded CLASSIC PartData.
Definition Beam.cpp:152
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
Definition Beam.cpp:101
virtual ~Beam()
Definition Beam.cpp:98
The base class for all OPAL exceptions.