64 Tracker(beamline, reference, revBeam, revTrack),
92 const std::vector<unsigned long long> &maxSteps,
94 const std::vector<double> &zstop,
95 const std::vector<double> &dt):
96 Tracker(beamline, bunch, reference, revBeam, revTrack),
117 for (
unsigned int i = 0; i < zstop.size(); ++ i) {
118 stepSizes_m.push_back(dt[i], zstop[i], maxSteps[i]);
145 cavities.insert(cavities.end(), travelingwaves.begin(), travelingwaves.end());
147 for (FieldList::iterator fit = cavities.begin(); fit != cavities.end(); ++ fit) {
148 if ((*fit).getElement()->getName() == elName) {
155 INFOMSG(
"Restored cavity phase from the h5 file. Name: " << element->
getName() <<
", phase: " << maxPhase <<
" rad" <<
endl);
166 typedef std::vector<MaxPhasesT>::iterator
iterator_t;
172 for (; it <
end; ++ it) {
265 double time =
itsBunch_m->getT() - globalTimeShift;
270 unsigned long long step =
itsBunch_m->getGlobalTrackStep();
278 *
gmsg <<
"* Executing ParallelTTracker\n"
280 <<
"* Max integration steps = " <<
stepSizes_m.getMaxSteps()
281 <<
", next step = " << step <<
endl <<
endl;
290 unsigned long long trackSteps =
stepSizes_m.getNumSteps() + step;
294 for (; step < trackSteps; ++ step) {
359 msg <<
level2 <<
"Dump phase space of last step" <<
endl;
364 *
gmsg <<
endl <<
"* Done executing ParallelTTracker at "
415 const unsigned int localNum =
itsBunch_m->getLocalNum();
416 for (
unsigned int i = 0; i < localNum; ++ i) {
439 const unsigned int localNum =
itsBunch_m->getLocalNum();
440 for (
unsigned int i = 0; i < localNum; ++ i) {
488 const unsigned int localNum1 =
itsBunch_m->getLocalNum();
489 for (
unsigned int i = 0; i < localNum1; ++ i) {
503 for (
int binNumber = 0; binNumber <
itsBunch_m->getLastEmittedEnergyBin() &&
504 binNumber < itsBunch_m->getNumberOfEnergyBins(); ++binNumber) {
518 const unsigned int localNum2 =
itsBunch_m->getLocalNum();
519 for (
unsigned int i = 0; i < localNum2; ++ i) {
530 const unsigned int localNum =
itsBunch_m->getLocalNum();
531 bool locPartOutOfBounds =
false, globPartOutOfBounds =
false;
544 IndexMap::value_t::const_iterator it =
elements.begin();
545 const IndexMap::value_t::const_iterator
end =
elements.end();
547 for (; it !=
end; ++ it) {
554 for (
unsigned int i = 0; i < localNum; ++ i) {
563 if ((*it)->apply(i,
itsBunch_m->getT() + 0.5 * dt, localE, localB)) {
567 locPartOutOfBounds =
true;
582#ifdef ENABLE_OPAL_FEL
590 if (globPartOutOfBounds) {
606 msg <<
level1 <<
"* Deleted " <<
ne <<
" particles, "
611#ifdef ENABLE_OPAL_FEL
615 IndexMap::value_t::const_iterator it =
elements.begin();
626 CoordinateSystemTrafo refToLocalCSTrafo = (
itsOpalBeamline_m.getMisalignment((*it)) *
636 bool hasWake =
false;
641 const unsigned int localNum =
itsBunch_m->getLocalNum();
643 IndexMap::value_t::const_iterator it =
elements.begin();
644 const IndexMap::value_t::const_iterator
end =
elements.end();
646 for (; it !=
end; ++ it) {
647 if ((*it)->hasWake() && !hasWake) {
656 wfInstance = (*it)->getWake();
662 wfInstance = (*it)->getWake();
667 "empty wake function");
671 msg <<
level2 <<
"============== START WAKE CALCULATION =============" <<
endl;
682 for (
unsigned int i = 0; i < localNum; ++ i) {
690 for (
unsigned int i = 0; i < localNum; ++ i) {
701 msg <<
level2 <<
"=============== END WAKE CALCULATION ==============" <<
endl;
708 std::set<IndexMap::value_t::value_type> elementsWithParticleMatterInteraction;
709 std::set<ParticleMatterInteractionHandler*> particleMatterinteractionHandlers;
714 if ((*it)->hasParticleMatterInteraction()) {
715 elementsWithParticleMatterInteraction.insert(*it);
716 particleMatterinteractionHandlers.insert((*it)->getParticleMatterInteraction());
720 currentRange.
end = std::max(currentRange.
end, range.
end);
723 elements.insert(touching.begin(), touching.end());
729 if (!elementsWithParticleMatterInteraction.empty()) {
730 std::set<ParticleMatterInteractionHandler*> oldSPHandlers;
731 std::vector<ParticleMatterInteractionHandler*> leftBehindSPHandlers, newSPHandlers;
733 oldSPHandlers.insert(it);
736 leftBehindSPHandlers.resize(std::max(oldSPHandlers.size(),
737 particleMatterinteractionHandlers.size()));
738 auto last = std::set_difference(oldSPHandlers.begin(), oldSPHandlers.end(),
739 particleMatterinteractionHandlers.begin(), particleMatterinteractionHandlers.end(),
740 leftBehindSPHandlers.begin());
741 leftBehindSPHandlers.resize(last - leftBehindSPHandlers.begin());
743 for (
auto it: leftBehindSPHandlers) {
744 if (!it->stillActive()) {
749 newSPHandlers.resize(std::max(oldSPHandlers.size(),
750 elementsWithParticleMatterInteraction.size()));
751 last = std::set_difference(particleMatterinteractionHandlers.begin(), particleMatterinteractionHandlers.end(),
752 oldSPHandlers.begin(), oldSPHandlers.end(),
753 newSPHandlers.begin());
754 newSPHandlers.resize(last - newSPHandlers.begin());
756 for (
auto it: newSPHandlers) {
761 msg <<
level2 <<
"============== START PARTICLE MATTER INTERACTION CALCULATION =============" <<
endl;
767 if (!(*it)->stillActive()) {
768 auto next = std::next(it);
782 int degradersWithParticlesCount = 0;
784 it->setFlagAllParticlesIn(
false);
785 if (it->getParticlesInMat() > 0) {
786 onlyDegraderWithParticles = it;
787 ++ degradersWithParticlesCount;
793 unsigned int localNum =
itsBunch_m->getLocalNum();
794 unsigned int totalNum = 0;
796 bool allParticlesInMat = (totalNum == 0 &&
797 degradersWithParticlesCount == 1);
799 if (allParticlesInMat) {
801 msg <<
"All particles in degrader" <<
endl;
804 auto boundingSphere =
itsBunch_m->getLocalBoundingSphere();
805 unsigned int rediffusedParticles = 0;
806 unsigned int numEnteredParticles = 0;
813 const unsigned int localNum =
itsBunch_m->getLocalNum();
814 for (
unsigned int i = 0; i < localNum; ++i) {
818 boundingSphere.first = refToLocalCSTrafo.
transformTo(boundingSphere.first);
823 boundingSphere.first = localToRefCSTrafo.
transformTo(boundingSphere.first);
825 const unsigned int newLocalNum =
itsBunch_m->getLocalNum();
826 for (
unsigned int i = 0; i < newLocalNum; ++i) {
831 rediffusedParticles += it->getRediffused();
832 numEnteredParticles += it->getNumEntered();
835 if (it->getFlagAllParticlesIn()) {
837 if (timeDifference > 0.0) {
838 const unsigned int numSteps = std::ceil(timeDifference /
itsBunch_m->getdT());
842 for (
unsigned int i = 0; i < numSteps; ++ i) {
853 if (numEnteredParticles > 0 || rediffusedParticles > 0) {
854 totalNum -= (numEnteredParticles + rediffusedParticles);
870 msg <<
level2 <<
"============== END PARTICLE MATTER INTERACTION CALCULATION =============" <<
endl;
880 INFOMSG(
"*****************************************************************" <<
endl);
881 INFOMSG(
"do repartition because of repartFreq_m" <<
endl);
882 INFOMSG(
"*****************************************************************" <<
endl);
887 INFOMSG(
"*****************************************************************" <<
endl);
889 INFOMSG(
"*****************************************************************" <<
endl);
897 if (
itsBunch_m->getGlobalTrackStep() % 1000 + 1 == 1000) {
899 }
else if (
itsBunch_m->getGlobalTrackStep() % 100 + 1 == 100) {
906 msg << myt2.
time() <<
" "
907 <<
"Step " << std::setw(6) <<
itsBunch_m->getGlobalTrackStep() <<
"; "
908 <<
" -- no emission yet -- "
917 msg << myt2.
time() <<
" "
918 <<
"Step " << std::setw(6) <<
itsBunch_m->getGlobalTrackStep() <<
"; "
919 <<
"only " << std::setw(4) << totalParticles_f <<
" particles emitted; "
925 "there seems to be something wrong with the position of the bunch!");
928 msg << myt2.
time() <<
" "
929 <<
"Step " << std::setw(6) <<
itsBunch_m->getGlobalTrackStep() <<
" "
957 repartFreq_m = std::numeric_limits<unsigned int>::max();
975 const unsigned int localNum =
itsBunch_m->getLocalNum();
976 for (
unsigned int i = 0; i < localNum; ++i) {
987 msg <<
level2 <<
"Do emission for " <<
itsBunch_m->getTEmission() <<
" [s] using "
989 <<
"Change dT from " <<
itsBunch_m->getdT() <<
" [s] to "
990 <<
itsBunch_m->getEmissionDeltaT() <<
" [s] during emission " <<
endl;;
1006 if (psDump || statDump) {
1014 FDext[0] =
itsBunch_m->toLabTrafo_m.rotateFrom(externalB);
1019 std::vector<std::pair<std::string, unsigned int> > collimatorLosses;
1021 if (!collimators.empty()) {
1022 for (FieldList::iterator it = collimators.begin(); it != collimators.end(); ++ it) {
1025 unsigned int losses = coll->
getLosses();
1026 collimatorLosses.push_back(std::make_pair(
name, losses));
1028 std::sort(collimatorLosses.begin(), collimatorLosses.end(),
1029 [](
const std::pair<std::string, unsigned int>&
a,
const std::pair<std::string, unsigned int>& b) ->bool {
1030 return a.first < b.first;
1032 std::vector<unsigned int> bareLosses(collimatorLosses.size(),0);
1033 for (
size_t i = 0; i < collimatorLosses.size(); ++ i){
1034 bareLosses[i] = collimatorLosses[i].second;
1037 reduce(&bareLosses[0], &bareLosses[0] + bareLosses.size(), &bareLosses[0],
OpAddAssign());
1039 for (
size_t i = 0; i < collimatorLosses.size(); ++ i){
1040 collimatorLosses[i].second = bareLosses[i];
1046 msg <<
level3 <<
"* Wrote beam statistics." <<
endl;
1049 if (psDump && (
itsBunch_m->getTotalNum() > 0)) {
1051 const size_t localNum =
itsBunch_m->getLocalNum();
1055 bool driftToCorrectPosition = std::abs(distToLastStop) < 0.5 *
euclidean_norm(driftPerTimeStep);
1059 if (driftToCorrectPosition) {
1062 stashedR.
create(localNum);
1066 for (
size_t i = 0; i < localNum; ++ i) {
1072 driftPerTimeStep =
itsBunch_m->toLabTrafo_m.rotateTo(driftPerTimeStep);
1082 if (!statDump && !driftToCorrectPosition)
itsBunch_m->calcBeamParameters();
1087 if (driftToCorrectPosition) {
1090 stashedR.
destroy(localNum, 0);
1099 msg <<
level2 <<
"* Wrote beam phase space." <<
endl;
1110 const double dt = direction * std::min(
itsBunch_m->getT(),
1120 IndexMap::value_t::const_iterator it =
elements.begin();
1121 const IndexMap::value_t::const_iterator
end =
elements.end();
1123 for (; it !=
end; ++ it) {
1130 if ((*it)->applyToReferenceParticle(localR,
1135 *
gmsg <<
level1 <<
"The reference particle hit an element" <<
endl;
1151 const unsigned int localNum =
itsBunch_m->getLocalNum();
1152 for (
unsigned int i = 0; i < localNum; ++i) {
1207 double gamma = 0.1 /
itsBunch_m->getM() + 1.0;
1208 double beta =
sqrt(1.0 - 1.0 / std::pow(gamma, 2));
1258 for (
auto element: elementSet) {
1288 if (
itsBunch_m->hasFieldSolver() || numNodes == 1)
return;
1294 std::vector<long> localParticles(numNodes, 0);
1300 std::vector<DistributionInfo> send;
1301 std::vector<DistributionInfo> receive;
1304 if (localParticles[i] <= 0)
continue;
1307 if (j == i || localParticles[j] >= 0)
continue;
1309 long numParts = std::min(localParticles[i], -localParticles[j]);
1310 localParticles[i] -= numParts;
1311 localParticles[j] += numParts;
1320 send.push_back(request);
1322 receive.push_back(request);
1326 if (localParticles[i] == 0)
break;
1330 std::vector<MPI_Request> requests;
1331 const long sizeSingleParticle = 9 *
sizeof(double) +
sizeof(
short) +
sizeof(int) +
sizeof(
PID_t::Return_t);
1335 std::vector<char> send_msgbuf;
1337 if (!send.empty()) {
1340 unsigned int totalSend = 0, startIndex = 0;
1342 totalSend += request.howMany;
1344 send_msgbuf.reserve(totalSend * sizeSingleParticle);
1347 size_t sizePrior = send_msgbuf.size();
1348 for (
long i = 0; i < request.howMany; ++ i, -- idx) {
1349 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->R[idx](0)));
1350 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer + 3 *
sizeof(
double));
1351 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->P[idx](0)));
1352 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer + 3 *
sizeof(
double));
1353 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->Q[idx]));
1354 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
double));
1355 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->M[idx]));
1356 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
double));
1357 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->dt[idx]));
1358 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
double));
1359 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->POrigin[idx]));
1360 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
ParticleOrigin));
1361 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->TriID[idx]));
1362 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
int));
1363 buffer =
reinterpret_cast<const char*
>(&(
itsBunch_m->ID[idx]));
1364 send_msgbuf.insert(send_msgbuf.end(), buffer, buffer +
sizeof(
PID_t::Return_t));
1367 size_t sendSizeThis = send_msgbuf.size() - sizePrior;
1368 MPI_Request req =
Ippl::Comm->raw_isend(&(send_msgbuf[startIndex]),
1373 requests.push_back(req);
1375 startIndex += sendSizeThis;
1378 itsBunch_m->destroy(totalSend, idx + 1,
true);
1381 for (
unsigned int i = 0; i < receive.size(); ++ i) {
1384 const int bufsize =
Ippl::Comm->raw_probe_receive(recvbuf, node, tag);
1388 while (j < bufsize) {
1392 const double *buffer =
reinterpret_cast<const double*
>(recvbuf + j);
1399 j += 9 *
sizeof(double);
1408 const int *buffer =
reinterpret_cast<const int*
>(recvbuf + j);
1423 if (!requests.empty()) {
1424 MPI_Waitall(requests.size(), &(requests[0]), MPI_STATUSES_IGNORE);
ParticleSpatialLayout< double, 3 >::ParticlePos_t Ppos_t
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
Quaternion getQuaternion(Vector_t u, Vector_t ref)
std::list< ClassicField > FieldList
TBeamline< FlaggedElmPtr > FlaggedBeamline
A beam line with flagged elements.
Tps< T > sqrt(const Tps< T > &x)
Square root.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
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
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
Inform & level1(Inform &inf)
Inform & level3(Inform &inf)
std::string::const_iterator iterator_t
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 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)
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()
void setOpenMode(OpenMode openMode)
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)
BoundingBox getBoundingBox() const
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)
bool hasEndOfLineReached(const BoundingBox &globalBoundingBox)
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)
void kickParticles(const BorisPusher &pusher)
void updateReference(const BorisPusher &pusher)
void updateRefToLabCSTrafo()
unsigned int emissionSteps_m
void shiftZStopLeft(double back)
virtual const std::string & getName() const
Get element name.
void getMisalignment(double &x, double &y, double &s) const
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)
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 transformTo(const Vector_t &r) const
Vector_t rotateTo(const Vector_t &r) const
CoordinateSystemTrafo inverted() const
Quaternion conjugate() const
Tracker(const Beamline &, const PartData &, bool backBeam, bool backTrack)
Constructor.
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
bool isOutside(const Vector_t &position) const
void merge(OpalBeamline &rhs)
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
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)
static Communicate * Comm
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t