OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
OpalRBend3D.cpp
Go to the documentation of this file.
1 //
2 // Class OpalRBend
3 // The parent class of all OPAL bending magnets.
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/OpalRBend3D.h"
19 #include "Attributes/Attributes.h"
20 #include "Structure/OpalWake.h"
22 #include "AbsBeamline/RBend3D.h"
24 
25 #include <iostream>
26 
27 
29  OpalElement(SIZE, "RBEND3D", "The \"RBEND3D\" element defines an RBEND with 3D field maps"),
30  owk_m(0),
31  parmatint_m(nullptr) {
33  ("ANGLE", "Upright dipole coefficient in m^(-1)");
35  ("K0", "Normal dipole coefficient in m^(-1)");
37  ("K0S", "Skew dipole coefficient in m^(-1)");
39  ("E1", "Entry pole face angle in rad", 0.0);
41  ("FMAPFN", "Filename for the fieldmap");
43  ("GAP", "Full gap height of the magnet (m)", 0.0);
45  ("HAPERT", "Bend plane magnet aperture (m)", 0.0);
47  ("DESIGNENERGY", "the mean energy of the particles in MeV");
48 
50 
51  setElement(new RBend3D("RBEND3D"));
52 }
53 
54 OpalRBend3D::OpalRBend3D(const std::string& name, OpalRBend3D* parent):
55  OpalElement(name, parent),
56  owk_m(0),
57  parmatint_m(nullptr)
58 {
59  setElement(new RBend3D(name));
60 }
61 
63  delete owk_m;
64  delete parmatint_m;
65 }
66 
67 OpalRBend3D* OpalRBend3D::clone(const std::string& name) {
68  return new OpalRBend3D(name, this);
69 }
70 
71 
74 
75  // Define geometry.
76  RBend3D* bend =
77  dynamic_cast<RBend3D*>(getElement());
78 
79  double length = Attributes::getReal(itsAttr[LENGTH]);
81  double e1 = Attributes::getReal(itsAttr[E1]);
82  double k0 =
84  length ? 2 * sin(angle / 2) / length : angle;
85  double k0s = itsAttr[K0S] ? Attributes::getReal(itsAttr[K0S]) : 0.0;
86 
87  // Set field amplitude or bend angle.
88  if (itsAttr[ANGLE]) {
89  if (bend->isPositioned() && angle < 0.0) {
90  e1 = -e1;
91  angle = -angle;
92 
93  Quaternion rotAboutZ(0, 0, 0, 1);
95  bend->releasePosition();
97  rotAboutZ * g2l.getRotation()));
98  bend->fixPosition();
99  }
100  bend->setBendAngle(angle);
101  } else {
102  bend->setFieldAmplitude(k0, k0s);
103  }
104 
105  if (itsAttr[FMAPFN]) {
107  } else if (bend->getName() != "RBEND3D") {
108  ERRORMSG(bend->getName() << ": No filename for a field map given." << endl);
109  throw OpalException("OpalRBend3D::update", bend->getName() + ": No filename for field map given");
110  }
111 
112  bend->setEntranceAngle(e1);
113 
114  // Energy in eV.
115  if (itsAttr[DESIGNENERGY] && Attributes::getReal(itsAttr[DESIGNENERGY]) != 0.0) {
116  bend->setDesignEnergy(Attributes::getReal(itsAttr[DESIGNENERGY]), false);
117  } else if (bend->getName() != "RBEND3D") {
118  throw OpalException("OpalRBend3D::update",
119  "RBend3D requires non-zero DESIGNENERGY");
120  }
121 
122  bend->setFullGap(Attributes::getReal(itsAttr[GAP]));
123 
124  if (itsAttr[HAPERT]) {
125  double hapert = Attributes::getReal(itsAttr[HAPERT]);
126  bend->setAperture(ApertureType::RECTANGULAR, std::vector<double>({hapert, hapert, 1.0}));
127  }
128 
129  if (itsAttr[LENGTH]) {
130  bend->setElementLength(Attributes::getReal(itsAttr[LENGTH]));
131  } else
132  bend->setElementLength(0.0);
133 
134  if (itsAttr[WAKEF] && itsAttr[DESIGNENERGY] && owk_m == nullptr) {
135  owk_m = (OpalWake::find(Attributes::getString(itsAttr[WAKEF])))->clone(getOpalName() + std::string("_wake"));
136  owk_m->initWakefunction(*bend);
137  bend->setWake(owk_m->wf_m);
138  }
139 
140  if (itsAttr[PARTICLEMATTERINTERACTION] && parmatint_m == nullptr) {
141  const std::string matterDescriptor = Attributes::getString(itsAttr[PARTICLEMATTERINTERACTION]);
143  parmatint_m = orig->clone(matterDescriptor);
146  }
147 
148  // Transmit "unknown" attributes.
150 }
151 
152 void OpalRBend3D::print(std::ostream& os) const {
153  OpalElement::print(os);
154 }
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:240
virtual void setBendAngle(double angle)
Definition: BendBase.h:87
WakeFunction * wf_m
Definition: OpalWake.h:56
void setFieldAmplitude(double k0, double k0s)
Definition: BendBase.cpp:56
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)
void setCSTrafoGlobal2Local(const CoordinateSystemTrafo &ori)
Definition: ElementBase.h:491
virtual OpalRBend3D * clone(const std::string &name)
Make clone.
Definition: OpalRBend3D.cpp:67
#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
OpalRBend3D()
Exemplar constructor.
Definition: OpalRBend3D.cpp:28
virtual void print(std::ostream &) const
Print the object.
Interface for solenoids.
Definition: RBend3D.h:39
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
void releasePosition()
Definition: ElementBase.h:546
virtual void setWake(WakeFunction *wf)
attach a wake field to the element
The base class for all OPAL exceptions.
Definition: OpalException.h:28
virtual void update()
Update the embedded CLASSIC bend.
Definition: OpalRBend3D.cpp:72
OpalWake * owk_m
Definition: OpalRBend3D.h:63
void initParticleMatterInteractionHandler(ElementBase &element)
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:332
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:120
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
virtual void setEntranceAngle(double entranceAngle)
Definition: BendBase.h:97
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
const std::string name
ParticleMatterInteraction * parmatint_m
Definition: OpalRBend3D.h:64
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.
virtual void setElementLength(double length)
Set design length.
Definition: ElementBase.h:419
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
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 ~OpalRBend3D()
Definition: OpalRBend3D.cpp:62
virtual void print(std::ostream &) const
Print the object.
virtual void update()
Update the embedded CLASSIC element.
void registerOwnership() const
void fixPosition()
Definition: ElementBase.h:551