OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
ParallelTTracker.cpp
Go to the documentation of this file.
1//
2// Class ParallelTTracker
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//
23
24#include <cfloat>
25#include <cmath>
26#include <fstream>
27#include <limits>
28#include <iomanip>
29#include <iostream>
30#include <sstream>
31#include <string>
32
33#include "AbsBeamline/Monitor.h"
37#include "BasicActions/Option.h"
38#ifdef ENABLE_OPAL_FEL
40#endif
41#include "Beamlines/Beamline.h"
45#include "Physics/Units.h"
51#include "Utilities/Options.h"
52#include "Utilities/Timer.h"
53#include "Utilities/Util.h"
55
56extern Inform* gmsg;
57
58class PartData;
59
61 const PartData &reference,
62 bool revBeam,
63 bool revTrack):
64 Tracker(beamline, reference, revBeam, revTrack),
65 itsDataSink_m(nullptr),
66 itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getInitialDirection()),
67 globalEOL_m(false),
68 wakeStatus_m(false),
69 wakeFunction_m(nullptr),
70 pathLength_m(0.0),
71 zstart_m(0.0),
72 dtCurrentTrack_m(0.0),
73 minStepforReBin_m(-1),
74 minBinEmitted_m(std::numeric_limits<size_t>::max()),
75 repartFreq_m(-1),
76 emissionSteps_m(std::numeric_limits<unsigned int>::max()),
77 numParticlesInSimulation_m(0),
78 timeIntegrationTimer1_m(IpplTimings::getTimer("TIntegration1")),
79 timeIntegrationTimer2_m(IpplTimings::getTimer("TIntegration2")),
80 fieldEvaluationTimer_m(IpplTimings::getTimer("External field eval")),
81 BinRepartTimer_m(IpplTimings::getTimer("Binaryrepart")),
82 WakeFieldTimer_m(IpplTimings::getTimer("WakeField")),
83 particleMatterStatus_m(false)
84{}
85
88 DataSink &ds,
89 const PartData &reference,
90 bool revBeam,
91 bool revTrack,
92 const std::vector<unsigned long long> &maxSteps,
93 double zstart,
94 const std::vector<double> &zstop,
95 const std::vector<double> &dt):
96 Tracker(beamline, bunch, reference, revBeam, revTrack),
97 itsDataSink_m(&ds),
98 itsOpalBeamline_m(beamline.getOrigin3D(), beamline.getInitialDirection()),
99 globalEOL_m(false),
100 wakeStatus_m(false),
101 wakeFunction_m(nullptr),
102 pathLength_m(0.0),
103 zstart_m(zstart),
104 dtCurrentTrack_m(0.0),
105 minStepforReBin_m(-1),
106 minBinEmitted_m(std::numeric_limits<size_t>::max()),
107 repartFreq_m(-1),
108 emissionSteps_m(std::numeric_limits<unsigned int>::max()),
109 numParticlesInSimulation_m(0),
110 timeIntegrationTimer1_m(IpplTimings::getTimer("TIntegration1")),
111 timeIntegrationTimer2_m(IpplTimings::getTimer("TIntegration2")),
112 fieldEvaluationTimer_m(IpplTimings::getTimer("External field eval")),
113 BinRepartTimer_m(IpplTimings::getTimer("Binaryrepart")),
114 WakeFieldTimer_m(IpplTimings::getTimer("WakeField")),
115 particleMatterStatus_m(false)
116{
117 for (unsigned int i = 0; i < zstop.size(); ++ i) {
118 stepSizes_m.push_back(dt[i], zstop[i], maxSteps[i]);
119 }
120
123}
124
126
128 const FlaggedBeamline* fbl = static_cast<const FlaggedBeamline*>(&bl);
129 if (fbl->getRelativeFlag()) {
130 OpalBeamline stash(fbl->getOrigin3D(), fbl->getInitialDirection());
131 stash.swap(itsOpalBeamline_m);
132 fbl->iterate(*this, false);
136 stash.swap(itsOpalBeamline_m);
137 } else {
138 fbl->iterate(*this, false);
139 }
140}
141
142void ParallelTTracker::updateRFElement(std::string elName, double maxPhase) {
145 cavities.insert(cavities.end(), travelingwaves.begin(), travelingwaves.end());
146
147 for (FieldList::iterator fit = cavities.begin(); fit != cavities.end(); ++ fit) {
148 if ((*fit).getElement()->getName() == elName) {
149
150 RFCavity *element = static_cast<RFCavity *>((*fit).getElement().get());
151
152 element->setPhasem(maxPhase);
153 element->setAutophaseVeto();
154
155 INFOMSG("Restored cavity phase from the h5 file. Name: " << element->getName() << ", phase: " << maxPhase << " rad" << endl);
156 return;
157 }
158 }
159}
160
163}
164
167
168 if (OpalData::getInstance()->hasPriorTrack() ||
169 OpalData::getInstance()->inRestartRun()) {
172 for (; it < end; ++ it) {
173 updateRFElement((*it).first, (*it).second);
174 }
175 }
176}
177
179 Inform msg("ParallelTTracker ", *gmsg);
181
183 const double globalTimeShift = itsBunch_m->weHaveEnergyBins()? OpalData::getInstance()->getGlobalPhaseShift(): 0.0;
185
186 // the time step needs to be positive in the setup
189
191
192 if (OpalData::getInstance()->hasPriorTrack() || OpalData::getInstance()->inRestartRun()) {
194 }
195
197
198 double minTimeStep = stepSizes_m.getMinTimeStep();
199
201
202 if ( OpalData::getInstance()->hasPriorTrack() ||
203 OpalData::getInstance()->inRestartRun()) {
204
207
209 } else {
210
213 itsBunch_m->toLabTrafo_m = beamlineToLab;
214
215 itsBunch_m->RefPartR_m = beamlineToLab.transformTo(Vector_t(0.0));
216 itsBunch_m->RefPartP_m = beamlineToLab.rotateTo(momentum * Vector_t(0, 0, 1));
217
218 if (itsBunch_m->getTotalNum() > 0) {
220 momentum = itsReference.getP() / itsBunch_m->getM();
221 itsBunch_m->RefPartP_m = beamlineToLab.rotateTo(momentum * Vector_t(0, 0, 1));
222 }
223
224 if (zstart_m > pathLength_m) {
225 findStartPosition(pusher);
226 }
227
229 }
230 }
231
233 if (back_track) {
237 ++ stepSizes_m;
238 }
239 }
240
241 Vector_t rmin(0.0), rmax(0.0);
242 if (itsBunch_m->getTotalNum() > 0) {
243 itsBunch_m->get_bounds(rmin, rmax);
244 }
245
250 -rmin(2),
251 itsBunch_m->getT(),
252 (back_track? -minTimeStep: minTimeStep),
255
256 oth.execute();
257 BoundingBox globalBoundingBox = oth.getBoundingBox();
258
260
262
263 setTime();
264
265 double time = itsBunch_m->getT() - globalTimeShift;
266 itsBunch_m->setT(time);
267
268 *gmsg << level1 << *itsBunch_m << endl;
269
270 unsigned long long step = itsBunch_m->getGlobalTrackStep();
271 OPALTimer::Timer myt1;
272 *gmsg << "* Track start at: " << myt1.time() << ", t= " << Util::getTimeString(time) << "; "
273 << "zstart at: " << Util::getLengthString(pathLength_m)
274 << endl;
275
277
278 *gmsg << "* Executing ParallelTTracker\n"
279 << "* Initial dt = " << Util::getTimeString(itsBunch_m->getdT()) << "\n"
280 << "* Max integration steps = " << stepSizes_m.getMaxSteps()
281 << ", next step = " << step << endl << endl;
282
284
285 globalEOL_m = false;
286 wakeStatus_m = false;
287 deletedParticles_m = false;
289 while (!stepSizes_m.reachedEnd()) {
290 unsigned long long trackSteps = stepSizes_m.getNumSteps() + step;
293
294 for (; step < trackSteps; ++ step) {
295 Vector_t rmin(0.0), rmax(0.0);
296 if (itsBunch_m->getTotalNum() > 0) {
297 itsBunch_m->get_bounds(rmin, rmax);
298 }
299
300 timeIntegration1(pusher);
301
302 itsBunch_m->Ef = Vector_t(0.0);
303 itsBunch_m->Bf = Vector_t(0.0);
304
306
308 emitParticles(step);
310
312
313 timeIntegration2(pusher);
314
316
317 if (itsBunch_m->getT() > 0.0 ||
318 itsBunch_m->getdT() < 0.0) {
319 updateReference(pusher);
320 }
321
322 if (deletedParticles_m) {
324 deletedParticles_m = false;
325 }
327
328 if (hasEndOfLineReached(globalBoundingBox)) break;
329
330 bool const psDump = ((itsBunch_m->getGlobalTrackStep() % Options::psDumpFreq) + 1 == Options::psDumpFreq);
331 bool const statDump = ((itsBunch_m->getGlobalTrackStep() % Options::statDumpFreq) + 1 == Options::statDumpFreq);
332 dumpStats(step, psDump, statDump);
333
335
337 double driftPerTimeStep = std::abs(itsBunch_m->getdT()) * Physics::c * beta;
338 if (std::abs(stepSizes_m.getZStop() - pathLength_m) < 0.5 * driftPerTimeStep) {
339 break;
340 }
341 }
342
343 if (globalEOL_m)
344 break;
345
346 ++ stepSizes_m;
347 }
348
350
353 }
354
355 bool const psDump = (((itsBunch_m->getGlobalTrackStep() - 1) % Options::psDumpFreq) + 1 != Options::psDumpFreq);
356 bool const statDump = (((itsBunch_m->getGlobalTrackStep() - 1) % Options::statDumpFreq) + 1 != Options::statDumpFreq);
357 writePhaseSpace((step + 1), psDump, statDump);
358
359 msg << level2 << "Dump phase space of last step" << endl;
360
362
363 OPALTimer::Timer myt3;
364 *gmsg << endl << "* Done executing ParallelTTracker at "
365 << myt3.time() << endl << endl;
366
368
370}
371
373
374 itsBeamline_m.accept(*this);
375
377
381}
382
384
386 pushParticles(pusher);
388}
389
390
392 /*
393 transport and emit particles
394 that passed the cathode in the first
395 half-step or that would pass it in the
396 second half-step.
397
398 to make IPPL and the field solver happy
399 make sure that at least 10 particles are emitted
400
401 also remember that node 0 has
402 all the particles to be emitted
403
404 this has to be done *after* the calculation of the
405 space charges! thereby we neglect space charge effects
406 in the very first step of a new-born particle.
407
408 */
409
411 kickParticles(pusher);
412 //switchElements();
413 pushParticles(pusher);
414
415 const unsigned int localNum = itsBunch_m->getLocalNum();
416 for (unsigned int i = 0; i < localNum; ++ i) {
417 itsBunch_m->dt[i] = itsBunch_m->getdT();
418 }
419
421}
422
423void ParallelTTracker::selectDT(bool backTrack) {
424
426 double dt = itsBunch_m->getEmissionDeltaT();
427 itsBunch_m->setdT(dt);
428 } else {
429 double dt = dtCurrentTrack_m;
430 itsBunch_m->setdT(dt);
431 }
432 if (backTrack) {
434 }
435}
436
437void ParallelTTracker::changeDT(bool backTrack) {
438 selectDT(backTrack);
439 const unsigned int localNum = itsBunch_m->getLocalNum();
440 for (unsigned int i = 0; i < localNum; ++ i) {
441 itsBunch_m->dt[i] = itsBunch_m->getdT();
442 }
443}
444
446 if (!itsBunch_m->weHaveEnergyBins()) return;
447
451
452 transformBunch(refToGun);
453
455
456 Vector_t externalE = Vector_t(0.0);
457 Vector_t externalB = Vector_t(0.0);
459 gunToLab.rotateTo(Vector_t(0.0)),
460 itsBunch_m->getT() + 0.5 * itsBunch_m->getdT(),
461 externalE,
462 externalB);
463 itsBunch_m->emitParticles(externalE(2));
464
468
469 transformBunch(refToGun.inverted());
470 }
471
472 if (step > minStepforReBin_m) {
473 itsBunch_m->Rebin();
475 }
476}
477
478
479void ParallelTTracker::computeSpaceChargeFields(unsigned long long step) {
480 if (numParticlesInSimulation_m <= minBinEmitted_m || !itsBunch_m->hasFieldSolver()) {
481 return;
482 }
483
485 Quaternion alignment = getQuaternion(itsBunch_m->get_pmean(), Vector_t(0, 0, 1));
486 CoordinateSystemTrafo beamToReferenceCSTrafo(Vector_t(0, 0, pathLength_m), alignment.conjugate());
487 CoordinateSystemTrafo referenceToBeamCSTrafo = beamToReferenceCSTrafo.inverted();
488 const unsigned int localNum1 = itsBunch_m->getLocalNum();
489 for (unsigned int i = 0; i < localNum1; ++ i) {
490 itsBunch_m->R[i] = referenceToBeamCSTrafo.transformTo(itsBunch_m->R[i]);
491 }
492
494
495 if (step % repartFreq_m + 1 == repartFreq_m) {
497 }
498
503 for (int binNumber = 0; binNumber < itsBunch_m->getLastEmittedEnergyBin() &&
504 binNumber < itsBunch_m->getNumberOfEnergyBins(); ++binNumber) {
505
506 itsBunch_m->setBinCharge(binNumber);
508 itsBunch_m->computeSelfFields(binNumber);
509 itsBunch_m->Q = Q_back;
510
511 }
512
513 } else {
516 }
517
518 const unsigned int localNum2 = itsBunch_m->getLocalNum();
519 for (unsigned int i = 0; i < localNum2; ++ i) {
520 itsBunch_m->R[i] = beamToReferenceCSTrafo.transformTo(itsBunch_m->R[i]);
521 itsBunch_m->Ef[i] = beamToReferenceCSTrafo.rotateTo(itsBunch_m->Ef[i]);
522 itsBunch_m->Bf[i] = beamToReferenceCSTrafo.rotateTo(itsBunch_m->Bf[i]);
523 }
524}
525
526
529 Inform msg("ParallelTTracker ", *gmsg);
530 const unsigned int localNum = itsBunch_m->getLocalNum();
531 bool locPartOutOfBounds = false, globPartOutOfBounds = false;
532 Vector_t rmin(0.0), rmax(0.0);
533 if (itsBunch_m->getTotalNum() > 0)
534 itsBunch_m->get_bounds(rmin, rmax);
536
537 try {
538 elements = oth.query(pathLength_m + 0.5 * (rmax(2) + rmin(2)), rmax(2) - rmin(2));
539 } catch(IndexMap::OutOfBounds &e) {
540 globalEOL_m = true;
541 return;
542 }
543
544 IndexMap::value_t::const_iterator it = elements.begin();
545 const IndexMap::value_t::const_iterator end = elements.end();
546
547 for (; it != end; ++ it) {
548 CoordinateSystemTrafo refToLocalCSTrafo = (itsOpalBeamline_m.getMisalignment((*it)) *
550 CoordinateSystemTrafo localToRefCSTrafo = refToLocalCSTrafo.inverted();
551
552 (*it)->setCurrentSCoordinate(pathLength_m + rmin(2));
553
554 for (unsigned int i = 0; i < localNum; ++ i) {
555 if (itsBunch_m->Bin[i] < 0) continue;
556
557 itsBunch_m->R[i] = refToLocalCSTrafo.transformTo(itsBunch_m->R[i]);
558 itsBunch_m->P[i] = refToLocalCSTrafo.rotateTo(itsBunch_m->P[i]);
559 double &dt = itsBunch_m->dt[i];
560
561 Vector_t localE(0.0), localB(0.0);
562
563 if ((*it)->apply(i, itsBunch_m->getT() + 0.5 * dt, localE, localB)) {
564 itsBunch_m->R[i] = localToRefCSTrafo.transformTo(itsBunch_m->R[i]);
565 itsBunch_m->P[i] = localToRefCSTrafo.rotateTo(itsBunch_m->P[i]);
566 itsBunch_m->Bin[i] = -1;
567 locPartOutOfBounds = true;
568
569 continue;
570 }
571
572 itsBunch_m->R[i] = localToRefCSTrafo.transformTo(itsBunch_m->R[i]);
573 itsBunch_m->P[i] = localToRefCSTrafo.rotateTo(itsBunch_m->P[i]);
574 itsBunch_m->Ef[i] += localToRefCSTrafo.rotateTo(localE);
575 itsBunch_m->Bf[i] += localToRefCSTrafo.rotateTo(localB);
576 }
577 }
578
580
582#ifdef ENABLE_OPAL_FEL
583 computeUndulator(elements);
584#endif
586
587 reduce(locPartOutOfBounds, globPartOutOfBounds, OpOrAssign());
588
589 size_t ne = 0;
590 if (globPartOutOfBounds) {
591 if (itsBunch_m->hasFieldSolver()) {
593 } else {
595 }
597 deletedParticles_m = true;
598 }
599
600 size_t totalNum = itsBunch_m->getTotalNum();
603 }
604
605 if (ne > 0) {
606 msg << level1 << "* Deleted " << ne << " particles, "
607 << "remaining " << numParticlesInSimulation_m << " particles" << endl;
608 }
609}
610
611#ifdef ENABLE_OPAL_FEL
612void ParallelTTracker::computeUndulator(IndexMap::value_t &elements) {
613 // Check if bunch has entered undulator field.
614 UndulatorRep* und;
615 IndexMap::value_t::const_iterator it = elements.begin();
616 for (; it != elements.end(); ++ it)
617 if ((*it)->getType() == ElementType::UNDULATOR) {
618 und = dynamic_cast<UndulatorRep*>(it->get());
619 if (!und->getHasBeenSimulated())
620 break;
621 }
622 if (it == elements.end())
623 return;
624
625 // Apply MITHRA full wave solver for undulator.
626 CoordinateSystemTrafo refToLocalCSTrafo = (itsOpalBeamline_m.getMisalignment((*it)) *
628
629 und->apply(itsBunch_m, refToLocalCSTrafo);
630
632}
633#endif
634
636 bool hasWake = false;
637 WakeFunction *wfInstance;
638
639 Inform msg("ParallelTTracker ", *gmsg);
640
641 const unsigned int localNum = itsBunch_m->getLocalNum();
642
643 IndexMap::value_t::const_iterator it = elements.begin();
644 const IndexMap::value_t::const_iterator end = elements.end();
645
646 for (; it != end; ++ it) {
647 if ((*it)->hasWake() && !hasWake) {
649
650 hasWake = true;
651
652 if ((*it)->getWake()->getType() == WakeType::CSRWakeFunction ||
653 (*it)->getWake()->getType() == WakeType::CSRIGFWakeFunction) {
654 if ((*it)->getType() == ElementType::RBEND ||
655 (*it)->getType() == ElementType::SBEND) {
656 wfInstance = (*it)->getWake();
657 wakeFunction_m = wfInstance;
658 } else {
659 wfInstance = wakeFunction_m;
660 }
661 } else {
662 wfInstance = (*it)->getWake();
663 }
664
665 if (!wfInstance) {
666 throw OpalException("ParallelTTracker::computeWakefield",
667 "empty wake function");
668 }
669
670 if (!wakeStatus_m) {
671 msg << level2 << "============== START WAKE CALCULATION =============" << endl;
672 wfInstance->initialize((*it).get());
673 wakeStatus_m = true;
674 }
675
677
678 Quaternion alignment = getQuaternion(itsBunch_m->get_pmean(), Vector_t(0, 0, 1));
679 CoordinateSystemTrafo referenceToBeamCSTrafo(Vector_t(0.0), alignment);
680 CoordinateSystemTrafo beamToReferenceCSTrafo = referenceToBeamCSTrafo.inverted();
681
682 for (unsigned int i = 0; i < localNum; ++ i) {
683 itsBunch_m->R[i] = referenceToBeamCSTrafo.transformTo(itsBunch_m->R[i]);
684 itsBunch_m->P[i] = referenceToBeamCSTrafo.rotateTo(itsBunch_m->P[i]);
685 itsBunch_m->Ef[i] = referenceToBeamCSTrafo.rotateTo(itsBunch_m->Ef[i]);
686 }
687
688 wfInstance->apply(itsBunch_m);
689
690 for (unsigned int i = 0; i < localNum; ++ i) {
691 itsBunch_m->R[i] = beamToReferenceCSTrafo.transformTo(itsBunch_m->R[i]);
692 itsBunch_m->P[i] = beamToReferenceCSTrafo.rotateTo(itsBunch_m->P[i]);
693 itsBunch_m->Ef[i] = beamToReferenceCSTrafo.rotateTo(itsBunch_m->Ef[i]);
694 }
695
697 }
698 }
699
700 if (wakeStatus_m && !hasWake) {
701 msg << level2 << "=============== END WAKE CALCULATION ==============" << endl;
702 wakeStatus_m = false;
703 }
704}
705
707 Inform msg("ParallelTTracker ", *gmsg);
708 std::set<IndexMap::value_t::value_type> elementsWithParticleMatterInteraction;
709 std::set<ParticleMatterInteractionHandler*> particleMatterinteractionHandlers;
710 IndexMap::key_t currentRange{0.0, 0.0};
711
712 while (elements.size() > 0) {
713 auto it = elements.begin();
714 if ((*it)->hasParticleMatterInteraction()) {
715 elementsWithParticleMatterInteraction.insert(*it);
716 particleMatterinteractionHandlers.insert((*it)->getParticleMatterInteraction());
717
718 IndexMap::key_t range = oth.getRange(*it, pathLength_m);
719 currentRange.begin = std::min(currentRange.begin, range.begin);
720 currentRange.end = std::max(currentRange.end, range.end);
721
722 IndexMap::value_t touching = oth.getTouchingElements(range);
723 elements.insert(touching.begin(), touching.end());
724 }
725
726 elements.erase(it);
727 }
728
729 if (!elementsWithParticleMatterInteraction.empty()) {
730 std::set<ParticleMatterInteractionHandler*> oldSPHandlers;
731 std::vector<ParticleMatterInteractionHandler*> leftBehindSPHandlers, newSPHandlers;
733 oldSPHandlers.insert(it);
734 }
735
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());
742
743 for (auto it: leftBehindSPHandlers) {
744 if (!it->stillActive()) {
746 }
747 }
748
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());
755
756 for (auto it: newSPHandlers) {
758 }
759
761 msg << level2 << "============== START PARTICLE MATTER INTERACTION CALCULATION =============" << endl;
763 }
764 } else {
765 for (auto it = activeParticleMatterInteractionHandlers_m.begin();
767 if (!(*it)->stillActive()) {
768 auto next = std::next(it);
770 it = next;
771 } else {
772 it = std::next(it);
773 }
774 }
775 }
776
778 do {
780 //check if more than one degrader has particles
781 ParticleMatterInteractionHandler* onlyDegraderWithParticles = nullptr;
782 int degradersWithParticlesCount = 0;
784 it->setFlagAllParticlesIn(false);
785 if (it->getParticlesInMat() > 0) {
786 onlyDegraderWithParticles = it;
787 ++ degradersWithParticlesCount;
788 }
789 }
790
791 //if max particles per node is 2, and only one degrader has particles set
792 //AllParticlesIn for this degrader to true
793 unsigned int localNum = itsBunch_m->getLocalNum();
794 unsigned int totalNum = 0;
795 reduce(localNum, totalNum, OpAddAssign());
796 bool allParticlesInMat = (totalNum == 0 &&
797 degradersWithParticlesCount == 1);
798
799 if (allParticlesInMat) {
800 onlyDegraderWithParticles->setFlagAllParticlesIn(true);
801 msg << "All particles in degrader" << endl;
802 }
803
804 auto boundingSphere = itsBunch_m->getLocalBoundingSphere();
805 unsigned int rediffusedParticles = 0;
806 unsigned int numEnteredParticles = 0;
808 ElementBase* element = it->getElement();
809 CoordinateSystemTrafo refToLocalCSTrafo = (element->getMisalignment() *
811 CoordinateSystemTrafo localToRefCSTrafo = refToLocalCSTrafo.inverted();
812
813 const unsigned int localNum = itsBunch_m->getLocalNum();
814 for (unsigned int i = 0; i < localNum; ++i) {
815 itsBunch_m->R[i] = refToLocalCSTrafo.transformTo(itsBunch_m->R[i]);
816 itsBunch_m->P[i] = refToLocalCSTrafo.rotateTo(itsBunch_m->P[i]);
817 }
818 boundingSphere.first = refToLocalCSTrafo.transformTo(boundingSphere.first);
819
820 it->apply(itsBunch_m, boundingSphere);
821 it->print(msg);
822
823 boundingSphere.first = localToRefCSTrafo.transformTo(boundingSphere.first);
824
825 const unsigned int newLocalNum = itsBunch_m->getLocalNum();
826 for (unsigned int i = 0; i < newLocalNum; ++i) {
827 itsBunch_m->R[i] = localToRefCSTrafo.transformTo(itsBunch_m->R[i]);
828 itsBunch_m->P[i] = localToRefCSTrafo.rotateTo(itsBunch_m->P[i]);
829 }
830
831 rediffusedParticles += it->getRediffused();
832 numEnteredParticles += it->getNumEntered();
833
834 //if all particles were in material update time to time in degrader
835 if (it->getFlagAllParticlesIn()) {
836 double timeDifference = it->getTime() - itsBunch_m->getdT() - itsBunch_m->getT();
837 if (timeDifference > 0.0) {
838 const unsigned int numSteps = std::ceil(timeDifference / itsBunch_m->getdT());
839 const double origdT = itsBunch_m->getdT();
840 itsBunch_m->setdT(timeDifference / numSteps);
842 for (unsigned int i = 0; i < numSteps; ++ i) {
843 updateReference(pusher);
844 }
845 itsBunch_m->setdT(origdT);
846 }
847 itsBunch_m->setT(it->getTime() - itsBunch_m->getdT());
848 }
849 }
850
851 //perform boundp only if there are particles in the bunch, or there are particles
852 //comming out of the degrader
853 if (numEnteredParticles > 0 || rediffusedParticles > 0) {
854 totalNum -= (numEnteredParticles + rediffusedParticles);
855 if (totalNum > minBinEmitted_m && itsBunch_m->hasFieldSolver()) {
857 } else {
859 }
860 }
861
862 //if bunch has no particles update time to time in degrader
863 if (itsBunch_m->getTotalNum() == 0)
865
866 } while (itsBunch_m->getTotalNum() == 0);
867
868
870 msg << level2 << "============== END PARTICLE MATTER INTERACTION CALCULATION =============" << endl;
872 }
873 }
874}
875
877 size_t particles_or_bins = std::max(minBinEmitted_m, size_t(1000));
878 if (itsBunch_m->hasFieldSolver() && numParticlesInSimulation_m > particles_or_bins) {
879
880 INFOMSG("*****************************************************************" << endl);
881 INFOMSG("do repartition because of repartFreq_m" << endl);
882 INFOMSG("*****************************************************************" << endl);
887 INFOMSG("*****************************************************************" << endl);
888 INFOMSG("do repartition done" << endl);
889 INFOMSG("*****************************************************************" << endl);
890 }
891}
892
893void ParallelTTracker::dumpStats(long long step, bool psDump, bool statDump) {
894 OPALTimer::Timer myt2;
895 Inform msg("ParallelTTracker ", *gmsg);
896
897 if (itsBunch_m->getGlobalTrackStep() % 1000 + 1 == 1000) {
898 msg << level1;
899 } else if (itsBunch_m->getGlobalTrackStep() % 100 + 1 == 100) {
900 msg << level2;
901 } else {
902 msg << level3;
903 }
904
906 msg << myt2.time() << " "
907 << "Step " << std::setw(6) << itsBunch_m->getGlobalTrackStep() << "; "
908 << " -- no emission yet -- "
909 << "t= " << Util::getTimeString(itsBunch_m->getT())
910 << endl;
911 return;
912 }
913
915 size_t totalParticles_f = numParticlesInSimulation_m;
916 if (totalParticles_f <= minBinEmitted_m) {
917 msg << myt2.time() << " "
918 << "Step " << std::setw(6) << itsBunch_m->getGlobalTrackStep() << "; "
919 << "only " << std::setw(4) << totalParticles_f << " particles emitted; "
920 << "t= " << Util::getTimeString(itsBunch_m->getT()) << ", "
922 << endl;
924 throw OpalException("ParallelTTracker::dumpStats()",
925 "there seems to be something wrong with the position of the bunch!");
926 } else {
927
928 msg << myt2.time() << " "
929 << "Step " << std::setw(6) << itsBunch_m->getGlobalTrackStep() << " "
930 << "at " << Util::getLengthString(pathLength_m) << ", "
931 << "t= " << Util::getTimeString(itsBunch_m->getT()) << ", "
933 << endl;
934
935 writePhaseSpace(step, psDump, statDump);
936 }
937}
938
939
941 Inform msg("ParallelTTracker ", *gmsg);
942
944 RealVariable *ar = dynamic_cast<RealVariable *>(OpalData::getInstance()->find("MINBINEMITTED"));
945 if (ar)
946 minBinEmitted_m = static_cast<size_t>(ar->getReal());
947 msg << level2 << "MINBINEMITTED " << minBinEmitted_m << endl;
948
950 RealVariable *br = dynamic_cast<RealVariable *>(OpalData::getInstance()->find("MINSTEPFORREBIN"));
951 if (br)
952 minStepforReBin_m = static_cast<int>(br->getReal());
953 msg << level2 << "MINSTEPFORREBIN " << minStepforReBin_m << endl;
954
955 // there is no point to do repartitioning with one node
956 if (Ippl::getNodes() == 1) {
958 } else {
960 RealVariable *rep = dynamic_cast<RealVariable *>(OpalData::getInstance()->find("REPARTFREQ"));
961 if (rep)
962 repartFreq_m = static_cast<int>(rep->getReal());
963 msg << level2 << "REPARTFREQ " << repartFreq_m << endl;
964 }
965}
966
967
970 globalEOL_m = globalEOL_m || globalBoundingBox.isOutside(itsBunch_m->RefPartR_m);
971 return globalEOL_m;
972}
973
975 const unsigned int localNum = itsBunch_m->getLocalNum();
976 for (unsigned int i = 0; i < localNum; ++i) {
977 itsBunch_m->dt[i] = itsBunch_m->getdT();
978 }
979}
980
982 Inform msg("ParallelTTracker ", *gmsg);
983
984 if (!itsBunch_m->doEmission()) return;
985
987 msg << level2 << "Do emission for " << itsBunch_m->getTEmission() << " [s] using "
988 << itsBunch_m->getNumberOfEnergyBins() << " energy bins " << endl
989 << "Change dT from " << itsBunch_m->getdT() << " [s] to "
990 << itsBunch_m->getEmissionDeltaT() << " [s] during emission " << endl;;
991
992}
993
994void ParallelTTracker::writePhaseSpace(const long long /*step*/, bool psDump, bool statDump) {
995 extern Inform *gmsg;
996 Inform msg("OPAL ", *gmsg);
997 Vector_t externalE, externalB;
998 Vector_t FDext[2]; // FDext = {BHead, EHead, BRef, ERef, BTail, ETail}.
999
1000 // Sample fields at (xmin, ymin, zmin), (xmax, ymax, zmax) and the centroid location. We
1001 // are sampling the electric and magnetic fields at the back, front and
1002 // center of the beam.
1003 Vector_t rmin, rmax;
1004 itsBunch_m->get_bounds(rmin, rmax);
1005
1006 if (psDump || statDump) {
1007 externalB = Vector_t(0.0);
1008 externalE = Vector_t(0.0);
1011 itsBunch_m->getT() - 0.5 * itsBunch_m->getdT(),
1012 externalE,
1013 externalB);
1014 FDext[0] = itsBunch_m->toLabTrafo_m.rotateFrom(externalB);
1015 FDext[1] = itsBunch_m->toLabTrafo_m.rotateFrom(externalE * Units::Vpm2MVpm);
1016 }
1017
1018 if (statDump) {
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) {
1023 FlexibleCollimator* coll = static_cast<FlexibleCollimator*>(it->getElement().get());
1024 std::string name = coll->getName();
1025 unsigned int losses = coll->getLosses();
1026 collimatorLosses.push_back(std::make_pair(name, losses));
1027 }
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;
1031 });
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;
1035 }
1036
1037 reduce(&bareLosses[0], &bareLosses[0] + bareLosses.size(), &bareLosses[0], OpAddAssign());
1038
1039 for (size_t i = 0; i < collimatorLosses.size(); ++ i){
1040 collimatorLosses[i].second = bareLosses[i];
1041 }
1042 }
1043 // Write statistical data.
1044 itsDataSink_m->dumpSDDS(itsBunch_m, FDext, collimatorLosses);
1045
1046 msg << level3 << "* Wrote beam statistics." << endl;
1047 }
1048
1049 if (psDump && (itsBunch_m->getTotalNum() > 0)) {
1050 // Write fields to .h5 file.
1051 const size_t localNum = itsBunch_m->getLocalNum();
1052 double distToLastStop = stepSizes_m.getFinalZStop() - pathLength_m;
1055 bool driftToCorrectPosition = std::abs(distToLastStop) < 0.5 * euclidean_norm(driftPerTimeStep);
1056 Ppos_t stashedR;
1057 Vector_t stashedRefPartR;
1058
1059 if (driftToCorrectPosition) {
1060 const double tau = distToLastStop / euclidean_norm(driftPerTimeStep) * itsBunch_m->getdT();
1061 if (localNum > 0) {
1062 stashedR.create(localNum);
1063 stashedR = itsBunch_m->R;
1064 stashedRefPartR = itsBunch_m->RefPartR_m;
1065
1066 for (size_t i = 0; i < localNum; ++ i) {
1067 itsBunch_m->R[i] += tau * (Physics::c * itsBunch_m->P[i] / Util::getGamma(itsBunch_m->P[i]) -
1068 driftPerTimeStep / itsBunch_m->getdT());
1069 }
1070 }
1071
1072 driftPerTimeStep = itsBunch_m->toLabTrafo_m.rotateTo(driftPerTimeStep);
1073 itsBunch_m->RefPartR_m = itsBunch_m->RefPartR_m + tau * driftPerTimeStep / itsBunch_m->getdT();
1074 CoordinateSystemTrafo update(tau * driftPerTimeStep / itsBunch_m->getdT(),
1075 Quaternion(1.0, 0.0, 0.0, 0.0));
1077
1079
1081 }
1082 if (!statDump && !driftToCorrectPosition) itsBunch_m->calcBeamParameters();
1083
1084 msg << *itsBunch_m << endl;
1086
1087 if (driftToCorrectPosition) {
1088 if (localNum > 0) {
1089 itsBunch_m->R = stashedR;
1090 stashedR.destroy(localNum, 0);
1091 }
1092
1093 itsBunch_m->RefPartR_m = stashedRefPartR;
1095
1097 }
1098
1099 msg << level2 << "* Wrote beam phase space." << endl;
1100 }
1101}
1102
1106}
1107
1109 const double direction = back_track? -1: 1;
1110 const double dt = direction * std::min(itsBunch_m->getT(),
1111 direction * itsBunch_m->getdT());
1112 const double scaleFactor = Physics::c * dt;
1113 Vector_t Ef(0.0), Bf(0.0);
1114
1115 itsBunch_m->RefPartR_m /= scaleFactor;
1117 itsBunch_m->RefPartR_m *= scaleFactor;
1118
1120 IndexMap::value_t::const_iterator it = elements.begin();
1121 const IndexMap::value_t::const_iterator end = elements.end();
1122
1123 for (; it != end; ++ it) {
1124 const CoordinateSystemTrafo &refToLocalCSTrafo = itsOpalBeamline_m.getCSTrafoLab2Local((*it));
1125
1126 Vector_t localR = refToLocalCSTrafo.transformTo(itsBunch_m->RefPartR_m);
1127 Vector_t localP = refToLocalCSTrafo.rotateTo(itsBunch_m->RefPartP_m);
1128 Vector_t localE(0.0), localB(0.0);
1129
1130 if ((*it)->applyToReferenceParticle(localR,
1131 localP,
1132 itsBunch_m->getT() - 0.5 * dt,
1133 localE,
1134 localB)) {
1135 *gmsg << level1 << "The reference particle hit an element" << endl;
1136 globalEOL_m = true;
1137 }
1138
1139 Ef += refToLocalCSTrafo.rotateFrom(localE);
1140 Bf += refToLocalCSTrafo.rotateFrom(localB);
1141 }
1142
1143 pusher.kick(itsBunch_m->RefPartR_m, itsBunch_m->RefPartP_m, Ef, Bf, dt);
1144
1145 itsBunch_m->RefPartR_m /= scaleFactor;
1147 itsBunch_m->RefPartR_m *= scaleFactor;
1148}
1149
1151 const unsigned int localNum = itsBunch_m->getLocalNum();
1152 for (unsigned int i = 0; i < localNum; ++i) {
1153 itsBunch_m->R[i] = trafo.transformTo(itsBunch_m->R[i]);
1154 itsBunch_m->P[i] = trafo.rotateTo(itsBunch_m->P[i]);
1155 itsBunch_m->Ef[i] = trafo.rotateTo(itsBunch_m->Ef[i]);
1156 itsBunch_m->Bf[i] = trafo.rotateTo(itsBunch_m->Bf[i]);
1157 }
1158}
1159
1163
1165
1166 CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
1167
1168 transformBunch(update);
1169
1171}
1172
1174 double t = itsBunch_m->getT();
1175 t += tau;
1176 itsBunch_m->setT(t);
1177
1178 // the push method below pushes for half a time step. Hence the ref particle
1179 // should be pushed for 2 * tau
1180 itsBunch_m->RefPartR_m /= (Physics::c * 2 * tau);
1182 itsBunch_m->RefPartR_m *= (Physics::c * 2 * tau);
1183
1185
1188 CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
1190}
1191
1193
1194 StepSizeConfig stepSizesCopy(stepSizes_m);
1195 if (back_track) {
1196 stepSizesCopy.shiftZStopLeft(zstart_m);
1197 }
1198
1199 double t = 0.0;
1200 itsBunch_m->setT(t);
1201
1202 dtCurrentTrack_m = stepSizesCopy.getdT();
1203 selectDT();
1204
1207 double gamma = 0.1 / itsBunch_m->getM() + 1.0;
1208 double beta = sqrt(1.0 - 1.0 / std::pow(gamma, 2));
1210 }
1211
1212 while (true) {
1213 autophaseCavities(pusher);
1214
1215 t += itsBunch_m->getdT();
1216 itsBunch_m->setT(t);
1217
1221
1223
1224 if (pathLength_m > stepSizesCopy.getZStop()) {
1225 ++ stepSizesCopy;
1226
1227 if (stepSizesCopy.reachedEnd()) {
1228 -- stepSizesCopy;
1229 double tau = (stepSizesCopy.getZStop() - pathLength_m) / speed;
1230 applyFractionalStep(pusher, tau);
1231
1232 break;
1233 }
1234
1235 dtCurrentTrack_m = stepSizesCopy.getdT();
1236 selectDT();
1237 }
1238
1239 if (std::abs(pathLength_m - zstart_m) <= 0.5 * itsBunch_m->getdT() * speed) {
1240 double tau = (zstart_m - pathLength_m) / speed;
1241 applyFractionalStep(pusher, tau);
1242
1243 break;
1244 }
1245 }
1246
1247 changeDT();
1248}
1249
1251
1252 double t = itsBunch_m->getT();
1254 pusher.push(nextR, itsBunch_m->RefPartP_m, itsBunch_m->getdT());
1255 nextR *= Physics::c * itsBunch_m->getdT();
1256
1257 auto elementSet = itsOpalBeamline_m.getElements(nextR);
1258 for (auto element: elementSet) {
1259 if (element->getType() == ElementType::TRAVELINGWAVE) {
1260 const TravelingWave *TWelement = static_cast<const TravelingWave *>(element.get());
1261 if (!TWelement->getAutophaseVeto()) {
1262 CavityAutophaser ap(itsReference, element);
1265 t, itsBunch_m->getdT());
1266 }
1267
1268 } else if (element->getType() == ElementType::RFCAVITY) {
1269 const RFCavity *RFelement = static_cast<const RFCavity *>(element.get());
1270 if (!RFelement->getAutophaseVeto()) {
1271 CavityAutophaser ap(itsReference, element);
1274 t, itsBunch_m->getdT());
1275 }
1276 }
1277 }
1278}
1279
1281 unsigned int who;
1282 unsigned int whom;
1283 unsigned int howMany;
1284};
1285
1287 const int numNodes = Ippl::getNodes();
1288 if (itsBunch_m->hasFieldSolver() || numNodes == 1) return;
1289
1290 long onAverage = itsBunch_m->getTotalNum() / Ippl::getNodes();
1292 ++ onAverage;
1293
1294 std::vector<long> localParticles(numNodes, 0);
1295 localParticles[Ippl::myNode()] = itsBunch_m->getLocalNum() - onAverage;
1296 allreduce(&(localParticles[0]),
1297 numNodes,
1298 std::plus<long>());
1299
1300 std::vector<DistributionInfo> send;
1301 std::vector<DistributionInfo> receive;
1302
1303 for (int i = 0; i < Ippl::getNodes(); ++ i) {
1304 if (localParticles[i] <= 0) continue;
1305
1306 for (int j = 0; j < Ippl::getNodes(); ++ j) {
1307 if (j == i || localParticles[j] >= 0) continue;
1308
1309 long numParts = std::min(localParticles[i], -localParticles[j]);
1310 localParticles[i] -= numParts;
1311 localParticles[j] += numParts;
1312
1313 if (i == Ippl::myNode() || j == Ippl::myNode()) {
1314 DistributionInfo request;
1315 request.who = i;
1316 request.whom = j;
1317 request.howMany = numParts;
1318
1319 if (i == Ippl::myNode()) {
1320 send.push_back(request);
1321 } else {
1322 receive.push_back(request);
1323 }
1324 }
1325
1326 if (localParticles[i] == 0) break;
1327 }
1328 }
1329
1330 std::vector<MPI_Request> requests;
1331 const long sizeSingleParticle = 9 * sizeof(double) + sizeof(short) + sizeof(int) + sizeof(PID_t::Return_t);
1332 long idx = itsBunch_m->getLocalNum() - 1;
1334
1335 std::vector<char> send_msgbuf;
1336
1337 if (!send.empty()) {
1338 const char *buffer;
1339
1340 unsigned int totalSend = 0, startIndex = 0;
1341 for (DistributionInfo &request: send) {
1342 totalSend += request.howMany;
1343 }
1344 send_msgbuf.reserve(totalSend * sizeSingleParticle);
1345
1346 for (DistributionInfo &request: send) {
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));
1365 }
1366
1367 size_t sendSizeThis = send_msgbuf.size() - sizePrior;
1368 MPI_Request req = Ippl::Comm->raw_isend(&(send_msgbuf[startIndex]),
1369 sendSizeThis,
1370 request.whom,
1371 tag);
1372
1373 requests.push_back(req);
1374
1375 startIndex += sendSizeThis;
1376 }
1377
1378 itsBunch_m->destroy(totalSend, idx + 1, true);
1379 }
1380
1381 for (unsigned int i = 0; i < receive.size(); ++ i) {
1382 int node = Communicate::COMM_ANY_NODE;
1383 char *recvbuf;
1384 const int bufsize = Ippl::Comm->raw_probe_receive(recvbuf, node, tag);
1385
1386 int j = 0;
1387
1388 while (j < bufsize) {
1389 ++ idx;
1390 itsBunch_m->create(1);
1391 {
1392 const double *buffer = reinterpret_cast<const double*>(recvbuf + j);
1393 itsBunch_m->R[idx] = Vector_t(buffer[0], buffer[1], buffer[2]);
1394 itsBunch_m->P[idx] = Vector_t(buffer[3], buffer[4], buffer[5]);
1395 itsBunch_m->Q[idx] = buffer[6];
1396 itsBunch_m->M[idx] = buffer[7];
1397 itsBunch_m->dt[idx] = buffer[8];
1398 }
1399 j += 9 * sizeof(double);
1400
1401 {
1402 const ParticleOrigin *buffer = reinterpret_cast<const ParticleOrigin*>(recvbuf + j);
1403 itsBunch_m->POrigin[idx] = buffer[0];
1404 }
1405 j += sizeof(ParticleOrigin);
1406
1407 {
1408 const int *buffer = reinterpret_cast<const int*>(recvbuf + j);
1409 itsBunch_m->TriID[idx] = buffer[0];
1410 }
1411 j += sizeof(int);
1412
1413 {
1414 const PID_t::Return_t *buffer = reinterpret_cast<const PID_t::Return_t*>(recvbuf + j);
1415 itsBunch_m->ID[idx] = buffer[0];
1416 }
1417 j += sizeof(PID_t::Return_t);
1418 }
1419
1420 delete[] recvbuf;
1421 }
1422
1423 if (!requests.empty()) {
1424 MPI_Waitall(requests.size(), &(requests[0]), MPI_STATUSES_IGNORE);
1425 }
1426}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
Quaternion getQuaternion(Vector_t u, Vector_t ref)
Definition: Quaternion.cpp:34
@ CSRIGFWakeFunction
@ CSRWakeFunction
std::list< ClassicField > FieldList
Definition: ClassicField.h:43
ParticleOrigin
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
elements
Definition: IndexMap.cpp:163
Inform * gmsg
Definition: Main.cpp:61
void allreduce(const T *input, T *output, int count, Op op)
Definition: GlobalComm.hpp:510
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
#define P_SPATIAL_TRANSFER_TAG
Definition: Tags.h:82
#define P_LAYOUT_CYCLE
Definition: Tags.h:86
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
Definition: IndexInlines.h:357
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Definition: PETE.h:728
std::complex< double > a
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< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level1(Inform &inf)
Definition: Inform.cpp:45
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
#define INFOMSG(msg)
Definition: IpplInfo.h:348
std::string::const_iterator iterator_t
Definition: array.cpp:19
const std::string name
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
constexpr double Vpm2MVpm
Definition: Units.h:125
std::string::iterator iterator
Definition: MSLang.h:16
T isinf(T x)
isinf function with adjusted return type
Definition: matheval.hpp:70
T isnan(T x)
isnan function with adjusted return type
Definition: matheval.hpp:66
int psDumpFreq
The frequency to dump the phase space, i.e.dump data when steppsDumpFreq==0.
Definition: Options.cpp:39
int minBinEmitted
The number of bins that have to be emitted before the bin are squashed into a single bin.
Definition: Options.cpp:51
int minStepForRebin
The number of steps into the simulation before the bins are squashed into a single bin.
Definition: Options.cpp:53
int repartFreq
The frequency to do particles repartition for better load balance between nodes.
Definition: Options.cpp:49
int statDumpFreq
The frequency to dump statistical values, e.e. dump data when stepstatDumpFreq==0.
Definition: Options.cpp:41
double getKineticEnergy(Vector_t p, double mass)
Definition: Util.h:55
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
Definition: Util.h:146
std::string getTimeString(double time, unsigned int precision=3)
Definition: Util.h:73
double getGamma(Vector_t p)
Definition: Util.h:45
std::string getLengthString(double spos, unsigned int precision=3)
Definition: Util.h:96
ParticleAttrib< Vector_t > Ef
double get_meanKineticEnergy() const
ParticlePos_t & R
virtual void resetInterpolationCache(bool clearCache=false)
ParticleAttrib< int > Bin
Vector_t RefPartP_m
void get_bounds(Vector_t &rmin, Vector_t &rmax) const
virtual void computeSelfFields()=0
size_t getLocalNum() const
void set_sPos(double s)
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
bool weHaveEnergyBins()
size_t boundp_destroyT()
ParticleAttrib< Vector_t > P
void switchToUnitlessPositions(bool use_dt_per_particle=false)
double getTEmission()
double getdT() const
double getEmissionDeltaT()
ParticleAttrib< ParticleOrigin > POrigin
bool getIfBeamEmitting()
Vector_t RefPartR_m
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 setdT(double dt)
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
virtual void boundp()
void create(size_t M)
long long getGlobalTrackStep() const
void setT(double t)
std::pair< Vector_t, double > getLocalBoundingSphere()
ParticleIndex_t & ID
double get_sPos() const
double getM() const
double getT() const
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
std::vector< MaxPhasesT >::iterator getLastMaxPhases()
Definition: OpalData.cpp:402
double getGlobalPhaseShift()
units: (sec)
Definition: OpalData.cpp:452
std::vector< MaxPhasesT >::iterator getFirstMaxPhases()
Definition: OpalData.cpp:398
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:566
void setInPrepState(bool state)
Definition: OpalData.cpp:300
void setPriorTrack(const bool &value=true)
true if in follow-up track
Definition: OpalData.cpp:308
void setGlobalPhaseShift(double shift)
units: (sec)
Definition: OpalData.cpp:447
static OpalData * getInstance()
Definition: OpalData.cpp:196
void setOpenMode(OpenMode openMode)
Definition: OpalData.cpp:349
double getPhaseAtMaxEnergy(const Vector_t &R, const Vector_t &P, double t, double dt)
std::set< std::shared_ptr< Component > > value_t
Definition: IndexMap.h:47
first_type begin
Definition: IndexMap.h:43
second_type end
Definition: IndexMap.h:44
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)
DataSink * itsDataSink_m
void updateReferenceParticle(const BorisPusher &pusher)
std::set< ParticleMatterInteractionHandler * > activeParticleMatterInteractionHandlers_m
WakeFunction * wakeFunction_m
size_t numParticlesInSimulation_m
virtual void execute()
Apply the algorithm to the top-level beamline.
IpplTimings::TimerRef timeIntegrationTimer1_m
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)
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 applyFractionalStep(const BorisPusher &pusher, double tau)
void kickParticles(const BorisPusher &pusher)
void updateReference(const BorisPusher &pusher)
unsigned int emissionSteps_m
double getMinTimeStep() const
StepSizeConfig & advanceToPos(double spos)
double getdT() const
void shiftZStopLeft(double back)
double getZStop() const
void push_back(double dt, double zstop, unsigned long numSteps)
bool reachedEnd() const
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
Definition: ElementBase.h:497
unsigned int getLosses() const
static void writeStatistics()
Definition: Monitor.cpp:215
virtual bool getAutophaseVeto() const
Definition: RFCavity.h:435
virtual void setPhasem(double phase)
Definition: RFCavity.h:390
virtual void setAutophaseVeto(bool veto=true)
Definition: RFCavity.h:430
void apply(PartBunchBase< double, 3 > *itsBunch, CoordinateSystemTrafo const &refToLocalCSTrafo)
Definition: Undulator.cpp:87
bool getHasBeenSimulated() const
Definition: Undulator.cpp:347
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
Particle reference data.
Definition: PartData.h:35
double getP() const
The constant reference momentum per particle.
Definition: PartData.h:114
double gamma
Definition: PartData.h:97
double beta
Definition: PartData.h:96
Quaternion conjugate() const
Definition: Quaternion.h:105
const Beamline & itsBeamline_m
Definition: Tracker.h:122
PartBunchBase< double, 3 > * itsBunch_m
The bunch of particles to be tracked.
Definition: Tracker.h:151
An abstract sequence of beam line components.
Definition: Beamline.h:34
bool getRelativeFlag() const
Definition: TBeamline.h:453
Quaternion getInitialDirection() const
Definition: TBeamline.h:443
Vector_t getOrigin3D() const
Definition: TBeamline.h:433
virtual void iterate(BeamlineVisitor &, bool r2l) const
Apply visitor to all elements of the line.
Definition: TBeamline.h:205
virtual void initialize(const ElementBase *)
Definition: WakeFunction.h:43
virtual void apply(PartBunchBase< double, 3 > *bunch)=0
bool isOutside(const Vector_t &position) const
Definition: BoundingBox.h:62
FieldList getElementByType(ElementType)
Vector_t rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
Definition: OpalBeamline.h:178
CoordinateSystemTrafo getMisalignment(const std::shared_ptr< Component > &comp) const
Definition: OpalBeamline.h:200
void merge(OpalBeamline &rhs)
Vector_t transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
Definition: OpalBeamline.h:166
bool containsSource()
Definition: OpalBeamline.h:205
void prepareSections()
void compute3DLattice()
CoordinateSystemTrafo getCSTrafoLab2Local(const std::shared_ptr< Component > &comp) const
Definition: OpalBeamline.h:190
void switchElementsOff()
void save3DInput()
unsigned long getFieldAt(const unsigned int &, const Vector_t &, const long &, const double &, Vector_t &, Vector_t &)
void save3DLattice()
void activateElements()
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
Definition: BorisPusher.h:65
void push(Vector_t &R, const Vector_t &P, const double &dt) const
Definition: BorisPusher.h:131
void dumpSDDS(PartBunchBase< double, 3 > *beam, Vector_t FDext[], const double &azimuth=-1) const
Definition: DataSink.cpp:105
void storeCavityInformation()
Write cavity information from H5 file.
Definition: DataSink.cpp:134
void dumpH5(PartBunchBase< double, 3 > *beam, Vector_t FDext[]) const
Definition: DataSink.cpp:86
The base class for all OPAL exceptions.
Definition: OpalException.h:28
std::string time() const
Return time.
Definition: Timer.cpp:42
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)
Definition: Communicate.h:196
virtual int raw_probe_receive(char *&, int &, int &)
Definition: Communicate.h:208
void barrier(void)
int next_tag(int t, int s=1000)
Definition: TagMaker.h:39
Definition: Inform.h:42
static int getNodes()
Definition: IpplInfo.cpp:670
static int myNode()
Definition: IpplInfo.cpp:691
static Communicate * Comm
Definition: IpplInfo.h:84
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6