OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
OpalMultipole.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: OpalMultipole.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.3.4.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: OpalMultipole
10 // The class of OPAL general multipoles.
11 //
12 // ------------------------------------------------------------------------
13 //
14 // $Date: 2002/12/09 15:06:07 $
15 // $Author: jsberg $
16 //
17 // ------------------------------------------------------------------------
18 
19 #include "Elements/OpalMultipole.h"
23 #include "Attributes/Attributes.h"
26 #include "Expressions/SValue.h"
27 #include "Expressions/SRefExpr.h"
28 #include "Physics/Physics.h"
29 #include "Utilities/Options.h"
30 #include <iostream>
31 #include <sstream>
32 #include <vector>
33 
34 
35 // Class OpalMultipole
36 // ------------------------------------------------------------------------
37 
39  OpalElement(SIZE, "MULTIPOLE",
40  "The \"MULTIPOLE\" element defines a thick multipole.\n"
41  "* If the length is non-zero, the strengths are per unit "
42  "length.\n* If the length is zero, the strengths are the "
43  "values integrated over the length.\n"
44  "* With zero length no synchrotron radiation can be calculated.") {
46  ("KN", "Normalised multipole strengths (normal) in m^(-k)");
48  ("DKN", "Normalised multipole strengths errors(normal) in m^(-k)");
50  ("KS", "Normalised multipole strengths (skew) in m^(-k)");
52  ("DKS", "Normalised multipole strength errors (skew) in m^(-k)");
53 
55 
56  setElement((new MultipoleRep("MULTIPOLE"))->makeWrappers());
57 }
58 
59 
60 OpalMultipole::OpalMultipole(const std::string &name, OpalMultipole *parent):
61  OpalElement(name, parent) {
62  setElement((new MultipoleRep(name))->makeWrappers());
63 }
64 
65 
67 {}
68 
69 
70 OpalMultipole *OpalMultipole::clone(const std::string &name) {
71  return new OpalMultipole(name, this);
72 }
73 
74 
75 void OpalMultipole::print(std::ostream &os) const {
77 }
78 
79 
80 void OpalMultipole::
83  const MultipoleWrapper *mult =
84  dynamic_cast<const MultipoleWrapper *>(base.removeAlignWrapper());
85  BMultipoleField field;
86 
87  // Get the desired field.
88  if(flag == ERROR_FLAG) {
89  field = mult->errorField();
90  } else if(flag == ACTUAL_FLAG) {
91  field = mult->getField();
92  } else if(flag == IDEAL_FLAG) {
93  field = mult->getDesign().getField();
94  }
95 
96  double length = getLength();
97  double scale = Physics::c / OpalData::getInstance()->getP0();
98  if(length != 0.0) scale *= length;
99 
100  for(int order = 1; order <= field.order(); ++order) {
101  std::ostringstream ss;
102  ss << (order - 1) << std::ends;
103  std::string orderString = ss.str();
104 
105  std::string normName = "K" + orderString + "L";
106  registerRealAttribute(normName)->setReal(scale * field.normal(order));
107 
108  std::string skewName = "K" + orderString + "SL";
109  registerRealAttribute(skewName)->setReal(scale * field.skew(order));
110 
111  scale *= double(order);
112  }
113 }
114 
115 
118 
119  // Magnet length.
120  MultipoleRep *mult =
121  dynamic_cast<MultipoleRep *>(getElement()->removeWrappers());
122  double length = getLength();
123  mult->setElementLength(length);
124 
125  // Field components.
126  BMultipoleField field;
127 
128  const std::vector<double> norm = Attributes::getRealArray(itsAttr[KN]);
129  std::vector<double> normErrors = Attributes::getRealArray(itsAttr[DKN]);
130  const std::vector<double> skew = Attributes::getRealArray(itsAttr[KS]);
131  std::vector<double> skewErrors = Attributes::getRealArray(itsAttr[DKS]);
132  int normSize = norm.size();
133  int skewSize = skew.size();
134  normErrors.resize(normSize, 0.0);
135  skewErrors.resize(skewSize, 0.0);
136  double factor = OpalData::getInstance()->getP0() / Physics::c;
137  int top = (normSize > skewSize) ? normSize : skewSize;
138 
139  for(int comp = 1; comp <= top; comp++) {
140  factor /= double(comp);
141  if(comp <= normSize) {
142  field.setNormalComponent(comp, norm[comp-1] * factor);
143  mult->setNormalComponent(comp, norm[comp-1], normErrors[comp-1]);
144  }
145  if(comp <= skewSize) {
146  field.setSkewComponent(comp, skew[comp-1] * factor);
147  mult->setSkewComponent(comp, skew[comp-1], skewErrors[comp-1]);
148  }
149  }
150 
151  mult->setField(field);
152 
153  // Transmit "unknown" attributes.
155 }
virtual ElementBase * removeAlignWrapper()
Remove align wrapper.
virtual const Multipole & getDesign() const
Get design corrector.
void setSkewComponent(int, double)
Set skew component.
Definition: Multipole.h:155
Interface for basic beam line object.
Definition: ElementBase.h:128
virtual void fillRegisteredAttributes(const ElementBase &, ValueFlag)
Fill in all registered attributes.
double normal(int) const
Get component.
virtual void setField(const BMultipoleField &field)
Set mulitpole field.
double getP0() const
Return value of global reference momentum.
Definition: OpalData.cpp:623
Representation for a general multipole.
Definition: MultipoleRep.h:31
virtual BMultipoleField & getField() override=0
Get multipole field.
ValueFlag
Switch for value desired on ATTLIST command.
Definition: OpalElement.h:71
void setNormalComponent(int n, double Bn)
Set component.
virtual BMultipoleField & getField()
Get field.
virtual ElementBase * removeWrappers()
Return the design element.
void setNormalComponent(int, double)
Set normal component.
Definition: Multipole.h:150
virtual void setElementLength(double length)
Set design length.
Definition: ElementBase.h:515
virtual double getLength() const
Return element length.
Representation of a perturbed multipole.
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
void setSkewComponent(int n, double Bn)
Set component.
The MULTIPOLE element.
Definition: OpalMultipole.h:28
static OpalData * getInstance()
Definition: OpalData.cpp:209
double skew(int) const
Get component.
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
Base class for all beam line elements.
Definition: OpalElement.h:41
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Definition: Attributes.cpp:258
OpalMultipole()
Exemplar constructor.
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:133
void registerOwnership() const
virtual void update()
Update the embedded CLASSIC element.
virtual OpalMultipole * clone(const std::string &name)
Make clone.
virtual void updateUnknown(ElementBase *)
Transmit the ``unknown&#39;&#39; (not known to OPAL) attributes to CLASSIC.
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:128
The magnetic field of a multipole.
virtual ~OpalMultipole()
const std::string name
virtual BMultipoleField & errorField() const
Get multipole field error.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
Definition: Attributes.cpp:253
virtual void print(std::ostream &) const
Print the object.
virtual void update()
Update the embedded CLASSIC multipole.
static AttCell * registerRealAttribute(const std::string &name)
Register a ``real&#39;&#39; element attribute.
int order() const
Return order.
virtual void fillRegisteredAttributes(const ElementBase &, ValueFlag)
Fill in all registered attributes.
virtual void print(std::ostream &) const
Print the object.
virtual void setReal(double)
Store the value.
Definition: AttCell.cpp:34