OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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(NULL) {
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(NULL) {
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]);
67  double angle = Attributes::getReal(itsAttr[ANGLE]);
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.
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(ElementBase::RECTANGULAR, std::vector<double>({hapert, gap, 1.0}));
158  } else {
159  bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({0.5, gap, 1.0}));
160  }
161 
162  if (itsAttr[WAKEF] && itsAttr[DESIGNENERGY] && owk_m == NULL) {
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])
170  else
171  bend->setK1(0.0);
172 
174  const std::string matterDescriptor = Attributes::getString(itsAttr[PARTICLEMATTERINTERACTION]);
176  parmatint_m = orig->clone(matterDescriptor);
179  }
180 
181  // Transmit "unknown" attributes.
183 }
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
const std::string name
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:120
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:125
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:281
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
double getP0() const
Return value of global reference momentum.
Definition: OpalData.cpp:569
static OpalData * getInstance()
Definition: OpalData.cpp:195
void setK1(double k1)
Set quadrupole field component.
Definition: Bend2D.h:305
void setNSlices(const std::size_t &nSlices)
Definition: Bend2D.cpp:1636
void setFieldMapFN(std::string fileName)
Definition: BendBase.h:137
virtual void setDesignEnergy(const double &energy, bool changeable=true)
Definition: BendBase.h:118
void setFullGap(double)
Definition: BendBase.h:108
void setFieldAmplitude(double k0, double k0s)
Definition: BendBase.cpp:56
virtual const std::string & getName() const
Get element name.
void fixPosition()
Definition: ElementBase.h:568
void setAperture(const ApertureType &type, const std::vector< double > &args)
Definition: ElementBase.h:536
bool isPositioned() const
Definition: ElementBase.h:573
void releasePosition()
Definition: ElementBase.h:563
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
Definition: ElementBase.h:515
virtual void setParticleMatterInteraction(ParticleMatterInteractionHandler *spys)
void setCSTrafoGlobal2Local(const CoordinateSystemTrafo &ori)
Definition: ElementBase.h:508
virtual void setWake(WakeFunction *wf)
attach a wake field to the element
virtual void setBendAngle(double angle) override
Definition: RBend.cpp:119
virtual void setEntranceAngle(double entranceAngle) override
Definition: RBend.cpp:124
Quaternion getRotation() const
virtual void setEntryFaceRotation(double e1)
Set pole entry face rotation.
Definition: RBendRep.cpp:103
virtual void setEntryFaceCurvature(double h1)
Set entry pole face curvature.
Definition: RBendRep.cpp:119
virtual void setSlices(double sl)
Set number of slices.
Definition: RBendRep.cpp:136
virtual void setStepsize(double ds)
Set stepsize.
Definition: RBendRep.cpp:140
virtual void setField(const BMultipoleField &field)
Set field.
Definition: RBendRep.cpp:145
virtual RBendGeometry & getGeometry()
Get geometry.
Definition: RBendRep.cpp:76
virtual void setExitFaceRotation(double e2)
Set exit pole face rotation.
Definition: RBendRep.cpp:107
virtual void setExitFaceCurvature(double h2)
Set exit pole face curvature.
Definition: RBendRep.cpp:123
The geometry for a RBend element.
Definition: RBendGeometry.h:41
void setBendAngle(double angle)
Set angle.
virtual void setElementLength(double length)
Set design length.
The magnetic field of a multipole.
void setNormalComponent(int n, double Bn)
Set component.
void setSkewComponent(int n, double Bn)
Set component.
Base class for all bending magnets.
Definition: OpalBend.h:30
@ SLICES
Definition: OpalBend.h:44
@ NSLICES
Definition: OpalBend.h:52
@ ROTATION
Definition: OpalBend.h:48
@ STEPSIZE
Definition: OpalBend.h:44
@ HAPERT
Definition: OpalBend.h:47
@ FMAPFN
Definition: OpalBend.h:45
@ DESIGNENERGY
Definition: OpalBend.h:49
@ ANGLE
Definition: OpalBend.h:36
@ PARTICLEMATTERINTERACTION
Definition: OpalElement.h:39
virtual void updateUnknown(ElementBase *)
Transmit the `‘unknown’' (not known to OPAL) attributes to CLASSIC.
virtual void update()
Update the embedded CLASSIC element.
void registerOwnership() const
virtual OpalRBend * clone(const std::string &name)
Make clone.
Definition: OpalRBend.cpp:54
OpalRBend()
Exemplar constructor.
Definition: OpalRBend.cpp:28
virtual void update()
Update the embedded CLASSIC bend.
Definition: OpalRBend.cpp:59
ParticleMatterInteraction * parmatint_m
Definition: OpalRBend.h:51
OpalWake * owk_m
Definition: OpalRBend.h:50
virtual ~OpalRBend()
Definition: OpalRBend.cpp:48
WakeFunction * wf_m
Definition: OpalWake.h:57
static OpalWake * find(const std::string &name)
Find named WAKE.
Definition: OpalWake.cpp:125
void initWakefunction(const ElementBase &element)
Definition: OpalWake.cpp:146
virtual ParticleMatterInteraction * clone(const std::string &name)
Make clone.
static ParticleMatterInteraction * find(const std::string &name)
Find named PARTICLEMATTERINTERACTION.
ParticleMatterInteractionHandler * handler_m
void initParticleMatterInteractionHandler(ElementBase &element)
The base class for all OPAL exceptions.
Definition: OpalException.h:28