OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
ThickTracker.h
Go to the documentation of this file.
1 //
2 // Class ThickTracker
3 // Tracks using thick-lens algorithm.
4 //
5 // Copyright (c) 2018, Philippe Ganz, ETH Zürich
6 // All rights reserved
7 //
8 // Implemented as part of the Master thesis
9 // "s-based maps from TPS & Lie-Series applied to Proton-Therapy Gantries"
10 //
11 // This file is part of OPAL.
12 //
13 // OPAL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20 //
21 
22 #ifndef OPAL_ThickTracker_HH
23 #define OPAL_ThickTracker_HH
24 
25 #include "Algorithms/Tracker.h"
26 
27 #include "Hamiltonian.h"
28 
29 #include "Algorithms/IndexMap.h"
30 #include "AbsBeamline/Drift.h"
32 #include "AbsBeamline/Multipole.h"
33 #include "AbsBeamline/RBend3D.h"
34 #include "AbsBeamline/SBend.h"
35 #include "AbsBeamline/Vacuum.h"
36 
37 #include "Elements/OpalBeamline.h"
38 
39 #include <cmath>
40 #include <list>
41 #include <string>
42 #include <tuple>
43 #include <vector>
44 
45 class BMultipoleField;
46 class DataSink;
47 
48 template <class T, unsigned Dim>
49 class PartBunchBase;
50 
52 // [p]
53 // Phase space coordinates numbering:
54 // [tab 3 b]
55 // [row]number [&]name [&]unit [/row]
56 // [row]0 [&]$x$ [&]metres [/row]
57 // [row]1 [&]$p_x/p_r$ [&]1 [/row]
58 // [row]2 [&]$y$ [&]metres [/row]
59 // [row]3 [&]$p_y/p_r$ [&]1 [/row]
60 // [row]4 [&]$v*delta_t$ [&]metres [/row]
61 // [row]5 [&]$delta_p/p_r$ [&]1 [/row]
62 // [/tab][p]
63 // Where $p_r$ is the constant reference momentum defining the reference
64 // frame velocity, $m$ is the rest mass of the particles, and $v$ is the
65 // instantaneous velocity of the particle.
66 // [p]
67 // Other units used:
68 // [tab 2 b]
69 // [row]quantity [&]unit [/row]
70 // [row]reference momentum [&]electron-volts [/row]
71 // [row]velocity [&]metres/second [/row]
72 // [row]accelerating voltage [&]volts [/row]
73 // [row]frequencies [&]hertz [/row]
74 // [row]phase lags [&]$2*pi$ [/row]
75 // [/tab][p]
76 // Approximations used:
77 // [ul]
78 // [li]
79 // [li]
80 // [li]
81 // [/ul]
82 //
83 // On going through an element, we use the following steps:
84 // To complete the map, we propagate the closed orbit and add that to the map.
85 
86 class ThickTracker: public Tracker {
87 
88 private:
92  typedef std::tuple<series_t, std::size_t, double> tuple_t;
93  typedef std::list<tuple_t> beamline_t;
95 
96 public:
97 
99  // The beam line to be tracked is "bl".
100  // The particle reference data are taken from "data".
101  // The particle bunch tracked is initially empty.
102  // If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
103  // If [b]revTrack[/b] is true, we track against the beam.
104  explicit ThickTracker(const Beamline &bl, const PartData &data,
105  bool revBeam, bool revTrack);
106 
108  // The beam line to be tracked is "bl".
109  // The particle reference data are taken from "data".
110  // The particle bunch tracked is taken from [b]bunch[/b].
111  // If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
112  // If [b]revTrack[/b] is true, we track against the beam.
113  explicit ThickTracker(const Beamline &bl,
115  Beam &beam,
116  DataSink &ds,
117  const PartData &data,
118  bool revBeam, bool revTrack,
119  const std::vector<unsigned long long> &maxSTEPS,
120  double zstart,
121  const std::vector<double> &zstop,
122  const std::vector<double> &dt,
123  const int& truncOrder);
124 
125  virtual ~ThickTracker();
126 
128  // overwrite the execute-methode from DefaultVisitor
129  virtual void execute();
130 
132  // overwrite the execute-methode from DefaultVisitor
133  virtual void visitBeamline(const Beamline &);
134 
136  virtual void visitCCollimator(const CCollimator &);
137 
139  virtual void visitCorrector(const Corrector &);
140 
142  virtual void visitDegrader(const Degrader &);
143 
145  virtual void visitDrift(const Drift &);
146 
148  virtual void visitFlexibleCollimator(const FlexibleCollimator &);
149 
151  virtual void visitMarker(const Marker &);
152 
154  virtual void visitMonitor(const Monitor &);
155 
157  virtual void visitMultipole(const Multipole &);
158 
160  virtual void visitProbe(const Probe &);
161 
163  virtual void visitRBend(const RBend &);
164 
166  virtual void visitRFCavity(const RFCavity &);
167 
169  virtual void visitSBend(const SBend &);
170 
172  virtual void visitSeptum(const Septum &);
173 
175  virtual void visitSolenoid(const Solenoid &);
176 
178  virtual void visitTravelingWave(const TravelingWave &);
179 
181  virtual void visitVacuum(const Vacuum &);
182 
183  void prepareSections();
184 
185  /*
186  void insertFringeField(SBend* pSBend, std::list<structMapTracking>& mBL, double& beta0,
187  double& gamma0, double& P0, double& q, std::array<double,2>& entrFringe, std::string e);
188  */
189 
190 private:
191 
192  // Not implemented.
193  ThickTracker() = delete;
194  ThickTracker(const ThickTracker &) = delete;
195  void operator=(const ThickTracker &) = delete;
196 
197  void throwElementError_m(std::string element) {
198  throw LogicalError("ThickTracker::execute()",
199  "Element '" + element + "' not supported.");
200  }
201 
205  void checkElementOrder_m();
206 
210  void fillGaps_m();
211 
215  void track_m();
216 
218  const Vector_t& P) const;
219 
220  void vectorToParticle_m(const particle_t& particle,
221  Vector_t& R,
222  Vector_t& P) const;
223 
228  void advanceParticles_m(const map_t& map);
229 
235  void updateParticle_m(particle_t& particle,
236  const map_t& map);
237 
241  void dump_m();
242 
243 
249  void update_m(const double& spos,
250  const std::size_t& step);
251 
252 
257  void write_m(const map_t& map);
258 
267  void concatenateMaps_m(const map_t& x, map_t& y);
268 
269 
288  void advanceDispersion_m(fMatrix_t tempMatrix,
289  FMatrix<double, 1, 4> initialVal,
290  double pos);
291 
300  void applyEntranceFringe(double edge, double curve,
301  const BMultipoleField &field, double scale);
302 
311  void applyExitFringe(double edge, double curve,
312  const BMultipoleField &field, double scale);
313 
315 
318 
320 
322 
323  double zstart_m;
324  double zstop_m;
325  double threshold_m;
327 
329 
331 
335 };
336 
337 
338 inline void ThickTracker::visitCCollimator(const CCollimator &/*coll*/) {
339 // itsOpalBeamline_m.visit(coll, *this, itsBunch_m);
340  this->throwElementError_m("CCollimator");
341 }
342 
343 
344 inline void ThickTracker::visitCorrector(const Corrector &/*coll*/) {
345 // itsOpalBeamline_m.visit(corr, *this, itsBunch_m);
346  this->throwElementError_m("Corrector");
347 }
348 
349 
350 inline void ThickTracker::visitDegrader(const Degrader &/*deg*/) {
351 // itsOpalBeamline_m.visit(deg, *this, itsBunch_m);
352  this->throwElementError_m("Degrader");
353 }
354 
355 
356 inline void ThickTracker::visitDrift(const Drift &drift) {
357  itsOpalBeamline_m.visit(drift, *this, itsBunch_m);
358 
359  double gamma = itsReference.getGamma();
360  std::size_t nSlices = drift.getNSlices();
361  double length = drift.getElementLength();
362 
363  elements_m.push_back(std::make_tuple(hamiltonian_m.drift(gamma),
364  nSlices,
365  length));
366 }
367 
368 
370 // itsOpalBeamline_m.visit(coll, *this, itsBunch_m);
371  this->throwElementError_m("FlexibleCollimator");
372 }
373 
374 
375 inline void ThickTracker::visitMarker(const Marker &/*marker*/) {
376 // itsOpalBeamline_m.visit(marker, *this, itsBunch_m);
377 // this->throwElementError_m("Marker");
378 }
379 
380 
381 inline void ThickTracker::visitMonitor(const Monitor &/*mon*/) {
382 // itsOpalBeamline_m.visit(mon, *this, itsBunch_m);
383  this->throwElementError_m("Monitor");
384 }
385 
386 
387 inline void ThickTracker::visitMultipole(const Multipole &mult) {
388  itsOpalBeamline_m.visit(mult, *this, itsBunch_m);
389 
390  std::size_t nSlices = mult.getNSlices();
391  double length = mult.getElementLength();
392  double gamma = itsReference.getGamma();
393  double p0 = itsReference.getP();
394  double q = itsReference.getQ(); // particle change [e]
395  double gradB = mult.getField().getNormalComponent(2) * ( Physics::c/ p0 ); // [T / m]
396  //FIXME remove the next line
397  gradB = std::round(gradB*1e6)*1e-6;
398 
399  double k1 = gradB * q *Physics::c / p0; // [1 / m^2]
400 
401  elements_m.push_back(std::make_tuple(hamiltonian_m.quadrupole(gamma, q, k1),
402  nSlices,
403  length));
404 }
405 
406 
407 inline void ThickTracker::visitProbe(const Probe &/*probe*/) {
408 // itsOpalBeamline_m.visit(prob, *this, itsBunch_m);
409  this->throwElementError_m("Probe");
410 }
411 
412 
413 inline void ThickTracker::visitRBend(const RBend &/*bend*/) {
414 // itsOpalBeamline_m.visit(bend, *this, itsBunch_m);
415  this->throwElementError_m("RBend");
416 }
417 
418 
419 inline void ThickTracker::visitRFCavity(const RFCavity &/*as*/) {
420 // itsOpalBeamline_m.visit(as, *this, itsBunch_m);
421  this->throwElementError_m("RFCavity");
422 }
423 
424 
425 inline void ThickTracker::visitSBend(const SBend &bend) {
426  itsOpalBeamline_m.visit(bend, *this, itsBunch_m);
427 
428  double q = itsReference.getQ(); // particle change [e]
429  double ekin = bend.getDesignEnergy();
430 
431  double m = itsReference.getM(); // eV / c^2
432  double gamma = ekin / m + 1.0;
433  double beta = std::sqrt(1.0 - 1.0 / ( gamma * gamma ) );
434  double p0 = gamma * beta * m; // eV / c
435 
436  double B = bend.getB() * Physics::c / p0; // T = V * s / m^2
437  double r = std::abs(p0 / ( q * B * Physics::c )); // m
438 
439  double k0 = B * q * Physics::c / p0; // V * s * e * m / (m^2 * s * c )
440 
441  // [1/m]
442  double h = 1.0 / r;
443 
444  double L = bend.getElementLength();
445 
446  if ( k0 < 0.0 )
447  h *= -1.0;
448 
449  std::size_t nSlices = bend.getNSlices();
450 
451  double arclength = 2.0 * r * std::asin( L / ( 2.0 * r ) ); //bend.getEffectiveLength();
452 
453  // Fringe fields currently not working
454  //FIXME e1 not initialised
455  //insert Entrance Fringefield
456  double e1 = bend.getEntranceAngle();
457  if (std::abs(e1) > 1e-6){
458  elements_m.push_back(std::make_tuple(hamiltonian_m.fringeField(e1, h),
459  1, 0.0));
460  }
461 
462  //insert Dipole "body"
463  elements_m.push_back(std::make_tuple(hamiltonian_m.sbend(gamma, h, k0),
464  nSlices,
465  arclength));
466 
467  //FIXME e2 not initialised
468  //insert Exit Fringe field
469  double e2 = bend.getExitAngle();
470  if (std::abs(e2) > 1e-6){
471  elements_m.push_back(std::make_tuple(hamiltonian_m.fringeField(e2, h),
472  1, 0.0));
473  }
474 }
475 
476 
477 inline void ThickTracker::visitSeptum(const Septum &/*sept*/) {
478 // itsOpalBeamline_m.visit(sept, *this, itsBunch_m);
479  this->throwElementError_m("Septum");
480 }
481 
482 
483 inline void ThickTracker::visitSolenoid(const Solenoid &/*solenoid*/) {
484 // itsOpalBeamline_m.visit(solenoid, *this, itsBunch_m);
485  this->throwElementError_m("Solenoid");
486 }
487 
488 
490 // itsOpalBeamline_m.visit(as, *this, itsBunch_m);
491  this->throwElementError_m("TravelingWave");
492 }
493 
494 
495 inline void ThickTracker::visitVacuum(const Vacuum &/*vac*/) {
496  //itsOpalBeamline_m.visit(vac, *this, itsBunch_m);
497  this->throwElementError_m("Vacuum");
498 }
499 
500 #endif // OPAL_ThickTracker_HH
Hamiltonian::series_t drift(const double &gamma0)
Definition: Hamiltonian.cpp:37
A templated representation for vectors.
Definition: FTps.h:34
double threshold_m
Threshold for element overlaps and gaps.
Definition: ThickTracker.h:325
virtual void visitSBend(const SBend &)
Apply the algorithm to a sector bend.
Definition: ThickTracker.h:425
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
particle_t particleToVector_m(const Vector_t &R, const Vector_t &P) const
std::size_t getNSlices() const
Definition: Bend2D.cpp:1649
double getQ() const
The constant charge per particle.
Definition: PartData.h:118
Hamiltonian::series_t series_t
Definition: ThickTracker.h:89
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a solenoid.
Definition: ThickTracker.h:483
Interface for a marker.
Definition: Marker.h:32
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Hamiltonian::series_t fringeField(const double &phi, const double &k0)
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
Definition: ThickTracker.h:338
double zstart_m
Start of beam line.
Definition: ThickTracker.h:323
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
Definition: ThickTracker.h:387
Hamiltonian::series_t quadrupole(const double &gamma0, const double &q, const double &k1)
void applyEntranceFringe(double edge, double curve, const BMultipoleField &field, double scale)
virtual ~ThickTracker()
Definition: TSVMeta.h:24
FVps< double, 6 > map_t
Definition: ThickTracker.h:90
Interface for solenoids.
Definition: Solenoid.h:36
Hamiltonian hamiltonian_m
Definition: ThickTracker.h:314
FVector< double, 6 > particle_t
Definition: ThickTracker.h:91
Track using thick-lens algorithm.
Definition: ThickTracker.h:86
IpplTimings::TimerRef mapCombination_m
map accumulation along elements_m -&gt; Transfermap
Definition: ThickTracker.h:333
An abstract sequence of beam line components.
Definition: Beamline.h:34
Interface for general multipole.
Definition: Multipole.h:47
double getNormalComponent(int n) const
Get component.
Hamiltonian::series_t sbend(const double &gamma0, const double &h, const double &k0)
Definition: Hamiltonian.cpp:76
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
Definition: ThickTracker.h:369
Interface for drift space.
Definition: Drift.h:33
Definition: SBend.h:68
virtual void visitProbe(const Probe &)
Apply the algorithm to a probe.
Definition: ThickTracker.h:407
Interface for general corrector.
Definition: Corrector.h:35
void fillGaps_m()
Fills undefined beam path with a Drift Space.
Definition: Vacuum.h:61
double getM() const
The constant mass per particle.
Definition: PartData.h:122
Vector_t RefPartP_m
Definition: ThickTracker.h:317
void vectorToParticle_m(const particle_t &particle, Vector_t &R, Vector_t &P) const
std::list< tuple_t > beamline_t
Definition: ThickTracker.h:93
IpplTimings::TimerRef mapTracking_m
track particles trough maps of elements_m
Definition: ThickTracker.h:334
void advanceParticles_m(const map_t &map)
DataSink * itsDataSink_m
Definition: ThickTracker.h:319
Timing::TimerRef TimerRef
Definition: IpplTimings.h:176
void advanceDispersion_m(fMatrix_t tempMatrix, FMatrix< double, 1, 4 > initialVal, double pos)
Writes Dispersion in X and Y plane.
virtual void visitSeptum(const Septum &)
Apply the algorithm to a septum.
Definition: ThickTracker.h:477
virtual BMultipoleField & getField() override=0
Get multipole field.
double getEntranceAngle() const
Definition: BendBase.h:103
clearpage the user may choose between constant or variable radius This model includes fringe fields L
Definition: multipole_t.tex:7
virtual void execute()
Apply the algorithm to the top-level beamline.
beamline_t elements_m
elements in beam line
Definition: ThickTracker.h:326
Vector_t RefPartR_m
Definition: ThickTracker.h:316
OpalBeamline itsOpalBeamline_m
Definition: ThickTracker.h:321
void updateParticle_m(particle_t &particle, const map_t &map)
std::size_t getNSlices() const
Definition: Drift.cpp:68
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
Definition: ThickTracker.h:413
std::size_t getNSlices() const
Definition: Multipole.cpp:147
void operator=(const ThickTracker &)=delete
CoordinateSystemTrafo referenceToLabCSTrafo_m
Definition: ThickTracker.h:328
const PartData itsReference
The reference information.
void concatenateMaps_m(const map_t &x, map_t &y)
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:415
void applyExitFringe(double edge, double curve, const BMultipoleField &field, double scale)
IpplTimings::TimerRef mapCreation_m
creation of elements_m
Definition: ThickTracker.h:332
Definition: RBend.h:58
Vector truncated power series in n variables.
Definition: Component.h:34
std::tuple< series_t, std::size_t, double > tuple_t
Definition: ThickTracker.h:92
void write_m(const map_t &map)
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a beam position monitor.
Definition: ThickTracker.h:381
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
Definition: ThickTracker.h:375
void checkElementOrder_m()
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
Definition: ThickTracker.h:419
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
Definition: Tracker.h:151
virtual void visitVacuum(const Vacuum &)
Apply the algorithm to a vacuum space.
Definition: ThickTracker.h:495
int truncOrder_m
truncation order of map tracking
Definition: ThickTracker.h:330
void visit(const T &, BeamlineVisitor &, PartBunchBase< double, 3 > *)
Definition: OpalBeamline.h:105
Definition: Probe.h:28
virtual double getExitAngle() const override
Definition: Bend2D.h:326
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift space.
Definition: ThickTracker.h:356
double getDesignEnergy() const
Definition: BendBase.h:126
constexpr double e
The value of .
Definition: Physics.h:39
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a closed orbit corrector.
Definition: ThickTracker.h:344
void update_m(const double &spos, const std::size_t &step)
void throwElementError_m(std::string element)
Definition: ThickTracker.h:197
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:126
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Definition: PETE.h:726
Definition: Septum.h:23
virtual double getB() const =0
Get dipole field of SBend.
ThickTracker()=delete
Definition: Beam.h:31
Logical error exception.
Definition: LogicalError.h:33
FMatrix< double, 6, 6 > fMatrix_t
Definition: ThickTracker.h:94
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a degrader.
Definition: ThickTracker.h:350
virtual void visitTravelingWave(const TravelingWave &)
Apply the algorithm to a traveling wave.
Definition: ThickTracker.h:489
void prepareSections()
The magnetic field of a multipole.
double zstop_m
End of beam line.
Definition: ThickTracker.h:324
double getGamma() const
The relativistic gamma per particle.
Definition: PartData.h:138