OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
TrackRun.cpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------
2 // /*$RCSfile*/: TrackRun.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1.4.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: TrackRun
10 // The class for the OPAL RUN command.
11 //
12 // ------------------------------------------------------------------------
13 //
14 // $Date: 2004/11/12 20:10:11 $
15 // $Author: adelmann $
16 //
17 // ------------------------------------------------------------------------
18 
19 #include "Track/TrackRun.h"
23 #include "Algorithms/Tracker.h"
24 #include "Algorithms/ThinTracker.h"
26 
28 
32 #include "Algorithms/NilTracker.h"
33 
34 #include "Attributes/Attributes.h"
35 #include "Beamlines/TBeamline.h"
36 
37 #include "BasicActions/Option.h"
38 
40 #include "Track/Track.h"
42 #include "Utilities/Round.h"
43 #include "Utilities/Util.h"
44 #include "Structure/Beam.h"
46 #include "Structure/FieldSolver.h"
47 #include "Structure/DataSink.h"
52 
53 #include "OPALconfig.h"
54 #include "changes.h"
55 
56 #include <boost/algorithm/string.hpp>
57 #include <boost/regex.hpp>
58 #include <boost/filesystem.hpp>
59 
60 #include <fstream>
61 #include <iomanip>
62 
63 extern Inform *gmsg;
64 
65 using namespace Physics;
66 
67 // ------------------------------------------------------------------------
68 
69 namespace {
70 
71  // The attributes of class TrackRun.
72  enum {
73  METHOD, // Tracking method to use.
74  TURNS, // The number of turns to be tracked.
75  MBMODE, // The working way for multi-bunch mode for OPAL-cycl: "FORCE" or "AUTO"
76  PARAMB, // The control parameter for "AUTO" mode of multi-bunch,
77  MB_ETA, // The scale parameter for binning in multi-bunch mode
78  MB_BINNING, // The binning type in multi-bunch mode
79  BEAM, // The beam to track
80  FIELDSOLVER, // The field solver attached
81  BOUNDARYGEOMETRY, // The boundary geometry
82  DISTRIBUTION, // The particle distribution
83  MULTIPACTING, // MULTIPACTING flag
84  TRACKBACK,
85  SIZE
86  };
87 }
88 
89 const std::string TrackRun::defaultDistribution("DISTRIBUTION");
90 
92  Action(SIZE, "RUN",
93  "The \"RUN\" sub-command tracks the defined particles through "
94  "the given lattice."),
95  itsTracker(NULL),
96  dist(NULL),
97  fs(NULL),
98  ds(NULL),
99  phaseSpaceSink_m(NULL) {
101  ("METHOD", "Name of tracking algorithm to use:\n"
102  "\t\t\t\"THIN\" (default) or \"THICK, OPAL-T,OPAL-T3D, OPAL-CYCL\".", "THIN");
104  ("TURNS", "Number of turns to be tracked; Number of neighboring bunches to be tracked in cyclotron", 1.0);
105 
107  ("MBMODE", "The working way for multi-bunch mode for OPAL-cycl: FORCE or AUTO ", "FORCE");
108 
109  itsAttr[PARAMB] = Attributes::makeReal
110  ("PARAMB", "Control parameter to define when to start multi-bunch mode, only available in \"AUTO\" mode ", 5.0);
111 
112  itsAttr[MB_ETA] = Attributes::makeReal("MB_ETA",
113  "The scale parameter for binning in multi-bunch mode",
114  0.01);
115 
116  itsAttr[MB_BINNING] = Attributes::makeString
117  ("MB_BINNING", "Type of energy binning in multi-bunch mode: GAMMA or BUNCH", "GAMMA");
118 
120  ("BEAM", "Name of beam ", "BEAM");
121  itsAttr[FIELDSOLVER] = Attributes::makeString
122  ("FIELDSOLVER", "Field solver to be used ", "FIELDSOLVER");
123  itsAttr[BOUNDARYGEOMETRY] = Attributes::makeString
124  ("BOUNDARYGEOMETRY", "Boundary geometry to be used NONE (default)", "NONE");
126  ("DISTRIBUTION", "List of particle distributions to be used ");
127  itsAttr[MULTIPACTING] = Attributes::makeBool
128  ("MULTIPACTING", "Multipacting flag, default: false. Set true to initialize primary particles according to BoundaryGeometry", false);
129  itsAttr[TRACKBACK] = Attributes::makeBool
130  ("TRACKBACK", "Track in reverse direction, default: false", false);
132 
134 }
135 
136 
137 TrackRun::TrackRun(const std::string &name, TrackRun *parent):
138  Action(name, parent),
139  itsTracker(NULL),
140  dist(NULL),
141  fs(NULL),
142  ds(NULL),
143  phaseSpaceSink_m(NULL) {
145 }
146 
147 
149 {
150  delete phaseSpaceSink_m;
151 }
152 
153 
154 TrackRun *TrackRun::clone(const std::string &name) {
155  return new TrackRun(name, this);
156 }
157 
158 
160  const int currentVersion = ((OPAL_VERSION_MAJOR * 100) + OPAL_VERSION_MINOR) * 100;
161  if (Options::version < currentVersion) {
162  unsigned int fileVersion = Options::version / 100;
163  bool newerChanges = false;
164  for (auto it = Versions::changes.begin(); it != Versions::changes.end(); ++ it) {
165  if (it->first > fileVersion) {
166  newerChanges = true;
167  break;
168  }
169  }
170  if (newerChanges) {
171  Inform errorMsg("Error");
172  errorMsg << "\n******************** V E R S I O N M I S M A T C H ***********************\n" << endl;
173  for (auto it = Versions::changes.begin(); it != Versions::changes.end(); ++ it) {
174  if (it->first > fileVersion) {
175  errorMsg << it->second << endl;
176  }
177  }
178  errorMsg << "\n"
179  << "* Make sure you do understand these changes and adjust your input file \n"
180  << "* accordingly. Then add\n"
181  << "* OPTION, VERSION = " << currentVersion << ";\n"
182  << "* to your input file. " << endl;
183  errorMsg << "\n****************************************************************************\n" << endl;
184  throw OpalException("TrackRun::execute", "Version mismatch");
185  }
186  }
187 
188  // Get algorithm to use.
189  std::string method = Util::toUpper(Attributes::getString(itsAttr[METHOD]));
190  if(method == "THIN") {
191  *gmsg << " Method == \"THIN\"" << endl;
192  itsTracker = new ThinTracker(*Track::block->use->fetchLine(),
194  false, false);
195  } else if(method == "THICK") {
197  } else if(method == "PARALLEL-SLICE" || method == "OPAL-E") {
199  } else if(method == "PARALLEL-T" || method == "OPAL-T") {
200  setupTTracker();
201  } else if(method == "CYCLOTRON-T" || method == "OPAL-CYCL") {
203  } else {
204  throw OpalException("TrackRun::execute()",
205  "Method name \"" + method + "\" unknown.");
206  }
207 
208  if(method == "THIN" || method == "THICK") {
209  int turns = int(Round(Attributes::getReal(itsAttr[TURNS])));
210 
211  // Track for the all but last turn.
212  for(int turn = 1; turn < turns; ++turn) {
213  itsTracker->execute();
214  }
215 
216  // Track the last turn.
217  itsTracker->execute();
218 
219  } else {
220  itsTracker->execute();
221 
222  opal->setRestartRun(false);
223  }
224 
226  if(method == "PARALLEL-SLICE")
228 
229  delete itsTracker;
230 }
231 
234  bool isFollowupTrack = opal->hasSLBunchAllocated();
235 
236  if(!opal->hasSLBunchAllocated()) {
237  *gmsg << "* ********************************************************************************** " << endl;
238  *gmsg << "* Selected Tracking Method == PARALLEL-SLICE, NEW TRACK" << endl;
239  *gmsg << "* ********************************************************************************** " << endl;
240  } else if(isFollowupTrack) {
241  *gmsg << "* ********************************************************************************** " << endl;
242  *gmsg << "* Selected Tracking Method == PARALLEL-SLICE, FOLLOWUP TRACK" << endl;
243  *gmsg << "* ********************************************************************************** " << endl;
244  }
245 
248 
249  if(opal->inRestartRun()) {
250  phaseSpaceSink_m = new H5PartWrapperForPS(opal->getInputBasename() + std::string(".h5"),
251  opal->getRestartStep(),
253  H5_O_WRONLY);
254  } else if (isFollowupTrack) {
255  phaseSpaceSink_m = new H5PartWrapperForPS(opal->getInputBasename() + std::string(".h5"),
256  -1,
257  opal->getInputBasename() + std::string(".h5"),
258  H5_O_WRONLY);
259  } else {
260  phaseSpaceSink_m = new H5PartWrapperForPS(opal->getInputBasename() + std::string(".h5"),
261  H5_O_WRONLY);
262  }
263 
264  std::vector<std::string> distr_str = Attributes::getStringArray(itsAttr[DISTRIBUTION]);
265  const size_t numberOfDistributions = distr_str.size();
266  if (numberOfDistributions == 0) {
268  } else {
269  dist = Distribution::find(distr_str.at(0));
270  // dist->setNumberOfDistributions(numberOfDistributions);
271 
272  // if(numberOfDistributions > 1) {
273  // *gmsg << "Found more than one distribution: ";
274  // for(size_t i = 1; i < numberOfDistributions; ++ i) {
275  // Distribution *d = Distribution::find(distr_str.at(i));
276 
277  // d->setNumberOfDistributions(numberOfDistributions);
278  // distrs_m.push_back(d);
279 
280  // *gmsg << " " << distr_str.at(i);
281  // }
282  // *gmsg << endl;
283  // }
284  }
285 
288 
289  double charge = 0.0;
290 
291  if(!opal->hasSLBunchAllocated()) {
292  if(!opal->inRestartRun()) {
293 
294  dist->createOpalE(beam, distrs_m, Track::block->slbunch, 0.0, 0.0);
296 
297  } else {
298  /***
299  reload slice distribution
300  */
301 
303  }
304  } else {
305  charge = 1.0;
306  }
307 
308  Track::block->slbunch->setdT(Track::block->dT.front());
309  // set the total charge
310  charge = beam->getCharge() * beam->getCurrent() / (beam->getFrequency() * 1e6);
311  Track::block->slbunch->setCharge(charge);
312  // set coupling constant
313  double coefE = 1.0 / (4 * pi * epsilon_0);
315  //Track::block->slbunch->calcBeamParameters();
316 
317 
318  initDataSink();
319 
320  if (Track::block->bunch->getTotalNum() > 0) {
321  double spos = Track::block->zstart;
322  auto &zstop = Track::block->zstop;
323  auto it = Track::block->dT.begin();
324 
325  unsigned int i = 0;
326  while (i + 1 < zstop.size() && zstop[i + 1] < spos) {
327  ++ i;
328  ++ it;
329  }
330 
331  Track::block->bunch->setdT(*it);
332  } else {
333  Track::block->zstart = 0.0;
334  }
335 
336  if(!opal->hasBunchAllocated())
337  *gmsg << *dist << endl;
338  *gmsg << *beam << endl;
339  *gmsg << *Track::block->slbunch << endl;
340  *gmsg << "Phase space dump frequency is set to " << Options::psDumpFreq
341  << " Inputfile is " << opal->getInputFn() << endl;
342 
343 
344  // findPhasesForMaxEnergy();
345 
346  itsTracker = new ParallelSliceTracker(*Track::block->use->fetchLine(),
347  dynamic_cast<EnvelopeBunch &>(*Track::block->slbunch),
348  *ds,
349  Track::block->reference,
350  false,
351  false,
352  Track::block->localTimeSteps,
353  Track::block->zstart,
354  Track::block->zstop,
355  Track::block->dT);
356 }
357 
358 
359 
361 {
362  bool isFollowupTrack = opal->hasBunchAllocated();
363 
364  if(isFollowupTrack) {
365  *gmsg << "* ********************************************************************************** " << endl;
366  *gmsg << "* Selected Tracking Method == THICK, FOLLOWUP TRACK" << endl;
367  *gmsg << "* ********************************************************************************** " << endl;
369  } else {
370  *gmsg << "* ********************************************************************************** " << endl;
371  *gmsg << "* Selected Tracking Method == THICK, NEW TRACK" << endl;
372  *gmsg << "* ********************************************************************************** " << endl;
373  }
374 
376  if (Attributes::getString(itsAttr[BOUNDARYGEOMETRY]) != "NONE") {
377  // Ask the dictionary if BoundaryGeometry is allocated.
378  // If it is allocated use the allocated BoundaryGeometry
379  if (!OpalData::getInstance()->hasGlobalGeometry()) {
381  clone(getOpalName() + std::string("_geometry"));
383  }
384  }
385 
387 
388  if(opal->inRestartRun()) {
389  phaseSpaceSink_m = new H5PartWrapperForPT(opal->getInputBasename() + std::string(".h5"),
390  opal->getRestartStep(),
392  H5_O_WRONLY);
393  } else if (isFollowupTrack) {
394  phaseSpaceSink_m = new H5PartWrapperForPT(opal->getInputBasename() + std::string(".h5"),
395  -1,
396  opal->getInputBasename() + std::string(".h5"),
397  H5_O_WRONLY);
398  } else {
399  phaseSpaceSink_m = new H5PartWrapperForPT(opal->getInputBasename() + std::string(".h5"),
400  H5_O_WRONLY);
401  }
402 
403  double charge = setDistributionParallelT(beam);
404 
405  Track::block->bunch->setdT(Track::block->dT.front());
408 
409  if (!isFollowupTrack && !opal->inRestartRun())
410  Track::block->bunch->setT(Track::block->t0_m);
411  if (Track::block->bunch->getIfBeamEmitting()) {
413  } else {
414  Track::block->bunch->setCharge(charge);
415  }
416  // set coupling constant
417  double coefE = 1.0 / (4 * pi * epsilon_0);
419 
420 
421  // statistical data are calculated (rms, eps etc.)
423 
424  initDataSink();
425 
426  if(!opal->hasBunchAllocated())
427  *gmsg << *dist << endl;
428 
429  if (Track::block->bunch->getTotalNum() > 0) {
430  double spos = /*Track::block->bunch->get_sPos() +*/ Track::block->zstart;
431  auto &zstop = Track::block->zstop;
432  auto &timeStep = Track::block->localTimeSteps;
433  auto &dT = Track::block->dT;
434 
435  unsigned int i = 0;
436  while (i + 1 < zstop.size() && zstop[i + 1] < spos) {
437  ++ i;
438  }
439 
440  zstop.erase(zstop.begin(), zstop.begin() + i);
441  timeStep.erase(timeStep.begin(), timeStep.begin() + i);
442  dT.erase(dT.begin(), dT.begin() + i);
443 
444  Track::block->bunch->setdT(dT.front());
445  } else {
446  Track::block->zstart = 0.0;
447  }
448 
449  *gmsg << *beam << endl;
450  *gmsg << *fs << endl;
451  *gmsg << level2
452  << "Phase space dump frequency " << Options::psDumpFreq << " and "
453  << "statistics dump frequency " << Options::statDumpFreq << " w.r.t. the time step." << endl;
454 
455  itsTracker = new ThickTracker(*Track::block->use->fetchLine(),
457  false, false, Track::block->localTimeSteps,
460 }
461 
462 
465  bool isFollowupTrack = opal->hasBunchAllocated();
466 
467  if(isFollowupTrack) {
468  *gmsg << "* ********************************************************************************** " << endl;
469  *gmsg << "* Selected Tracking Method == PARALLEL-T, FOLLOWUP TRACK" << endl;
470  *gmsg << "* ********************************************************************************** " << endl;
472  } else {
473  *gmsg << "* ********************************************************************************** " << endl;
474  *gmsg << "* Selected Tracking Method == PARALLEL-T, NEW TRACK" << endl;
475  *gmsg << "* ********************************************************************************** " << endl;
476  }
477 
480 
481  if (Attributes::getString(itsAttr[BOUNDARYGEOMETRY]) != "NONE") {
482  // Ask the dictionary if BoundaryGeometry is allocated.
483  // If it is allocated use the allocated BoundaryGeometry
486  clone(getOpalName() + std::string("_geometry"));
488  }
489  }
490 
492 
493  if(opal->inRestartRun()) {
494  phaseSpaceSink_m = new H5PartWrapperForPT(opal->getInputBasename() + std::string(".h5"),
495  opal->getRestartStep(),
497  H5_O_WRONLY);
498  } else if (isFollowupTrack) {
499  phaseSpaceSink_m = new H5PartWrapperForPT(opal->getInputBasename() + std::string(".h5"),
500  -1,
501  opal->getInputBasename() + std::string(".h5"),
502  H5_O_WRONLY);
503  } else {
504  phaseSpaceSink_m = new H5PartWrapperForPT(opal->getInputBasename() + std::string(".h5"),
505  H5_O_WRONLY);
506  }
507 
508  double charge = setDistributionParallelT(beam);
509 
510  Track::block->bunch->setdT(Track::block->dT.front());
513 
514  if (!isFollowupTrack && !opal->inRestartRun())
515  Track::block->bunch->setT(Track::block->t0_m);
516 
517  bool mpacflg = Attributes::getBool(itsAttr[MULTIPACTING]);
518  if(!mpacflg) {
519  if (Track::block->bunch->getIfBeamEmitting()) {
521  } else {
522  Track::block->bunch->setCharge(charge);
523  }
524  // set coupling constant
525  double coefE = 1.0 / (4 * pi * epsilon_0);
527 
528 
529  // statistical data are calculated (rms, eps etc.)
531  } else {
532  Track::block->bunch->setChargeZeroPart(charge);// just set bunch->qi_m=charge, don't set bunch->Q[] as we have not initialized any particle yet.
533  Track::block->bunch->calcBeamParametersInitial();// we have not initialized any particle yet.
534  }
535 
536 
537  initDataSink();
538 
539  if(!opal->hasBunchAllocated()) {
540  if(!mpacflg) {
541  *gmsg << std::scientific;
542  *gmsg << *dist << endl;
543  } else {
544  *gmsg << "* Multipacting flag is true. The particle distribution in the run command will be ignored " << endl;
545  }
546  }
547 
548  if (Track::block->bunch->getTotalNum() > 0) {
549  double spos = Track::block->zstart;
550  auto &zstop = Track::block->zstop;
551  auto it = Track::block->dT.begin();
552 
553  unsigned int i = 0;
554  while (i + 1 < zstop.size() && zstop[i + 1] < spos) {
555  ++ i;
556  ++ it;
557  }
558 
559  Track::block->bunch->setdT(*it);
560  } else {
561  Track::block->zstart = 0.0;
562  }
563 
564  *gmsg << *beam << endl;
565  *gmsg << *fs << endl;
566 
567  // findPhasesForMaxEnergy();
568 
569  *gmsg << level2
570  << "Phase space dump frequency " << Options::psDumpFreq << " and "
571  << "statistics dump frequency " << Options::statDumpFreq << " w.r.t. the time step." << endl;
572 #ifdef P3M_TEST
573 
575 
576 #else
577  itsTracker = new ParallelTTracker(*Track::block->use->fetchLine(),
579  *ds,
581  false,
582  Attributes::getBool(itsAttr[TRACKBACK]),
586  Track::block->dT);
587 #endif
588 // #endif
589  // itsTracker->setMpacflg(mpacflg); // set multipacting flag in ParallelTTracker
590 }
591 
595 
596  if (Attributes::getString(itsAttr[BOUNDARYGEOMETRY]) != "NONE") {
597  // Ask the dictionary if BoundaryGeometry is allocated.
598  // If it is allocated use the allocated BoundaryGeometry
599  if (!OpalData::getInstance()->hasGlobalGeometry()) {
601  clone(getOpalName() + std::string("_geometry"));
603  }
604  }
605 
607 
609 
610  std::vector<std::string> distr_str = Attributes::getStringArray(itsAttr[DISTRIBUTION]);
611  if (distr_str.size() == 0) {
613  } else {
614  dist = Distribution::find(distr_str.at(0));
615  }
616 
617  // set macromass and charge for simulation particles
618  double macromass = 0.0;
619  double macrocharge = 0.0;
620 
621  // multi-bunch parameters
622  const int specifiedNumBunch = int(std::abs(Round(Attributes::getReal(itsAttr[TURNS]))));
623  const double mbPara = Attributes::getReal(itsAttr[PARAMB]);
624  const std::string mbMode = Util::toUpper(Attributes::getString(itsAttr[MBMODE]));
625  const double mbEta = Attributes::getReal(itsAttr[MB_ETA]);
626  const std::string mbBinning = Attributes::getString(itsAttr[MB_BINNING]);
627 
628  if(opal->inRestartRun()) {
629  phaseSpaceSink_m = new H5PartWrapperForPC(opal->getInputBasename() + std::string(".h5"),
630  opal->getRestartStep(),
632  H5_O_WRONLY);
633  } else if (opal->hasBunchAllocated()) {
634  phaseSpaceSink_m = new H5PartWrapperForPC(opal->getInputBasename() + std::string(".h5"),
635  -1,
636  opal->getInputBasename() + std::string(".h5"),
637  H5_O_WRONLY);
638  } else {
639  phaseSpaceSink_m = new H5PartWrapperForPC(opal->getInputBasename() + std::string(".h5"),
640  H5_O_WRONLY);
641  }
642 
643  if(beam->getNumberOfParticles() < 3 || beam->getCurrent() == 0.0) {
644  macrocharge = beam->getCharge() * q_e;
645  macromass = beam->getMass();
647  beam->getNumberOfParticles(),
648  beam->getCurrent(),*Track::block->use->fetchLine());
649 
650  } else {
651 
657  macrocharge = beam->getCurrent() / (beam->getFrequency() * 1.0e6); // [MHz]-->[Hz]
658 
659  if(!opal->hasBunchAllocated()) {
660  if(!opal->inRestartRun()) {
661  macrocharge /= beam->getNumberOfParticles();
662  macromass = beam->getMass() * macrocharge / (beam->getCharge() * q_e);
664  beam->getNumberOfParticles(),
665  beam->getCurrent(),
666  *Track::block->use->fetchLine());
667 
668  } else {
670  beam->getNumberOfParticles(),
671  opal->getRestartStep(),
672  specifiedNumBunch,
674  macrocharge /= beam->getNumberOfParticles();
675  macromass = beam->getMass() * macrocharge / (beam->getCharge() * q_e);
676  }
677  }
678  }
679  Track::block->bunch->setMass(macromass); // set the Mass per macro-particle, [GeV/c^2]
680  Track::block->bunch->setCharge(macrocharge); // set the charge per macro-particle, [C]
681 
682  *gmsg << "* Mass of simulation particle= " << macromass << " GeV/c^2" << endl;
683  *gmsg << "* Charge of simulation particle= " << macrocharge << " [C]" << endl;
684 
685  Track::block->bunch->setdT(1.0 / (Track::block->stepsPerTurn * beam->getFrequency() * 1.0e6));
687 
688  // set coupling constant
689  double coefE = 1.0 / (4 * pi * epsilon_0);
691 
692  // statistical data are calculated (rms, eps etc.)
694 
695  initDataSink(specifiedNumBunch);
696 
697  if(!opal->hasBunchAllocated()) {
698  *gmsg << "* ********************************************************************************** " << endl;
699  *gmsg << "* Selected Tracking Method == CYCLOTRON-T, NEW TRACK" << endl;
700  *gmsg << "* ********************************************************************************** " << endl;
701  } else {
702  *gmsg << "* ********************************************************************************** " << endl;
703  *gmsg << "* Selected Tracking Method == CYCLOTRON-T, FOLLOWUP TRACK" << endl;
704  *gmsg << "* ********************************************************************************** " << endl;
705  }
706  *gmsg << "* Number of neighbour bunches= " << specifiedNumBunch << endl;
707  *gmsg << "* DT = " << Track::block->dT.front() << endl;
708  *gmsg << "* MAXSTEPS = " << Track::block->localTimeSteps.front() << endl;
709  *gmsg << "* Phase space dump frequency = " << Options::psDumpFreq << endl;
710  *gmsg << "* Statistics dump frequency = " << Options::statDumpFreq << " w.r.t. the time step." << endl;
711  *gmsg << "* ********************************************************************************** " << endl;
712 
713  itsTracker = new ParallelCyclotronTracker(*Track::block->use->fetchLine(),
715  false, false, Track::block->localTimeSteps.front(),
717  specifiedNumBunch, mbEta, mbPara, mbMode, mbBinning);
718 
719  ParallelCyclotronTracker* cyclTracker = dynamic_cast<ParallelCyclotronTracker*>(itsTracker);
720 
721  if(opal->inRestartRun()) {
722 
724  cyclTracker->setBeGa(h5pw->getMeanMomentum());
725 
726  cyclTracker->setPr(h5pw->getReferencePr());
727  cyclTracker->setPt(h5pw->getReferencePt());
728  cyclTracker->setPz(h5pw->getReferencePz());
729 
730  cyclTracker->setR(h5pw->getReferenceR());
731  cyclTracker->setTheta(h5pw->getReferenceT());
732  cyclTracker->setZ(h5pw->getReferenceZ());
733 
734  // The following is for restarts in local frame
735  cyclTracker->setPhi(h5pw->getAzimuth());
736  cyclTracker->setPsi(h5pw->getElevation());
737  cyclTracker->setPreviousH5Local(h5pw->getPreviousH5Local());
738 
739  if ( specifiedNumBunch > 1 ) {
740  cyclTracker->setLastDumpedStep(opal->getRestartStep());
741  }
742  }
743 
744  // statistical data are calculated (rms, eps etc.)
746 
747  *gmsg << *dist << endl;
748  *gmsg << *beam << endl;
749  *gmsg << *fs << endl;
750  // *gmsg << *Track::block->bunch << endl;
751 }
752 
755 
756  if (Util::toUpper(fs->getType()) != std::string("NONE")) {
757  size_t numGridPoints = fs->getMX()*fs->getMY()*fs->getMT(); // total number of gridpoints
759  size_t numParticles = beam->getNumberOfParticles();
760 
761  if (!opal->inRestartRun() && numParticles < numGridPoints
762  && Util::toUpper(fs->getType()) != std::string("SAAMG") // in SPIRAL/SAAMG we're meshing the whole domain -DW
763 #ifdef ENABLE_AMR
764  && !Options::amr)
765 #else
766  )
767 #endif
768  {
769  throw OpalException("TrackRun::setupFieldsolver()",
770  "The number of simulation particles (" + std::to_string(numParticles) + ") \n" +
771  "is smaller than the number of gridpoints (" + std::to_string(numGridPoints) + ").\n" +
772  "Please increase the number of particles or reduce the size of the mesh.\n");
773  }
774 
778 
779  }
780 
783  if (fs->hasPeriodicZ())
784  Track::block->bunch->setBCForDCBeam();
785  else
787 }
788 
789 
790 void TrackRun::initDataSink(const int& numBunch) {
791  if(!opal->inRestartRun()) {
792  if(!opal->hasDataSinkAllocated()) {
793  opal->setDataSink(new DataSink(phaseSpaceSink_m, false, numBunch));
794  } else {
795  ds = opal->getDataSink();
797  }
798  } else {
799  opal->setDataSink(new DataSink(phaseSpaceSink_m, true, numBunch));
800  }
801 
802  ds = opal->getDataSink();
803 }
804 
805 
807 
808  // If multipacting flag is not set, get distribution(s).
809  if (!Attributes::getBool(itsAttr[MULTIPACTING])) {
810  /*
811  * Distribution(s) can be set via a single distribution or a list
812  * (array) of distributions. If an array is defined the first in the
813  * list is treated as the primary distribution. All others are added to
814  * it to create the full distribution.
815  */
816  std::vector<std::string> distributionArray
818  const size_t numberOfDistributions = distributionArray.size();
819 
820  if (numberOfDistributions == 0) {
822  } else {
823  dist = Distribution::find(distributionArray.at(0));
824  dist->setNumberOfDistributions(numberOfDistributions);
825 
826  if (numberOfDistributions > 1) {
827  *gmsg << endl
828  << "---------------------------------" << endl
829  << "Found more than one distribution:" << endl << endl;
830  *gmsg << "Main Distribution" << endl
831  << "---------------------------------" << endl
832  << distributionArray.at(0) << endl << endl
833  << "Secondary Distribution(s)" << endl
834  << "---------------------------------" << endl;
835 
836  for (size_t i = 1; i < numberOfDistributions; ++ i) {
837  Distribution *distribution = Distribution::find(distributionArray.at(i));
838  distribution->setNumberOfDistributions(numberOfDistributions);
839  distrs_m.push_back(distribution);
840 
841  *gmsg << distributionArray.at(i) << endl;
842  }
843  *gmsg << endl
844  << "---------------------------------" << endl << endl;
845  }
846  }
847  }
848 
849  /*
850  * Initialize distributions.
851  */
852  size_t numberOfParticles = beam->getNumberOfParticles();
853  if (!opal->hasBunchAllocated()) {
854  if (!opal->inRestartRun()) {
855  if (!Attributes::getBool(itsAttr[MULTIPACTING])) {
856  /*
857  * Here we are not doing a restart or doing a mulitpactor run
858  * and we do not have a bunch already allocated.
859  */
861  distrs_m,
862  numberOfParticles);
863 
864  /*
865  * If this is an injected beam (rather than an emitted beam), we
866  * make sure it doesn't have any particles at z < 0.
867  */
868 
870  }
871  } else {
872  /*
873  * Read in beam from restart file.
874  */
875  dist->doRestartOpalT(Track::block->bunch, numberOfParticles, opal->getRestartStep(), phaseSpaceSink_m);
876  }
877  }
878 
879  // Return charge per macroparticle.
880  return beam->getCharge() * beam->getCurrent() / (beam->getFrequency()*1.0e6) / numberOfParticles;
881 
882 }
std::vector< double > zstop
The location at which the simulation stops.
Definition: Track.h:88
void doRestartOpalCycl(PartBunchBase< double, 3 > *p, size_t Np, int restartStep, const int specifiedNumBunch, H5PartWrapper *h5wrapper)
double Round(double value)
Round the double argument.
Definition: Round.cpp:23
std::string getRestartFileName()
get opals restart h5 format filename
Definition: OpalData.cpp:354
double zstart
The location at which the simulation starts.
Definition: Track.h:85
double getAzimuth() const
static FieldSolver * find(const std::string &name)
Find named FieldSolver.
double setDistributionParallelT(Beam *beam)
Definition: TrackRun.cpp:806
The RUN command.
Definition: TrackRun.h:38
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
void doRestartOpalE(EnvelopeBunch *p, size_t Np, int restartStep, H5PartWrapper *h5wrapper)
double getReferenceR() const
void setupSliceTracker()
Definition: TrackRun.cpp:232
void setInOPALCyclMode()
Definition: OpalData.cpp:304
std::vector< Distribution * > distrs_m
Definition: TrackRun.h:77
double getMT() const
Return meshsize.
core of the envelope tracker based on Rene Bakkers BET implementation
Definition: EnvelopeBunch.h:60
void bunchIsAllocated()
Definition: OpalData.cpp:413
double getMass() const
Return Particle&#39;s rest mass in GeV.
Definition: Beam.cpp:197
void setRestartRun(const bool &value=true)
set OPAL in restart mode
Definition: OpalData.cpp:340
void setInOPALEnvMode()
Definition: OpalData.cpp:312
The base class for all OPAL actions.
Definition: Action.h:30
void createOpalCycl(PartBunchBase< double, 3 > *beam, size_t numberOfParticles, double current, const Beamline &bl)
int timeIntegrator
The ID of time integrator.
Definition: Track.h:95
std::vector< double > dT
The initial timestep.
Definition: Track.h:69
void setCharge(double _Q)
set the charge of the bunch
The base class for all OPAL exceptions.
Definition: OpalException.h:28
bool inRestartRun()
true if we do a restart run
Definition: OpalData.cpp:336
void setDistribution(Distribution *d, std::vector< Distribution * > addedDistributions, size_t &np)
void changeH5Wrapper(H5PartWrapper *h5wrapper)
Definition: DataSink.cpp:138
double getCurrent() const
Return the beam current in A.
Definition: Beam.cpp:189
double getReferencePz() const
bool hasSLBunchAllocated()
true if we already allocated a ParticleBunch object
Definition: OpalData.cpp:393
bool hasDataSinkAllocated()
true if we already allocated a DataSink object
Definition: OpalData.cpp:426
Inform * gmsg
Definition: Main.cpp:21
std::string toUpper(const std::string &str)
Definition: Util.cpp:130
int getRestartStep()
get the step where to restart
Definition: OpalData.cpp:349
double getEmissionTimeShift() const
static Distribution * find(const std::string &name)
void setupTTracker()
Definition: TrackRun.cpp:463
double getReferencePr() const
void setLocalTrackStep(long long n)
step in a TRACK command
TrackRun()
Exemplar constructor.
Definition: TrackRun.cpp:91
bool getPreviousH5Local() const
FRONT * fs
Definition: hypervolume.cpp:59
double t0_m
Definition: Track.h:76
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
void setdT(double dt)
#define OPAL_VERSION_MINOR
Definition: OPALconfig.h:7
double getMY() const
Return meshsize.
Distribution * dist
Definition: TrackRun.h:75
void setupFieldsolver()
Definition: TrackRun.cpp:753
OpalData * opal
Definition: TrackRun.h:85
void setDataSink(DataSink *s)
Definition: OpalData.cpp:430
int statDumpFreq
The frequency to dump statistical values, e.e. dump data when stepstatDumpFreq==0.
Definition: Options.cpp:54
virtual void setBCAllOpen()
std::vector< unsigned long long > localTimeSteps
Maximal number of timesteps.
Definition: Track.h:79
double getReferencePt() const
bool hasGlobalGeometry()
Definition: OpalData.cpp:510
bool getBool(const Attribute &attr)
Return logical value.
Definition: Attributes.cpp:66
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
size_t getNumberOfParticles()
Return the number of (macro)particles.
Definition: Beam.cpp:160
Attribute makeStringArray(const std::string &name, const std::string &help)
Create a string array attribute.
Definition: Attributes.cpp:373
static OpalData * getInstance()
Definition: OpalData.cpp:209
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:284
double getCharge() const
Return the charge number in elementary charge.
Definition: Beam.cpp:193
void setCouplingConstant(double c)
void calcBeamParameters()
EnvelopeBunch * slbunch
Definition: Track.h:51
double getReferenceT() const
virtual TrackRun * clone(const std::string &name)
Make clone.
Definition: TrackRun.cpp:154
int version
opal version of input file
Definition: Options.cpp:97
ParticleAttrib< short > PType
void setGlobalGeometry(BoundaryGeometry *bg)
Definition: OpalData.cpp:502
bool hasBunchAllocated()
true if we already allocated a ParticleBunch object
Definition: OpalData.cpp:409
std::vector< std::string > getStringArray(const Attribute &attr)
Get string array value.
Definition: Attributes.cpp:378
void initDataSink(const int &numBunch=1)
Definition: TrackRun.cpp:790
const double pi
Definition: fftpack.cpp:894
void addProblemCharacteristicValue(const std::string &name, unsigned int value)
Definition: OpalData.cpp:818
static Beam * find(const std::string &name)
Find named BEAM.
Definition: Beam.cpp:150
double getFrequency() const
Return the beam frequency in MHz.
Definition: Beam.cpp:205
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:194
static BoundaryGeometry * find(const std::string &name)
virtual Beamline * fetchLine() const =0
Return the embedded CLASSIC beam line.
void setStepsPerTurn(int n)
DataSink * ds
Definition: TrackRun.h:81
static Track * block
The block of track data.
Definition: Track.h:63
H5PartWrapper * phaseSpaceSink_m
Definition: TrackRun.h:83
std::string getInputFn()
get opals input filename
Definition: OpalData.cpp:713
std::map< unsigned int, std::string > changes
Definition: changes.cpp:7
void setMass(double mass)
int truncOrder
Trunction order for map tracking.
Definition: Track.h:98
void setupThickTracker()
Definition: TrackRun.cpp:360
PartBunchBase< double, 3 > * bunch
The particle bunch to be tracked.
Definition: Track.h:49
virtual void execute()
Apply the algorithm to the top-level beamline.
int psDumpFreq
The frequency to dump the phase space, i.e.dump data when steppsDumpFreq==0.
Definition: Options.cpp:48
bool amr
Definition: Options.cpp:100
BeamSequence * use
The lattice to be tracked through.
Definition: Track.h:57
#define OPAL_VERSION_MAJOR
Definition: OPALconfig.h:6
virtual ~TrackRun()
Definition: TrackRun.cpp:148
Track using thick-lens algorithm.
Definition: ThickTracker.h:104
void setCharge(double q)
double getMeanMomentum() const
static const std::string defaultDistribution
Definition: TrackRun.h:87
void setGlobalPhaseShift(double shift)
units: (sec)
Definition: OpalData.cpp:492
The BEAM definition.
Definition: Beam.h:35
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
Definition: Attributes.cpp:56
constexpr double q_e
The elementary charge in As.
Definition: Physics.h:76
double deltaTau
Definition: Track.h:72
const std::string name
void doRestartOpalT(PartBunchBase< double, 3 > *p, size_t Np, int restartStep, H5PartWrapper *h5wrapper)
void createOpalE(Beam *beam, std::vector< Distribution * > addedDistributions, EnvelopeBunch *envelopeBunch, double distCenter, double Bz0)
DataSink * getDataSink()
Definition: OpalData.cpp:435
void initCartesianFields()
double dtScInit
Definition: Track.h:72
double getReferenceZ() const
constexpr double epsilon_0
The permittivity of vacuum in As/Vm.
Definition: Physics.h:58
Tracker * itsTracker
Definition: TrackRun.h:73
std::string getType()
virtual void setSolver(FieldSolver *fs)
double getMX() const
Return meshsize.
void setBeamFrequency(double v)
void setupCyclotronTracker()
Definition: TrackRun.cpp:592
void setInOPALTMode()
Definition: OpalData.cpp:308
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:217
bool hasPeriodicZ()
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:717
double getElevation() const
void calcBeamParametersInitial()
Definition: Inform.h:41
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:296
void setNumberOfDistributions(unsigned int n)
Definition: Distribution.h:342
double getTEmission()
virtual void execute()
Execute the command.
Definition: TrackRun.cpp:159
PartData reference
The reference data.
Definition: Track.h:54
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:205
virtual void runTests()
void setChargeZeroPart(double q)
void slbunchIsAllocated()
Definition: OpalData.cpp:397
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
FieldSolver * fs
Definition: TrackRun.h:79
Track with thin lens algorithm.
Definition: ThinTracker.h:47
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:307