33#include <boost/numeric/ublas/io.hpp>
62 const Beamline& beamline,
const PartData& reference,
bool revBeam,
bool revTrack)
63 :
Tracker(beamline, reference, revBeam, revTrack),
64 itsDataSink_m(nullptr),
65 itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getInitialDirection()),
69 wakeFunction_m(nullptr),
72 dtCurrentTrack_m(0.0),
73 minStepforReBin_m(-1),
75 emissionSteps_m(
std::numeric_limits<unsigned int>::
max()),
76 numParticlesInSimulation_m(0),
77 timeIntegrationTimer1_m(
IpplTimings::getTimer(
"TIntegration1")),
78 timeIntegrationTimer2_m(
IpplTimings::getTimer(
"TIntegration2")),
79 fieldEvaluationTimer_m(
IpplTimings::getTimer(
"External field eval")),
80 PluginElemTimer_m(
IpplTimings::getTimer(
"PluginElements")),
81 BinRepartTimer_m(
IpplTimings::getTimer(
"Binaryrepart")),
82 OrbThreader_m(
IpplTimings::getTimer(
"OrbThreader")) {
87 bool revBeam,
bool revTrack,
const std::vector<unsigned long long>& maxSteps,
double zstart,
88 const std::vector<double>& zstop,
const std::vector<double>& dt)
89 :
Tracker(beamline, bunch, reference, revBeam, revTrack),
91 itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getInitialDirection()),
95 wakeFunction_m(nullptr),
98 dtCurrentTrack_m(0.0),
99 minStepforReBin_m(-1),
101 emissionSteps_m(
std::numeric_limits<unsigned int>::
max()),
102 numParticlesInSimulation_m(0),
103 timeIntegrationTimer1_m(
IpplTimings::getTimer(
"TIntegration1")),
104 timeIntegrationTimer2_m(
IpplTimings::getTimer(
"TIntegration2")),
105 fieldEvaluationTimer_m(
IpplTimings::getTimer(
"External field eval")),
106 BinRepartTimer_m(
IpplTimings::getTimer(
"Binaryrepart")),
107 OrbThreader_m(
IpplTimings::getTimer(
"OrbThreader")) {
109 for (
unsigned int i = 0; i < zstop.size(); ++i) {
121 *
gmsg <<
"Adding ScalingFFAMagnet" <<
endl;
139 localpair->first = elementType;
141 for (
int i = 0; i < 8; i++)
142 *(((localpair->second).first) + i) = *(BcParameter + i);
144 (localpair->second).
second = elptr;
160 *
gmsg <<
"* ----------------------------- Ring ------------------------------------- *" <<
endl;
174 if (referenceTheta <= -180.0 || referenceTheta > 180.0) {
176 "Error in ParallelTracker::visitRing",
"PHIINIT is out of [-180, 180)!");
191 double BcParameter[8] = {};
212 *
gmsg <<
"Adding Vertical FFA Magnet" <<
endl;
217 "ParallelCyclotronTracker::visitVerticalFFAMagnet",
218 "Need to define a RINGDEFINITION to use VerticalFFAMagnet element");
240 "ParallelCylcotronTracker::visitOffset",
241 "Attempt to place an offset when Ring not defined");
250 cavities.insert(cavities.end(), travelingwaves.begin(), travelingwaves.end());
253 if ((*fit).getElement()->getName() == elName) {
259 *
ippl::Info <<
"Restored cavity phase from the h5 file. Name: " << element->
getName()
260 <<
", phase: " << maxPhase <<
" rad" <<
endl;
276 *
gmsg <<
"* Total number of particles after PluginElement= "
295 for (; it <
end; ++it) {
307 const double globalTimeShift =
353 bool const psDump0 = 0;
354 bool const statDump0 = 0;
357 msg <<
level2 <<
"Dump initial phase space" <<
endl;
381 *
gmsg <<
"* Executing ParallelTracker\n"
405 for (; step < trackSteps; ++step) {
410 *
gmsg <<
"* Bunch bounds at step " << step + 1 <<
": "
558 bool const statDump =
587 bool const statDump =
593 *
gmsg <<
"* Dump phase space of last step" <<
endl;
648 KOKKOS_LAMBDA(
const size_t i) {
673 KOKKOS_LAMBDA(
const size_t i) {
686 *
gmsg <<
"no solver avaidable " <<
endl;
712 typedef Kokkos::View<double**> ViewMatrixType;
713 ViewMatrixType Rot(
"Rot", 3, 3);
714 ViewMatrixType::HostMirror h_Rot = Kokkos::create_mirror_view(Rot);
717 for (
int i = 0; i < 3; ++i ) {
718 for (
int j = 0; j < 3; ++j ) {
719 h_Rot( i, j ) = rot(i, j);
723 Kokkos::deep_copy(Rot, h_Rot);
733 KOKKOS_LAMBDA(
const size_t k) {
736 for (
size_t i = 0; i < 3; ++i ) {
738 for (
size_t j = 0; j < 3; ++j ) {
739 Rview(k)[i] += Rot(i, j) * x(j);
771 KOKKOS_LAMBDA(
const size_t k) {
777 for (
size_t i = 0; i < 3; ++i ) {
780 for (
size_t j = 0; j < 3; ++j ) {
781 Eview(k)[i] += Rot(j,i) *
e(j);
782 Bview(k)[i] += Rot(j,i) * b(j);
787 for (
size_t i = 0; i < 3; ++i ) {
789 for (
size_t j = 0; j < 3; ++j ) {
790 Rview(k)[i] += Rot(j,i) * x(j);
801 bool locPartOutOfBounds =
false, globPartOutOfBounds =
false;
814 IndexMap::value_t::const_iterator it =
elements.begin();
815 const IndexMap::value_t::const_iterator
end =
elements.end();
817 for (; it !=
end; ++it) {
827 for (
unsigned int i = 0; i < localNum; ++i) {
837 if ((*it)->apply(i,
itsBunch_m->
getT() + 0.5 * dt, localE, localB)) {
841 locPartOutOfBounds =
true;
856 ippl::Comm->reduce(locPartOutOfBounds, globPartOutOfBounds, 1, std::logical_or<bool>());
859 if (globPartOutOfBounds) {
876 msg <<
level1 <<
"* Deleted " << ne <<
" particles, "
883 *
ippl::Info <<
"*****************************************************************" <<
endl;
885 *
ippl::Info <<
"*****************************************************************" <<
endl;
889 *
ippl::Info <<
"*****************************************************************" <<
endl;
891 *
ippl::Info <<
"*****************************************************************" <<
endl;
911 <<
" -- no emission yet -- "
920 "ParallelTracker::dumpStats()",
921 "there seems to be something wrong with the position of the bunch!");
971 KOKKOS_LAMBDA(
const int i) {
986 if (psDump || statDump) {
992 FDext[0] = externalB;
1000 *
gmsg <<
"* Wrote beam statistics." <<
endl;
1085 const double direction =
back_track ? -1 : 1;
1095 IndexMap::value_t::const_iterator it =
elements.begin();
1096 const IndexMap::value_t::const_iterator
end =
elements.end();
1098 for (; it !=
end; ++it) {
1106 if ((*it)->applyToReferenceParticle(
1107 localR, localP,
itsBunch_m->
getT() - 0.5 * dt, localE, localB)) {
1108 *
gmsg <<
level1 <<
"The reference particle hit an element" <<
endl;
1133 *
gmsg <<
"* ParallelTracker::transformBunch() is not implemented." <<
endl;
1169 if (normP < 1
e-12) {
1177 double dot = P.
dot(target);
1178 bool aligned = std::abs(std::abs(
dot) - 1.0) < 1
e-6;
1182 *
gmsg <<
"* Warning: Reference particle momentum is aligned with z-axis; no quaternion rotation applied." <<
endl;
1276 for (
auto element : elementSet) {
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Quaternion getQuaternion(ippl::Vector< double, 3 > u, ippl::Vector< double, 3 > ref)
boost::numeric::ublas::matrix< double > matrix_t
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
std::list< ClassicField > FieldList
std::string::const_iterator iterator_t
KOKKOS_INLINE_FUNCTION double euclidean_norm(const Vector_t< T, D > &v)
constexpr KOKKOS_INLINE_FUNCTION auto second()
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
Inform & level1(Inform &inf)
constexpr double e
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double Vpm2MVpm
std::string::iterator iterator
T isinf(T x)
isinf function with adjusted return type
T isnan(T x)
isnan function with adjusted return type
int psDumpFreq
The frequency to dump the phase space, i.e.dump data when steppsDumpFreq==0.
int repartFreq
The frequency to do particles repartition for better load balance between nodes.
int statDumpFreq
The frequency to dump statistical values, e.e. dump data when stepstatDumpFreq==0.
double getGamma(ippl::Vector< double, 3 > p)
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
std::string getTimeString(double time, unsigned int precision=3)
std::string getLengthString(double spos, unsigned int precision=3)
std::unique_ptr< Inform > Info
KOKKOS_INLINE_FUNCTION Vector< T, Dim > max(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
std::unique_ptr< mpi::Communicator > Comm
Interface for a single beam element.
virtual const std::string & getName() const
Get element name.
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
void updateGeometry(Vector_t< double, 3 > startPosition, Vector_t< double, 3 > startDirection)
virtual bool getAutophaseVeto() const
virtual void setPhasem(double phase)
virtual void setAutophaseVeto(bool veto=true)
Ring describes a ring type geometry for tracking.
double getBeamRInit() const
Get the initial beam radius.
virtual void initialise(PartBunch_t *bunch, double &startField, double &endField) override
Initialise the Ring.
double getBeamPRInit() const
Get the initial beam radial momentum.
Vector_t< double, 3 > getNextPosition() const
Get the initial element's start position in cartesian coordinates.
double getSymmetry() const
Get the rotational symmetry of the ring (number of cells)
Vector_t< double, 3 > getNextNormal() const
Get the initial element's start normal in cartesian coordinates.
virtual ElementBase * clone() const override
Inherited copy constructor.
double getBeamPhiInit() const
Get the initial beam azimuthal angle.
double getHarmonicNumber()
Get the harmonic number for RF (number of bunches in the ring)
void appendElement(const Component &element)
Add element to the ring.
Sector bending magnet with an FFA-style field index and spiral end shape.
Bending magnet with an exponential dependence on field in the vertical plane.
std::vector< MaxPhasesT >::iterator getLastMaxPhases()
double getGlobalPhaseShift()
units: (sec)
std::vector< MaxPhasesT >::iterator getFirstMaxPhases()
Object * find(const std::string &name)
Find entry.
void setInPrepState(bool state)
void setGlobalPhaseShift(double shift)
units: (sec)
static OpalData * getInstance()
void setOpenMode(OpenMode openMode)
double getMassPerParticle() const
void performBunchSanityChecks() const
size_t boundp_destroyT()
This is only temporary in order to get the collimator and pepperpot working.
void calcBeamParameters()
Vector_t< T, Dim > get_pmean() const
Vector_t< T, Dim > RefPartR_m
Reference particle structures.
std::shared_ptr< ParticleContainer_t > getParticleContainer()
double get_meanKineticEnergy()
void get_bounds(Vector_t< T, Dim > &rmin, Vector_t< T, Dim > &rmax) const
void set_sPos(double s)
get the spos of the primary beam
size_t getLocalNum() const
double getChargePerParticle() const
get the macro particle charge
Vector_t< T, Dim > get_centroid() const
long long getGlobalTrackStep() const
size_t getTotalNum() const
Vector_t< T, Dim > RefPartP_m
void setGlobalMeanR(Vector_t< T, Dim > globalMeanR)
CoordinateSystemTrafo toLabTrafo_m
const PartData itsReference
The reference information.
double getPhaseAtMaxEnergy(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, double t, double dt)
ippl::Vector< double, 3 > getOrigin() const
ippl::Vector< double, 3 > transformFrom(const ippl::Vector< double, 3 > &r) const
ippl::Vector< double, 3 > rotateFrom(const ippl::Vector< double, 3 > &r) const
ippl::Vector< double, 3 > rotateTo(const ippl::Vector< double, 3 > &r) const
matrix_t getRotationMatrix() const
ippl::Vector< double, 3 > transformTo(const ippl::Vector< double, 3 > &r) const
CoordinateSystemTrafo inverted() const
std::set< std::shared_ptr< Component > > value_t
IndexMap::value_t query(IndexMap::key_t::first_type step, IndexMap::key_t::second_type length)
BoundingBox getBoundingBox() const
virtual void visitScalingFFAMagnet(const ScalingFFAMagnet &bend)
Apply the algorithm to a scaling FFA.
void pushParticles(const BorisPusher &pusher)
void emitParticles(long long step)
void updateRFElement(std::string elName, double maxPhi)
void changeDT(bool backTrack=false)
IpplTimings::TimerRef BinRepartTimer_m
void restoreCavityPhases()
virtual void visitOffset(const Offset &)
Apply the algorithm to a offset (placement).
beamline_list FieldDimensions
void doBinaryRepartition()
void updateRefToLabCSTrafo()
void autophaseCavities(const BorisPusher &pusher)
bool applyPluginElements(const double dt)
IpplTimings::TimerRef OrbThreader_m
virtual void execute()
Apply the algorithm to the top-level beamline.
std::vector< PluginElement * > pluginElements_m
void kickParticles(const BorisPusher &pusher)
void setOptionalVariables()
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)
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)
void computeSpaceChargeFields(unsigned long long step)
std::pair< ElementType, element_pair > type_pair
bool hasEndOfLineReached(const BoundingBox &globalBoundingBox)
void dumpStats(long long step, bool psDump, bool statDump)
IpplTimings::TimerRef timeIntegrationTimer1_m
IpplTimings::TimerRef PluginElemTimer_m
void selectDT(bool backTrack=false)
void findStartPosition(const BorisPusher &pusher)
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.
double getBeta() const
The relativistic beta per particle.
double getGamma() const
The relativistic gamma per particle.
Quaternion conjugate() const
double getMinTimeStep() const
StepSizeConfig & advanceToPos(double spos)
void printDirect(Inform &out) const
void shiftZStopLeft(double back)
void push_back(double dt, double zstop, unsigned long numSteps)
unsigned long getNumSteps() const
unsigned long long getMaxSteps() const
void sortAscendingZStop()
const Beamline & itsBeamline_m
PartBunch_t * itsBunch_m
The bunch of particles to be tracked.
An abstract sequence of beam line components.
bool getRelativeFlag() const
Quaternion getInitialDirection() const
Vector_t< double, 3 > getOrigin3D() const
virtual void iterate(BeamlineVisitor &, bool r2l) const
Apply visitor to all elements of the line.
FieldList getElementByType(ElementType)
Vector_t< double, 3 > rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
CoordinateSystemTrafo getMisalignment(const std::shared_ptr< Component > &comp) const
void merge(OpalBeamline &rhs)
unsigned long getFieldAt(const unsigned int &, const Vector_t< double, 3 > &, const long &, const double &, Vector_t< double, 3 > &, Vector_t< double, 3 > &)
CoordinateSystemTrafo getCSTrafoLab2Local(const std::shared_ptr< Component > &comp) const
Vector_t< double, 3 > transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
std::set< std::shared_ptr< Component > > getElements(const Vector_t< double, 3 > &x)
void swap(OpalBeamline &rhs)
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
KOKKOS_INLINE_FUNCTION void push(Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &dt) const
bool isOutside(const Vector_t< double, 3 > &position) const
void dumpH5(PartBunch_t *beam, Vector_t< double, 3 > FDext[]) const
void storeCavityInformation()
Write cavity information from H5 file.
void dumpSDDS(PartBunch_t *beam, Vector_t< double, 3 > FDext[], const double &azimuth=-1) const
The base class for all OPAL exceptions.
std::string time() const
Return time.
virtual double getReal() const
Return value.
KOKKOS_INLINE_FUNCTION T dot(const Vector< T, Dim > &rhs) const
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)