45 const std::string& mode,
46 const std::string& binning)
47 : onebunch_m(
OpalData::getInstance()->getInputBasename() +
"-onebunch.h5")
48 , numBunch_m(numBunch)
50 , coeffDBunches_m(para)
51 , radiusLastTurn_m(0.0)
52 , radiusThisTurn_m(0.0)
70 *
gmsg <<
"***---------------------------- MULTI-BUNCHES MULTI-ENERGY-BINS MODE "
71 <<
"----------------------------*** " <<
endl;
79 const int BinCount = 1;
81 const int MaxBinNum = 1000;
84 size_t partInBin[MaxBinNum] = {0};
95 *
gmsg <<
"In this restart job, the multi-bunches mode is forcely set to AUTO mode." <<
endl;
98 *
gmsg <<
"In this restart job, the multi-bunches mode is forcely set to FORCE mode." <<
endl
99 <<
"If the existing bunch number is less than the specified number of TURN, "
100 <<
"readin the phase space of STEP#0 from h5 file consecutively" <<
endl;
112 *
gmsg <<
"* Store beam to H5 file for multibunch simulation ... ";
123 momentum.
create(localNum);
135 std::map<std::string, double> additionalAttributes = {
136 std::make_pair(
"REFPR", 0.0),
137 std::make_pair(
"REFPT", 0.0),
138 std::make_pair(
"REFPZ", 0.0),
139 std::make_pair(
"REFR", 0.0),
140 std::make_pair(
"REFTHETA", 0.0),
141 std::make_pair(
"REFZ", 0.0),
142 std::make_pair(
"AZIMUTH", 0.0),
143 std::make_pair(
"ELEVATION", 0.0),
144 std::make_pair(
"B-ref_x", 0.0),
145 std::make_pair(
"B-ref_z", 0.0),
146 std::make_pair(
"B-ref_y", 0.0),
147 std::make_pair(
"E-ref_x", 0.0),
148 std::make_pair(
"E-ref_z", 0.0),
149 std::make_pair(
"E-ref_y", 0.0),
150 std::make_pair(
"B-head_x", 0.0),
151 std::make_pair(
"B-head_z", 0.0),
152 std::make_pair(
"B-head_y", 0.0),
153 std::make_pair(
"E-head_x", 0.0),
154 std::make_pair(
"E-head_z", 0.0),
155 std::make_pair(
"E-head_y", 0.0),
156 std::make_pair(
"B-tail_x", 0.0),
157 std::make_pair(
"B-tail_z", 0.0),
158 std::make_pair(
"B-tail_y", 0.0),
159 std::make_pair(
"E-tail_x", 0.0),
160 std::make_pair(
"E-tail_z", 0.0),
161 std::make_pair(
"E-tail_y", 0.0)
166 h5wrapper.
writeStep(beam, additionalAttributes);
180 *
gmsg <<
"* Read beam from H5 file for multibunch simulation ... ";
197 if ( numParticles == 0 ) {
204 size_t firstParticle = numParticlesPerNode *
Ippl::myNode();
205 size_t lastParticle = firstParticle + numParticlesPerNode - 1;
207 lastParticle = numParticles - 1;
211 numParticles = lastParticle - firstParticle + 1;
216 std::unique_ptr<PartBunchBase<double, 3> > tmpBunch =
nullptr;
219 if ( amrbunch_p !=
nullptr ) {
226 tmpBunch->
create(numParticles);
228 h5wrapper.
readStep(tmpBunch.get(), firstParticle, lastParticle);
231 beam->
create(numParticles);
233 for(
size_t ii = 0; ii < numParticles; ++ ii, ++ localNum) {
234 beam->
R[localNum] = tmpBunch->R[ii];
235 beam->
P[localNum] = tmpBunch->P[ii];
236 beam->
M[localNum] = tmpBunch->M[ii];
237 beam->
Q[localNum] = tmpBunch->Q[ii];
239 beam->
Bin[localNum] = bunchNum;
240 beam->
bunchNum[localNum] = bunchNum;
256 bool& flagTransition)
271 *
gmsg <<
"* MBM: Checking for automatically injecting new bunch ..." <<
endl;
283 double XYrms = std::hypot(Rrms[0], Rrms[1]);
290 flagTransition =
true;
295 *
gmsg <<
"* MBM: XYrms = " << XYrms <<
" [m]" <<
endl;
311 *
gmsg <<
"* MBM: Injecting a new bunch ..." <<
endl;
327 "We shouldn't be here in single bunch mode.");
333 <<
" injected, total particle number = "
362 if ( mbmode.compare(
"FORCE") == 0 ) {
363 *
gmsg <<
"FORCE mode: The multi bunches will be injected consecutively" <<
endl
364 <<
" after each revolution, until get \"TURNS\" bunches." <<
endl;
366 }
else if ( mbmode.compare(
"AUTO") == 0 ) {
367 *
gmsg <<
"AUTO mode: The multi bunches will be injected only when the" <<
endl
368 <<
" distance between two neighboring bunches is below" <<
endl
369 <<
" the limitation. The control parameter is set to "
378 if ( binning.compare(
"BUNCH_BINNING") == 0 ) {
379 *
gmsg <<
"Use 'BUNCH_BINNING' injection for binnning." <<
endl;
381 }
else if ( binning.compare(
"GAMMA_BINNING") == 0 ) {
382 *
gmsg <<
"Use 'GAMMA_BINNING' for binning." <<
endl;
396 *
gmsg <<
"Radial position at restart position = ";
398 *
gmsg <<
"Initial radial position = ";
412 const unsigned long localNum = beam->
getLocalNum();
414 long int bunchTotalNum = 0;
415 unsigned long bunchLocalNum = 0;
425 std::vector<double> local(7 * dim + 1);
429 for(
unsigned long k = 0; k < localNum; ++k) {
430 if ( beam->
bunchNum[k] != bunchNr ) {
440 for (
unsigned int i = 0; i < dim; ++i) {
442 double r = beam->
R[k](i);
443 double p = beam->
P[k](i);
449 local[i + dim + 1] += p;
453 local[i + 2 * dim + 1] += r2;
456 local[i + 3 * dim + 1] += p * p;
459 local[i + 4 * dim + 1] += r * p;
462 local[i + 5 * dim + 1] += r2 * r;
465 local[i + 6 * dim + 1] += r2 * r2;
470 allreduce(bunchTotalNum, 1, std::plus<long int>());
474 throw OpalException(
"MultiBunchHandler::calcBunchBeamParameters()",
475 "Bunch number " + std::to_string(bunchNr) +
476 " exceeds bunch index " + std::to_string(beam->
getNumBunch() - 1));
481 if ( bunchTotalNum == 0 )
486 local[0] -= bunchLocalNum;
489 allreduce(local.data(), local.size(), std::plus<double>());
491 double invN = 1.0 / double(bunchTotalNum);
492 binfo.
ekin = local[0] * invN;
497 for (
unsigned int i = 0; i < dim; ++i) {
499 double w = local[i + 1] * invN;
500 double pw = local[i + dim + 1] * invN;
501 double w2 = local[i + 2 * dim + 1] * invN;
502 double pw2 = local[i + 3 * dim + 1] * invN;
503 double wpw = local[i + 4 * dim + 1] * invN;
504 double w3 = local[i + 5 * dim + 1] * invN;
505 double w4 = local[i + 6 * dim + 1] * invN;
511 binfo.
prms[i] = pw2 - pw * pw;
512 if ( binfo.
prms[i] < 0 ) {
520 binfo.
rrms[i] = w2 - w * w;
523 binfo.
emit[i] = (binfo.
rrms[i] * binfo.
prms[i] - wpw * wpw);
530 - 3.0 * w * w * w * w;
531 binfo.
halo[i] = tmp / ( binfo.
rrms[i] * binfo.
rrms[i] );
540 double denom = 1.0 / (binfo.
rrms[i] * binfo.
prms[i]);
541 binfo.
correlation[i] = (std::isfinite(denom)) ? wpw * denom : 0.0;
544 double tmp = 1.0 /
std::pow(binfo.
ekin / m0 + 1.0, 2.0);
561 binfo_m[b].pathlength += lpaths[b];
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sqrt(const Tps< T > &x)
Square root.
void allreduce(const T *input, T *output, int count, Op op)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
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
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)
set the working sub-mode for multi-bunch mode: "FORCE" or "AUTO"
void updateTime(const double &dt)
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 setBinning(std::string binning)
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)