OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
314 
316 
317 
320 
322 
324 
325  double zstart_m;
326  double zstop_m;
327  double threshold_m;
329 
331 
332 
334 
338 };
339 
340 
341 inline void ThickTracker::visitCCollimator(const CCollimator &/*coll*/) {
342 // itsOpalBeamline_m.visit(coll, *this, itsBunch_m);
343  this->throwElementError_m("CCollimator");
344 }
345 
346 
347 inline void ThickTracker::visitCorrector(const Corrector &/*coll*/) {
348 // itsOpalBeamline_m.visit(corr, *this, itsBunch_m);
349  this->throwElementError_m("Corrector");
350 }
351 
352 
353 inline void ThickTracker::visitDegrader(const Degrader &/*deg*/) {
354 // itsOpalBeamline_m.visit(deg, *this, itsBunch_m);
355  this->throwElementError_m("Degrader");
356 }
357 
358 
359 inline void ThickTracker::visitDrift(const Drift &drift) {
360  itsOpalBeamline_m.visit(drift, *this, itsBunch_m);
361 
362 
363  double gamma = itsReference.getGamma();
364  std::size_t nSlices = drift.getNSlices();
365  double length = drift.getElementLength();
366 
367  elements_m.push_back(std::make_tuple(hamiltonian_m.drift(gamma),
368  nSlices,
369  length));
370 }
371 
372 
374 // itsOpalBeamline_m.visit(coll, *this, itsBunch_m);
375  this->throwElementError_m("FlexibleCollimator");
376 }
377 
378 
379 
380 inline void ThickTracker::visitMarker(const Marker &/*marker*/) {
381 // itsOpalBeamline_m.visit(marker, *this, itsBunch_m);
382 // this->throwElementError_m("Marker");
383 }
384 
385 
386 inline void ThickTracker::visitMonitor(const Monitor &/*mon*/) {
387 // itsOpalBeamline_m.visit(mon, *this, itsBunch_m);
388  this->throwElementError_m("Monitor");
389 }
390 
391 
392 inline void ThickTracker::visitMultipole(const Multipole &mult) {
393  itsOpalBeamline_m.visit(mult, *this, itsBunch_m);
394 
395  std::size_t nSlices = mult.getNSlices();
396  double length = mult.getElementLength();
397  double gamma = itsReference.getGamma();
398  double p0 = itsReference.getP();
399  double q = itsReference.getQ(); // particle change [e]
400  double gradB = mult.getField().getNormalComponent(2) * ( Physics::c/ p0 ); // [T / m]
401  //FIXME remove the next line
402  gradB = std::round(gradB*1e6)*1e-6;
403 
404  double k1 = gradB * q *Physics::c / p0; // [1 / m^2]
405 
406  elements_m.push_back(std::make_tuple(hamiltonian_m.quadrupole(gamma, q, k1),
407  nSlices,
408  length));
409 }
410 
411 inline void ThickTracker::visitProbe(const Probe &/*probe*/) {
412 // itsOpalBeamline_m.visit(prob, *this, itsBunch_m);
413  this->throwElementError_m("Probe");
414 }
415 
416 
417 inline void ThickTracker::visitRBend(const RBend &/*bend*/) {
418 // itsOpalBeamline_m.visit(bend, *this, itsBunch_m);
419  this->throwElementError_m("RBend");
420 }
421 
422 
423 inline void ThickTracker::visitRFCavity(const RFCavity &/*as*/) {
424 // itsOpalBeamline_m.visit(as, *this, itsBunch_m);
425  this->throwElementError_m("RFCavity");
426 }
427 
428 
429 inline void ThickTracker::visitSBend(const SBend &bend) {
430  itsOpalBeamline_m.visit(bend, *this, itsBunch_m);
431 
432  double q = itsReference.getQ(); // particle change [e]
433  double ekin = bend.getDesignEnergy();
434 
435  double m = itsReference.getM(); // eV / c^2
436  double gamma = ekin / m + 1.0;
437  double beta = std::sqrt(1.0 - 1.0 / ( gamma * gamma ) );
438  double p0 = gamma * beta * m; // eV / c
439 
440  double B = bend.getB() * Physics::c / p0; // T = V * s / m^2
441  double r = std::abs(p0 / ( q * B * Physics::c )); // m
442 
443  double k0 = B * q * Physics::c / p0; // V * s * e * m / (m^2 * s * c )
444 
445  // [1/m]
446  double h = 1.0 / r;
447 
448  double L = bend.getElementLength();
449 
450  if ( k0 < 0.0 )
451  h *= -1.0;
452 
453  std::size_t nSlices = bend.getNSlices();
454 
455  double arclength = 2.0 * r * std::asin( L / ( 2.0 * r ) ); //bend.getEffectiveLength();
456 
457  // Fringe fields currently not working
458  //FIXME e1 not initialised
459  //insert Entrance Fringefield
460  double e1 = bend.getEntranceAngle();
461  if (std::abs(e1) > 1e-6){
462  elements_m.push_back(std::make_tuple(hamiltonian_m.fringeField(e1, h),
463  1, 0.0));
464  }
465 
466  //insert Dipole "body"
467  elements_m.push_back(std::make_tuple(hamiltonian_m.sbend(gamma, h, k0),
468  nSlices,
469  arclength));
470 
471  //FIXME e2 not initialised
472  //insert Exit Fringe field
473  double e2 = bend.getExitAngle();
474  if (std::abs(e2) > 1e-6){
475  elements_m.push_back(std::make_tuple(hamiltonian_m.fringeField(e2, h),
476  1, 0.0));
477  }
478 
479 }
480 
481 
482 inline void ThickTracker::visitSeptum(const Septum &/*sept*/) {
483 // itsOpalBeamline_m.visit(sept, *this, itsBunch_m);
484  this->throwElementError_m("Septum");
485 }
486 
487 
488 inline void ThickTracker::visitSolenoid(const Solenoid &/*solenoid*/) {
489 // itsOpalBeamline_m.visit(solenoid, *this, itsBunch_m);
490  this->throwElementError_m("Solenoid");
491 }
492 
493 
495 // itsOpalBeamline_m.visit(as, *this, itsBunch_m);
496  this->throwElementError_m("TravelingWave");
497 }
498 
499 
500 inline void ThickTracker::visitVacuum(const Vacuum &vac) {
501  itsOpalBeamline_m.visit(vac, *this, itsBunch_m);
502 }
503 
504 #endif // OPAL_ThickTracker_HH
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Definition: PETE.h:726
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
Hamiltonian::series_t sbend(const double &gamma0, const double &h, const double &k0)
Definition: Hamiltonian.cpp:76
Hamiltonian::series_t drift(const double &gamma0)
Definition: Hamiltonian.cpp:37
Hamiltonian::series_t quadrupole(const double &gamma0, const double &q, const double &k1)
Hamiltonian::series_t fringeField(const double &phi, const double &k0)
Track using thick-lens algorithm.
Definition: ThickTracker.h:86
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a solenoid.
Definition: ThickTracker.h:488
Vector_t RefPartP_m
Definition: ThickTracker.h:319
FVps< double, 6 > map_t
Definition: ThickTracker.h:90
OpalBeamline itsOpalBeamline_m
Definition: ThickTracker.h:323
void advanceDispersion_m(fMatrix_t tempMatrix, FMatrix< double, 1, 4 > initialVal, double pos)
Writes Dispersion in X and Y plane.
int truncOrder_m
truncation order of map tracking
Definition: ThickTracker.h:333
void throwElementError_m(std::string element)
Definition: ThickTracker.h:197
std::list< tuple_t > beamline_t
Definition: ThickTracker.h:93
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
Definition: ThickTracker.h:373
particle_t particleToVector_m(const Vector_t &R, const Vector_t &P) const
virtual void visitSBend(const SBend &)
Apply the algorithm to a sector bend.
Definition: ThickTracker.h:429
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
Definition: ThickTracker.h:423
Vector_t RefPartR_m
Definition: ThickTracker.h:318
void fillGaps_m()
Fills undefined beam path with a Drift Space.
virtual void visitTravelingWave(const TravelingWave &)
Apply the algorithm to a traveling wave.
Definition: ThickTracker.h:494
void applyExitFringe(double edge, double curve, const BMultipoleField &field, double scale)
CoordinateSystemTrafo referenceToLabCSTrafo_m
Definition: ThickTracker.h:330
void advanceParticles_m(const map_t &map)
double threshold_m
Threshold for element overlaps and gaps.
Definition: ThickTracker.h:327
void applyEntranceFringe(double edge, double curve, const BMultipoleField &field, double scale)
beamline_t elements_m
elements in beam line
Definition: ThickTracker.h:328
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
void prepareSections()
virtual void visitSeptum(const Septum &)
Apply the algorithm to a septum.
Definition: ThickTracker.h:482
virtual void visitProbe(const Probe &)
Apply the algorithm to a probe.
Definition: ThickTracker.h:411
void concatenateMaps_m(const map_t &x, map_t &y)
void operator=(const ThickTracker &)=delete
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift space.
Definition: ThickTracker.h:359
void updateParticle_m(particle_t &particle, const map_t &map)
void write_m(const map_t &map)
ThickTracker()=delete
Hamiltonian hamiltonian_m
Definition: ThickTracker.h:315
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a degrader.
Definition: ThickTracker.h:353
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a beam position monitor.
Definition: ThickTracker.h:386
void vectorToParticle_m(const particle_t &particle, Vector_t &R, Vector_t &P) const
IpplTimings::TimerRef mapTracking_m
track particles trough maps of elements_m
Definition: ThickTracker.h:337
IpplTimings::TimerRef mapCombination_m
map accumulation along elements_m -> Transfermap
Definition: ThickTracker.h:336
std::tuple< series_t, std::size_t, double > tuple_t
Definition: ThickTracker.h:92
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
Definition: ThickTracker.h:380
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
Definition: ThickTracker.h:341
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
Definition: ThickTracker.h:392
virtual void execute()
Apply the algorithm to the top-level beamline.
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a closed orbit corrector.
Definition: ThickTracker.h:347
virtual ~ThickTracker()
ThickTracker(const ThickTracker &)=delete
void update_m(const double &spos, const std::size_t &step)
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
Definition: ThickTracker.h:417
Hamiltonian::series_t series_t
Definition: ThickTracker.h:89
void checkElementOrder_m()
virtual void visitVacuum(const Vacuum &)
Apply the algorithm to a vacuum space.
Definition: ThickTracker.h:500
double zstart_m
Start of beam line.
Definition: ThickTracker.h:325
FMatrix< double, 6, 6 > fMatrix_t
Definition: ThickTracker.h:94
DataSink * itsDataSink_m
Definition: ThickTracker.h:321
double zstop_m
End of beam line.
Definition: ThickTracker.h:326
FVector< double, 6 > particle_t
Definition: ThickTracker.h:91
IpplTimings::TimerRef mapCreation_m
creation of elements_m
Definition: ThickTracker.h:335
virtual double getExitAngle() const override
Definition: Bend2D.h:326
std::size_t getNSlices() const
Definition: Bend2D.cpp:1641
double getDesignEnergy() const
Definition: BendBase.h:126
double getEntranceAngle() const
Definition: BendBase.h:103
Vector truncated power series in n variables.
Definition: FVps.h:39
Interface for general corrector.
Definition: Corrector.h:35
Interface for drift space.
Definition: Drift.h:33
std::size_t getNSlices() const
Definition: Drift.cpp:68
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:432
Interface for a marker.
Definition: Marker.h:32
Interface for general multipole.
Definition: Multipole.h:47
virtual BMultipoleField & getField() override=0
Get multipole field.
std::size_t getNSlices() const
Definition: Multipole.cpp:147
Definition: Probe.h:28
Definition: RBend.h:58
Interface for RF cavity.
Definition: RFCavity.h:37
Definition: SBend.h:68
virtual double getB() const =0
Get dipole field of SBend.
Definition: Septum.h:23
Interface for solenoids.
Definition: Solenoid.h:36
Interface for Traveling Wave.
Definition: TravelingWave.h:37
Definition: Vacuum.h:67
const PartData itsReference
The reference information.
Particle reference data.
Definition: PartData.h:35
double getQ() const
The constant charge per particle.
Definition: PartData.h:104
double getGamma() const
The relativistic gamma per particle.
Definition: PartData.h:129
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:114
double getM() const
The constant mass per particle.
Definition: PartData.h:109
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
Definition: Tracker.h:151
An abstract sequence of beam line components.
Definition: Beamline.h:34
The magnetic field of a multipole.
double getNormalComponent(int n) const
Get component.
A templated representation for vectors.
Definition: FVector.h:38
Logical error exception.
Definition: LogicalError.h:33
void visit(const T &, BeamlineVisitor &, PartBunchBase< double, 3 > *)
Definition: OpalBeamline.h:105
Definition: Beam.h:32
Timing::TimerRef TimerRef
Definition: IpplTimings.h:176