OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
OpalRBend.cpp
Go to the documentation of this file.
1 //
2 // Class OpalRBend
3 // The RBEND element.
4 //
5 // Copyright (c) 200x - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved
7 //
8 // This file is part of OPAL.
9 //
10 // OPAL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17 //
18 #include "Elements/OpalRBend.h"
20 #include "Attributes/Attributes.h"
21 #include "BeamlineCore/RBendRep.h"
22 #include "Fields/BMultipoleField.h"
23 #include "Physics/Physics.h"
24 #include "Structure/OpalWake.h"
27 
29  OpalBend("RBEND",
30  "The \"RBEND\" element defines a rectangular bending magnet."),
31  owk_m(0),
32  parmatint_m(nullptr) {
33 
35 
36  setElement(new RBendRep("RBEND"));
37 }
38 
39 
40 OpalRBend::OpalRBend(const std::string& name, OpalRBend* parent):
41  OpalBend(name, parent),
42  owk_m(0),
43  parmatint_m(nullptr) {
44  setElement(new RBendRep(name));
45 }
46 
47 
49  delete owk_m;
50  delete parmatint_m;
51 }
52 
53 
54 OpalRBend* OpalRBend::clone(const std::string& name) {
55  return new OpalRBend(name, this);
56 }
57 
58 
61 
62  // Define geometry.
63  RBendRep* bend =
64  dynamic_cast<RBendRep*>(getElement());
65 
66  double length = Attributes::getReal(itsAttr[LENGTH]);
68  double e1 = Attributes::getReal(itsAttr[E1]);
69  RBendGeometry& geometry = bend->getGeometry();
70  geometry.setElementLength(length);
71  geometry.setBendAngle(angle);
72 
73  // Define number of slices for map tracking
75 
76  // Define pole face angles.
81 
82  // Define integration parameters.
85 
86  // Define field.
87  double factor = OpalData::getInstance()->getP0() / Physics::c;
88  BMultipoleField field;
89  double k0 =
91  length ? 2 * sin(angle / 2) / length : angle;
92  double k0s = itsAttr[K0S] ? Attributes::getReal(itsAttr[K0S]) : 0.0;
93  //JMJ 4/10/2000: above line replaced
94  // length ? angle / length : angle;
95  // to avoid closed orbit created by RBEND with default K0.
96  field.setNormalComponent(1, factor * k0);
97  field.setSkewComponent(1, factor * Attributes::getReal(itsAttr[K0S]));
98  field.setNormalComponent(2, factor * Attributes::getReal(itsAttr[K1]));
99  field.setSkewComponent(2, factor * Attributes::getReal(itsAttr[K1S]));
100  field.setNormalComponent(3, factor * Attributes::getReal(itsAttr[K2]) / 2.0);
101  field.setSkewComponent(3, factor * Attributes::getReal(itsAttr[K2S]) / 2.0);
102  field.setNormalComponent(4, factor * Attributes::getReal(itsAttr[K3]) / 6.0);
103  field.setSkewComponent(4, factor * Attributes::getReal(itsAttr[K3S]) / 6.0);
104  bend->setField(field);
105 
106  // Set field amplitude or bend angle.
107  if (itsAttr[ANGLE]) {
108  if (bend->isPositioned() && angle < 0.0) {
109  e1 = -e1;
110  angle = -angle;
111 
112  Quaternion rotAboutZ(0, 0, 0, 1);
114  bend->releasePosition();
116  rotAboutZ * g2l.getRotation()));
117  bend->fixPosition();
118  }
119  bend->setBendAngle(angle);
120  } else {
121  bend->setFieldAmplitude(k0, k0s);
122  }
123  bend->setEntranceAngle(e1);
124 
125  if (itsAttr[ROTATION])
126  throw OpalException("OpalRBend::update",
127  "ROTATION not supported any more; use PSI instead");
128 
129 
130  if (itsAttr[FMAPFN]) {
132  } else if (bend->getName() != "RBEND") {
133  ERRORMSG(bend->getName() << ": No filename for a field map given. "
134  "Will assume the default map "
135  "\"1DPROFILE1-DEFAULT\"."
136  << endl);
137  bend->setFieldMapFN("1DPROFILE1-DEFAULT");
138  }
139 
140  // Energy in eV.
141  if (itsAttr[DESIGNENERGY] && Attributes::getReal(itsAttr[DESIGNENERGY]) != 0.0) {
142  bend->setDesignEnergy(Attributes::getReal(itsAttr[DESIGNENERGY]), false);
143  } else if (bend->getName() != "RBEND") {
144  throw OpalException("OpalRBend::update",
145  "RBend requires non-zero DESIGNENERGY");
146  }
147 
148  double gap = Attributes::getReal(itsAttr[GAP]);
149  bend->setFullGap(gap);
150 
151  if (itsAttr[APERT])
152  throw OpalException("OpalRBend::update",
153  "APERTURE in RBEND not supported; use GAP and HAPERT instead");
154 
155  if (itsAttr[HAPERT]) {
156  double hapert = Attributes::getReal(itsAttr[HAPERT]);
157  bend->setAperture(ApertureType::RECTANGULAR, std::vector<double>({hapert, gap, 1.0}));
158  } else {
159  bend->setAperture(ApertureType::RECTANGULAR, std::vector<double>({0.5, gap, 1.0}));
160  }
161 
162  if (itsAttr[WAKEF] && itsAttr[DESIGNENERGY] && owk_m == nullptr) {
163  owk_m = (OpalWake::find(Attributes::getString(itsAttr[WAKEF])))->clone(getOpalName() + std::string("_wake"));
164  owk_m->initWakefunction(*bend);
165  bend->setWake(owk_m->wf_m);
166  }
167 
168  if (itsAttr[K1])
169  bend->setK1(Attributes::getReal(itsAttr[K1]));
170  else
171  bend->setK1(0.0);
172 
173  if (itsAttr[PARTICLEMATTERINTERACTION] && parmatint_m == nullptr) {
174  const std::string matterDescriptor = Attributes::getString(itsAttr[PARTICLEMATTERINTERACTION]);
176  parmatint_m = orig->clone(matterDescriptor);
179  }
180 
181  // Transmit "unknown" attributes.
183 }
virtual void update()
Update the embedded CLASSIC bend.
Definition: OpalRBend.cpp:59
static OpalData * getInstance()
Definition: OpalData.cpp:196
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
ParticleMatterInteraction * parmatint_m
Definition: OpalRBend.h:51
WakeFunction * wf_m
Definition: OpalWake.h:56
void setFieldAmplitude(double k0, double k0s)
Definition: BendBase.cpp:56
virtual void setSlices(double sl)
Set number of slices.
Definition: RBendRep.cpp:136
void setBendAngle(double angle)
Set angle.
The geometry for a RBend element.
Definition: RBendGeometry.h:41
item[EANGLE] Entrance edge angle(radians).\item[ROTATION] Rotation of the magnet about its central axis(radians
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
Definition: ElementBase.h:498
virtual void setParticleMatterInteraction(ParticleMatterInteractionHandler *spys)
virtual RBendGeometry & getGeometry()
Get geometry.
Definition: RBendRep.cpp:76
Base class for all bending magnets.
Definition: OpalBend.h:30
void setCSTrafoGlobal2Local(const CoordinateSystemTrafo &ori)
Definition: ElementBase.h:491
void setSkewComponent(int n, double Bn)
Set component.
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
void setFullGap(double)
Definition: BendBase.h:108
static ParticleMatterInteraction * find(const std::string &name)
Find named PARTICLEMATTERINTERACTION.
Vector_t getOrigin() const
void setNormalComponent(int n, double Bn)
Set component.
virtual void setEntryFaceRotation(double e1)
Set pole entry face rotation.
Definition: RBendRep.cpp:103
virtual void setField(const BMultipoleField &field)
Set field.
Definition: RBendRep.cpp:145
virtual void setEntranceAngle(double entranceAngle) override
Definition: RBend.cpp:124
virtual const std::string & getName() const
Get element name.
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:125
virtual OpalRBend * clone(const std::string &name)
Make clone.
Definition: OpalRBend.cpp:54
void releasePosition()
Definition: ElementBase.h:546
virtual void setExitFaceCurvature(double h2)
Set exit pole face curvature.
Definition: RBendRep.cpp:123
virtual void setWake(WakeFunction *wf)
attach a wake field to the element
The base class for all OPAL exceptions.
Definition: OpalException.h:28
OpalWake * owk_m
Definition: OpalRBend.h:50
void initParticleMatterInteractionHandler(ElementBase &element)
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:120
virtual void setExitFaceRotation(double e2)
Set exit pole face rotation.
Definition: RBendRep.cpp:107
void initWakefunction(const ElementBase &element)
Definition: OpalWake.cpp:147
bool isPositioned() const
Definition: ElementBase.h:556
void setFieldMapFN(std::string fileName)
Definition: BendBase.h:137
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:310
void setK1(double k1)
Set quadrupole field component.
Definition: Bend2D.h:305
double getP0() const
Return value of global reference momentum.
Definition: OpalData.cpp:575
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
const std::string name
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
ParticleMatterInteractionHandler * handler_m
virtual void setDesignEnergy(const double &energy, bool changeable=true)
Definition: BendBase.h:118
virtual ParticleMatterInteraction * clone(const std::string &name)
Make clone.
OpalRBend()
Exemplar constructor.
Definition: OpalRBend.cpp:28
virtual void setEntryFaceCurvature(double h1)
Set entry pole face curvature.
Definition: RBendRep.cpp:119
virtual void updateUnknown(ElementBase *)
Transmit the ``unknown&#39;&#39; (not known to OPAL) attributes to CLASSIC.
Quaternion getRotation() const
void setAperture(const ApertureType &type, const std::vector< double > &args)
Definition: ElementBase.h:519
virtual void setStepsize(double ds)
Set stepsize.
Definition: RBendRep.cpp:140
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
static OpalWake * find(const std::string &name)
Find named WAKE.
Definition: OpalWake.cpp:127
virtual void setElementLength(double length)
Set design length.
virtual ~OpalRBend()
Definition: OpalRBend.cpp:48
virtual void update()
Update the embedded CLASSIC element.
void registerOwnership() const
The magnetic field of a multipole.
void setNSlices(const std::size_t &nSlices)
Definition: Bend2D.cpp:1644
void fixPosition()
Definition: ElementBase.h:551
virtual void setBendAngle(double angle) override
Definition: RBend.cpp:119