OPALX (Object Oriented Parallel Accelerator Library for Exascale) MINIorX
OPALX
ParallelTracker.h
Go to the documentation of this file.
1//
2// Class ParallelTracker
3// OPAL-T tracker.
4// The visitor class for tracking particles with time as independent
5// variable.
6//
7// Copyright (c) 200x - 2014, Christof Kraus, Paul Scherrer Institut, Villigen PSI, Switzerland
8// 2015 - 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
9// 2017 - 2020, Christof Metzger-Kraus
10// All rights reserved
11//
12// This file is part of OPAL.
13//
14// OPAL is free software: you can redistribute it and/or modify
15// it under the terms of the GNU General Public License as published by
16// the Free Software Foundation, either version 3 of the License, or
17// (at your option) any later version.
18//
19// You should have received a copy of the GNU General Public License
20// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
21//
22#ifndef OPAL_ParallelTracker_HH
23#define OPAL_ParallelTracker_HH
24
26#include "Algorithms/Tracker.h"
28#include "Structure/DataSink.h"
29
30#include "BasicActions/Option.h"
31#include "Utilities/Options.h"
32
33#include "Physics/Physics.h"
34
35#include "Algorithms/IndexMap.h"
37
38#include "AbsBeamline/Drift.h"
40#include "AbsBeamline/Marker.h"
44#include "AbsBeamline/Ring.h"
48#include "Beamlines/Beamline.h"
50
51#include <list>
52#include <memory>
53#include <tuple>
54#include <vector>
55
56class ParticleMatterInteractionHandler;
57class PluginElement;
58
59class ParallelTracker : public Tracker {
60
62
64
65 /*
66 Ring specifics
67 */
68
69 // we store a pointer explicitly to the Ring
71
73
75
77
78 WakeFunction* wakeFunction_m;
79
81
83 double zstart_m;
84
90
92
93 // This variable controls the minimal number of steps of emission (using bins)
94 // before we can merge the bins
96
97 // this variable controls the minimal number of steps until we repartition the particles
98 unsigned long long repartFreq_m;
99
100 unsigned int emissionSteps_m;
101
103
111
112 std::set<ParticleMatterInteractionHandler*> activeParticleMatterInteractionHandlers_m;
114
115public:
116 typedef std::vector<double> dvector_t;
117 typedef std::vector<int> ivector_t;
118 typedef std::pair<double[8], Component*> element_pair;
119 typedef std::pair<ElementType, element_pair> type_pair;
120 typedef std::list<type_pair*> beamline_list;
121
123 // The beam line to be tracked is "bl".
124 // The particle reference data are taken from "data".
125 // The particle bunch tracked is initially empty.
126 // If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
127 // If [b]revTrack[/b] is true, we track against the beam.
128 explicit ParallelTracker(const Beamline& bl, const PartData& data, bool revBeam, bool revTrack);
129
131 // The beam line to be tracked is "bl".
132 // The particle reference data are taken from "data".
133 // The particle bunch tracked is taken from [b]bunch[/b].
134 // If [b]revBeam[/b] is true, the beam runs from s = C to s = 0.
135 // If [b]revTrack[/b] is true, we track against the beam.
136 explicit ParallelTracker(
137 const Beamline& bl, PartBunch_t* bunch, DataSink& ds, const PartData& data, bool revBeam,
138 bool revTrack, const std::vector<unsigned long long>& maxSTEPS, double zstart,
139 const std::vector<double>& zstop, const std::vector<double>& dt);
140
141 virtual ~ParallelTracker();
142
144 // overwrite the execute-methode from DefaultVisitor
145 virtual void execute();
146
148 // overwrite the execute-methode from DefaultVisitor
149 virtual void visitBeamline(const Beamline&);
150
152 virtual void visitDrift(const Drift&);
153
155 virtual void visitRing(const Ring& ring);
156
158 virtual void visitMarker(const Marker&);
159
161 virtual void visitMultipole(const Multipole&);
162
164 virtual void visitMultipoleT(const MultipoleT&);
165
167 virtual void visitOffset(const Offset&);
168
170 virtual void visitRFCavity(const RFCavity&);
171
173 virtual void visitSolenoid(const Solenoid&);
174
176 virtual void visitTravelingWave(const TravelingWave&);
177
179 virtual void visitScalingFFAMagnet(const ScalingFFAMagnet& bend);
180
182 virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet& bend);
183
184 // made following public: __host__ __device__ lambda cannot have private or protected access within its class
185 void kickParticles(const BorisPusher& pusher);
186
187 void pushParticles(const BorisPusher& pusher);
188
189 void timeIntegration2(BorisPusher& pusher);
190
191 void changeDT(bool backTrack = false);
192
193 void computeSpaceChargeFields(unsigned long long step);
194
195 void setTime();
196private:
197 // Not implemented.
201
202 /*
203 Ring specifics
204 */
205
206 unsigned turnnumber_m;
207
208 std::list<Component*> myElements;
211 double bega;
214 double referenceZ = 0.0;
215
218 double referencePz = 0.0;
220
223
226
227 void buildupFieldList(double BcParameter[], ElementType elementType, Component* elptr);
228
229 std::vector<PluginElement*> pluginElements_m;
230
231
232
233
234
235 /********************** END VARIABLES ***********************************/
236
237 void updateReferenceParticle(const BorisPusher& pusher);
238
239 void writePhaseSpace(const long long step, bool psDump, bool statDump);
240
241 /********** BEGIN AUTOPHSING STUFF **********/
242 void updateRFElement(std::string elName, double maxPhi);
244 void saveCavityPhases();
245 void restoreCavityPhases();
246 /************ END AUTOPHSING STUFF **********/
247
248 void prepareSections();
249
250 void timeIntegration1(BorisPusher& pusher);
251 void selectDT(bool backTrack = false);
252 void emitParticles(long long step);
256
257 // void prepareOpalBeamlineSections();
258 void dumpStats(long long step, bool psDump, bool statDump);
260 bool hasEndOfLineReached(const BoundingBox& globalBoundingBox);
262
263 void doBinaryRepartition();
264
265 void transformBunch(const CoordinateSystemTrafo& trafo);
266
267 void updateReference(const BorisPusher& pusher);
269 void applyFractionalStep(const BorisPusher& pusher, double tau);
270 void findStartPosition(const BorisPusher& pusher);
271 void autophaseCavities(const BorisPusher& pusher);
272
273 bool applyPluginElements(const double dt);
274};
275
276inline void ParallelTracker::visitDrift(const Drift& drift) {
277 itsOpalBeamline_m.visit(drift, *this, itsBunch_m);
278}
279
280inline void ParallelTracker::visitMarker(const Marker& marker) {
281 itsOpalBeamline_m.visit(marker, *this, itsBunch_m);
282}
283
286}
287
290}
291
294}
295
298}
299
302}
303
304inline void ParallelTracker::kickParticles(const BorisPusher& pusher) {
305
306 // auto Rview = itsBunch_m->getParticleContainer()->R.getView();
307 auto Pview = itsBunch_m->getParticleContainer()->P.getView();
308 // auto dtview = itsBunch_m->getParticleContainer()->dt.getView();
309 auto Efview = itsBunch_m->getParticleContainer()->E.getView();
310 auto Bfview = itsBunch_m->getParticleContainer()->B.getView();
311
313 double mass = itsBunch_m->getMassPerParticle(); // itsReference.getM();
314 double charge = itsBunch_m->getChargePerParticle(); // itsReference.getQ();
315
317 "kickParticles", ippl::getRangePolicy(Pview),
318 KOKKOS_LAMBDA(const size_t i) {
346 Vector_t<double, 3> p = Pview(i);
347 pusher.kick(0, p, Efview(i), Bfview(i), 0, mass, charge);
348 Pview(i) = p;
349 });
350
352 itsBunch_m->getParticleContainer()->update();
353 ippl::Comm->barrier();
354}
355
356inline void ParallelTracker::pushParticles(const BorisPusher& pusher) {
357
360
361 auto Rview = itsBunch_m->getParticleContainer()->R.getView();
362 auto Pview = itsBunch_m->getParticleContainer()->P.getView();
363 //auto dtview = itsBunch_m->getParticleContainer()->dt.getView();
364
366 "pushParticles", ippl::getRangePolicy(Rview),
367 KOKKOS_LAMBDA(const size_t i) {
377
378 Vector_t<double, 3> x = Rview(i);
379 pusher.push(x, Pview(i), 0); // this 0 is "dt" that is not used with unitless positions!
380 Rview(i) = x;
381 });
382
384 itsBunch_m->getParticleContainer()->update();
385 ippl::Comm->barrier();
386}
387
388#endif // OPAL_ParallelTracker_HH
ElementType
Definition: ElementBase.h:88
elements
Definition: IndexMap.cpp:162
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
void mult(Field &u, const double c)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
std::unique_ptr< mpi::Communicator > Comm
Definition: Ippl.h:22
Interface for a single beam element.
Definition: Component.h:50
Interface for drift space.
Definition: Drift.h:31
Interface for a marker.
Definition: Marker.h:32
Interface for general multipole.
Definition: Multipole.h:45
@Class Offset
Definition: Offset.h:66
Ring describes a ring type geometry for tracking.
Definition: Ring.h:62
Sector bending magnet with an FFA-style field index and spiral end shape.
Interface for solenoids.
Definition: Solenoid.h:34
Bending magnet with an exponential dependence on field in the vertical plane.
double getMassPerParticle() const
void switchToUnitlessPositions(bool use_dt_per_particle=false)
std::shared_ptr< ParticleContainer_t > getParticleContainer()
Definition: PartBunch.h:221
double getChargePerParticle() const
get the macro particle charge
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
std::set< std::shared_ptr< Component > > value_t
Definition: IndexMap.h:47
virtual void visitScalingFFAMagnet(const ScalingFFAMagnet &bend)
Apply the algorithm to a scaling FFA.
ParallelTracker(const ParallelTracker &)
void pushParticles(const BorisPusher &pusher)
void emitParticles(long long step)
void updateRFElement(std::string elName, double maxPhi)
void changeDT(bool backTrack=false)
std::vector< int > ivector_t
IpplTimings::TimerRef BinRepartTimer_m
virtual void visitSolenoid(const Solenoid &)
Apply the algorithm to a RF cavity.
std::list< type_pair * > beamline_list
DataSink * itsDataSink_m
virtual void visitOffset(const Offset &)
Apply the algorithm to a offset (placement).
beamline_list FieldDimensions
void autophaseCavities(const BorisPusher &pusher)
void printRFPhases()
double bega
The reference variables.
std::set< ParticleMatterInteractionHandler * > activeParticleMatterInteractionHandlers_m
IpplTimings::TimerRef WakeFieldTimer_m
bool applyPluginElements(const double dt)
IpplTimings::TimerRef OrbThreader_m
virtual void visitMultipole(const Multipole &)
Apply the algorithm to a multipole.
virtual void visitDrift(const Drift &)
Apply the algorithm to a drift space.
virtual void execute()
Apply the algorithm to the top-level beamline.
std::vector< PluginElement * > pluginElements_m
void kickParticles(const BorisPusher &pusher)
virtual void visitMultipoleT(const MultipoleT &)
Apply the algorithm to an arbitrary multipole.
std::vector< double > dvector_t
unsigned long long repartFreq_m
void transformBunch(const CoordinateSystemTrafo &trafo)
virtual void visitRing(const Ring &ring)
Apply the algorithm to a ring.
void writePhaseSpace(const long long step, bool psDump, bool statDump)
void timeIntegration2(BorisPusher &pusher)
void computeWakefield(IndexMap::value_t &elements)
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
double zstart_m
where to start
size_t numParticlesInSimulation_m
void applyFractionalStep(const BorisPusher &pusher, double tau)
std::list< Component * > myElements
void updateReference(const BorisPusher &pusher)
void updateReferenceParticle(const BorisPusher &pusher)
void buildupFieldList(double BcParameter[], ElementType elementType, Component *elptr)
IpplTimings::TimerRef timeIntegrationTimer2_m
void computeExternalFields(OrbitThreader &oth)
unsigned int emissionSteps_m
virtual void visitTravelingWave(const TravelingWave &)
Apply the algorithm to a traveling wave.
void computeSpaceChargeFields(unsigned long long step)
std::pair< ElementType, element_pair > type_pair
bool hasEndOfLineReached(const BoundingBox &globalBoundingBox)
std::pair< double[8], Component * > element_pair
WakeFunction * wakeFunction_m
void dumpStats(long long step, bool psDump, bool statDump)
void computeParticleMatterInteraction(IndexMap::value_t elements, OrbitThreader &oth)
void handleRestartRun()
void operator=(const ParallelTracker &)
IpplTimings::TimerRef timeIntegrationTimer1_m
IpplTimings::TimerRef PluginElemTimer_m
void selectDT(bool backTrack=false)
virtual void visitMarker(const Marker &)
Apply the algorithm to a marker.
void findStartPosition(const BorisPusher &pusher)
virtual void visitRFCavity(const RFCavity &)
Apply the algorithm to a RF cavity.
IpplTimings::TimerRef fieldEvaluationTimer_m
void timeIntegration1(BorisPusher &pusher)
StepSizeConfig stepSizes_m
stores informations where to change the time step and where to stop the simulation,...
virtual ~ParallelTracker()
OpalBeamline itsOpalBeamline_m
virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet &bend)
Apply the algorithm to a vertical FFA magnet.
Particle reference data.
Definition: PartData.h:37
PartBunch_t * itsBunch_m
The bunch of particles to be tracked.
Definition: Tracker.h:123
An abstract sequence of beam line components.
Definition: Beamline.h:34
void visit(const T &, BeamlineVisitor &, PartBunch_t *)
Definition: OpalBeamline.h:104
KOKKOS_INLINE_FUNCTION void kick(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &P, const Vector_t< double, 3 > &Ef, const Vector_t< double, 3 > &Bf, const double &dt) const
Definition: BorisPusher.h:67
KOKKOS_INLINE_FUNCTION void push(Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &dt) const
Definition: BorisPusher.h:129
Timing::TimerRef TimerRef
Definition: IpplTimings.h:144