OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
LinearMapper.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: LinearMapper.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.5.2.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: LinearMapper
10 // The visitor class for building a linear map for a beamline using
11 // linear maps for all elements.
12 //
13 // ------------------------------------------------------------------------
14 //
15 // $Date: 2003/11/07 18:01:13 $
16 // $Author: dbruhwil $
17 //
18 // ------------------------------------------------------------------------
19 
21 
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/Monitor.h"
32 #include "AbsBeamline/Multipole.h"
33 #include "AbsBeamline/Patch.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 
49 #include "Fields/BMultipoleField.h"
50 #include "FixedAlgebra/FTpsMath.h"
51 #include "FixedAlgebra/LinearFun.h"
53 #include "Physics/Physics.h"
54 
55 using Physics::c;
56 
59 
60 
61 // Class LinearMapper
62 // ------------------------------------------------------------------------
63 
64 LinearMapper::LinearMapper(const Beamline &beamline, const PartData &reference,
65  bool revBeam, bool revTrack):
66  AbstractMapper(beamline, reference, revBeam, revTrack)
67 {}
68 
69 
71 {}
72 
73 
75  map = itsMap;
76 }
77 
78 
80  map = FVps<double, 6>(itsMap);
81 }
82 
83 
85  itsMap = map;
86 }
87 
88 
91 }
92 
93 
95  // *** MISSING *** Map for beam-beam.
96 }
97 
99  // *** MISSING *** Map for beam stripping.
100 }
101 
104 }
105 
106 
108  FVps<double, 6> map(itsMap);
111 }
112 
113 
115  // Drift through first half of length.
116  double length = flip_s * corr.getElementLength();
117  if(length) applyDrift(length / 2.0);
118 
119  // Apply kick.
120  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
121  const BDipoleField &field = corr.getField();
122  itsMap[PX] -= field.getBy() * scale;
123  itsMap[PY] += field.getBx() * scale;
124 
125  // Drift through second half of length.
126  if(length) applyDrift(length / 2.0);
127 }
128 
131 }
132 
135 }
136 
137 
138 void LinearMapper::visitDrift(const Drift &drift) {
140 }
141 
144 }
145 
147  // Assume the particle go through the magnet's window.
149 }
150 
151 
152 void LinearMapper::visitMarker(const Marker &marker) {
153  // Do nothing.
154 }
155 
156 
159 }
160 
161 
162 void LinearMapper::visitMultipole(const Multipole &multipole) {
163  double length = flip_s * multipole.getElementLength();
164  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
165  const BMultipoleField &field = multipole.getField();
166 
167  if(length) {
168  // Normal case: Finite-length multipole, field coefficients are B.
169  applyMultipoleBody(length, length, field, scale);
170  } else {
171  // Special case: Thin multipole, field coefficients are integral(B*dl).
172  scale *= flip_s;
173  applyThinMultipole(field, scale);
174  }
175 }
176 
177 
178 void LinearMapper::visitPatch(const Patch &patch) {
179  Euclid3D transform = patch.getPatch();
180  if(back_track) transform = Inverse(transform);
181  applyTransform(transform, 0.0);
182 }
183 
184 void LinearMapper::visitProbe(const Probe &Prob) {
185  // Do nothing.
186 }
187 
188 
189 #include "Algorithms/rbendmap.h"
190 
191 void LinearMapper::visitRBend(const RBend &bend) {
192  visitRBend0(bend);
193 }
194 
195 void LinearMapper::visitRBend0(const RBend &bend) {
196 
197  const RBendGeometry &geometry = bend.getGeometry();
198  double length = flip_s * geometry.getElementLength();
199  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
200  const BMultipoleField &field = bend.getField();
201 
202  if(length == 0.0) {
203  double half_angle = flip_s * geometry.getBendAngle() / 2.0;
204  Euclid3D rotat = Euclid3D::YRotation(- half_angle);
205 
206  // Transform from in-plane to mid-plane.
207  applyTransform(rotat, 0.0);
208 
209  // Apply multipole kick.
210  applyThinMultipole(field, scale);
211 
212  // Transform from mid-plane to out-plane.
213  applyTransform(rotat, 0.0);
214  } else {
215  double refLength = flip_s * geometry.getArcLength();
216  scale *= flip_B;
217  if(back_track) {
218  // Transform from global to local.
219  applyTransform(Inverse(geometry.getExitPatch()), 0.0);
220  // Apply entrance fringe field.
221  applyEntranceFringe(bend.getExitFaceRotation(), field, scale);
222 
223  // Traverse rbend body.
224  applyMultipoleBody(length, refLength, field, scale);
225 
226  // Apply exit fringe field.
227  applyExitFringe(bend.getEntryFaceRotation(), field, scale);
228 
229  // Apply rotation local to global.
230  applyTransform(Inverse(geometry.getEntrancePatch()), 0.0);
231  } else {
232  // Apply rotation global to local.
233  applyTransform(geometry.getEntrancePatch(), 0.0);
234 
235  // Apply entrance fringe field.
236  applyEntranceFringe(bend.getEntryFaceRotation(), field, scale);
237 
238  // Traverse rbend body.
239  applyMultipoleBody(length, refLength, field, scale);
240 
241  // Apply exit fringe field.
242  applyExitFringe(bend.getExitFaceRotation(), field, scale);
243 
244  // Apply rotation local to global.
245  applyTransform(geometry.getExitPatch(), 0.0);
246  }
247  }
248 }
249 
250 
252  // Drift through half length.
253  double length = flip_s * as.getElementLength();
254  if(length) applyDrift(length / 2.0);
255 
256  // Apply accelerating voltage.
257  double freq = as.getFrequency();
258  double peak = flip_s * as.getAmplitude() / itsReference.getP();
259  Linear phase = as.getPhase() + (freq / c) * itsMap[T];
260  itsMap[PT] += peak * sin(phase);
261 
262  // Drift through half length.
263  if(length) applyDrift(length / 2.0);
264 }
265 
266 
268  // *** MISSING *** Map for RF Quadrupole.
270 }
271 
272 
273 void LinearMapper::visitSBend(const SBend &bend) {
274  const PlanarArcGeometry &geometry = bend.getGeometry();
275  double length = flip_s * geometry.getElementLength();
276  double scale = (flip_B * itsReference.getQ() * c) / itsReference.getP();
277  const BMultipoleField &field = bend.getField();
278 
279  if(length == 0.0) {
280  double half_angle = geometry.getBendAngle() / 2.0;
281  Euclid3D rotat = Euclid3D::YRotation(- half_angle);
282 
283  // Transform from in-plane to mid-plane.
284  applyTransform(rotat, 0.0);
285 
286  // Apply multipole kick.
287  // Curvature is unknown for zero-length bend.
288  applyThinMultipole(field, scale);
289 
290  // Transform from mid-plane to out-plane.
291  applyTransform(rotat, 0.0);
292  } else {
293  double h = geometry.getCurvature();
294  double refLength = flip_s * geometry.getArcLength();
295 
296  if(back_track) {
297  // Apply entrance fringe field.
298  applyEntranceFringe(bend.getExitFaceRotation(), field, scale);
299 
300  // Traverse sbend body.
301  applySBendBody(length, refLength, h, field, scale);
302 
303  // Apply exit fringe field.
304  applyExitFringe(bend.getEntryFaceRotation(), field, scale);
305  } else {
306  // Apply entrance fringe field.
307  applyEntranceFringe(bend.getEntryFaceRotation(), field, scale);
308 
309  // Traverse sbend body.
310  applySBendBody(length, refLength, h, field, scale);
311 
312  // Apply exit fringe field.
313  applyExitFringe(bend.getExitFaceRotation(), field, scale);
314  }
315  }
316 }
317 
318 
320  // Drift through first half of length.
321  double length = flip_s * sep.getElementLength();
322  if(length) applyDrift(length / 2.0);
323 
324  // Electrostatic kick.
325  double scale = (length * itsReference.getQ()) / itsReference.getP();
326  double Ex = scale * sep.getEx();
327  double Ey = scale * sep.getEy();
328  Linear pt = 1.0 + itsMap[PT];
329  itsMap[PX] += Ex / pt;
330  itsMap[PY] += Ey / pt;
331 
332  if(length) applyDrift(length / 2.0);
333 }
334 
335 
337  // Assume the particle go through the magnet's window.
339 }
340 
341 
342 void LinearMapper::visitSolenoid(const Solenoid &solenoid) {
343  double length = flip_s * solenoid.getElementLength();
344 
345  if(length) {
346  double ks = (flip_B * itsReference.getQ() * solenoid.getBz() * c) /
347  (2.0 * itsReference.getP());
348 
349  if(ks) {
350  double C = cos(ks * length);
351  double S = sin(ks * length);
352 
353  Linear xt = C * itsMap[X] + S * itsMap[Y];
354  Linear yt = C * itsMap[Y] - S * itsMap[X];
355  Linear pxt = C * itsMap[PX] + S * itsMap[PY];
356  Linear pyt = C * itsMap[PY] - S * itsMap[PX];
357 
358  itsMap[X] = C * xt + (S / ks) * pxt;
359  itsMap[Y] = C * yt + (S / ks) * pyt;
360  itsMap[PX] = C * pxt - (S * ks) * xt;
361  itsMap[PY] = C * pyt - (S * ks) * yt;
362 
363  double kin = itsReference.getM() / itsReference.getP();
364  itsMap[T] += length * itsMap[PT] * kin * kin;
365  } else {
366  applyDrift(length);
367  }
368  }
369 }
370 
371 
373  //do nothing
374 }
375 
377  // Do nothing.
378 }
379 
380 
382  if(wrap.offset().isIdentity()) {
383  wrap.getElement()->accept(*this);
384  } else {
385  Euclid3D e1 = wrap.getEntranceTransform();
386  Euclid3D e2 = wrap.getExitTransform();
387 
388  if(back_track) {
389  // Tracking right to left.
390  applyTransform(Inverse(e2), 0.0);
391  wrap.getElement()->accept(*this);
392  applyTransform(Inverse(e1), 0.0);
393  } else {
394  // Tracking left to right.
395  applyTransform(e1, 0.0);
396  wrap.getElement()->accept(*this);
397  applyTransform(e2, 0.0);
398  }
399  }
400 }
401 
402 
404  FVps<double, 6> map(itsMap);
407 }
408 
409 
411 (double k, double L, double &c, double &s, double &d, double &f) {
412  double t = k * L * L;
413  if(std::abs(t) < 1.0e-4) {
414  c = 1.0 - t / 2.0;
415  s = L * (1.0 - t / 6.0);
416  d = L * L * (0.5 - t / 24.0);
417  f = L * L * L * ((1.0 / 6.0) - t / 120.0);
418  } else if(k > 0.0) {
419  double r = sqrt(k);
420  c = cos(r * L);
421  s = sin(r * L) / r;
422  d = (1.0 - c) / k;
423  f = (L - s) / k;
424  } else {
425  double r = sqrt(- k);
426  c = cosh(r * L);
427  s = sinh(r * L) / r;
428  d = (1.0 - c) / k;
429  f = (L - s) / k;
430  }
431 }
432 
433 
434 void LinearMapper::applyDrift(double length) {
435  double kin = itsReference.getM() / itsReference.getP();
436  itsMap[X] += length * itsMap[PX];
437  itsMap[Y] += length * itsMap[PY];
438  itsMap[T] += length * itsMap[PT] * kin * kin;
439 }
440 
441 
443  const BMultipoleField &field,
444  double scale) {
445  double hx = scale * field.normal(1);
446  double ex = hx * tan(angle);
447  double ey = hx * tan(angle + itsMap[PX][0]);
448  itsMap[PX] += ex * itsMap[X];
449  itsMap[PY] -= ey * itsMap[Y];
450 }
451 
452 
454  const BMultipoleField &field,
455  double scale) {
456  double hx = scale * field.normal(1);
457  double ex = hx * tan(angle);
458  double ey = hx * tan(angle - itsMap[PX][0]);
459  itsMap[PX] += ex * itsMap[X];
460  itsMap[PY] -= ey * itsMap[Y];
461 }
462 
463 
464 void LinearMapper::applyLinearMap(double length, double refLength, double h,
465  const Series2 &Fx, const Series2 &Fy) {
466  // Extract the phase coordinates.
467  Linear x = itsMap[X];
468  Linear px = itsMap[PX];
469  Linear y = itsMap[Y];
470  Linear py = itsMap[PY];
471  Linear pt = itsMap[PT];
472 
473  // Split position variables into constant and variable terms.
474  double x0 = x[0];
475  double y0 = y[0];
476  x[0] = 0.0;
477  y[0] = 0.0;
478 
479  // Extract coefficients for equations of motion.
480  // Indexing: 0 = constant, 1 = X, 2 = Y.
481  double kx = Fx[1];
482  double ks = (Fx[2] - Fy[1]) / 2.0;
483  double ky = - Fy[2];
484  Linear hx = h * (1.0 + pt) - Fx[0];
485  double hy = Fy[0];
486 
487  // Parameters for longitudinal motion.
488  double kin = itsReference.getM() / itsReference.getE();
489  double refTime = refLength * kin * kin;
490 
491  // Test for zero skew quadrupole component.
492  if(ks == 0.0) {
493  // Transport coefficients.
494  double cx, sx, dx, fx, cy, sy, dy, fy;
495  makeFocus(kx, length, cx, sx, dx, fx);
496  makeFocus(ky, length, cy, sy, dy, fy);
497  double wx = - kx * sx;
498  double wy = - ky * sy;
499 
500  // Advance through field.
501  itsMap[X] = cx * x + sx * px + dx * hx;
502  itsMap[PX] = wx * x + cx * px + sx * hx;
503  itsMap[Y] = cy * y + sy * py + dy * hy;
504  itsMap[PY] = wy * y + cy * py + sy * hy;
505  itsMap[T] += h * (sx * x + dx * px + fx * hx);
506  } else {
507  // Find transformation to principal axes.
508  double s1 = (kx + ky) / 2.0;
509  double d1 = (kx - ky) / 2.0;
510  double root = sqrt(d1 * d1 + ks * ks);
511  double c2 = d1 / root;
512  double s2 = ks / root;
513 
514  // Transport coefficients.
515  double cu, su, du, fu, cv, sv, dv, fv;
516  double ku = s1 + (d1 * d1 - ks * ks) / root;
517  double kv = s1 - (d1 * d1 - ks * ks) / root;
518  makeFocus(ku, length, cu, su, du, fu);
519  makeFocus(kv, length, cv, sv, dv, fv);
520  double wu = - ku * su;
521  double wv = - kv * sv;
522 
523  // Rotate the coordinates to orientation of quadrupole.
524  Linear u = c2 * x - s2 * y;
525  Linear v = c2 * y + s2 * x;
526  Linear pu = c2 * px - s2 * py;
527  Linear pv = c2 * py + s2 * px;
528  Linear hu = c2 * (h + hx) - s2 * hy;
529  Linear hv = c2 * hy + s2 * (h + hx);
530 
531  // Advance through field.
532  itsMap[X] = ((cu + cv) * x + (cu - cv) * u +
533  (su + sv) * px + (su - sv) * pu +
534  (du + dv) * hx + (du - dv) * hu) / 2.0;
535  itsMap[PX] = ((wu + wv) * x + (wu - wv) * u +
536  (cu + cv) * px + (cu - cv) * pu +
537  (su + sv) * hx + (su - sv) * hu) / 2.0;
538  itsMap[Y] = ((cu + cv) * y - (cu - cv) * v +
539  (su + sv) * py - (su - sv) * pv +
540  (du + dv) * hy - (du - dv) * hv) / 2.0;
541  itsMap[PY] = ((wu + wv) * y - (wu - wv) * v +
542  (cu + cv) * py - (cu - cv) * pv +
543  (su + sv) * hy - (su - sv) * hv) / 2.0;
544  itsMap[T] += ((su + sv) * x + (su - sv) * u +
545  (du + dv) * px + (du - dv) * pu +
546  (fu + fv) * hx + (fu - fv) * hu) * (h / 2.0);
547  }
548 
549  // Add in constant terms.
550  itsMap[X] += x0;
551  itsMap[Y] += y0;
552  itsMap[T] += refTime * pt + length * h * x0;
553 }
554 
555 
556 Series2
558  //std::cerr << "==> In buildSBendVectorPotential(const BMultipoleField &field, double h)..."
559  // << std::endl;
560  // Check sanity.
561  if(h == 0.) {
562  std::cerr << " <*** ERROR ***> in LinearMapper::buildSBendVectorPotential():\n"
563  << " attempt to use an infinite radius of curvature." << std::endl;
564  throw DomainError("buildSBendVectorPotential(const BMultipoleField &, double)");
565  }
566 
567  int order = field.order();
568  Series2 As;
569 
570  //std::cerr << "order = " << order << std::endl;
571  //for (int m = 1; m <= order; ++m) {
572  //std::cerr << "Order " << m << ": "
573  // << field.normal(m) << " " << field.skew(m) << std::endl;
574  //}
575 
576  if(order > 0) {
577  static Series2 x = Series2::makeVariable(0);
578  static Series2 y = Series2::makeVariable(1);
579 
580  // Terms even/odd in y.
581  Series2 Ae = + field.normal(order);
582  Series2 Ao = - field.skew(order);
583 
584  int i = order;
585  while(i > 1) {
586  --i;
587  Ae = Ae * x + field.normal(i);
588  Ao = Ao * x - field.skew(i);
589  };
590  Ae.setTruncOrder(Ae.getMaxOrder());
591  Ao.setTruncOrder(Ao.getMaxOrder());
592 
593  {
594  Series2 hx1 = 1. + h * x;
595  Ae = + (Ae * hx1).integral(0);
596  Ao = - (Ao * hx1);
597  }
598  // Add terms up to maximum order.
599  As = Ae + y * Ao;
600 
601  int k = 2;
602  if(k <= order) {
603  Series2 yp = y * y / 2.0;
604  Series2 radius = 1.0 / h + x;
605 
606  while(true) {
607  // Terms even in y.
608  Ae = Ae.derivative(0);
609  Ae = Ae / radius - Ae.derivative(0); // use following line to include case h==0.
610  // Ae = (h==0. ? 0. : Ae/radius) - Ae.derivative(0);
611  As += Ae * yp;
612  if(++k > order) break;
613  yp *= y / double(k);
614 
615  // Terms odd in y.
616  Ao = Ao.derivative(0);
617  Ao = Ao / radius - Ao.derivative(0); // use following line to include case h==0.
618  // Ao = (h==0. ? 0. : Ao/radius) - Ao.derivative(0);
619  As += Ao * yp;
620  if(++k > order) break;
621  yp *= y / double(k);
622  }
623  }
624  }
625 
626  //std::cerr << " As = " << As << std::endl;
627  double x0 = itsMap[X][0], y0 = itsMap[Y][0];
628  if(x0 != 0. || y0 != 0.) {
629  FVps<double, 2> to_fixpt;
630  to_fixpt[0] += x0;
631  to_fixpt[1] += y0;
632  As = As.substitute(to_fixpt);
633  }
634  //std::cerr << " As(r-fp) = " << As << std::endl;
635 
636  return As;
637 }
638 
639 
640 void LinearMapper::applyMultipoleBody(double length, double refLength,
641  const BMultipoleField &field, double scale) {
642  // Determine normalised field coefficients around actual orbit.
643  // Fx and Fy are the normalised field coefficients,
644  // expressed as linear functions in x and y.
645  int order = field.order();
646 
647  if(order > 0) {
648  static Series2 x = Series2::makeVariable(0);
649  static Series2 y = Series2::makeVariable(1);
650 
651  Series2 Fx = field.normal(order);
652  Series2 Fy = - field.skew(order);
653 
654  while(order > 1) {
655  Series2 Fxt = x * Fx - y * Fy;
656  Series2 Fyt = x * Fy + y * Fx;
657  --order;
658  Fx = Fxt + field.normal(order);
659  Fy = Fyt - field.skew(order);
660  };
661  Fx.setTruncOrder(Fx.getMaxOrder());
662  Fy.setTruncOrder(Fy.getMaxOrder());
663 
664  Fx *= scale;
665  Fy *= scale;
666 
667  FVps<double, 2> to_fixpt;
668  to_fixpt[0] += itsMap[X][0];
669  to_fixpt[1] += itsMap[Y][0];
670 
671  Fx = Fx.substitute(to_fixpt);
672  Fy = Fy.substitute(to_fixpt);
673  applyLinearMap(length, refLength, 0.0, Fx, Fy);
674  } else applyDrift(length);
675 }
676 
677 
678 void LinearMapper::applySBendBody(double length, double refLength, double h,
679  const BMultipoleField &field, double scale) {
680  // Determine normalised field coefficients around actual orbit.
681  // As is the vector potential times (1 + h*x),
682  // expressed as a linear function in x and y.
683  Series2 As = buildSBendVectorPotential(field, h) * scale;
684 
685  // Fx and Fy are the normalised field coefficients times (1 + h*x).
686  Series2 Fx = + As.derivative(0);
687  Series2 Fy = - As.derivative(1);
688  applyLinearMap(length, refLength, h, Fx, Fy);
689 }
690 
691 
693 (const BMultipoleField &field, double scale) {
694  int order = field.order();
695 
696  if(order > 0) {
697  Linear x = itsMap[X];
698  Linear y = itsMap[Y];
699  Linear kx = + field.normal(order);
700  Linear ky = - field.skew(order);
701 
702  while(--order > 0) {
703  Linear kxt = x * kx - y * ky;
704  Linear kyt = x * ky + y * kx;
705  kx = kxt + field.normal(order);
706  ky = kyt - field.skew(order);
707  }
708 
709  itsMap[PX] -= kx * scale;
710  itsMap[PY] += ky * scale;
711  }
712 }
713 
714 
715 void LinearMapper::applyTransform(const Euclid3D &euclid, double refLength) {
716  if(! euclid.isIdentity()) {
717  Linear px1 = itsMap[PX];
718  Linear py1 = itsMap[PY];
719  Linear pt = itsMap[PT] + 1.0;
720  Linear pz1 = sqrt(pt * pt - px1 * px1 - py1 * py1);
721 
722  itsMap[PX] = euclid.M(0, 0) * px1 + euclid.M(1, 0) * py1 + euclid.M(2, 0) * pz1;
723  itsMap[PY] = euclid.M(0, 1) * px1 + euclid.M(1, 1) * py1 + euclid.M(2, 1) * pz1;
724  Linear pz2 = euclid.M(0, 2) * px1 + euclid.M(1, 2) * py1 + euclid.M(2, 2) * pz1;
725 
726  Linear x = itsMap[X] - euclid.getX();
727  Linear y = itsMap[Y] - euclid.getY();
728  Linear x2 =
729  euclid.M(0, 0) * x + euclid.M(1, 0) * y - euclid.M(2, 0) * euclid.getZ();
730  Linear y2 =
731  euclid.M(0, 1) * x + euclid.M(1, 1) * y - euclid.M(2, 1) * euclid.getZ();
732  Linear s2 =
733  euclid.M(0, 2) * x + euclid.M(1, 2) * y - euclid.M(2, 2) * euclid.getZ();
734  Linear sByPz = s2 / pz2;
735 
736  double kin = itsReference.getM() / itsReference.getP();
737  Linear E = sqrt(pt * pt + kin * kin);
738  double refTime = refLength / itsReference.getBeta();
739  itsMap[X] = x2 - sByPz * itsMap[PX];
740  itsMap[Y] = y2 - sByPz * itsMap[PY];
741  itsMap[T] += pt * (refTime / E + sByPz);
742  }
743 }
Build transfer map.
virtual double getExitFaceRotation() const =0
Get exit pole face rotation.
void applyLinearMap(double length, double refLength, double h, const FTps< double, 2 > &Fx, const FTps< double, 2 > &Fy)
Apply linear map, defined by the linear expansions Fx and Fy.
virtual ElementBase * getElement() const
Return the contained element.
Definition: rbendmap.h:8
virtual double getArcLength() const
Get arc length.
virtual void visitPatch(const Patch &pat)
Apply the algorithm to a patch.
Euclid3D & offset() const
Return the offset.
virtual BMultipoleField & getField() override=0
Get multipole expansion of field.
virtual ~LinearMapper()
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void visitAlignWrapper(const AlignWrapper &)
Apply the algorithm to an offset beamline object wrapper.
double getX() const
Get displacement.
Definition: Euclid3D.h:216
virtual BDipoleField & getField()=0
Return the corrector field.
constexpr double e
The value of .
Definition: Physics.h:40
int getMaxOrder() const
Get maximum order.
Definition: FTps.h:174
double getE() const
The constant reference Energy per particle.
Definition: PartData.h:122
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.
virtual void trackMap(FVps< double, 6 > &, const PartData &, bool revBeam, bool revTrack) const
Track a map.
void applyMultipoleBody(double length, double refLength, const BMultipoleField &field, double scale)
Apply body of SBend.
virtual void visitSeptum(const Septum &)
Apply the algorithm to a Septum.
Interface for electrostatic separator.
Definition: Separator.h:33
Euclid3D getExitPatch() const
Get patch.
virtual void trackMap(FVps< double, 6 > &map, const PartData &, bool revBeam, bool revTrack) const
Track a map.
Definition: Component.cpp:78
virtual void visitLambertson(const Lambertson &)
Apply the algorithm to a Lambertson.
virtual double getArcLength() const
Get arc length.
virtual double getPhase() const =0
Get RF phase.
void applyExitFringe(double edge, const BMultipoleField &field, double scale)
Interface for beam position monitors.
Definition: Monitor.h:41
Interface for RF Quadrupole.
Definition: RFQuadrupole.h:30
A simple arc in the XZ plane.
Definition: rbendmap.h:8
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
virtual double getBz() const =0
Get solenoid field Bz in Teslas.
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RFCavity.
Define the position of a misaligned element.
Definition: AlignWrapper.h:39
Interface for RF cavity.
Definition: ParallelPlate.h:36
double getZ() const
Get displacement.
Definition: Euclid3D.h:224
virtual void visitComponent(const Component &)
Apply the algorithm to an arbitrary component.
virtual double getElementLength() const override
Get design length.
Definition: RFCavity.cpp:818
virtual Euclid3D getEntranceTransform() const
Get entrance patch.
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a Multipole.
Particle reference data.
Definition: PartData.h:38
virtual double getEx() const =0
Get horizontal component Ex of field in V/m.
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
Interface for general corrector.
Definition: Corrector.h:35
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
Euclid3D getEntrancePatch() const
Get patch.
Interface for a marker.
Definition: Marker.h:32
virtual double getBy() const
Get vertical component.
virtual void visitSeparator(const Separator &)
Apply the algorithm to a Separator.
virtual PlanarArcGeometry & getGeometry() override=0
Get SBend geometry.
Definition: rbendmap.h:8
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
virtual double getEntryFaceRotation() const =0
Get pole entry face rotation.
Interface for drift space.
Definition: Drift.h:33
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
void applySBendBody(double length, double refLength, double h, const BMultipoleField &field, double scale)
Apply thin multipole kick (integrated over length) to all particles.
Interface for general multipole.
Definition: Multipole.h:46
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a Monitor.
static Euclid3D YRotation(double angle)
Make rotation.
Definition: Euclid3D.cpp:164
T deg(T x)
Convert radians to degrees.
Definition: matheval.hpp:82
Euclid3D Inverse(const Euclid3D &t)
Euclidean inverse.
Definition: Euclid3D.h:204
virtual double getElementLength() const override
Get design length.
Definition: Solenoid.cpp:256
LinearMap< double, 6 > itsMap
Definition: LinearMapper.h:213
void applyTransform(const Euclid3D &, double refLength)
Apply transform.
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
virtual double getExitFaceRotation() const =0
Get exit pole face rotation.
double getBendAngle() const
Get angle.
virtual void visitRBend0(const RBend &)
Apply the algorithm to a RBend.
virtual void getMap(LinearMap< double, 6 > &) const
Return the linear part of the accumulated map.
Interface for probe.
Definition: Probe.h:16
FTps< double, 2 > buildSBendVectorPotential(const BMultipoleField &, double h)
Construct the vector potential for a SBend.
virtual Euclid3D getExitTransform() const
Get exit patch.
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a Solenoid.
double skew(int) const
Get component.
double getQ() const
The constant charge per particle.
Definition: PartData.h:107
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a Corrector.
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:511
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
virtual void visitProbe(const Probe &prob)
Apply the algorithm to a probe.
Displacement and rotation in space.
Definition: Euclid3D.h:68
Abstract beam-beam interaction.
Definition: BeamBeam.h:37
Definition: SBend.h:68
virtual void visitBeamStripping(const BeamStripping &)
Apply the algorithm to a beam stripping.
bool isIdentity() const
Test for identity.
Definition: Euclid3D.h:233
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a drift.
Interface for cyclotron valley.
virtual double getBx() const
Get horizontal component.
virtual void visitDrift(const Drift &)
Apply the algorithm to a Drift.
virtual void visitSBend(const SBend &)
Apply the algorithm to a SBend.
Interface for solenoids.
Definition: Solenoid.h:36
static void makeFocus(double k, double L, double &c, double &s, double &d, double &f)
Helper function for finding first-order coefficients.
virtual double getElementLength() const
Get element length.
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
virtual void visitRFQuadrupole(const RFQuadrupole &)
Apply the algorithm to a RFQuadrupole.
virtual void visitCyclotronValley(const CyclotronValley &)
Apply the algorithm to a CyclotronValley.
virtual double getElementLength() const
Get element length.
virtual void visitDiagnostic(const Diagnostic &)
Apply the algorithm to a Diagnostic.
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
virtual double getEntryFaceRotation() const =0
Get pole entry face rotation.
FTps derivative(int var) const
Partial derivative.
Definition: FTps.hpp:1396
The geometry for a RBend element.
Definition: RBendGeometry.h:41
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:117
LinearFun< double, 6 > Linear
Definition: IdealMapper.cpp:41
virtual void visitParallelPlate(const ParallelPlate &)
Apply the algorithm to a ParallelPlate.
The magnetic field of a multipole.
double hv(FRONT)
Domain error exception.
Definition: DomainError.h:32
Interface for RF cavity.
Definition: RFCavity.h:37
double getM() const
The constant mass per particle.
Definition: PartData.h:112
void applyEntranceFringe(double edge, const BMultipoleField &field, double scale)
Transforms fringing fields.
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Abstract collimator.
Definition: Degrader.h:37
virtual void visitMarker(const Marker &)
Apply the algorithm to a Marker.
FTps< double, 2 > Series2
virtual void visitBeamBeam(const BeamBeam &)
Apply the algorithm to a BeamBeam.
double getCurvature() const
Get curvature.
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
virtual RBendGeometry & getGeometry() override=0
Get RBend geometry.
virtual double getBendAngle() const
Get angle.
virtual void visitMapIntegrator(const MapIntegrator &)
Apply the algorithm to an integrator capable of mapping.
void setTruncOrder(int order)
Set truncation order.
Definition: FTps.hpp:393
Linear function in N variables of type T.
Definition: LinearFun.h:39
Truncated power series in N variables of type T.
Interface for a geometric patch.
Definition: Patch.h:34
Interface for a single beam element.
Definition: Component.h:51
virtual const Euclid3D & getPatch() const =0
Get patch transform.
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
const PartData itsReference
The reference information.
double getY() const
Get displacement.
Definition: Euclid3D.h:220
void applyThinMultipole(const BMultipoleField &field, double factor)
Thin multipole kick.
Tps< T > sinh(const Tps< T > &x)
Hyperbolic sine.
Definition: TpsMath.h:204
static FTps makeVariable(int var)
Make variable.
Definition: FTps.hpp:481
int order() const
Return order.
virtual void setMap(const LinearMap< double, 6 > &)
Reset the linear part of the accumulated map for restart.
void applyDrift(double length)
Apply drift length.
Definition: rbendmap.h:8
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Interface for a Lambertson septum.
Definition: Lambertson.h:33
Integrate a map.
Definition: MapIntegrator.h:41