OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Mapper.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: Mapper.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.3 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: Mapper
10 // The visitor class for building a VpsMap for a beamline
11 // using a thin-lens approximation for all elements.
12 //
13 // ------------------------------------------------------------------------
14 // Class category: Algorithms
15 // ------------------------------------------------------------------------
16 //
17 // $Date: 2000/05/03 08:16:05 $
18 // $Author: mad $
19 //
20 // ------------------------------------------------------------------------
21 
22 #include "Algorithms/Mapper.h"
25 #include "Fields/BMultipoleField.h"
26 #include "FixedAlgebra/FTpsMath.h"
27 #include "FixedAlgebra/LinearMap.h"
29 #include "FixedAlgebra/FTps.h"
30 
33 
34 
35 // Class Mapper
36 // ------------------------------------------------------------------------
37 
38 Mapper::Mapper(const Beamline &beamline, const PartData &reference,
39  bool backBeam, bool backTrack):
40  AbstractMapper(beamline, reference, backBeam, backTrack),
41  itsMap()
42 {}
43 
44 
46 {}
47 
48 
51 }
52 
53 
56 }
57 
58 
59 void Mapper::getMap(Map &map) const {
60  map = itsMap;
61 }
62 
63 
65  itsMap = Map(map);
66 }
67 
68 
70  itsMap = Map(map);
71 }
72 
73 
74 void Mapper::setMap(const Map &map) {
75  itsMap = map;
76 }
77 
78 
79 void Mapper::visitComponent(const Component &comp) {
81 }
82 
83 
84 void Mapper::visitPatch(const Patch &patch) {
85  Euclid3D transform = patch.getPatch();
86  if(back_path) transform = Inverse(transform);
87  applyTransform(transform);
88 }
89 
90 
92  if(wrap.offset().isIdentity()) {
93  wrap.getElement()->accept(*this);
94  } else {
95  Euclid3D e1 = wrap.getEntranceTransform();
96  Euclid3D e2 = wrap.getExitTransform();
97 
98  if(back_path) {
99  // Tracking right to left.
100  applyTransform(Inverse(e2));
101  wrap.getElement()->accept(*this);
102  applyTransform(Inverse(e1));
103  } else {
104  // Tracking left to right.
105  applyTransform(e1);
106  wrap.getElement()->accept(*this);
107  applyTransform(e2);
108  }
109  }
110 }
111 
112 
115 }
116 
117 
118 void Mapper::applyDrift(double length) {
119  double kin = itsReference.getM() / itsReference.getP();
120  double refTime = length / itsReference.getBeta();
121 
122  Series px = itsMap[PX];
123  Series py = itsMap[PY];
124  Series pt = itsMap[PT] + 1.0;
125  Series pz = sqrt(pt * pt - px * px - py * py);
126  Series E = sqrt(pt * pt + kin * kin);
127 
128  itsMap[X] += length * px / pz;
129  itsMap[Y] += length * py / pz;
130  itsMap[T] += pt * (refTime / E - length / pz);
131 }
132 
133 
135 (const BMultipoleField &field, double scale) {
136  int order = field.order();
137 
138  if(order > 0) {
139  Series x = itsMap[X];
140  Series y = itsMap[Y];
141  Series kx = + field.normal(order);
142  Series ky = - field.skew(order);
143 
144  while(--order > 0) {
145  Series kxt = x * kx - y * ky;
146  Series kyt = x * ky + y * kx;
147  kx = kxt + field.normal(order);
148  ky = kyt - field.skew(order);
149  }
150 
151  itsMap[PX] -= kx * scale;
152  itsMap[PY] += ky * scale;
153  }
154 }
155 
156 
158 (const BMultipoleField &field, double scale, double h) {
159  Series As = buildSBendVectorPotential(field, h) * scale;
160 
161  // These substitutions work because As depends on x and y only,
162  // and not on px or py.
163  itsMap[PX] -= As.derivative(X).substitute(itsMap);
164  itsMap[PY] -= As.derivative(Y).substitute(itsMap);
165 }
166 
167 
168 void Mapper::applyTransform(const Euclid3D &euclid, double refLength) {
169  if(! euclid.isIdentity()) {
170  double kin = itsReference.getM() / itsReference.getP();
171  double refTime = refLength / itsReference.getBeta();
172  Series px = itsMap[PX];
173  Series py = itsMap[PY];
174  Series pt = itsMap[PT] + 1.0;
175  Series pz = sqrt(pt * pt - px * px - py * py);
176 
177  itsMap[PX] = euclid.M(0, 0) * px + euclid.M(1, 0) * py + euclid.M(2, 0) * pz;
178  itsMap[PY] = euclid.M(0, 1) * px + euclid.M(1, 1) * py + euclid.M(2, 1) * pz;
179  pz = euclid.M(0, 2) * px + euclid.M(1, 2) * py + euclid.M(2, 2) * pz;
180 
181  Series x = itsMap[X] - euclid.getX();
182  Series y = itsMap[Y] - euclid.getY();
183  Series x2 =
184  euclid.M(0, 0) * x + euclid.M(1, 0) * y - euclid.M(2, 0) * euclid.getZ();
185  Series y2 =
186  euclid.M(0, 1) * x + euclid.M(1, 1) * y - euclid.M(2, 1) * euclid.getZ();
187  Series s2 =
188  euclid.M(0, 2) * x + euclid.M(1, 2) * y - euclid.M(2, 2) * euclid.getZ();
189  Series sByPz = s2 / pz;
190 
191  Series E = sqrt(pt * pt + kin * kin);
192  itsMap[X] = x2 - sByPz * itsMap[PX];
193  itsMap[Y] = y2 - sByPz * itsMap[PY];
194  itsMap[T] += pt * (refTime / E + sByPz);
195  }
196 }
Build transfer map.
virtual ElementBase * getElement() const
Return the contained element.
Definition: rbendmap.h:8
Euclid3D & offset() const
Return the offset.
void applyThinSBend(const BMultipoleField &field, double scale, double h)
Thin SBend kick.
Definition: Mapper.cpp:158
double getX() const
Get displacement.
Definition: Euclid3D.h:216
double normal(int) const
Get component.
virtual void visitAlignWrapper(const AlignWrapper &)
Apply the algorithm to an align wrapper.
Definition: Mapper.cpp:91
virtual void trackMap(FVps< double, 6 > &, const PartData &, bool revBeam, bool revTrack) const
Track a map.
virtual void trackMap(FVps< double, 6 > &map, const PartData &, bool revBeam, bool revTrack) const
Track a map.
Definition: Component.cpp:78
Definition: rbendmap.h:8
Define the position of a misaligned element.
Definition: AlignWrapper.h:39
double getZ() const
Get displacement.
Definition: Euclid3D.h:224
virtual Euclid3D getEntranceTransform() const
Get entrance patch.
Particle reference data.
Definition: PartData.h:38
Definition: rbendmap.h:8
double getBeta() const
The relativistic beta per particle.
Definition: PartData.h:127
double M(int row, int col) const
Get component.
Definition: Euclid3D.h:228
FTps< double, 6 > Series
Definition: LieMapper.cpp:60
Euclid3D Inverse(const Euclid3D &t)
Euclidean inverse.
Definition: Euclid3D.h:204
virtual void visitComponent(const Component &)
Apply the algorithm to an arbitrary component.
Definition: Mapper.cpp:79
virtual Euclid3D getExitTransform() const
Get exit patch.
double skew(int) const
Get component.
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
Displacement and rotation in space.
Definition: Euclid3D.h:68
bool isIdentity() const
Test for identity.
Definition: Euclid3D.h:233
void applyThinMultipole(const BMultipoleField &field, double factor)
Thin multipole kick.
Definition: Mapper.cpp:135
An abstract sequence of beam line components.
Definition: Beamline.h:37
FTps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
Definition: FTps.hpp:1075
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
virtual void getMap(LinearMap< double, 6 > &) const
Return the linear part of the accumulated map.
Definition: Mapper.cpp:49
FTps derivative(int var) const
Partial derivative.
Definition: FTps.hpp:1396
virtual void setMap(const LinearMap< double, 6 > &)
Reset the linear part of the accumulated map for restart.
Definition: Mapper.cpp:64
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:117
virtual void visitPatch(const Patch &pat)
Apply the algorithm to a patch.
Definition: Mapper.cpp:84
void applyTransform(const Euclid3D &, double refLength=0.0)
Apply transform.
Definition: Mapper.cpp:168
The magnetic field of a multipole.
double getM() const
The constant mass per particle.
Definition: PartData.h:112
FVps< double, 6 > Map
Definition: ThickMapper.cpp:67
virtual ~Mapper()
Definition: Mapper.cpp:45
Interface for a geometric patch.
Definition: Patch.h:34
virtual void visitMapIntegrator(const MapIntegrator &)
Apply the algorithm to an integrator capable of mapping.
Definition: Mapper.cpp:113
Interface for a single beam element.
Definition: Component.h:51
virtual const Euclid3D & getPatch() const =0
Get patch transform.
const PartData itsReference
The reference information.
double getY() const
Get displacement.
Definition: Euclid3D.h:220
int order() const
Return order.
Definition: rbendmap.h:8
FVps< double, 6 > itsMap
The transfer map being built.
Definition: Mapper.h:152
void applyDrift(double length)
Apply drift length.
Definition: Mapper.cpp:118
Integrate a map.
Definition: MapIntegrator.h:41