33#include <boost/numeric/ublas/io.hpp>
62 const Beamline& beamline,
const PartData& reference,
bool revBeam,
bool revTrack)
63 :
Tracker(beamline, reference, revBeam, revTrack),
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),
109 for (
unsigned int i = 0; i < zstop.size(); ++i) {
110 stepSizes_m.push_back(dt[i], zstop[i], maxSteps[i]);
121 *
gmsg <<
"Adding ScalingFFAMagnet" << endl;
136 beamline_list::iterator sindex;
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;
176 "Error in ParallelTracker::visitRing",
"PHIINIT is out of [-180, 180)!");
191 double BcParameter[8] = {};
196 *
gmsg <<
"* Initial beam radius = " <<
referenceR <<
" [mm] " << endl;
199 *
gmsg <<
"* Total reference momentum = " <<
referencePtot <<
" [beta gamma]" << endl;
200 *
gmsg <<
"* Reference azimuthal momentum = " <<
referencePt <<
" [beta gamma]" << endl;
201 *
gmsg <<
"* Reference radial momentum = " <<
referencePr <<
" [beta gamma]" << endl;
202 *
gmsg <<
"* " <<
opalRing_m->getSymmetry() <<
" fold field symmetry " << endl;
203 *
gmsg <<
"* Harmonic number h = " <<
opalRing_m->getHarmonicNumber() <<
" " << endl;
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());
252 for (FieldList::iterator fit = cavities.begin(); fit != cavities.end(); ++fit) {
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= "
290 typedef std::vector<MaxPhasesT>::iterator
iterator_t;
295 for (; it <
end; ++it) {
302 Inform msg(
"ParallelTracker ", *
gmsg);
307 const double globalTimeShift =
347 *
gmsg <<
"ParallelTrack: momentum= " <<
itsBunch_m->getParticleContainer()->getMeanP()(2) << endl;
348 *
gmsg <<
"itsBunch_m->RefPartR_m= " <<
itsBunch_m->RefPartR_m << endl;
349 *
gmsg <<
"itsBunch_m->RefPartP_m= " <<
itsBunch_m->RefPartP_m << endl;
353 bool const psDump0 = 0;
354 bool const statDump0 = 0;
357 msg << level2 <<
"Dump initial phase space" << endl;
374 double time =
itsBunch_m->getT() - globalTimeShift;
377 unsigned long long step =
itsBunch_m->getGlobalTrackStep();
381 *
gmsg <<
"* Executing ParallelTracker\n"
383 <<
"* Max integration steps = " <<
stepSizes_m.getMaxSteps() <<
", next step = " << step
398 unsigned long long trackSteps =
stepSizes_m.getNumSteps() + step;
402 for (; step < trackSteps; ++step) {
439 bool const statDump =
465 bool const statDump =
471 *
gmsg <<
"* Dump phase space of last step" << endl;
476 *
gmsg << endl <<
"* Done executing ParallelTracker at " << myt3.
time() << endl << endl;
521 auto dtview =
itsBunch_m->getParticleContainer()->dt.getView();
524 Kokkos::parallel_for(
525 "changeDT", ippl::getRangePolicy(dtview),
526 KOKKOS_LAMBDA(
const int i) {
546 auto dtview =
itsBunch_m->getParticleContainer()->dt.getView();
549 Kokkos::parallel_for(
550 "changeDT", ippl::getRangePolicy(dtview),
551 KOKKOS_LAMBDA(
const int i) {
564 *
gmsg <<
"no solver avaidable " << endl;
587 const ippl::Vector<double, 3> org = referenceToBeamCSTrafo.
getOrigin();
590 typedef Kokkos::View<double**> ViewMatrixType;
591 ViewMatrixType Rot(
"Rot", 3, 3);
592 ViewMatrixType::HostMirror h_Rot = Kokkos::create_mirror_view(Rot);
595 for (
int i = 0; i < 3; ++i ) {
596 for (
int j = 0; j < 3; ++j ) {
597 h_Rot( i, j ) = rot(i, j);
601 Kokkos::deep_copy( Rot, h_Rot );
603 auto Rview =
itsBunch_m->getParticleContainer()->R.getView();
604 auto Eview =
itsBunch_m->getParticleContainer()->E.getView();
605 auto Bview =
itsBunch_m->getParticleContainer()->B.getView();
607 Kokkos::parallel_for(
608 "referenceToBeamCSTrafo", ippl::getRangePolicy(Rview),
609 KOKKOS_LAMBDA(
const int i) {
610 ippl::Vector<double, 3> x({Rview(i)[0],Rview(i)[1],Rview(i)[2]});
612 for (
int j = 0; j < 3; ++j ) {
613 for (
int i = 0; i < 3; ++i ) {
614 Rview(j) = Rot(i,j) * x(i);
617 Eview(i) = ippl::Vector<double, 3>(0.0);
618 Bview(i) = ippl::Vector<double, 3>(0.0);
642 Kokkos::parallel_for(
643 "CSTrafo:transformTo", ippl::getRangePolicy(Rview),
644 KOKKOS_LAMBDA(
const int i) {
645 ippl::Vector<double, 3> x({Rview(i)[0],Rview(i)[1],Rview(i)[2]});
646 ippl::Vector<double, 3> e({Eview(i)[0],Eview(i)[1],Eview(i)[2]});
647 ippl::Vector<double, 3> b({Bview(i)[0],Bview(i)[1],Bview(i)[2]});
650 for (
int i = 0; i < 3; ++i ) {
651 for (
int j = 0; j < 3; ++j ) {
652 Eview(i) = Rot(i,j) * e(i);
653 Bview(i) = Rot(i,j) * b(i);
658 for (
int j = 0; j < 3; ++j ) {
659 for (
int i = 0; i < 3; ++i ) {
660 Rview(i) = Rot(j,i) * x(i);
669 Inform msg(
"ParallelTracker ", *
gmsg);
670 const unsigned int localNum =
itsBunch_m->getLocalNum();
671 bool locPartOutOfBounds =
false, globPartOutOfBounds =
false;
684 IndexMap::value_t::const_iterator it =
elements.begin();
685 const IndexMap::value_t::const_iterator
end =
elements.end();
687 for (; it !=
end; ++it) {
697 for (
unsigned int i = 0; i < localNum; ++i) {
707 if ((*it)->apply(i,
itsBunch_m->getT() + 0.5 * dt, localE, localB)) {
711 locPartOutOfBounds =
true;
726 ippl::Comm->reduce(locPartOutOfBounds, globPartOutOfBounds, 1, std::logical_or<bool>());
729 if (globPartOutOfBounds) {
746 msg << level1 <<
"* Deleted " << ne <<
" particles, "
753 *ippl::Info <<
"*****************************************************************" << endl;
754 *ippl::Info <<
"do repartition because of repartFreq_m" << endl;
755 *ippl::Info <<
"*****************************************************************" << endl;
757 ippl::Comm->barrier();
759 *ippl::Info <<
"*****************************************************************" << endl;
760 *ippl::Info <<
"do repartition done" << endl;
761 *ippl::Info <<
"*****************************************************************" << endl;
780 <<
"Step " << std::setw(6) <<
itsBunch_m->getGlobalTrackStep() <<
"; "
781 <<
" -- no emission yet -- "
790 "ParallelTracker::dumpStats()",
791 "there seems to be something wrong with the position of the bunch!");
794 <<
"Step " << std::setw(6) <<
itsBunch_m->getGlobalTrackStep() <<
" "
815 if (ippl::Comm->size() == 1) {
816 repartFreq_m = std::numeric_limits<unsigned long long>::max();
836 auto dtview =
itsBunch_m->getParticleContainer()->dt.getView();
839 Kokkos::parallel_for(
840 "changeDT", ippl::getRangePolicy(dtview),
841 KOKKOS_LAMBDA(
const int i) {
856 if (psDump || statDump) {
862 FDext[0] = externalB;
870 *
gmsg <<
"* Wrote beam statistics." << endl;
873 if (psDump && (
itsBunch_m->getTotalNum() > 0)) {
945 *
gmsg << level2 <<
"* Wrote beam phase space." << endl;
965 IndexMap::value_t::const_iterator it =
elements.begin();
966 const IndexMap::value_t::const_iterator
end =
elements.end();
968 for (; it !=
end; ++it) {
976 if ((*it)->applyToReferenceParticle(
977 localR, localP,
itsBunch_m->getT() - 0.5 * dt, localE, localB)) {
978 *
gmsg << level1 <<
"The reference particle hit an element" << endl;
994 const unsigned int localNum =
itsBunch_m->getLocalNum();
995 for (
unsigned int i = 0; i < localNum; ++i) {
1112 for (
auto element : elementSet) {
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
Quaternion getQuaternion(ippl::Vector< double, 3 > u, ippl::Vector< double, 3 > ref)
boost::numeric::ublas::matrix< double > matrix_t
ippl::Vector< T, Dim > Vector_t
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
std::list< ClassicField > FieldList
std::string::const_iterator iterator_t
TBeamline< FlaggedElmPtr > FlaggedBeamline
A beam line with flagged elements.
KOKKOS_INLINE_FUNCTION double euclidean_norm(const Vector_t< T, D > &v)
constexpr double c
The velocity of light in m/s.
constexpr double Vpm2MVpm
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)
Interface for a single beam element.
virtual const std::string & getName() const
Get element name.
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.
virtual ElementBase * clone() const override
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)
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 > 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)
unsigned int emissionSteps_m
void computeSpaceChargeFields(unsigned long long step)
std::pair< ElementType, element_pair > type_pair
bool hasEndOfLineReached(const BoundingBox &globalBoundingBox)
WakeFunction * wakeFunction_m
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
virtual ~ParallelTracker()
OpalBeamline itsOpalBeamline_m
virtual void visitVerticalFFAMagnet(const VerticalFFAMagnet &bend)
Apply the algorithm to a vertical FFA magnet.
Quaternion conjugate() const
void shiftZStopLeft(double back)
Tracker(const Beamline &, const PartData &, bool backBeam, bool backTrack)
Constructor.
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.
void merge(OpalBeamline &rhs)
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
The base class for all OPAL exceptions.
std::string time() const
Return time.
virtual double getReal() const
Return value.