49 const std::string& mode,
50 const std::string& binning)
74 *
gmsg <<
"***-------------------- MULTI-BUNCHES MULTI-ENERGY-BINS MODE --------------------*** " <<
endl;
82 const int BinCount = 1;
84 const int MaxBinNum = 1000;
87 size_t partInBin[MaxBinNum] = {0};
98 *
gmsg <<
"In this restart job, the multi-bunches mode is forcely set to AUTO mode." <<
endl;
101 *
gmsg <<
"In this restart job, the multi-bunches mode is forcely set to FORCE mode." <<
endl
102 <<
"If the existing bunch number is less than the specified number of TURN, "
103 <<
"readin the phase space of STEP#0 from h5 file consecutively" <<
endl;
115 *
gmsg <<
"* Store beam to H5 file for multibunch simulation ... ";
126 momentum.
create(localNum);
138 std::map<std::string, double> additionalAttributes = {
139 std::make_pair(
"REFPR", 0.0),
140 std::make_pair(
"REFPT", 0.0),
141 std::make_pair(
"REFPZ", 0.0),
142 std::make_pair(
"REFR", 0.0),
143 std::make_pair(
"REFTHETA", 0.0),
144 std::make_pair(
"REFZ", 0.0),
145 std::make_pair(
"AZIMUTH", 0.0),
146 std::make_pair(
"ELEVATION", 0.0),
147 std::make_pair(
"B-ref_x", 0.0),
148 std::make_pair(
"B-ref_z", 0.0),
149 std::make_pair(
"B-ref_y", 0.0),
150 std::make_pair(
"E-ref_x", 0.0),
151 std::make_pair(
"E-ref_z", 0.0),
152 std::make_pair(
"E-ref_y", 0.0),
153 std::make_pair(
"B-head_x", 0.0),
154 std::make_pair(
"B-head_z", 0.0),
155 std::make_pair(
"B-head_y", 0.0),
156 std::make_pair(
"E-head_x", 0.0),
157 std::make_pair(
"E-head_z", 0.0),
158 std::make_pair(
"E-head_y", 0.0),
159 std::make_pair(
"B-tail_x", 0.0),
160 std::make_pair(
"B-tail_z", 0.0),
161 std::make_pair(
"B-tail_y", 0.0),
162 std::make_pair(
"E-tail_x", 0.0),
163 std::make_pair(
"E-tail_z", 0.0),
164 std::make_pair(
"E-tail_y", 0.0)
169 h5wrapper.
writeStep(beam, additionalAttributes);
182 *
gmsg <<
"* Read beam from H5 file for multibunch simulation ... ";
199 if ( numParticles == 0 ) {
206 size_t firstParticle = numParticlesPerNode *
Ippl::myNode();
207 size_t lastParticle = firstParticle + numParticlesPerNode - 1;
209 lastParticle = numParticles - 1;
213 numParticles = lastParticle - firstParticle + 1;
218 std::unique_ptr<PartBunchBase<double, 3> > tmpBunch =
nullptr;
221 if ( amrbunch_p !=
nullptr ) {
228 tmpBunch->create(numParticles);
230 h5wrapper.
readStep(tmpBunch.get(), firstParticle, lastParticle);
233 beam->
create(numParticles);
235 for(
size_t ii = 0; ii < numParticles; ++ ii, ++ localNum) {
236 beam->
R[localNum] = tmpBunch->R[ii];
237 beam->
P[localNum] = tmpBunch->P[ii];
238 beam->
M[localNum] = tmpBunch->M[ii];
239 beam->
Q[localNum] = tmpBunch->Q[ii];
241 beam->
Bin[localNum] = bunchNum;
242 beam->
bunchNum[localNum] = bunchNum;
258 bool& flagTransition) {
272 *
gmsg <<
"* MBM: Checking for automatically injecting new bunch ..." <<
endl;
282 double XYrms = std::hypot(Rrms[0], Rrms[1]);
289 flagTransition =
true;
294 *
gmsg <<
"* MBM: XYrms = " << XYrms <<
" [m]" <<
endl;
309 *
gmsg <<
"* MBM: Injecting a new bunch ..." <<
endl;
325 "We shouldn't be here in single bunch mode.");
331 <<
" injected, total particle number = "
361 static const std::map<std::string, MultiBunchMode> stringMBMode_s = {
365 mode_m = stringMBMode_s.at(mbmode);
369 *
gmsg <<
"FORCE mode: The multi bunches will be injected consecutively" <<
endl
370 <<
" after each revolution, until get \"TURNS\" bunches." <<
endl;
373 *
gmsg <<
"AUTO mode: The multi bunches will be injected only when the" <<
endl
374 <<
" distance between two neighboring bunches is below" <<
endl
375 <<
" the limitation. The control parameter is set to "
380 "Unknown \"MBMODE\" multi-bunch mode for OPAL-cycl");
387 static const std::map<std::string, MultiBunchBinning> stringMBBinning_s = {
391 binning_m = stringMBBinning_s.at(binning);
395 *
gmsg <<
"\nUse 'BUNCH_BINNING' injection for binnning.\n" <<
endl;
398 *
gmsg <<
"\nUse 'GAMMA_BINNING' injection for binnning.\n" <<
endl;
402 "Unknown \"MB_BINNING\" type of energy binning in multi-bunch mode");
415 *
gmsg <<
"Radial position at restart position = ";
417 *
gmsg <<
"Initial radial position = ";
430 const unsigned long localNum = beam->
getLocalNum();
432 long int bunchTotalNum = 0;
433 unsigned long bunchLocalNum = 0;
443 std::vector<double> local(7 * dim + 1);
447 for(
unsigned long k = 0; k < localNum; ++k) {
448 if ( beam->
bunchNum[k] != bunchNr ) {
456 local[0] += std::sqrt(
dot(beam->
P[k], beam->
P[k]) + 1.0);
458 for (
unsigned int i = 0; i < dim; ++i) {
460 double r = beam->
R[k](i);
461 double p = beam->
P[k](i);
467 local[i + dim + 1] += p;
471 local[i + 2 * dim + 1] += r2;
474 local[i + 3 * dim + 1] += p * p;
477 local[i + 4 * dim + 1] += r * p;
480 local[i + 5 * dim + 1] += r2 * r;
483 local[i + 6 * dim + 1] += r2 * r2;
488 allreduce(bunchTotalNum, 1, std::plus<long int>());
492 throw OpalException(
"MultiBunchHandler::calcBunchBeamParameters()",
493 "Bunch number " + std::to_string(bunchNr) +
494 " exceeds bunch index " + std::to_string(beam->
getNumBunch() - 1));
499 if (bunchTotalNum == 0) {
505 local[0] -= bunchLocalNum;
508 allreduce(local.data(), local.size(), std::plus<double>());
510 double invN = 1.0 / double(bunchTotalNum);
511 binfo.
ekin = local[0] * invN;
516 for (
unsigned int i = 0; i < dim; ++i) {
518 double w = local[i + 1] * invN;
519 double pw = local[i + dim + 1] * invN;
520 double w2 = local[i + 2 * dim + 1] * invN;
521 double pw2 = local[i + 3 * dim + 1] * invN;
522 double wpw = local[i + 4 * dim + 1] * invN;
523 double w3 = local[i + 5 * dim + 1] * invN;
524 double w4 = local[i + 6 * dim + 1] * invN;
530 binfo.
prms[i] = pw2 - pw * pw;
531 if ( binfo.
prms[i] < 0 ) {
539 binfo.
rrms[i] = w2 - w * w;
542 binfo.
emit[i] = (binfo.
rrms[i] * binfo.
prms[i] - wpw * wpw);
543 binfo.
emit[i] = std::sqrt(std::max(binfo.
emit[i], 0.0));
549 - 3.0 * w * w * w * w;
550 binfo.
halo[i] = tmp / ( binfo.
rrms[i] * binfo.
rrms[i] );
553 binfo.
rrms[i] = std::sqrt(binfo.
rrms[i]);
556 binfo.
prms[i] = std::sqrt(binfo.
prms[i]);
559 double denom = 1.0 / (binfo.
rrms[i] * binfo.
prms[i]);
560 binfo.
correlation[i] = (std::isfinite(denom)) ? wpw * denom : 0.0;
563 double tmp = 1.0 / std::pow(binfo.
ekin / m0 + 1.0, 2.0);
564 binfo.
dEkin = binfo.
prms[1] * m0 * std::sqrt(1.0 - tmp);
580 binfo_m[b].pathlength += lpaths[b];
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
ParticleSpatialLayout< double, 3 >::ParticlePos_t Ppos_t
void allreduce(const T *input, T *output, int count, Op op)
Inform & endl(Inform &inf)
ParticleAttrib< int > Bin
bool resetPartBinID2(const double eta)
reset Bin[] for each particle according to the method given in paper PAST-AB(064402) by G....
void setNumBunch(short n)
size_t getLocalNum() const
ParticleAttrib< double > M
size_t getTotalNum() const
ParticleAttrib< Vector_t > P
void setLocalNumPerBunch(size_t numpart, short n)
ParticleAttrib< ParticleOrigin > POrigin
Vector_t get_rrms() const
ParticleAttrib< double > Q
void calcBeamParameters()
short getNumBunch() const
static const unsigned Dimension
Vector_t get_centroid() const
ParticleAttrib< short > bunchNum
void setTotalNumPerBunch(size_t numpart, short n)
void setPBins(PartBins *pbin)
The global OPAL structure.
static OpalData * getInstance()
void saveBunch(PartBunchBase< double, 3 > *beam)
bool calcBunchBeamParameters(PartBunchBase< double, 3 > *beam, short bunchNr)
MultiBunchHandler(PartBunchBase< double, 3 > *beam, const int &numBunch, const double &eta, const double ¶, const std::string &mode, const std::string &binning)
MultiBunchBinning binning_m
beaminfo_t & getBunchInfo(short bunchNr)
void setMode(const std::string &mbmode)
void updateTime(const double &dt)
void setBinning(const std::string &binning)
void setRadiusTurns(const double &radius)
short numBunch_m
The number of bunches specified in TURNS of RUN command.
bool readBunch(PartBunchBase< double, 3 > *beam, const PartData &ref)
void updatePathLength(const std::vector< double > &lpaths)
short injectBunch(PartBunchBase< double, 3 > *beam, const PartData &ref, bool &flagTransition)
std::vector< beaminfo_t > binfo_m
void updateParticleBins(PartBunchBase< double, 3 > *beam)
long unsigned int nParticles
pbase_t * getAmrParticleBase()
size_t getNumParticles() const
virtual void writeStep(PartBunchBase< double, 3 > *, const std::map< std::string, double > &additionalStepAttributes)
virtual void writeHeader()
virtual void readStep(PartBunchBase< double, 3 > *, h5_ssize_t firstParticle, h5_ssize_t lastParticle)
The base class for all OPAL exceptions.
virtual void create(size_t)
static Communicate * Comm
Timing::TimerRef TimerRef
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t