OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
24 #include "Attributes/Attributes.h"
25 #include "Expressions/SAutomatic.h"
26 #include "Expressions/SRefExpr.h"
27 #include "Physics/Physics.h"
29 
30 #include <cmath>
31 #include <iterator>
32 
33 using namespace Expressions;
34 
35 
36 // The attributes of class Beam.
37 namespace {
38  enum {
39  PARTICLE, // The particle name
40  MASS, // The particle rest mass in GeV
41  CHARGE, // The particle charge in proton charges
42  ENERGY, // The particle energy in GeV
43  PC, // The particle momentum in GeV/c
44  GAMMA, // ENERGY / MASS
45  BCURRENT, // Beam current in A
46  BFREQ, // Beam frequency in MHz
47  NPART, // Number of particles per bunch
48  SIZE
49  };
50 }
51 
52 const double Beam::energy_scale = 1.0e9;
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 *energy_scale, 1.0 * energy_scale) {
59 
61  ("PARTICLE", "Name of particle to be used",
62  {"ELECTRON",
63  "PROTON",
64  "POSITRON",
65  "ANTIPROTON",
66  "CARBON",
67  "HMINUS",
68  "URANIUM",
69  "MUON",
70  "DEUTERON",
71  "XENON",
72  "H2P",
73  "ALPHA"});
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 
90  itsAttr[BCURRENT] = Attributes::makeReal
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 
114 Beam::Beam(const std::string& name, Beam* parent):
115  Definition(name, parent),
116  reference(parent->reference)
117 {}
118 
119 
121 {}
122 
123 
124 bool Beam::canReplaceBy(Object* object) {
125  // Can replace only by another BEAM.
126  return dynamic_cast<Beam*>(object) != 0;
127 }
128 
129 
130 Beam* 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. Set either GAMMA, ENERGY or PC.");
141  }
142 }
143 
144 
145 Beam* Beam::find(const std::string& name) {
146  Beam* beam = dynamic_cast<Beam*>(OpalData::getInstance()->find(name));
147 
148  if (beam == 0) {
149  throw OpalException("Beam::find()", "Beam \"" + name + "\" not found.");
150  }
151 
152  return beam;
153 }
154 
156  return (size_t)Attributes::getReal(itsAttr[NPART]);
157 }
158 
159 const PartData& Beam::getReference() const {
160  // Cast away const, to allow logically constant Beam to update.
161  const_cast<Beam*>(this)->update();
162  return reference;
163 }
164 
165 double Beam::getCurrent() const {
166  return Attributes::getReal(itsAttr[BCURRENT]);
167 }
168 
169 double Beam::getCharge() const {
170  return Attributes::getReal(itsAttr[CHARGE]);
171 }
172 
173 double Beam::getMass() const {
174  return Attributes::getReal(itsAttr[MASS]);
175 }
176 
177 std::string Beam::getParticleName() const {
178  return Attributes::getString(itsAttr[PARTICLE]);
179 }
180 
181 double Beam::getFrequency() const {
182  return Attributes::getReal(itsAttr[BFREQ]);
183 }
184 
186  return std::copysign(1.0, getCharge()) * getCurrent()
187  / (getFrequency() * 1.0e6)
189 }
190 
191 double Beam::getMassPerParticle() const {
192  return getMass() * getChargePerParticle() / (getCharge() * Physics::q_e);
193 }
194 
195 void Beam::update() {
196  // Find the particle name.
197  if (itsAttr[PARTICLE]) {
198  static const char *names[] = {
199  "ELECTRON",
200  "PROTON",
201  "POSITRON",
202  "ANTIPROTON",
203  "CARBON",
204  "HMINUS",
205  "URANIUM",
206  "MUON",
207  "DEUTERON",
208  "XENON",
209  "H2P",
210  "ALPHA"
211  };
212 
213  static const double masses[] = {
214  Physics::m_e,
215  Physics::m_p,
216  Physics::m_e,
217  Physics::m_p,
218  Physics::m_c,
220  Physics::m_u,
222  Physics::m_d,
226  };
227 
228  static const double charges[] = {
229  -1.0, 1.0, 1.0, -1.0, 12.0, -1.0, 35.0, -1.0, 1.0, 20.0, 1.0, 2.0
230  };
231  const unsigned int numParticleNames = std::end(names) - std::begin(names);
232 
233  std::string pName = Attributes::getString(itsAttr[PARTICLE]);
234  for (unsigned int i = 0; i < numParticleNames; ++ i) {
235  if (pName == names[i]) {
236  Attributes::setReal(itsAttr[MASS], masses[i]);
237  Attributes::setReal(itsAttr[CHARGE], charges[i]);
238  break;
239  }
240  }
241  }
242 
243  // Set up particle reference; convert all to eV for CLASSIC.
244  double mass =
246  double charge = itsAttr[CHARGE] ? Attributes::getReal(itsAttr[CHARGE]) : 1.0;
247  reference = PartData(charge, mass, 1.0);
248 
249  // Checks
250  if (itsAttr[GAMMA]) {
251  double gamma = Attributes::getReal(itsAttr[GAMMA]);
252  if (gamma > 1.0) {
253  reference.setGamma(gamma);
254  } else {
255  throw OpalException("Beam::update()",
256  "\"GAMMA\" should be greater than 1.");
257  }
258  } else if (itsAttr[ENERGY]) {
259  double energy = Attributes::getReal(itsAttr[ENERGY]) * energy_scale;
260  if (energy > reference.getM()) {
261  reference.setE(energy);
262  } else {
263  throw OpalException("Beam::update()",
264  "\"ENERGY\" should be greater than \"MASS\".");
265  }
266  } else if (itsAttr[PC]) {
267  double pc = Attributes::getReal(itsAttr[PC]) * energy_scale;
268  if (pc > 0.0) {
269  reference.setP(pc);
270  } else {
271  throw OpalException("Beam::update()",
272  "\"PC\" should be greater than 0.");
273  }
274  }
275 
276  // Set default name.
277  if (getOpalName().empty()) setOpalName("UNNAMED_BEAM");
278 }
279 
280 
281 //ff
282 double Beam::getGamma() const { //obtain value for gamma
283  return Attributes::getReal(itsAttr[GAMMA]);
284 }
285 
286 //ff
287 double Beam::getPC() const { //obtain value for PC
288  return Attributes::getReal(itsAttr[PC]);
289 }
290 
291 
292 void Beam::print(std::ostream& os) const {
293  double charge = Attributes::getReal(itsAttr[CHARGE]);
294  os << "* ************* B E A M ************************************************************ " << std::endl;
295  os << "* BEAM " << getOpalName() << '\n'
296  << "* PARTICLE " << Attributes::getString(itsAttr[PARTICLE]) << '\n'
297  << "* CURRENT " << Attributes::getReal(itsAttr[BCURRENT]) << " A\n"
298  << "* FREQUENCY " << Attributes::getReal(itsAttr[BFREQ]) << " MHz\n"
299  << "* CHARGE " << (charge > 0 ? '+' : '-') << "e * " << std::abs(charge) << " \n"
300  << "* REST MASS " << Attributes::getReal(itsAttr[MASS]) << " GeV\n"
301  << "* MOMENTUM " << Attributes::getReal(itsAttr[PC]) << '\n'
302  << "* NPART " << Attributes::getReal(itsAttr[NPART]) << '\n';
303  os << "* ********************************************************************************** " << std::endl;
304 }
@ SIZE
Definition: IndexMap.cpp:174
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TBTree< FnCopysign, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > copysign(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
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_xe
The xenon rest mass in GeV.
Definition: Physics.h:126
constexpr double m_alpha
The alpha particle rest mass in GeV.
Definition: Physics.h:129
constexpr double m_u
The uranium rest mass in GeV.
Definition: Physics.h:117
constexpr double m_p
The proton rest mass in GeV.
Definition: Physics.h:96
constexpr double m_h2p
The H2+ rest mass in GeV.
Definition: Physics.h:135
constexpr double q_e
The elementary charge in As.
Definition: Physics.h:75
constexpr double m_e
The electron rest mass in GeV.
Definition: Physics.h:84
constexpr double m_hm
The H- rest mass in GeV.
Definition: Physics.h:114
constexpr double m_mu
The muon rest mass in GeV.
Definition: Physics.h:120
constexpr double m_c
The carbon rest mass in GeV.
Definition: Physics.h:111
constexpr double m_d
The deuteron rest mass in GeV.
Definition: Physics.h:123
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
Particle reference data.
Definition: PartData.h:35
void setGamma(double gamma)
Set gamma.
Definition: PartData.cpp:83
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
Definition: Beam.h:32
std::string getParticleName() const
Return Particle's name.
Definition: Beam.cpp:177
double getCurrent() const
Return the beam current in A.
Definition: Beam.cpp:165
double getChargePerParticle() const
Charge per macro particle in C.
Definition: Beam.cpp:185
virtual void execute()
Check the BEAM data.
Definition: Beam.cpp:135
static Beam * find(const std::string &name)
Find named BEAM.
Definition: Beam.cpp:145
double getCharge() const
Return the charge number in elementary charge.
Definition: Beam.cpp:169
virtual Beam * clone(const std::string &name)
Make clone.
Definition: Beam.cpp:130
PartData reference
Definition: Beam.h:102
double getPC() const
Definition: Beam.cpp:287
double getFrequency() const
Return the beam frequency in MHz.
Definition: Beam.cpp:181
size_t getNumberOfParticles() const
Return the number of (macro)particles.
Definition: Beam.cpp:155
double getGamma() const
Definition: Beam.cpp:282
double getMassPerParticle() const
Mass per macro particle in GeV/c^2.
Definition: Beam.cpp:191
double getMass() const
Return Particle's rest mass in GeV.
Definition: Beam.cpp:173
virtual void update()
Update the BEAM data.
Definition: Beam.cpp:195
void print(std::ostream &os) const
Print the object.
Definition: Beam.cpp:292
Beam()
Exemplar constructor.
Definition: Beam.cpp:54
const PartData & getReference() const
Return the embedded CLASSIC PartData.
Definition: Beam.cpp:159
virtual bool canReplaceBy(Object *object)
Test if replacement is allowed.
Definition: Beam.cpp:124
virtual ~Beam()
Definition: Beam.cpp:120
static const double energy_scale
Definition: Beam.h:105
The base class for all OPAL exceptions.
Definition: OpalException.h:28