38 #ifdef ENABLE_OPAL_FEL
62 Tracker(beamline, reference, revBeam, revTrack),
64 itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getInitialDirection()),
70 dtCurrentTrack_m(0.0),
71 minStepforReBin_m(-1),
72 minBinEmitted_m(
std::numeric_limits<size_t>::
max()),
74 emissionSteps_m(
std::numeric_limits<unsigned int>::
max()),
75 numParticlesInSimulation_m(0),
76 timeIntegrationTimer1_m(
IpplTimings::getTimer(
"TIntegration1")),
77 timeIntegrationTimer2_m(
IpplTimings::getTimer(
"TIntegration2")),
78 fieldEvaluationTimer_m(
IpplTimings::getTimer(
"External field eval")),
79 BinRepartTimer_m(
IpplTimings::getTimer(
"Binaryrepart")),
80 WakeFieldTimer_m(
IpplTimings::getTimer(
"WakeField")),
81 particleMatterStatus_m(false)
90 const std::vector<unsigned long long> &maxSteps,
92 const std::vector<double> &zstop,
93 const std::vector<double> &dt):
94 Tracker(beamline, bunch, reference, revBeam, revTrack),
96 itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getInitialDirection()),
102 dtCurrentTrack_m(0.0),
103 minStepforReBin_m(-1),
104 minBinEmitted_m(
std::numeric_limits<size_t>::
max()),
106 emissionSteps_m(
std::numeric_limits<unsigned int>::
max()),
107 numParticlesInSimulation_m(0),
108 timeIntegrationTimer1_m(
IpplTimings::getTimer(
"TIntegration1")),
109 timeIntegrationTimer2_m(
IpplTimings::getTimer(
"TIntegration2")),
110 fieldEvaluationTimer_m(
IpplTimings::getTimer(
"External field eval")),
111 BinRepartTimer_m(
IpplTimings::getTimer(
"Binaryrepart")),
112 WakeFieldTimer_m(
IpplTimings::getTimer(
"WakeField")),
113 particleMatterStatus_m(false)
115 for (
unsigned int i = 0; i < zstop.size(); ++ i) {
143 cavities.insert(cavities.end(), travelingwaves.begin(), travelingwaves.end());
146 if ((*fit).getElement()->getName() == elName) {
153 INFOMSG(
"Restored cavity phase from the h5 file. Name: " << element->
getName() <<
", phase: " << maxPhase <<
" rad" <<
endl);
170 for (; it <
end; ++ it) {
275 *
gmsg <<
"* Executing ParallelTTracker\n"
278 <<
", next step = " << step <<
endl <<
endl;
291 for (; step < trackSteps; ++ step) {
356 msg <<
level2 <<
"Dump phase space of last step" <<
endl;
361 *
gmsg <<
endl <<
"* Done executing ParallelTTracker at "
412 for (
unsigned int i = 0; i < localNum; ++ i) {
436 for (
unsigned int i = 0; i < localNum; ++ i) {
476 if (numParticlesInSimulation_m <= minBinEmitted_m || !itsBunch_m->hasFieldSolver()) {
485 for (
unsigned int i = 0; i < localNum1; ++ i) {
500 binNumber < itsBunch_m->getNumberOfEnergyBins(); ++binNumber) {
515 for (
unsigned int i = 0; i < localNum2; ++ i) {
527 bool locPartOutOfBounds =
false, globPartOutOfBounds =
false;
540 IndexMap::value_t::const_iterator it =
elements.begin();
541 const IndexMap::value_t::const_iterator
end =
elements.end();
543 for (; it !=
end; ++ it) {
550 for (
unsigned int i = 0; i < localNum; ++ i) {
559 if ((*it)->apply(i,
itsBunch_m->
getT() + 0.5 * dt, localE, localB)) {
563 locPartOutOfBounds =
true;
578 #ifdef ENABLE_OPAL_FEL
586 if (globPartOutOfBounds) {
602 msg <<
level1 <<
"* Deleted " <<
ne <<
" particles, "
607 #ifdef ENABLE_OPAL_FEL
611 IndexMap::value_t::const_iterator it =
elements.begin();
632 bool hasWake =
false;
639 IndexMap::value_t::const_iterator it =
elements.begin();
640 const IndexMap::value_t::const_iterator
end =
elements.end();
642 for (; it !=
end; ++ it) {
643 if ((*it)->hasWake() && !hasWake) {
648 if ((*it)->getWake()->getType() ==
"CSRWakeFunction" ||
649 (*it)->getWake()->getType() ==
"CSRIGFWakeFunction") {
652 wfInstance = (*it)->getWake();
658 wfInstance = (*it)->getWake();
663 "empty wake function");
667 msg <<
level2 <<
"============== START WAKE CALCULATION =============" <<
endl;
678 for (
unsigned int i = 0; i < localNum; ++ i) {
686 for (
unsigned int i = 0; i < localNum; ++ i) {
697 msg <<
level2 <<
"=============== END WAKE CALCULATION ==============" <<
endl;
704 std::set<IndexMap::value_t::value_type> elementsWithParticleMatterInteraction;
705 std::set<ParticleMatterInteractionHandler*> particleMatterinteractionHandlers;
710 if ((*it)->hasParticleMatterInteraction()) {
711 elementsWithParticleMatterInteraction.insert(*it);
712 particleMatterinteractionHandlers.insert((*it)->getParticleMatterInteraction());
716 currentRange.end =
std::max(currentRange.end, range.
end);
719 elements.insert(touching.begin(), touching.end());
725 if (elementsWithParticleMatterInteraction.size() > 0) {
726 std::set<ParticleMatterInteractionHandler*> oldSPHandlers;
727 std::vector<ParticleMatterInteractionHandler*> leftBehindSPHandlers, newSPHandlers;
729 oldSPHandlers.insert(it);
732 leftBehindSPHandlers.resize(
std::max(oldSPHandlers.size(),
733 particleMatterinteractionHandlers.size()));
734 auto last = std::set_difference(oldSPHandlers.begin(), oldSPHandlers.end(),
735 particleMatterinteractionHandlers.begin(), particleMatterinteractionHandlers.end(),
736 leftBehindSPHandlers.begin());
737 leftBehindSPHandlers.resize(last - leftBehindSPHandlers.begin());
739 for (
auto it: leftBehindSPHandlers) {
740 if (!it->stillActive()) {
745 newSPHandlers.resize(
std::max(oldSPHandlers.size(),
746 elementsWithParticleMatterInteraction.size()));
747 last = std::set_difference(particleMatterinteractionHandlers.begin(), particleMatterinteractionHandlers.end(),
748 oldSPHandlers.begin(), oldSPHandlers.end(),
749 newSPHandlers.begin());
750 newSPHandlers.resize(last - newSPHandlers.begin());
752 for (
auto it: newSPHandlers) {
757 msg <<
level2 <<
"============== START PARTICLE MATTER INTERACTION CALCULATION =============" <<
endl;
767 int degradersWithParticlesCount = 0;
770 if (it->getParticlesInMat() > 0) {
771 onlyDegraderWithParticles = it;
772 ++ degradersWithParticlesCount;
779 unsigned int totalNum = 0;
781 bool allParticlesInMat = (totalNum == 0 &&
782 degradersWithParticlesCount == 1);
784 if (allParticlesInMat) {
786 msg <<
"All particles in degrader" <<
endl;
790 unsigned int rediffusedParticles = 0;
791 unsigned int numEnteredParticles = 0;
799 for (
unsigned int i = 0; i < localNum; ++i) {
803 boundingSphere.first = refToLocalCSTrafo.
transformTo(boundingSphere.first);
808 boundingSphere.first = localToRefCSTrafo.
transformTo(boundingSphere.first);
811 for (
unsigned int i = 0; i < newLocalNum; ++i) {
816 rediffusedParticles += it->getRediffused();
817 numEnteredParticles += it->getNumEntered();
820 if (it->getFlagAllParticlesIn()) {
822 if (timeDifference > 0.0) {
827 for (
unsigned int i = 0; i < numSteps; ++ i) {
838 if (numEnteredParticles > 0 || rediffusedParticles > 0) {
839 totalNum -= (numEnteredParticles + rediffusedParticles);
855 msg <<
level2 <<
"============== END PARTICLE MATTER INTERACTION CALCULATION =============" <<
endl;
865 INFOMSG(
"*****************************************************************" <<
endl);
866 INFOMSG(
"do repartition because of repartFreq_m" <<
endl);
867 INFOMSG(
"*****************************************************************" <<
endl);
872 INFOMSG(
"*****************************************************************" <<
endl);
874 INFOMSG(
"*****************************************************************" <<
endl);
891 msg << myt2.
time() <<
" "
893 <<
" -- no emission yet -- "
902 msg << myt2.
time() <<
" "
904 <<
"only " << std::setw(4) << totalParticles_f <<
" particles emitted; "
910 "there seems to be something wrong with the position of the bunch!");
913 msg << myt2.
time() <<
" "
960 for (
unsigned int i = 0; i < localNum; ++i) {
990 if (psDump || statDump) {
1003 std::vector<std::pair<std::string, unsigned int> > collimatorLosses;
1005 if (collimators.size() != 0) {
1009 unsigned int losses = coll->
getLosses();
1010 collimatorLosses.push_back(std::make_pair(
name, losses));
1012 std::sort(collimatorLosses.begin(), collimatorLosses.end(),
1013 [](
const std::pair<std::string, unsigned int>&
a,
const std::pair<std::string, unsigned int>& b) ->bool {
1014 return a.first < b.first;
1016 std::vector<unsigned int> bareLosses(collimatorLosses.size(),0);
1017 for (
size_t i = 0; i < collimatorLosses.size(); ++ i){
1018 bareLosses[i] = collimatorLosses[i].second;
1021 reduce(&bareLosses[0], &bareLosses[0] + bareLosses.size(), &bareLosses[0],
OpAddAssign());
1023 for (
size_t i = 0; i < collimatorLosses.size(); ++ i){
1024 collimatorLosses[i].second = bareLosses[i];
1030 msg <<
level3 <<
"* Wrote beam statistics." <<
endl;
1043 if (driftToCorrectPosition) {
1046 stashedR.
create(localNum);
1050 for (
size_t i = 0; i < localNum; ++ i) {
1071 if (driftToCorrectPosition) {
1074 stashedR.
destroy(localNum, 0);
1083 msg <<
level2 <<
"* Wrote beam phase space." <<
endl;
1104 IndexMap::value_t::const_iterator it =
elements.begin();
1105 const IndexMap::value_t::const_iterator
end =
elements.end();
1107 for (; it !=
end; ++ it) {
1114 if ((*it)->applyToReferenceParticle(localR,
1119 *
gmsg <<
level1 <<
"The reference particle hit an element" <<
endl;
1136 for (
unsigned int i = 0; i < localNum; ++i) {
1242 for (
auto element: elementSet) {
1278 std::vector<long> localParticles(numNodes, 0);
1284 std::vector<DistributionInfo> send;
1285 std::vector<DistributionInfo> receive;
1288 if (localParticles[i] <= 0)
continue;
1291 if (j == i || localParticles[j] >= 0)
continue;
1293 long numParts =
std::min(localParticles[i], -localParticles[j]);
1294 localParticles[i] -= numParts;
1295 localParticles[j] += numParts;
1304 send.push_back(request);
1306 receive.push_back(request);
1310 if (localParticles[i] == 0)
break;
1314 std::vector<MPI_Request> requests;
1315 const long sizeSingleParticle = 9 *
sizeof(double) +
sizeof(
short) +
sizeof(int) +
sizeof(
PID_t::Return_t);
1319 std::vector<char> send_msgbuf;
1321 if (send.size() > 0) {
1324 unsigned int totalSend = 0, startIndex = 0;
1326 totalSend += request.howMany;
1328 send_msgbuf.reserve(totalSend * sizeSingleParticle);
1331 size_t sizePrior = send_msgbuf.size();
1332 for (
long i = 0; i < request.howMany; ++ i, -- idx) {
1333 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->
R[idx](0)));
1334 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer + 3 *
sizeof(double));
1335 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->
P[idx](0)));
1336 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer + 3 *
sizeof(double));
1337 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->
Q[idx]));
1338 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(double));
1339 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->
M[idx]));
1340 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(double));
1341 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->
dt[idx]));
1342 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(double));
1344 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
ParticleOrigin));
1346 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(int));
1347 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->
ID[idx]));
1348 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
PID_t::Return_t));
1351 size_t sendSizeThis = send_msgbuf.size() - sizePrior;
1357 requests.push_back(req);
1359 startIndex += sendSizeThis;
1365 for (
unsigned int i = 0; i < receive.size(); ++ i) {
1372 while (j < bufsize) {
1376 const double *buffer =
reinterpret_cast<const double*
>(recvbuf + j);
1383 j += 9 *
sizeof(double);
1392 const int *buffer =
reinterpret_cast<const int*
>(recvbuf + j);
1407 if (requests.size() > 0) {
1408 MPI_Waitall(requests.size(), &(requests[0]), MPI_STATUSES_IGNORE);
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sqrt(const Tps< T > &x)
Square root.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
Quaternion getQuaternion(Vector_t u, Vector_t ref)
std::list< ClassicField > FieldList
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
void allreduce(const T *input, T *output, int count, Op op)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
#define P_SPATIAL_TRANSFER_TAG
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TBTree< FnCopysign, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > copysign(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Inform & level1(Inform &inf)
Inform & endl(Inform &inf)
Inform & level2(Inform &inf)
Inform & level3(Inform &inf)
std::string::const_iterator iterator_t
constexpr double e
The value of.
constexpr double c
The velocity of light in m/s.
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 minBinEmitted
The number of bins that have to be emitted before the bin are squashed into a single bin.
int minStepForRebin
The number of steps into the simulation before the bins are squashed into a single bin.
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 getKineticEnergy(Vector_t p, double mass)
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
std::string getTimeString(double time, unsigned int precision=3)
double getGamma(Vector_t p)
std::string getLengthString(double spos, unsigned int precision=3)
ParticleAttrib< Vector_t > Ef
double get_meanKineticEnergy() const
virtual void resetInterpolationCache(bool clearCache=false)
ParticleAttrib< int > Bin
virtual void computeSelfFields()=0
size_t getLocalNum() const
ParticleAttrib< double > M
size_t emitParticles(double eZ)
Emit particles in the given bin i.e. copy the particles from the bin structure into the particle cont...
size_t getTotalNum() const
ParticleAttrib< Vector_t > P
void switchToUnitlessPositions(bool use_dt_per_particle=false)
double getEmissionDeltaT()
ParticleAttrib< ParticleOrigin > POrigin
ParticleAttrib< double > Q
int getLastEmittedEnergyBin()
void calcBeamParameters()
Vector_t get_pmean_Distribution() const
size_t getNumberOfEmissionSteps()
CoordinateSystemTrafo toLabTrafo_m
void setGlobalMeanR(Vector_t globalMeanR)
virtual void do_binaryRepart()
ParticleAttrib< int > TriID
void calcGammas()
Compute the gammas of all bins.
ParticleAttrib< double > dt
void get_bounds(Vector_t &rmin, Vector_t &rmax)
virtual void setBinCharge(int bin, double q)
Set the charge of one bin to the value of q and all other to zero.
int getNumberOfEnergyBins()
Vector_t get_centroid() const
Vector_t get_pmean() const
void destroy(size_t M, size_t I, bool doNow=false)
ParticleAttrib< Vector_t > Bf
long long getGlobalTrackStep() const
std::pair< Vector_t, double > getLocalBoundingSphere()
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
void setOpenMode(OPENMODE openMode)
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 setPriorTrack(const bool &value=true)
true if in follow-up track
void setGlobalPhaseShift(double shift)
units: (sec)
static OpalData * getInstance()
double getPhaseAtMaxEnergy(const Vector_t &R, const Vector_t &P, double t, double dt)
std::set< std::shared_ptr< Component > > value_t
IndexMap::value_t query(IndexMap::key_t::first_type step, IndexMap::key_t::second_type length)
IndexMap::value_t getTouchingElements(const IndexMap::key_t &range) const
IndexMap::key_t getRange(const IndexMap::value_t::value_type &element, double position) const
void selectDT(bool backTrack=false)
void computeExternalFields(OrbitThreader &oth)
IpplTimings::TimerRef timeIntegrationTimer2_m
IpplTimings::TimerRef WakeFieldTimer_m
OpalBeamline itsOpalBeamline_m
double zstart_m
where to start
void transformBunch(const CoordinateSystemTrafo &trafo)
void autophaseCavities(const BorisPusher &pusher)
void computeWakefield(IndexMap::value_t &elements)
void computeSpaceChargeFields(unsigned long long step)
virtual void visitBeamline(const Beamline &)
Apply the algorithm to a beam line.
void timeIntegration2(BorisPusher &pusher)
virtual ~ParallelTTracker()
void updateReferenceParticle(const BorisPusher &pusher)
std::set< ParticleMatterInteractionHandler * > activeParticleMatterInteractionHandlers_m
WakeFunction * wakeFunction_m
void doBinaryRepartition()
size_t numParticlesInSimulation_m
void restoreCavityPhases()
virtual void execute()
Apply the algorithm to the top-level beamline.
IpplTimings::TimerRef timeIntegrationTimer1_m
void setOptionalVariables()
void pushParticles(const BorisPusher &pusher)
void dumpStats(long long step, bool psDump, bool statDump)
void changeDT(bool backTrack=false)
void emitParticles(long long step)
void findStartPosition(const BorisPusher &pusher)
void computeParticleMatterInteraction(IndexMap::value_t elements, OrbitThreader &oth)
bool particleMatterStatus_m
unsigned int repartFreq_m
void updateRFElement(std::string elName, double maxPhi)
void timeIntegration1(BorisPusher &pusher)
IpplTimings::TimerRef BinRepartTimer_m
void writePhaseSpace(const long long step, bool psDump, bool statDump)
StepSizeConfig stepSizes_m
IpplTimings::TimerRef fieldEvaluationTimer_m
void evenlyDistributeParticles()
void applyFractionalStep(const BorisPusher &pusher, double tau)
bool hasEndOfLineReached()
void kickParticles(const BorisPusher &pusher)
void updateReference(const BorisPusher &pusher)
void updateRefToLabCSTrafo()
unsigned int emissionSteps_m
double getMinTimeStep() const
StepSizeConfig & advanceToPos(double spos)
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()
double getFinalZStop() const
virtual const std::string & getName() const
Get element name.
void getMisalignment(double &x, double &y, double &s) const
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
unsigned int getLosses() const
static void writeStatistics()
virtual bool getAutophaseVeto() const
virtual void setPhasem(double phase)
virtual void setAutophaseVeto(bool veto=true)
Interface for Traveling Wave.
void apply(PartBunchBase< double, 3 > *itsBunch, CoordinateSystemTrafo const &refToLocalCSTrafo)
bool getHasBeenSimulated() const
const PartData itsReference
The reference information.
Vector_t rotateFrom(const Vector_t &r) const
Vector_t transformFrom(const Vector_t &r) const
Vector_t transformTo(const Vector_t &r) const
Vector_t rotateTo(const Vector_t &r) const
CoordinateSystemTrafo inverted() const
double getP() const
The constant reference momentum per particle.
Quaternion conjugate() const
const Beamline & itsBeamline_m
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
An abstract sequence of beam line components.
bool getRelativeFlag() const
Quaternion getInitialDirection() const
Vector_t getOrigin3D() const
virtual void iterate(BeamlineVisitor &, bool r2l) const
Apply visitor to all elements of the line.
void setFlagAllParticlesIn(bool p)
virtual void initialize(const ElementBase *)
virtual void apply(PartBunchBase< double, 3 > *bunch)=0
FieldList getElementByType(ElementBase::ElementType)
Vector_t rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
CoordinateSystemTrafo getMisalignment(const std::shared_ptr< Component > &comp) const
void merge(OpalBeamline &rhs)
Vector_t transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
CoordinateSystemTrafo getCSTrafoLab2Local(const std::shared_ptr< Component > &comp) const
unsigned long getFieldAt(const unsigned int &, const Vector_t &, const long &, const double &, Vector_t &, Vector_t &)
std::set< std::shared_ptr< Component > > getElements(const Vector_t &x)
void swap(OpalBeamline &rhs)
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
void push(Vector_t &R, const Vector_t &P, const double &dt) const
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
void storeCavityInformation()
Write cavity information from H5 file.
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
The base class for all OPAL exceptions.
std::string time() const
Return time.
virtual double getReal() const
Return value.
virtual void destroy(size_t M, size_t I, bool optDestroy=true)
virtual void create(size_t)
virtual MPI_Request raw_isend(void *, int, int, int)
virtual int raw_probe_receive(char *&, int &, int &)
int next_tag(int t, int s=1000)
static Communicate * Comm
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t