OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
ThinMapper.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: ThinMapper.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: ThinMapper
10 // The visitor class for building a map for a beamline
11 // using a thin-lens approximation for all elements.
12 //
13 // ------------------------------------------------------------------------
14 // Class category: Algorithms
15 // ------------------------------------------------------------------------
16 //
17 // $Date: 2000/03/27 09:32:33 $
18 // $Author: fci $
19 //
20 // ------------------------------------------------------------------------
21 
22 #include "Algorithms/ThinMapper.h"
24 #include "AbsBeamline/Corrector.h"
25 #include "AbsBeamline/Diagnostic.h"
26 #include "AbsBeamline/Drift.h"
27 #include "AbsBeamline/Degrader.h"
30 #include "AbsBeamline/Lambertson.h"
31 #include "AbsBeamline/Marker.h"
32 #include "AbsBeamline/Monitor.h"
33 #include "AbsBeamline/Multipole.h"
34 #include "AbsBeamline/Probe.h"
35 #include "AbsBeamline/RBend.h"
36 #include "AbsBeamline/RFCavity.h"
38 #include "AbsBeamline/SBend.h"
39 #include "AbsBeamline/Separator.h"
40 #include "AbsBeamline/Septum.h"
41 #include "AbsBeamline/Solenoid.h"
44 
48 #include "Beamlines/Beamline.h"
49 #include "Fields/BMultipoleField.h"
50 #include "FixedAlgebra/FTps.h"
51 #include "FixedAlgebra/FTpsMath.h"
52 #include "Physics/Physics.h"
53 
54 using Physics::c;
55 
57 
58 
59 // Class ThinMapper
60 // ------------------------------------------------------------------------
61 
62 ThinMapper::ThinMapper(const Beamline &beamline, const PartData &ref,
63  bool backBeam, bool backTrack):
64  Mapper(beamline, ref, backBeam, backTrack)
65 {}
66 
67 
69 {}
70 
71 
73  // *** MISSING *** Map algorithm on BeamBeam
74 }
75 
77  // *** MISSING *** Map algorithm on BeamStripping
78 }
79 
82 }
83 
86 }
87 
88 
90  // Drift through first half of length.
91  double length = flip_s * corr.getElementLength();
92  if(length) applyDrift(length / 2.0);
93 
94  // Apply kick.
95  double scale = (flip_s * flip_B * itsReference.getQ() * c) /
97  const BDipoleField &field = corr.getField();
98  itsMap[PX] -= field.getBy() * scale;
99  itsMap[PY] += field.getBx() * scale;
100 
101  // Drift through second half of length.
102  if(length) applyDrift(length / 2.0);
103 }
104 
105 
107  // The diagnostic has no effect on the map.
109 }
110 
111 
112 void ThinMapper::visitDrift(const Drift &drift) {
114 }
115 
118 }
119 
121  // Assume that the reference orbit is in the magnet's window.
123 }
124 
125 
127  // Do nothing.
128 }
129 
130 
133 }
134 
135 
137  double length = flip_s * mult.getElementLength();
138  const BMultipoleField &field = mult.getField();
139  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
140 
141  if(length) {
142  // Drift through first half of the length.
143  applyDrift(length / 2.0);
144 
145  // Apply thin multipole kick, field is per unit length.
146  scale *= length;
147  applyThinMultipole(field, scale);
148 
149  // Drift through second half of the length.
150  applyDrift(length / 2.0);
151  } else {
152  // Thin multipole, field is integral(K*dl).
153  scale *= flip_s;
154  applyThinMultipole(field, scale);
155  }
156 }
157 
159  // Do nothing.
160 }
161 
162 
163 void ThinMapper::visitRBend(const RBend &bend) {
164  // Geometry.
165  const RBendGeometry &geometry = bend.getGeometry();
166  double length = flip_s * geometry.getElementLength();
167  double angle = flip_s * geometry.getBendAngle();
168 
169  // Magnetic field.
170  const BMultipoleField &field = bend.getField();
171 
172  // Drift to mid-plane.
173  applyDrift(length / 2.0);
174 
175  // Apply multipole kick and linear approximation to geometric bend.
176  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
177  if(length) scale *= length;
178  int order = field.order();
179 
180  if(order > 0) {
181  Series x = itsMap[X];
182  Series y = itsMap[Y];
183  Series kx = + field.normal(order);
184  Series ky = - field.skew(order);
185 
186  while(--order > 0) {
187  Series kxt = x * kx - y * ky;
188  Series kyt = x * ky + y * kx;
189  kx = kxt + field.normal(order);
190  ky = kyt - field.skew(order);
191  }
192 
193  itsMap[PX] -= kx * scale - angle * (1.0 + itsMap[PT]);
194  itsMap[PY] += ky * scale;
195  itsMap[T] -= angle * x;
196  }
197 
198  // Drift to out-plane.
199  applyDrift(length / 2.0);
200 }
201 
202 
204  // Drift through half length.
205  double length = flip_s * as.getElementLength();
206  if(length) applyDrift(length / 2.0);
207 
208  // Apply accelerating voltage.
209  double kin = itsReference.getM() / itsReference.getP();
210  double freq = as.getFrequency();
211  double peak = flip_s * as.getAmplitude() / itsReference.getP();
212 
213  Series pt = itsMap[PT] + 1.0;
214  Series speed = (c * pt) / sqrt(pt * pt + kin * kin);
215  Series phase = as.getPhase() + freq * itsMap[T] / speed;
216  itsMap[PT] += peak * sin(phase) / pt;
217 
218  // Drift through half length.
219  if(length) applyDrift(length / 2.0);
220 }
221 
222 
224  // *** MISSING *** Map algorithm on RF Quadrupole.
226 }
227 
228 
229 void ThinMapper::visitSBend(const SBend &bend) {
230  const PlanarArcGeometry &geometry = bend.getGeometry();
231  double length = flip_s * geometry.getElementLength();
232  double angle = flip_s * geometry.getBendAngle();
233 
234  // Magnetic field.
235  const BMultipoleField &field = bend.getField();
236 
237  // Drift to mid-plane.
238  applyDrift(length / 2.0);
239 
240  // Apply multipole kick and linear approximation to geometric bend.
241  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
242  if(length) scale *= length;
243  int order = field.order();
244 
245  if(order > 0) {
246  Series x = itsMap[X];
247  Series y = itsMap[Y];
248  Series kx = + field.normal(order);
249  Series ky = - field.skew(order);
250 
251  while(--order > 0) {
252  Series kxt = x * kx - y * ky;
253  Series kyt = x * ky + y * kx;
254  kx = kxt + field.normal(order);
255  ky = kyt - field.skew(order);
256  }
257 
258  itsMap[PX] -= kx * scale - angle * (1.0 + itsMap[PT]);
259  itsMap[PY] += ky * scale;
260  itsMap[T] -= angle * x;
261  }
262 
263  // Drift to out-plane.
264  applyDrift(length / 2.0);
265 }
266 
267 
269  // Drift through first half of length.
270  double length = flip_s * sep.getElementLength();
271 
272  if(length) {
273  applyDrift(length / 2.0);
274 
275  double scale = (length * itsReference.getQ()) / itsReference.getP();
276  double Ex = scale * sep.getEx();
277  double Ey = scale * sep.getEy();
278  Series pt = 1.0 + itsMap[PT];
279  itsMap[PX] += Ex / pt;
280  itsMap[PY] += Ey / pt;
281 
282  applyDrift(length / 2.0);
283  }
284 }
285 
286 
287 void ThinMapper::visitSeptum(const Septum &sept) {
288  // Assume that the reference orbit is in the magnet's window.
290 }
291 
292 
293 void ThinMapper::visitSolenoid(const Solenoid &solenoid) {
294  double length = flip_s * solenoid.getElementLength();
295 
296  if(length) {
297  double ks = (flip_B * itsReference.getQ() * solenoid.getBz() * c) /
298  (2.0 * itsReference.getP());
299 
300  if(ks) {
301  Series pt = itsMap[PT] + 1.0;
302  Series px = itsMap[PX] + ks * itsMap[Y];
303  Series py = itsMap[PY] - ks * itsMap[X];
304  Series pz = sqrt(pt * pt - px * px - py * py);
305  Series k = ks / pz;
306  Series C = cos(k * length);
307  Series S = sin(k * length);
308 
309  Series xt = C * itsMap[X] + S * itsMap[Y];
310  Series yt = C * itsMap[Y] - S * itsMap[X];
311  Series pxt = C * itsMap[PX] + S * itsMap[PY];
312  Series pyt = C * itsMap[PY] - S * itsMap[PX];
313 
314  itsMap[X] = C * xt + (S / k) * pxt;
315  itsMap[Y] = C * yt + (S / k) * pyt;
316  itsMap[PX] = C * pxt - (S * k) * xt;
317  itsMap[PY] = C * pyt - (S * k) * yt;
318 
319  double kin = itsReference.getM() / itsReference.getP();
320  double ref = kin * kin;
321  itsMap[T] += length * (pt * ref - (px * px + py * py + 3.0 * pt * pt * ref) / 2.0);
322  } else {
323  applyDrift(length);
324  }
325  }
326 }
327 
328 
330  // Do nothing.
331 }
332 
334  // Do nothing.
335 }
336 
337 void ThinMapper::applyDrift(double length) {
338  double kin = itsReference.getM() / itsReference.getP();
339  double ref = kin * kin;
340  Series px = itsMap[PX];
341  Series py = itsMap[PY];
342  Series pt = itsMap[PT];
343  Series lByPz = length / (1.0 + pt);
344  itsMap[X] += px * lByPz;
345  itsMap[Y] += py * lByPz;
346  itsMap[T] += length * (pt * ref - (px * px + py * py + 3.0 * pt * pt * ref) / 2.0);
347 }
virtual BMultipoleField & getField() override=0
Get multipole expansion of field.
virtual BDipoleField & getField()=0
Return the corrector field.
virtual double getAmplitude() const =0
Get RF amplitude.
double normal(int) const
Get component.
The field of a magnetic dipole.
Definition: BDipoleField.h:31
virtual BMultipoleField & getField() override=0
Get multipole expansion of field.
Interface for septum magnet.
Definition: Septum.h:11
virtual BMultipoleField & getField() override=0
Get multipole field.
Interface for electrostatic separator.
Definition: Separator.h:33
virtual double getPhase() const =0
Get RF phase.
Interface for beam position monitors.
Definition: Monitor.h:41
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
Definition: ThinMapper.cpp:126
Interface for RF Quadrupole.
Definition: RFQuadrupole.h:30
A simple arc in the XZ plane.
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
virtual void visitParallelPlate(const ParallelPlate &)
Apply the algorithm to a ParallelPlate.
Definition: ThinMapper.cpp:329
virtual double getBz() const =0
Get solenoid field Bz in Teslas.
Interface for RF cavity.
Definition: ParallelPlate.h:36
virtual double getElementLength() const override
Get design length.
Definition: RFCavity.cpp:818
Particle reference data.
Definition: PartData.h:38
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a monitor.
Definition: ThinMapper.cpp:131
virtual double getEx() const =0
Get horizontal component Ex of field in V/m.
Interface for general corrector.
Definition: Corrector.h:35
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a corrector.
Definition: ThinMapper.cpp:89
virtual double getEy() const =0
Get vertical component Ey of field in V/m.
Abstract collimator.
Definition: RBend.h:73
Interface for beam diagnostics.
Definition: Diagnostic.h:32
Interface for a marker.
Definition: Marker.h:32
virtual double getBy() const
Get vertical component.
virtual PlanarArcGeometry & getGeometry() override=0
Get SBend geometry.
Interface for drift space.
Definition: Drift.h:33
Interface for general multipole.
Definition: Multipole.h:46
FTps< double, 6 > Series
Definition: LieMapper.cpp:60
virtual void visitSeptum(const Septum &)
Apply the algorithm to a septum.
Definition: ThinMapper.cpp:287
T deg(T x)
Convert radians to degrees.
Definition: matheval.hpp:82
virtual void visitCyclotronValley(const CyclotronValley &)
Apply the algorithm to a CyclotronValley.
Definition: ThinMapper.cpp:333
virtual double getElementLength() const override
Get design length.
Definition: Solenoid.cpp:256
double getBendAngle() const
Get angle.
Interface for probe.
Definition: Probe.h:16
virtual ~ThinMapper()
Definition: ThinMapper.cpp:68
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
Definition: ThinMapper.cpp:163
double skew(int) const
Get component.
double getQ() const
The constant charge per particle.
Definition: PartData.h:107
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:511
virtual void visitProbe(const Probe &)
Apply the algorithm to a probe.
Definition: ThinMapper.cpp:158
virtual double getFrequency() const =0
Get RF frequencey.
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
Interface for cyclotron collimator.
Definition: CCollimator.h:13
Abstract beam-beam interaction.
Definition: BeamBeam.h:37
Definition: SBend.h:68
Interface for cyclotron valley.
virtual void visitRFQuadrupole(const RFQuadrupole &)
Apply the algorithm to a RF quadrupole.
Definition: ThinMapper.cpp:223
void applyThinMultipole(const BMultipoleField &field, double factor)
Thin multipole kick.
Definition: Mapper.cpp:135
virtual double getBx() const
Get horizontal component.
Build transfer map.
Definition: Mapper.h:85
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a solenoid.
Definition: ThinMapper.cpp:293
Interface for solenoids.
Definition: Solenoid.h:36
virtual double getElementLength() const
Get element length.
An abstract sequence of beam line components.
Definition: Beamline.h:37
virtual double getElementLength() const
Get element length.
virtual void visitBeamBeam(const BeamBeam &)
Apply the algorithm to a beam-beam.
Definition: ThinMapper.cpp:72
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
The geometry for a RBend element.
Definition: RBendGeometry.h:41
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:117
virtual void visitBeamStripping(const BeamStripping &)
Apply the algorithm to a beam stripping.
Definition: ThinMapper.cpp:76
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
Definition: ThinMapper.cpp:203
virtual void visitSeparator(const Separator &)
Apply the algorithm to a separator.
Definition: ThinMapper.cpp:268
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
Definition: ThinMapper.cpp:116
The magnetic field of a multipole.
Interface for RF cavity.
Definition: RFCavity.h:37
double getM() const
The constant mass per particle.
Definition: PartData.h:112
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Abstract collimator.
Definition: Degrader.h:37
virtual void visitSBend(const SBend &)
Apply the algorithm to a sector bend.
Definition: ThinMapper.cpp:229
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
Definition: ThinMapper.cpp:84
virtual void visitDiagnostic(const Diagnostic &)
Apply the algorithm to a diagnostic.
Definition: ThinMapper.cpp:106
virtual void visitLambertson(const Lambertson &)
Apply the algorithm to a Lambertson.
Definition: ThinMapper.cpp:120
void applyDrift(double length)
Definition: ThinMapper.cpp:337
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift.
Definition: ThinMapper.cpp:112
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a drift.
Definition: ThinMapper.cpp:80
virtual RBendGeometry & getGeometry() override=0
Get RBend geometry.
virtual double getBendAngle() const
Get angle.
const PartData itsReference
The reference information.
int order() const
Return order.
FVps< double, 6 > itsMap
The transfer map being built.
Definition: Mapper.h:152
Interface for a Lambertson septum.
Definition: Lambertson.h:33
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
Definition: ThinMapper.cpp:136