OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
ParallelCyclotronTracker.h
Go to the documentation of this file.
1//
2// Class ParallelCyclotronTracker
3// Tracker for OPAL-Cycl
4//
5// Copyright (c) 2007 - 2014, Jianjun Yang, Andreas Adelmann and Matthias Toggweiler,
6// Paul Scherrer Institut, Villigen PSI, Switzerland
7// Copyright (c) 2014, Daniel Winklehner, MIT, Cambridge, MA, USA
8// Copyright (c) 2012 - 2022, Paul Scherrer Institut, Villigen PSI, Switzerland
9// All rights reserved
10//
11// Implemented as part of the PhD thesis
12// "Beam dynamics in high intensity cyclotrons including neighboring bunch effects"
13// and the paper
14// "Beam dynamics in high intensity cyclotrons including neighboring bunch effects:
15// Model, implementation, and application"
16// (https://journals.aps.org/prab/pdf/10.1103/PhysRevSTAB.13.064201)
17//
18// This file is part of OPAL.
19//
20// OPAL is free software: you can redistribute it and/or modify
21// it under the terms of the GNU General Public License as published by
22// the Free Software Foundation, either version 3 of the License, or
23// (at your option) any later version.
24//
25// You should have received a copy of the GNU General Public License
26// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
27//
28#ifndef OPAL_ParallelCyclotronTracker_HH
29#define OPAL_ParallelCyclotronTracker_HH
30
33#include "Algorithms/Tracker.h"
34#include "Steppers/Steppers.h"
35
36#include <memory>
37#include <tuple>
38#include <vector>
39
40class DataSink;
41class PluginElement;
42class LossDataSink;
43
44template <class T, unsigned Dim>
45class PartBunchBase;
46
49 double sinAzimuth;
50 double cosAzimuth;
52};
53
55
56public:
57 typedef std::vector<double> dvector_t;
58 typedef std::vector<int> ivector_t;
59 typedef std::pair<double[8], Component*> element_pair;
60 typedef std::pair<ElementType, element_pair> type_pair;
61 typedef std::list<type_pair*> beamline_list;
62
64 // The beam line to be tracked is "bl".
65 // The particle reference data are taken from "data".
66 // The particle bunch tracked is taken from [b]bunch[/b].
67 // If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
68 // If [b]revTrack[/b] is true, we track against the beam.
70 const PartData& data, bool revBeam,
71 bool revTrack, int maxSTEPS,
72 Steppers::TimeIntegrator timeintegrator,
73 const int& numBunch,
74 const double& mbEta,
75 const double& mbPara,
76 const std::string& mbMode,
77 const std::string& mbBinning);
78
80
82 // overwrite the execute-methode from DefaultVisitor
83 virtual void execute();
84
86 // R - position
87 // P - momentum; note the field is returned in the lab frame
88 // t - time
89 // Efield - filled with values for the electric field
90 // Bfield - filled with values for the magnetic field
91 // Returns a boolean value, true if the particle was out of the nominal
92 // field map boundary, else false.
94 const Vector_t& P,
95 const double& t,
96 Vector_t& Efield,
97 Vector_t& Bfield);
98
100 // overwrite the execute-methode from DefaultVisitor
101 virtual void visitBeamline(const Beamline&);
102
104 virtual void visitCCollimator(const CCollimator&);
105
107 virtual void visitCorrector(const Corrector&);
108
110 virtual void visitCyclotron(const Cyclotron& cycl);
111
113 virtual void visitDegrader(const Degrader&);
114
116 virtual void visitDrift(const Drift&);
117
119 virtual void visitFlexibleCollimator(const FlexibleCollimator&);
120
122 virtual void visitMarker(const Marker&);
123
125 virtual void visitMonitor(const Monitor&);
126
128 virtual void visitMultipole(const Multipole&);
129
131 virtual void visitMultipoleT(const MultipoleT&);
132
134 virtual void visitMultipoleTStraight(const MultipoleTStraight&);
135
138
141
143 virtual void visitOffset(const Offset&);
144
146 virtual void visitProbe(const Probe&);
147
149 virtual void visitRBend(const RBend&);
150
152 virtual void visitRFCavity(const RFCavity&);
153
155 virtual void visitRing(const Ring& ring);
156
158 virtual void visitSBend(const SBend&);
159
161 virtual void visitSBend3D(const SBend3D&);
162
164 virtual void visitScalingFFAMagnet(const ScalingFFAMagnet& bend);
165
167 virtual void visitSeptum(const Septum&);
168
170 virtual void visitSolenoid(const Solenoid&);
171
173 virtual void visitStripper(const Stripper&);
174
176 virtual void visitVacuum(const Vacuum&);
177
179 virtual void visitVariableRFCavity(const VariableRFCavity& cav);
180
183
185 virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet& bend);
186
188 inline void setLastDumpedStep(const int para) { lastDumpedStep_m = para; }
189
191 inline void setPr(double x) {referencePr = x;}
192 inline void setPt(double x) {referencePt = x;}
193 inline void setPz(double x) {referencePz = x;}
194 inline void setR(double x) {referenceR = x;}
195 inline void setTheta(double x) {referenceTheta = x;}
196 inline void setZ(double x) {referenceZ = x;}
197 inline void setBeGa(double x) {bega = x;}
198 inline void setPhi(double x) {referencePhi = x;}
199 inline void setPsi(double x) {referencePsi = x;}
200 inline void setPreviousH5Local(bool x) {previousH5Local = x;}
204
205private:
206 enum class TrackingMode: unsigned short {
207 UNDEFINED,
208 SINGLE,
209 SEO,
210 BUNCH
211 };
212
213 // Not implemented.
217
219 std::list<Component*> myElements;
221 std::vector<PluginElement*> pluginElements_m;
222 std::vector<CavityCrossData> cavCrossDatas_m;
223
225
227
229
232
234 static Vector_t const xaxis;
235 static Vector_t const yaxis;
236 static Vector_t const zaxis;
237
239 double bega;
242 double referenceZ = 0.0;
243
246 double referencePz = 0.0;
248
251
252 bool spiral_flag = false;
253
255
257
260
261 // only used for multi-bunch mode
262 std::unique_ptr<MultiBunchHandler> mbHandler_m;
263
265
266 // for each bunch we have a path length
268 // Multi time step tracker
269 void MtsTracker();
270
271 void GenericTracker();
272 bool getFieldsAtPoint(const double& t, const size_t& Pindex, Vector_t& Efield, Vector_t& Bfield);
273
274 /*
275 Local Variables both used by the integration methods
276 */
277
278 long long step_m;
279 long long restartStep0_m;
280
282
283 // only for dumping
284 double azimuth_m;
286
287 /* only for dumping to stat-file --> make azimuth monotonically increasing
288 * @param theta computed azimuth [deg]
289 * @param prevAzimuth previous angle [deg]
290 * @param azimuth to be updated [deg]
291 * @param bunchNr in restart mode only --> to compute initial azimuth
292 */
293 void dumpAngle(const double& theta,
294 double& prevAzimuth,
295 double& azimuth,
296 const short& bunchNr = 0);
297
298 double computeRadius(const Vector_t& meanR) const;
299
300 void computePathLengthUpdate(std::vector<double>& dl, const double& dt);
301
302 // external field arrays for dumping
304
305 const int myNode_m;
306 const size_t initialLocalNum_m;
307 const size_t initialTotalNum_m;
308
310 std::vector<std::unique_ptr<std::ofstream> > outfTheta_m;
312 std::vector<double> azimuth_angle_m;
314 void openFiles(size_t numFiles, std::string fn);
315 void closeFiles();
318 std::ofstream outfTrackOrbit_m;
319
320 void buildupFieldList(double BcParameter[], ElementType elementType, Component* elptr);
321
322 // angle range [0~2PI) degree
323 double calculateAngle(double x, double y);
324 // angle range [-PI~PI) degree
325 double calculateAngle2(double x, double y);
326
327 bool checkGapCross(Vector_t Rold, Vector_t Rnew, RFCavity* rfcavity, double& DistOld);
328 bool RFkick(RFCavity* rfcavity, const double t, const double dt, const int Pindex);
329
330 bool getTunes(dvector_t& t, dvector_t& r, dvector_t& z, int lastTurn, double& nur, double& nuz);
331
338
339 /*
340 * @param bunchNr if <= -1 --> take all particles in simulation, if bunchNr > -1,
341 * take only particles of *this* bunch
342 */
343 Vector_t calcMeanR(short bunchNr = -1) const;
344
345 Vector_t calcMeanP() const;
346
347 void repartition(); // Do repartition between nodes if step_m is multiple of Options::repartFreq
348
349 // Transform the x- and y-parts of a particle attribute (position, momentum, fields) from the
350 // global reference frame to the local reference frame.
351
352 // phi is the angle of the bunch measured counter-clockwise from the positive x-axis.
353 void globalToLocal(ParticleAttrib<Vector_t>& vectorArray,
354 double phi, Vector_t const translationToGlobal = 0);
355
356 // Transform the x- and y-parts of a particle attribute (position, momentum, fields) from the
357 // local reference frame to the global reference frame.
358 void localToGlobal(ParticleAttrib<Vector_t>& vectorArray,
359 double phi, Vector_t const translationToGlobal = 0);
360
361 // Overloaded version of globalToLocal using a quaternion for 3D rotation
362 inline void globalToLocal(ParticleAttrib<Vector_t>& vectorArray,
363 Quaternion_t const quaternion,
364 Vector_t const meanR = Vector_t(0.0));
365
366 // Overloaded version of localToGlobal using a quaternion for 3D rotation
367 inline void localToGlobal(ParticleAttrib<Vector_t>& vectorArray,
368 Quaternion_t const quaternion,
369 Vector_t const meanR = Vector_t(0.0));
370
371 // Overloaded version of globalToLocal using phi and theta for pseudo 3D rotation
372 inline void globalToLocal(ParticleAttrib<Vector_t>& particleVectors,
373 double const phi, double const psi,
374 Vector_t const meanR = Vector_t(0.0));
375
376 // Overloaded version of localToGlobal using phi and theta for pseudo 3D rotation
377 inline void localToGlobal(ParticleAttrib<Vector_t>& particleVectors,
378 double const phi, double const psi,
379 Vector_t const meanR = Vector_t(0.0));
380
381 // Overloaded version of globalToLocal using phi and theta for pseudo 3D rotation, single vector
382 inline void globalToLocal(Vector_t& myVector,
383 double const phi, double const psi,
384 Vector_t const meanR = Vector_t(0.0));
385
386 // Overloaded version of localToGlobal using phi and theta for pseudo 3D rotation, single vector
387 inline void localToGlobal(Vector_t& myVector,
388 double const phi, double const psi,
389 Vector_t const meanR = Vector_t(0.0));
390
391 // Rotate the particles by an angle and axis defined in the quaternion (4-vector w,x,y,z)
392 inline void rotateWithQuaternion(ParticleAttrib<Vector_t>& vectorArray, Quaternion_t const quaternion);
393
394 // Returns the quaternion of the rotation from vector u to vector v
395 inline void getQuaternionTwoVectors(Vector_t u, Vector_t v, Quaternion_t& quaternion);
396
397 // Normalization of a quaternion
398 inline void normalizeQuaternion(Quaternion_t& quaternion);
399
400 // Normalization of a quaternion
401 inline void normalizeVector(Vector_t& vector);
402
403 // Some rotations
404 inline void rotateAroundZ(ParticleAttrib<Vector_t>& particleVectors, double const phi);
405 inline void rotateAroundX(ParticleAttrib<Vector_t>& particleVectors, double const psi);
406 inline void rotateAroundZ(Vector_t& myVector, double const phi);
407 inline void rotateAroundX(Vector_t& myVector, double const psi);
408
409 // Push particles for time h.
410 // Apply effects of RF Gap Crossings.
411 // Unit assumptions: [itsBunch_m->R] = m, [itsBunch_m->P] = 1, [h] = s, [c] = m/s, [itsBunch_m->getT()] = s
412 bool push(double h);
413 // Kick particles for time h
414 // The fields itsBunch_m->Bf, itsBunch_m->Ef are used to calculate the forces
415 bool kick(double h);
416
417 // Apply the trilogy half push - kick - half push,
418 // considering only external fields
419 void borisExternalFields(double h);
420
421 // apply the plugin elements: probe, collimator, stripper, septum
422 bool applyPluginElements(const double dt);
423
424 // destroy particles if they are marked as Bin=-1 in the plugin elements or out of global aperture
425 bool deleteParticle(bool = false);
426
427 void initTrackOrbitFile();
428
429 void singleParticleDump();
430
431 void bunchDumpStatData();
432
434
436
438
439 void setTimeStep();
440
441 void checkFileMomentum();
442
443 void checkNumPart(std::string s);
444
445 // we store a pointer explicitly to the Ring
447
448 // to save geometry losses
449 std::unique_ptr<LossDataSink> lossDs_m;
450
451 // If Ring is defined take the harmonic number from Ring; else use
452 // cyclotron
453 double getHarmonicNumber() const;
454
455 typedef std::function<bool(const double&,
456 const size_t&,
457 Vector_t&,
459
460 std::unique_ptr< Stepper<function_t> > itsStepper_mp;
461
462 struct settings {
468
470
472
474 bool isTurnDone();
475
477 void update_m(double& t, const double& dt, const bool& finishedTurn);
478
482 std::tuple<double, double, double> initializeTracking_m();
483
484 void finalizeTracking_m(dvector_t& Ttime,
485 dvector_t& Tdeltr,
486 dvector_t& Tdeltz,
487 ivector_t& TturnNumber);
488
489 void setTrackingMode();
490
491 void seoMode_m(double& t, const double dt, bool& finishedTurn,
492 dvector_t& Ttime, dvector_t& Tdeltr,
493 dvector_t& Tdeltz, ivector_t& TturnNumber);
494
495 void singleMode_m(double& t, const double dt, bool& finishedTurn, double& oldReferenceTheta);
496
497 void bunchMode_m(double& t, const double dt, bool& finishedTurn);
498
499 void gapCrossKick_m(size_t i, double t, double dt,
500 const Vector_t& Rold, const Vector_t& Pold);
501
502
503 inline void dumpAzimuthAngles_m(const double& t,
504 const Vector_t& R,
505 const Vector_t& P,
506 const double& oldReferenceTheta,
507 const double& temp_meanTheta);
508
509 inline void dumpThetaEachTurn_m(const double& t,
510 const Vector_t& R,
511 const Vector_t& P,
512 const double& temp_meanTheta,
513 bool& finishedTurn);
514
516
517 bool computeExternalFields_m(const size_t& i,
518 const double& t,
519 Vector_t& Efield,
520 Vector_t& Bfield);
521
522 void injectBunch(bool& flagTransition);
523
524 void saveInjectValues();
525
526 bool isMultiBunch() const;
527
528 bool hasMultiBunch() const;
529
530 /*
531 * @param dt time step in ns
532 */
533 void updatePathLength(const double& dt);
534
535 /*
536 * @param dt time step in ns
537 */
538 void updateTime(const double& dt);
539
541
549 void initPathLength();
550};
551
558inline
560 double thetaXY = std::atan2(y, x);
561
562 if (thetaXY < 0) return thetaXY + Physics::two_pi;
563 return thetaXY;
564}
565
572inline
574 return std::atan2(y,x);
575}
576
577
578inline
580 return ( (mbHandler_m != nullptr) && itsBunch_m->weHaveBins() );
581}
582
583
584inline
586 return ( isMultiBunch() && mbHandler_m->getNumBunch() > 1 );
587}
588
589#endif // OPAL_ParallelCyclotronTracker_HH
ElementType
Definition: ElementBase.h:88
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
py::list function(PolynomialPatch *patch, py::list point)
constexpr double two_pi
The value of.
Definition: Physics.h:33
TimeIntegrator
Definition: Steppers.h:25
bool weHaveBins() const
void computePathLengthUpdate(std::vector< double > &dl, const double &dt)
void setLastDumpedStep(const int para)
set last dumped step
std::vector< PluginElement * > pluginElements_m
void dumpAzimuthAngles_m(const double &t, const Vector_t &R, const Vector_t &P, const double &oldReferenceTheta, const double &temp_meanTheta)
IpplTimings::TimerRef IntegrationTimer_m
IpplTimings::TimerRef PluginElemTimer_m
virtual void visitDegrader(const Degrader &)
Apply the algorithm to a degrader.
virtual void visitRBend(const RBend &)
Apply the algorithm to a rectangular bend.
static Vector_t const xaxis
The positive axes unit vectors.
virtual void visitProbe(const Probe &)
Apply the algorithm to a probe.
virtual void visitVacuum(const Vacuum &)
Apply the algorithm to a vacuum space.
void setPr(double x)
Method for restart.
void operator=(const ParallelCyclotronTracker &)
std::function< bool(const double &, const size_t &, Vector_t &, Vector_t &)> function_t
bool computeExternalFields_m(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &Efield, Vector_t &Bfield)
Calculate the field map at an arbitrary point.
std::vector< double > azimuth_angle_m
the different azimuthal angles for the outfTheta_m output files
std::unique_ptr< MultiBunchHandler > mbHandler_m
void injectBunch(bool &flagTransition)
std::pair< double[8], Component * > element_pair
void rotateAroundZ(ParticleAttrib< Vector_t > &particleVectors, double const phi)
virtual void visitStripper(const Stripper &)
Apply the algorithm to a particle stripper.
void normalizeQuaternion(Quaternion_t &quaternion)
virtual void visitCCollimator(const CCollimator &)
Apply the algorithm to a collimator.
void singleMode_m(double &t, const double dt, bool &finishedTurn, double &oldReferenceTheta)
void update_m(double &t, const double &dt, const bool &finishedTurn)
Update time and path length, write to output files.
std::vector< std::unique_ptr< std::ofstream > > outfTheta_m
output coordinates at different azimuthal angles and one after every turn
void rotateAroundX(ParticleAttrib< Vector_t > &particleVectors, double const psi)
double calculateAngle(double x, double y)
bool isTurnDone()
Check if turn done.
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
bool checkGapCross(Vector_t Rold, Vector_t Rnew, RFCavity *rfcavity, double &DistOld)
virtual void visitOffset(const Offset &)
Apply the algorithm to a offset (placement).
IpplTimings::TimerRef DelParticleTimer_m
void normalizeVector(Vector_t &vector)
bool RFkick(RFCavity *rfcavity, const double t, const double dt, const int Pindex)
virtual void visitScalingFFAMagnet(const ScalingFFAMagnet &bend)
Apply the algorithm to a scaling FFA magnet.
double computeRadius(const Vector_t &meanR) const
void updatePathLength(const double &dt)
virtual void visitMultipoleTStraight(const MultipoleTStraight &)
Apply the algorithm to an arbitrary straight multipole.
void openFiles(size_t numFiles, std::string fn)
@ open / close output coordinate files
virtual void visitSBend3D(const SBend3D &)
Apply the algorithm to a sector bend with 3D field map.
double bega
The reference variables.
void dumpAngle(const double &theta, double &prevAzimuth, double &azimuth, const short &bunchNr=0)
bool applyPluginElements(const double dt)
std::list< type_pair * > beamline_list
virtual void visitCorrector(const Corrector &)
Apply the algorithm to a closed orbit corrector.
std::tuple< double, double, double > initializeTracking_m()
std::pair< ElementType, element_pair > type_pair
virtual void visitRing(const Ring &ring)
Apply the algorithm to a ring.
IpplTimings::TimerRef BinRepartTimer_m
void globalToLocal(ParticleAttrib< Vector_t > &vectorArray, double phi, Vector_t const translationToGlobal=0)
bool getFieldsAtPoint(const double &t, const size_t &Pindex, Vector_t &Efield, Vector_t &Bfield)
std::vector< CavityCrossData > cavCrossDatas_m
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift space.
std::unique_ptr< Stepper< function_t > > itsStepper_mp
struct ParallelCyclotronTracker::settings setup_m
void finalizeTracking_m(dvector_t &Ttime, dvector_t &Tdeltr, dvector_t &Tdeltz, ivector_t &TturnNumber)
virtual void visitVariableRFCavityFringeField(const VariableRFCavityFringeField &cav)
Apply the algorithm to a variable RF cavity with Fringe Field.
void gapCrossKick_m(size_t i, double t, double dt, const Vector_t &Rold, const Vector_t &Pold)
void getQuaternionTwoVectors(Vector_t u, Vector_t v, Quaternion_t &quaternion)
virtual void visitSBend(const SBend &)
Apply the algorithm to a sector bend.
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
virtual void execute()
Apply the algorithm to the top-level beamline.
void dumpThetaEachTurn_m(const double &t, const Vector_t &R, const Vector_t &P, const double &temp_meanTheta, bool &finishedTurn)
void bunchMode_m(double &t, const double dt, bool &finishedTurn)
std::list< Component * > myElements
std::unique_ptr< LossDataSink > lossDs_m
virtual void visitMultipoleT(const MultipoleT &)
Apply the algorithm to an arbitrary multipole.
virtual void visitVariableRFCavity(const VariableRFCavity &cav)
Apply the algorithm to a variabel RF cavity.
void buildupFieldList(double BcParameter[], ElementType elementType, Component *elptr)
void rotateWithQuaternion(ParticleAttrib< Vector_t > &vectorArray, Quaternion_t const quaternion)
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a solenoid.
Steppers::TimeIntegrator stepper_m
std::vector< double > dvector_t
IpplTimings::TimerRef TransformTimer_m
ParallelCyclotronTracker(const ParallelCyclotronTracker &)
Vector_t calcMeanR(short bunchNr=-1) const
double calculateAngle2(double x, double y)
virtual void visitCyclotron(const Cyclotron &cycl)
Apply the algorithm to a cyclotron.
void localToGlobal(ParticleAttrib< Vector_t > &vectorArray, double phi, Vector_t const translationToGlobal=0)
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
bool getTunes(dvector_t &t, dvector_t &r, dvector_t &z, int lastTurn, double &nur, double &nuz)
virtual void visitFlexibleCollimator(const FlexibleCollimator &)
Apply the algorithm to a flexible collimator.
virtual void visitMultipoleTCurvedVarRadius(const MultipoleTCurvedVarRadius &)
Apply the algorithm to an arbitrary curved multipole of variable radius.
virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet &bend)
Apply the algorithm to a vertical FFA magnet.
virtual void visitSeptum(const Septum &)
Apply the algorithm to a septum.
IpplTimings::TimerRef DumpTimer_m
virtual void visitMultipoleTCurvedConstRadius(const MultipoleTCurvedConstRadius &)
Apply the algorithm to an arbitrary curved multipole of constant radius.
void seoMode_m(double &t, const double dt, bool &finishedTurn, dvector_t &Ttime, dvector_t &Tdeltr, dvector_t &Tdeltz, ivector_t &TturnNumber)
int maxSteps_m
The maximal number of steps the system is integrated.
virtual void visitMonitor(const Monitor &)
Apply the algorithm to a beam position monitor.
Interface for a single beam element.
Definition: Component.h:50
Interface for general corrector.
Definition: Corrector.h:35
Interface for drift space.
Definition: Drift.h:33
Interface for a marker.
Definition: Marker.h:32
Interface for general multipole.
Definition: Multipole.h:47
Definition: Offset.h:66
Definition: Probe.h:28
Definition: RBend.h:58
Ring describes a ring type geometry for tracking.
Definition: Ring.h:64
Definition: SBend.h:68
Definition: Septum.h:23
Interface for solenoids.
Definition: Solenoid.h:36
Definition: Vacuum.h:61
Particle reference data.
Definition: PartData.h:35
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
Timing::TimerRef TimerRef
Definition: IpplTimings.h:176
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6