45 #include <gsl/gsl_cdf.h>
46 #include <gsl/gsl_randist.h>
47 #include <gsl/gsl_sf_erf.h>
48 #include <gsl/gsl_linalg.h>
49 #include <gsl/gsl_blas.h>
53 #include <boost/regex.hpp>
54 #include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
63 for (
unsigned int i = 0; i < 6u; ++ i) {
76 "The DISTRIBUTION statement defines data for the 6D particle distribution."),
78 numberOfDistributions_m(1),
83 currentEmissionTime_m(0.0),
84 currentEnergyBin_m(1),
85 currentSampleBin_m(0),
86 numberOfEnergyBins_m(0),
87 numberOfSampleBins_m(0),
89 energyBinHist_m(NULL),
93 cathodeWorkFunc_m(0.0),
95 cathodeFermiEnergy_m(0.0),
97 emitEnergyUpperLimit_m(0.0),
98 totalNumberParticles_m(0),
99 totalNumberEmittedParticles_m(0),
104 tPulseLengthFWHM_m(0.0),
105 correlationMatrix_m(getUnit6x6()),
106 laserProfileFileName_m(
""),
107 laserImageName_m(
""),
108 laserIntensityCut_m(0.0),
109 laserProfile_m(NULL),
110 darkCurrentParts_m(0),
111 darkInwardMargin_m(0.0),
112 eInitThreshold_m(0.0),
114 fieldEnhancement_m(0.0),
131 defaultDistribution->
builtin =
true;
136 delete defaultDistribution;
142 randGen_m = gsl_rng_alloc(gsl_rng_default);
152 distT_m(parent->distT_m),
154 numberOfDistributions_m(parent->numberOfDistributions_m),
155 emitting_m(parent->emitting_m),
156 particleRefData_m(parent->particleRefData_m),
157 addedDistributions_m(parent->addedDistributions_m),
158 particlesPerDist_m(parent->particlesPerDist_m),
159 emissionModel_m(parent->emissionModel_m),
160 tEmission_m(parent->tEmission_m),
161 tBin_m(parent->tBin_m),
162 currentEmissionTime_m(parent->currentEmissionTime_m),
163 currentEnergyBin_m(parent->currentEmissionTime_m),
164 currentSampleBin_m(parent->currentSampleBin_m),
165 numberOfEnergyBins_m(parent->numberOfEnergyBins_m),
166 numberOfSampleBins_m(parent->numberOfSampleBins_m),
168 energyBinHist_m(NULL),
170 pTotThermal_m(parent->pTotThermal_m),
171 pmean_m(parent->pmean_m),
172 cathodeWorkFunc_m(parent->cathodeWorkFunc_m),
173 laserEnergy_m(parent->laserEnergy_m),
174 cathodeFermiEnergy_m(parent->cathodeFermiEnergy_m),
175 cathodeTemp_m(parent->cathodeTemp_m),
176 emitEnergyUpperLimit_m(parent->emitEnergyUpperLimit_m),
177 totalNumberParticles_m(parent->totalNumberParticles_m),
178 totalNumberEmittedParticles_m(parent->totalNumberEmittedParticles_m),
179 xDist_m(parent->xDist_m),
180 pxDist_m(parent->pxDist_m),
181 yDist_m(parent->yDist_m),
182 pyDist_m(parent->pyDist_m),
183 tOrZDist_m(parent->tOrZDist_m),
184 pzDist_m(parent->pzDist_m),
185 xWrite_m(parent->xWrite_m),
186 pxWrite_m(parent->pxWrite_m),
187 yWrite_m(parent->yWrite_m),
188 pyWrite_m(parent->pyWrite_m),
189 tOrZWrite_m(parent->tOrZWrite_m),
190 pzWrite_m(parent->pzWrite_m),
191 avrgpz_m(parent->avrgpz_m),
192 inputMoUnits_m(parent->inputMoUnits_m),
193 sigmaTRise_m(parent->sigmaTRise_m),
194 sigmaTFall_m(parent->sigmaTFall_m),
195 tPulseLengthFWHM_m(parent->tPulseLengthFWHM_m),
196 sigmaR_m(parent->sigmaR_m),
197 sigmaP_m(parent->sigmaP_m),
198 cutoffR_m(parent->cutoffR_m),
199 cutoffP_m(parent->cutoffP_m),
200 correlationMatrix_m(parent->correlationMatrix_m),
201 laserProfileFileName_m(parent->laserProfileFileName_m),
202 laserImageName_m(parent->laserImageName_m),
203 laserIntensityCut_m(parent->laserIntensityCut_m),
204 laserProfile_m(NULL),
205 darkCurrentParts_m(parent->darkCurrentParts_m),
206 darkInwardMargin_m(parent->darkInwardMargin_m),
207 eInitThreshold_m(parent->eInitThreshold_m),
208 workFunction_m(parent->workFunction_m),
209 fieldEnhancement_m(parent->fieldEnhancement_m),
210 fieldThrFN_m(parent->fieldThrFN_m),
211 maxFN_m(parent->maxFN_m),
212 paraFNA_m(parent-> paraFNA_m),
213 paraFNB_m(parent-> paraFNB_m),
214 paraFNY_m(parent-> paraFNY_m),
215 paraFNVYSe_m(parent-> paraFNVYSe_m),
216 paraFNVYZe_m(parent-> paraFNVYZe_m),
217 secondaryFlag_m(parent->secondaryFlag_m),
218 ppVw_m(parent->ppVw_m),
219 vVThermal_m(parent->vVThermal_m),
222 tRise_m(parent->tRise_m),
223 tFall_m(parent->tFall_m),
224 sigmaRise_m(parent->sigmaRise_m),
225 sigmaFall_m(parent->sigmaFall_m),
226 cutoff_m(parent->cutoff_m)
229 randGen_m = gsl_rng_alloc(gsl_rng_default);
266 if (myNode < remainder)
295 size_t numberOfLocalParticles = numberOfParticles;
297 numberOfLocalParticles = (numberOfParticles + 1) / 2;
305 mySeed = tv.tv_sec + tv.tv_usec;
310 *gmsg <<
level2 <<
"* Generation of distribution with seed = " << mySeed <<
" + core_id\n"
311 <<
"* is scalable with number of particles and cores." <<
endl;
314 *gmsg <<
level2 <<
"* Generation of distribution with seed = " << mySeed <<
"\n"
315 <<
"* isn't scalable with number of particles and cores." <<
endl;
348 unsigned int numAdditionalRNsPerParticle = 0;
353 numAdditionalRNsPerParticle = 2;
356 numAdditionalRNsPerParticle = 40;
358 numAdditionalRNsPerParticle = 20;
362 int saveProcessor = -1;
367 for (
size_t partIndex = 0; partIndex < numberOfLocalParticles; ++ partIndex) {
371 if (saveProcessor >= numNodes)
374 if (scalable || myNode == saveProcessor) {
375 std::vector<double> rns;
376 for (
unsigned int i = 0; i < numAdditionalRNsPerParticle; ++ i) {
382 for (
unsigned int i = 0; i < numAdditionalRNsPerParticle; ++ i) {
412 double vw = this->
getVw();
414 double f_max = vw / vt *
exp(-0.5);
415 double test_a = vt / vw;
416 double test_asq = test_a * test_a;
422 if (bg.
getN() != 0) {
423 for (
size_t i = 0; i < bg.
getN(); i++) {
425 if (count < N_mean) {
430 while(test_s > f_x) {
434 test_x *= 10 * test_a;
435 f_x = test_x / test_asq *
exp(-test_x * test_x / 2 / test_asq);
437 double v_emi = test_x * vw;
440 double betagamma = betaemit /
sqrt(1 - betaemit * betaemit);
448 beam->
P[lowMark + count] = betagamma * bg.
getMomenta(count);
450 beam->
Bin[lowMark + count] = 0;
452 beam->
TriID[lowMark + count] = 0;
456 beam->
dt[lowMark + count] = beam->
getdT();
468 *gmsg << *beam <<
endl;
480 if (bg.
getN() != 0) {
481 for (
size_t i = 0; i < bg.
getN(); i++) {
484 if (count < N_mean) {
490 beam->
P[lowMark + count] =
Vector_t(0.0);
491 beam->
Bin[lowMark + count] = 0;
493 beam->
TriID[lowMark + count] = 0;
497 beam->
dt[lowMark + count] = beam->
getdT();
513 *gmsg << *beam <<
endl;
523 size_t firstParticle = numParticlesPerNode *
Ippl::myNode();
524 size_t lastParticle = firstParticle + numParticlesPerNode - 1;
526 lastParticle = numParticles - 1;
529 numParticles = lastParticle - firstParticle + 1;
532 beam->
create(numParticles);
535 dataSource->
readStep(beam, firstParticle, lastParticle);
539 double actualT = beam->
getT();
545 *gmsg <<
"Total number of particles in the h5 file= " << beam->
getTotalNum() <<
"\n"
546 <<
"Global step= " << gtstep <<
"; Local step= " << ltstep <<
"; "
547 <<
"restart step= " << restartStep <<
"\n"
554 const int specifiedNumBunch,
559 INFOMSG(
"---------------- Start reading hdf5 file----------------" <<
endl);
564 size_t firstParticle = numParticlesPerNode *
Ippl::myNode();
565 size_t lastParticle = firstParticle + numParticlesPerNode - 1;
567 lastParticle = numParticles - 1;
570 numParticles = lastParticle - firstParticle + 1;
573 beam->
create(numParticles);
576 dataSource->
readStep(beam, firstParticle, lastParticle);
586 INFOMSG(
"total number of particles = " << globalN <<
endl);
587 INFOMSG(
"* Restart Energy = " << meanE <<
" (MeV), Path lenght = " << beam->
get_sPos() <<
" (m)" <<
endl);
591 double gamma = 1 + meanE / beam->
getM() * 1.0e6;
594 INFOMSG(
"* Gamma = " << gamma <<
", Beta = " << beta <<
endl);
597 INFOMSG(
"Restart from hdf5 file generated by OPAL-cycl" <<
endl);
598 if (specifiedNumBunch > 1) {
605 INFOMSG(
"Restart from hdf5 file generated by OPAL-t" <<
endl);
610 for (
unsigned int i = 0; i < newLocalN; ++i) {
611 for (
int d = 0; d < 3; ++d) {
612 meanR(d) += beam->
R[i](d);
613 meanP(d) += beam->
P[i](d);
620 INFOMSG(
"Rmean = " << meanR <<
"[m], Pmean=" << meanP <<
endl);
622 for (
unsigned int i = 0; i < newLocalN; ++i) {
628 INFOMSG(
"---------------Finished reading hdf5 file---------------" <<
endl);
636 *gmsg <<
"total number of slices = " << N <<
endl;
644 dataSource->
readStep(beam, starti, endi);
654 throw OpalException(
"Distribution::find()",
"Distribution \"" + name +
"\" not found.");
671 double tratio =
sqrt(2.0 *
log(10.0)) -
sqrt(2.0 *
log(10.0 / 9.0));
679 double inv_erf08 = 0.906193802436823;
680 double sqr2 =
sqrt(2.);
681 double t = a - sqr2 * sig * inv_erf08;
684 for (
int i = 0; i < 10; ++ i) {
685 sig = (t +
tRise_m - a) / (sqr2 * inv_erf08);
686 t = a - 0.5 * sqr2 * (sig + tmps) * inv_erf08;
687 sig = (0.5 * (t + tmpt) +
tRise_m - a) / (sqr2 * inv_erf08);
707 <<
"* ************* D I S T R I B U T I O N ********************************************" <<
endl;
710 os <<
"* In restart. Distribution read in from .h5 file." <<
endl;
713 os <<
"* Main Distribution" << endl
714 <<
"-----------------" << endl;
721 size_t distCount = 1;
724 os <<
"* Added Distribution #" << distCount <<
endl;
725 os <<
"* ----------------------" <<
endl;
739 os <<
"* Distribution is emitted. " <<
endl;
746 os <<
"* Distribution is injected." <<
endl;
750 os <<
"* **********************************************************************************" <<
endl;
773 for (
double dist : (*addedDistIt)->getXDist()) {
776 (*addedDistIt)->eraseXDist();
778 for (
double dist : (*addedDistIt)->getBGxDist()) {
781 (*addedDistIt)->eraseBGxDist();
783 for (
double dist : (*addedDistIt)->getYDist()) {
786 (*addedDistIt)->eraseYDist();
788 for (
double dist : (*addedDistIt)->getBGyDist()) {
791 (*addedDistIt)->eraseBGyDist();
793 for (
double dist : (*addedDistIt)->getTOrZDist()) {
796 (*addedDistIt)->eraseTOrZDist();
798 for (
double dist : (*addedDistIt)->getBGzDist()) {
801 (*addedDistIt)->eraseBGzDist();
825 double phi = 2.0 *
acos(
sqrt(additionalRNs[0]));
826 double theta = 2.0 *
Physics::pi * additionalRNs[1];
842 std::vector<double> &additionalRNs) {
850 unsigned int counter = 0;
853 double randFuncValue = additionalRNs[counter++];
855 double funcValue = ((1.0
856 - 1.0 / (1.0 + expRelativeEnergy * expRelativeLaserEnergy)) /
857 (1.0 + expRelativeEnergy));
859 if (randFuncValue <= funcValue)
862 if (counter == additionalRNs.size()) {
863 for (
unsigned int i = 0; i < counter; ++ i) {
864 additionalRNs[i] = gsl_rng_uniform(
randGen_m);
871 while (additionalRNs.size() - counter < 2) {
873 additionalRNs[counter] = gsl_rng_uniform(
randGen_m);
878 double energyExternal = energy - lowEnergyLimit;
880 double thetaInMax =
acos(
sqrt((lowEnergyLimit + laserEnergy_m) / (energyInternal)));
881 double thetaIn = additionalRNs[counter++] * thetaInMax;
882 double sinThetaOut =
sin(thetaIn) *
sqrt(energyInternal / energyExternal);
886 double betaGammaExternal
889 bgx = betaGammaExternal * sinThetaOut *
cos(phi);
890 bgy = betaGammaExternal * sinThetaOut *
sin(phi);
891 bgz = betaGammaExternal *
sqrt(1.0 -
pow(sinThetaOut, 2.0));
902 std::map<unsigned int, size_t> nPartFromFiles;
903 double totalWeight = 0.0;
910 std::ifstream inputFile;
913 inputFile.open(fileName.c_str());
916 nPartFromFiles.insert(std::make_pair(i, nPart));
917 if (nPart > numberOfParticles) {
919 "Number of particles is too small");
922 numberOfParticles -= nPart;
928 size_t numberOfCommittedPart = 0;
937 size_t particlesCurrentDist = numberOfParticles * currDist->
getWeight() / totalWeight;
939 numberOfCommittedPart += particlesCurrentDist;
944 if (numberOfParticles != numberOfCommittedPart) {
945 size_t diffNumber = numberOfParticles - numberOfCommittedPart;
957 if (diffNumber != 0) {
959 "Particles can't be distributed to distributions in array");
975 if (emissionSteps == 0)
1006 size_t numberOfDistParticles =
tOrZDist_m.size();
1009 if (numberOfDistParticles != numberOfParticles) {
1010 *gmsg <<
"\n--------------------------------------------------" <<
endl
1011 <<
"Warning!! The number of particles in the initial" <<
endl
1012 <<
"distribution is " << numberOfDistParticles <<
"." <<
endl <<
endl
1013 <<
"This is different from the number of particles" <<
endl
1014 <<
"defined by the BEAM command: " << numberOfParticles <<
endl <<
endl
1015 <<
"This is often happens when using a FROMFILE type" <<
endl
1016 <<
"distribution and not matching the number of" <<
endl
1017 <<
"particles in the particles file(s) with the number" <<
endl
1018 <<
"given in the BEAM command." <<
endl <<
endl
1019 <<
"The number of particles in the initial distribution" <<
endl
1020 <<
"(" << numberOfDistParticles <<
") "
1021 <<
"will take precedence." <<
endl
1022 <<
"---------------------------------------------------\n" <<
endl;
1024 numberOfParticles = numberOfDistParticles;
1033 if (inputUnits ==
"NONE")
1035 else if (inputUnits ==
"EV")
1044 if (
std::abs(value) < std::numeric_limits<double>::epsilon())
1071 size_t numberOfParticlesRead = 0;
1073 const boost::regex commentExpr(
"[[:space:]]*#.*");
1074 const std::string repl(
"");
1076 std::stringstream linestream;
1080 std::getline(inputFile, line);
1081 line = boost::regex_replace(line, commentExpr, repl);
1082 }
while (line.length() == 0 && !inputFile.fail());
1084 linestream.str(line);
1085 linestream >> tempInt;
1087 throw OpalException(
"Distribution::getNumberOfParticlesInFile",
1090 "' does not seem to be an ASCII file containing a distribution.");
1092 numberOfParticlesRead =
static_cast<size_t>(tempInt);
1096 return numberOfParticlesRead;
1102 <<
"------------------------------------------------------------------------------------\n";
1103 *gmsg <<
"READ INITIAL DISTRIBUTION FROM FILE \""
1106 *gmsg <<
"------------------------------------------------------------------------------------\n" <<
endl;
1109 std::ifstream inputFile;
1112 inputFile.open(fileName.c_str());
1113 if (inputFile.fail())
1114 throw OpalException(
"Distribution::createDistributionFromFile",
1115 "Open file operation failed, please check if \""
1117 +
"\" really exists.");
1125 unsigned int saveProcessor = 0;
1129 size_t numPartsToSend = 0;
1130 unsigned int distributeFrequency = 1000;
1131 size_t singleDataSize = ( 6 *
sizeof(double));
1132 unsigned int dataSize = distributeFrequency * singleDataSize;
1133 std::vector<char> data;
1135 data.reserve(dataSize);
1139 char lineBuffer[1024];
1140 unsigned int numParts = 0;
1141 while (!inputFile.eof()) {
1142 inputFile.getline(lineBuffer, 1024);
1146 std::istringstream line(lineBuffer);
1148 if (line.rdstate())
break;
1166 if (saveProcessor > 0u) {
1167 buffer =
reinterpret_cast<const char*
>(&R[0]);
1168 data.insert(data.end(), buffer, buffer + 3 *
sizeof(double));
1169 buffer =
reinterpret_cast<const char*
>(&P[0]);
1170 data.insert(data.end(), buffer, buffer + 3 *
sizeof(double));
1173 if (numPartsToSend % distributeFrequency == 0) {
1175 MPI_Bcast(&data[0], dataSize, MPI_CHAR, 0,
Ippl::getComm());
1178 std::vector<char>().swap(data);
1179 data.reserve(dataSize);
1196 if (numberOfParticlesRead != numParts) {
1197 throw OpalException(
"Distribution::createDistributionFromFile",
1199 std::to_string(numParts) +
1200 " particles in file '" +
1203 std::to_string(numberOfParticlesRead));
1205 MPI_Bcast(&data[0], dataSize, MPI_CHAR, 0,
Ippl::getComm());
1211 throw OpalException(
"Distribution::createDistributionFromFile",
1213 std::to_string(numberOfParticlesRead) +
1214 " particles in file '" +
1217 MPI_Bcast(&data[0], dataSize, MPI_CHAR, 0,
Ippl::getComm());
1220 while (i < dataSize) {
1223 const double *tmp =
reinterpret_cast<const double*
>(&data[i]);
1230 i += 6 *
sizeof(double);
1232 i += singleDataSize;
1240 }
while (dataSize == distributeFrequency * singleDataSize);
1243 pmean_m /= numberOfParticlesRead;
1259 if (LineName ==
"")
return;
1263 if (LineSequence == NULL)
1264 throw OpalException(
"Distribution::CreateMatchedGaussDistribution",
1265 "didn't find any Cyclotron element in line");
1269 size_t NumberOfCyclotrons = CyclotronVisitor.size();
1271 if (NumberOfCyclotrons > 1) {
1272 throw OpalException(
"Distribution::createMatchedGaussDistribution",
1273 "I am confused, found more than one Cyclotron element in line");
1275 if (NumberOfCyclotrons == 0) {
1276 throw OpalException(
"Distribution::createMatchedGaussDistribution",
1277 "didn't find any Cyclotron element in line");
1290 throw OpalException(
"Distribution::CreateMatchedGaussDistribution()",
1291 "Negative number of integration steps");
1294 throw OpalException(
"Distribution::CreateMatchedGaussDistribution()",
1295 "Negative number of sectors");
1297 if ( Nsectors > 1 && full ==
false )
1298 throw OpalException(
"Distribution::CreateMatchedGaussDistribution()",
1299 "Averaging over sectors can only be done with SECTOR=FALSE");
1301 *gmsg <<
"* ----------------------------------------------------" <<
endl;
1302 *gmsg <<
"* About to find closed orbit and matched distribution " <<
endl;
1303 *gmsg <<
"* I= " <<
I_m*1E3 <<
" (mA) E= " <<
E_m*1E-6 <<
" (MeV)" <<
endl;
1308 *gmsg <<
"* SECTOR: " <<
"match using all sectors, with" << endl
1309 <<
"* NSECTORS = " << Nsectors <<
" to average the field over" <<
endl;
1312 *gmsg <<
"* SECTOR: " <<
"match using single sector" <<
endl;
1314 *gmsg <<
"* NSTEPS = " << Nint << endl
1316 <<
" PHIINIT= " << CyclotronElement->
getPHIinit() << endl
1317 <<
"* ----------------------------------------------------" <<
endl;
1319 if ( CyclotronElement->
getFMLowE() < 0 ||
1322 throw OpalException(
"Distribution::CreateMatchedGaussDistribution()",
1323 "Missing attributes 'FMLOWE' and/or 'FMHIGHE' in "
1324 "'CYCLOTRON' definition.");
1327 std::size_t maxitCOF =
1333 double denergy = 1000.0 *
1336 if ( denergy < 0.0 )
1337 throw OpalException(
"Distribution:CreateMatchedGaussDistribution()",
1344 *gmsg <<
"* Stopping after closed orbit and tune calculation" <<
endl;
1345 typedef std::vector<double> container_t;
1346 typedef boost::numeric::odeint::runge_kutta4<container_t> rk4_t;
1349 cof_t cof(massIneV*1E-6, Nint, CyclotronElement,
false, Nsectors);
1350 cof.findOrbit(accuracy, maxitCOF,
E_m*1E-6, denergy, rguess,
true);
1353 "Do only tune calculation.");
1356 bool writeMap =
true;
1359 sGenerator_t *siggen =
new sGenerator_t(
I_m,
1371 if (siggen->match(accuracy,
1379 std::array<double,3> Emit = siggen->getEmittances();
1382 *gmsg <<
"* RGUESS " << rguess <<
" (m) " <<
endl;
1384 *gmsg <<
"* Converged (Ex, Ey, Ez) = (" << Emit[0] <<
", " << Emit[1] <<
", "
1385 << Emit[2] <<
") pi mm mrad for E= " <<
E_m*1E-6 <<
" (MeV)" <<
endl;
1386 *gmsg <<
"* Sigma-Matrix " <<
endl;
1388 for (
unsigned int i = 0; i < siggen->getSigma().size1(); ++ i) {
1389 *gmsg << std::setprecision(4) << std::setw(11) << siggen->getSigma()(i,0);
1390 for (
unsigned int j = 1; j < siggen->getSigma().size2(); ++ j) {
1391 if (siggen->getSigma()(i,j) < 10
e-12){
1392 *gmsg <<
" & " << std::setprecision(4) << std::setw(11) << 0.0;
1395 *gmsg <<
" & " << std::setprecision(4) << std::setw(11) << siggen->getSigma()(i,j);
1399 *gmsg <<
" \\\\" <<
endl;
1411 double gamma =
E_m / massIneV + 1.0;
1412 double beta =
std::sqrt(1.0 - 1.0 / (gamma * gamma));
1414 auto sigma = siggen->getSigma();
1416 for (
unsigned int i = 0; i < 6; ++ i)
1417 for (
unsigned int j = 0; j < 6; ++ j) sigma(i, j) *= 1
e-6;
1419 for (
unsigned int i = 0; i < 3; ++ i) {
1420 if ( sigma(2 * i, 2 * i) < 0 || sigma(2 * i + 1, 2 * i + 1) < 0 )
1421 throw OpalException(
"Distribution::CreateMatchedGaussDistribution()",
1422 "Negative value on the diagonal of the sigma matrix.");
1433 double pl2 = (
std::sqrt(sigma(5,5)) + 1)*(
std::sqrt(sigma(5,5)) + 1)*beta*gamma*beta*gamma -
1437 sigmaP_m[1] = gamma*(pl - beta*gamma);
1450 CyclotronElement->
setRinit(siggen->getInjectionRadius() * 1.0e3);
1451 CyclotronElement->
setPRinit(siggen->getInjectionMomentum());
1454 *gmsg <<
"* Not converged for " <<
E_m*1E-6 <<
" MeV" <<
endl;
1458 throw OpalException(
"Distribution::CreateMatchedGaussDistribution",
1459 "didn't find any matched distribution.");
1486 if (bg.
getN() != 0) {
1488 for (
size_t i = 0; i < bg.
getN(); i++) {
1490 if (count < N_mean) {
1496 beam->
P[lowMark + count] =
Vector_t(0.0);
1497 beam->
Bin[lowMark + count] = 0;
1499 beam->
TriID[lowMark + count] = 0;
1503 beam->
dt[lowMark + count] = beam->
getdT();
1514 *gmsg << &beam <<
endl;
1518 size_t numberOfParticles,
1519 double current,
const Beamline &bl) {
1533 size_t numberOfPartToCreate = numberOfParticles;
1586 std::vector<Distribution *> addedDistributions,
1593 double beamEnergy = beam->
getMass() * (beam->
getGamma() - 1.0) * 1.0e9;
1621 *gmsg <<
"Only FLATTOP, GAUSS and GUNGAUSSFLATTOPTH distribution types supported " <<
endl
1622 <<
"in envelope mode. Assuming FLATTOP." <<
endl;
1631 double beamCenter = -1.0 * beamWidth / 2.0;
1652 std::vector<Distribution *> addedDistributions,
1653 size_t &numberOfParticles) {
1660 size_t &numberOfParticles) {
1683 addedDist->setDistType();
1709 size_t distCount = 1;
1763 std::vector<std::vector<double> > mirrored;
1771 std::vector<double> tmp;
1772 tmp.push_back((*it).front());
1773 tmp.push_back((*it).back() + 0.5);
1774 mirrored.push_back(tmp);
1779 std::vector<double> tmp((*it).begin() + numAdditionals, (*it).end());
1780 mirrored.push_back(tmp);
1781 (*it).erase((*it).begin() + numAdditionals, (*it).end());
1826 size_t numberOfEmittedParticles = beam->
getLocalNum();
1827 size_t oldNumberOfEmittedParticles = numberOfEmittedParticles;
1836 std::vector<size_t> particlesToBeErased;
1842 for (
size_t particleIndex = 0; particleIndex <
tOrZDist_m.size(); particleIndex++) {
1850 particlesToBeErased.push_back(particleIndex);
1853 double deltaT =
tOrZDist_m.at(particleIndex);
1854 beam->
dt[numberOfEmittedParticles] = deltaT;
1856 double oneOverCDt = 1.0 / (
Physics::c * deltaT);
1858 double px =
pxDist_m.at(particleIndex);
1859 double py =
pyDist_m.at(particleIndex);
1860 double pz =
pzDist_m.at(particleIndex);
1861 std::vector<double> additionalRNs;
1866 "not enough additional particles");
1870 double particleGamma
1876 beam->
R[numberOfEmittedParticles]
1878 + px * deltaT *
Physics::c / (2.0 * particleGamma)),
1879 oneOverCDt * (
yDist_m.at(particleIndex)
1880 + py * deltaT *
Physics::c / (2.0 * particleGamma)),
1881 pz / (2.0 * particleGamma));
1882 beam->
P[numberOfEmittedParticles]
1886 beam->
Ef[numberOfEmittedParticles] =
Vector_t(0.0);
1887 beam->
Bf[numberOfEmittedParticles] =
Vector_t(0.0);
1889 beam->
TriID[numberOfEmittedParticles] = 0;
1890 numberOfEmittedParticles++;
1906 std::vector<size_t>::reverse_iterator ptbErasedIt;
1907 for (ptbErasedIt = particlesToBeErased.rbegin();
1908 ptbErasedIt < particlesToBeErased.rend();
1948 <<
" has emitted all particles (new emit)." <<
endl);
1976 size_t currentEmittedParticles = numberOfEmittedParticles - oldNumberOfEmittedParticles;
1980 return currentEmittedParticles;
2014 const size_t numberOfParticles =
tOrZDist_m.size();
2015 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2029 for (
size_t particleIndex = 0; particleIndex <
tOrZDist_m.size(); particleIndex++) {
2031 std::vector<double> partCoord;
2033 partCoord.push_back(
xDist_m.at(particleIndex));
2034 partCoord.push_back(
yDist_m.at(particleIndex));
2035 partCoord.push_back(
tOrZDist_m.at(particleIndex));
2036 partCoord.push_back(
pxDist_m.at(particleIndex));
2037 partCoord.push_back(
pyDist_m.at(particleIndex));
2038 partCoord.push_back(
pzDist_m.at(particleIndex));
2039 partCoord.push_back(0.0);
2069 gsl_qrng *quasiRandGen = gsl_qrng_alloc(gsl_qrng_halton, 2);
2071 int numberOfSampleBins
2073 int numberOfEnergyBins
2076 int binTotal = numberOfSampleBins * numberOfEnergyBins;
2078 double *distributionTable =
new double[binTotal + 1];
2082 double inv_erf08 = 0.906193802436823;
2083 double sqr2 =
sqrt(2.0);
2084 double t = a - sqr2 * sig * inv_erf08;
2088 for (
int i = 0; i < 10; ++ i) {
2089 sig = (t +
tRise_m - a) / (sqr2 * inv_erf08);
2090 t = a - 0.5 * sqr2 * (sig + tmps) * inv_erf08;
2091 sig = (0.5 * (t + tmpt) +
tRise_m - a) / (sqr2 * inv_erf08);
2103 double lo = -
tBin_m / 2.0 * numberOfEnergyBins;
2104 double hi =
tBin_m / 2.0 * numberOfEnergyBins;
2105 double dx =
tBin_m / numberOfSampleBins;
2108 double weight = 2.0;
2111 for (
int i = 0; i < binTotal + 1; ++ i, x += dx, weight = 6. - weight) {
2112 distributionTable[i] = gsl_sf_erf((x + a) / (
sqrt(2) * sig)) - gsl_sf_erf((x - a) / (
sqrt(2) * sig));
2113 tot += distributionTable[i] * weight;
2115 tot -= distributionTable[binTotal] * (5. - weight);
2116 tot -= distributionTable[0];
2118 int saveProcessor = -1;
2122 double tCoord = 0.0;
2124 int effectiveNumParticles = 0;
2126 std::vector<int> numParticlesInBin(numberOfEnergyBins,0);
2127 for (
int k = 0; k < numberOfEnergyBins; ++ k) {
2128 double loc_fraction = -distributionTable[numberOfSampleBins * k] / tot;
2131 for (
int i = numberOfSampleBins * k; i < numberOfSampleBins * (k + 1) + 1;
2132 ++ i, weight = 6. - weight) {
2133 loc_fraction += distributionTable[i] * weight / tot;
2135 loc_fraction -= distributionTable[numberOfSampleBins * (k + 1)]
2136 * (5. - weight) / tot;
2137 numParticlesInBin[k] =
static_cast<int>(
std::floor(loc_fraction * numberOfParticles + 0.5));
2138 effectiveNumParticles += numParticlesInBin[k];
2139 if (numParticlesInBin[k] > numParticlesInBin[largestBin]) largestBin = k;
2142 numParticlesInBin[largestBin] += (numberOfParticles - effectiveNumParticles);
2144 for (
int k = 0; k < numberOfEnergyBins; ++ k) {
2145 gsl_ran_discrete_t *table
2146 = gsl_ran_discrete_preproc(numberOfSampleBins,
2147 &(distributionTable[numberOfSampleBins * k]));
2149 for (
int i = 0; i < numParticlesInBin[k]; i++) {
2151 gsl_qrng_get(quasiRandGen, xx);
2152 tCoord = hi * (xx[1] +
static_cast<int>(gsl_ran_discrete(
randGen_m, table))
2153 - binTotal / 2 + k * numberOfSampleBins) / (binTotal / 2);
2156 if (saveProcessor >= numNodes)
2159 if (scalable || myNode == saveProcessor) {
2164 gsl_ran_discrete_free(table);
2167 gsl_qrng_free(quasiRandGen);
2168 delete [] distributionTable;
2196 for (
unsigned int index = 0; index < 3; index++) {
2200 if (
std::abs(emittance(index)) > std::numeric_limits<double>::epsilon()) {
2201 beta(index) =
pow(
sigmaR_m[index], 2.0) / emittance(index);
2202 gamma(index) =
pow(
sigmaP_m[index], 2.0) / emittance(index);
2208 *
sqrt(beta(index) * gamma(index));
2215 for (
unsigned int index = 0; index < 3; index++) {
2218 COSCHI[index] =
sqrt(1.0 / (1.0 +
pow(
alpha(index), 2.0)));
2219 SINCHI[index] = -
alpha(index) * COSCHI[index];
2220 CHI[index] =
atan2(SINCHI[index], COSCHI[index]);
2222 M[index] =
sqrt(emittance(index) * beta(index));
2223 PM[index] =
sqrt(emittance(index) * gamma(index));
2228 X[index] = L[index];
2229 PX[index] = PL[index];
2232 X[index] = M[index];
2233 PX[index] = PM[index];
2238 int saveProcessor = -1;
2259 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2263 double Ux = 0.0, U = 0.0;
2264 double Vx = 0.0, V = 0.0;
2266 A = splitter[0]->get(gsl_rng_uniform(
randGen_m));
2271 p[0] = PX[0] * (Ux * SINCHI[0] + Vx * COSCHI[0]);
2273 A = splitter[1]->get(gsl_rng_uniform(
randGen_m));
2278 p[1] = PX[1] * (U * SINCHI[1] + V * COSCHI[1]);
2280 A = splitter[2]->get(gsl_rng_uniform(
randGen_m));
2289 if (saveProcessor >= numNodes)
2292 if (scalable || myNode == saveProcessor) {
2302 for (
unsigned int index = 0; index < 3; index++) {
2303 delete splitter[index];
2309 int saveProcessor = -1;
2314 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2325 if (saveProcessor >= numNodes)
2328 if (scalable || myNode == saveProcessor) {
2331 yDist_m.push_back(y * sigmaR_m[1]);
2347 int saveProcessor = -1;
2351 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2361 if (quasiRandGen2D != NULL) {
2363 gsl_qrng_get(quasiRandGen2D, randNums);
2364 x = -1.0 + 2.0 * randNums[0];
2365 y = -1.0 + 2.0 * randNums[1];
2367 x = -1.0 + 2.0 * gsl_rng_uniform(
randGen_m);
2368 y = -1.0 + 2.0 * gsl_rng_uniform(
randGen_m);
2371 allow = (
pow(x, 2.0) +
pow(y, 2.0) <= 1.0);
2379 if (saveProcessor >= numNodes)
2382 if (scalable || myNode == saveProcessor) {
2391 gsl_qrng_free(quasiRandGen2D);
2405 int saveProcessor = -1;
2410 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2422 if (quasiRandGen2D != NULL) {
2424 gsl_qrng_get(quasiRandGen2D, randNums);
2425 x = -1.0 + 2.0 * randNums[0];
2426 y = -1.0 + 2.0 * randNums[1];
2428 x = -1.0 + 2.0 * gsl_rng_uniform(
randGen_m);
2429 y = -1.0 + 2.0 * gsl_rng_uniform(
randGen_m);
2432 allow = (
pow(x, 2.0) +
pow(y, 2.0) <= 1.0);
2438 if (quasiRandGen1D != NULL)
2439 gsl_qrng_get(quasiRandGen1D, &z);
2447 if (saveProcessor >= numNodes)
2450 if (scalable || myNode == saveProcessor) {
2460 gsl_qrng_free(quasiRandGen1D);
2461 gsl_qrng_free(quasiRandGen2D);
2466 gsl_matrix * corMat = gsl_matrix_alloc (6, 6);
2467 gsl_vector * rx = gsl_vector_alloc(6);
2468 gsl_vector * ry = gsl_vector_alloc(6);
2470 for (
unsigned int i = 0; i < 6; ++ i) {
2472 for (
unsigned int j = 0; j < i; ++ j) {
2480 *gmsg <<
"* m before gsl_linalg_cholesky_decomp" <<
endl;
2481 for (
int i = 0; i < 6; i++) {
2482 for (
int j = 0; j < 6; j++) {
2484 *gmsg <<
"* r(" << std::setprecision(1) << i <<
", : ) = "
2485 << std::setprecision(4) << std::setw(10) << gsl_matrix_get (corMat, i, j);
2487 *gmsg <<
" & " << std::setprecision(4) << std::setw(10) << gsl_matrix_get (corMat, i, j);
2489 *gmsg <<
" \\\\" <<
endl;
2496 int errcode = gsl_linalg_cholesky_decomp(corMat);
2525 if (errcode == GSL_EDOM) {
2527 "gsl_linalg_cholesky_decomp failed");
2530 for (
int i = 0; i < 5; ++ i) {
2531 for (
int j = i+1; j < 6 ; ++ j) {
2532 gsl_matrix_set (corMat, i, j, 0.0);
2537 *gmsg <<
"* m after gsl_linalg_cholesky_decomp" <<
endl;
2538 for (
int i = 0; i < 6; i++) {
2539 for (
int j = 0; j < 6; j++) {
2541 *gmsg <<
"* r(" << std::setprecision(1) << i <<
", : ) = "
2542 << std::setprecision(4) << std::setw(10) << gsl_matrix_get (corMat, i, j);
2544 *gmsg <<
" & " << std::setprecision(4) << std::setw(10) << gsl_matrix_get (corMat, i, j);
2546 *gmsg <<
" \\\\" <<
endl;
2550 int saveProcessor = -1;
2555 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2566 gsl_vector_set(rx, 0, gsl_ran_gaussian(
randGen_m, 1.0));
2567 gsl_vector_set(rx, 1, gsl_ran_gaussian(
randGen_m, 1.0));
2568 gsl_vector_set(rx, 2, gsl_ran_gaussian(
randGen_m, 1.0));
2569 gsl_vector_set(rx, 3, gsl_ran_gaussian(
randGen_m, 1.0));
2570 gsl_vector_set(rx, 4, gsl_ran_gaussian(
randGen_m, 1.0));
2571 gsl_vector_set(rx, 5, gsl_ran_gaussian(
randGen_m, 1.0));
2573 gsl_blas_dgemv(CblasNoTrans, 1.0, corMat, rx, 0.0, ry);
2575 x = gsl_vector_get(ry, 0);
2576 px = gsl_vector_get(ry, 1);
2577 y = gsl_vector_get(ry, 2);
2578 py = gsl_vector_get(ry, 3);
2579 z = gsl_vector_get(ry, 4);
2580 pz = gsl_vector_get(ry, 5);
2582 bool xAndYOk =
false;
2592 bool pxAndPyOk =
false;
2614 if (saveProcessor >= numNodes)
2617 if (scalable || myNode == saveProcessor) {
2627 gsl_vector_free(rx);
2628 gsl_vector_free(ry);
2629 gsl_matrix_free(corMat);
2637 if (flattopTime < 0.0)
2641 double distArea = flattopTime
2645 size_t numRise = numberOfParticles *
sigmaTRise_m * normalizedFlankArea / distArea;
2646 size_t numFall = numberOfParticles *
sigmaTFall_m * normalizedFlankArea / distArea;
2647 size_t numFlat = numberOfParticles - numRise - numFall;
2650 int saveProcessor = -1;
2655 for (
size_t partIndex = 0; partIndex < numFall; partIndex++) {
2671 if (saveProcessor >= numNodes)
2674 if (scalable || myNode == saveProcessor) {
2685 if (modulationAmp > 1.0)
2686 modulationAmp = 1.0;
2687 double numModulationPeriods
2689 double modulationPeriod = 0.0;
2690 if (numModulationPeriods != 0.0)
2691 modulationPeriod = flattopTime / numModulationPeriods;
2696 for (
size_t partIndex = 0; partIndex < numFlat; partIndex++) {
2701 if (modulationAmp == 0.0 || numModulationPeriods == 0.0) {
2703 if (quasiRandGen1D != NULL)
2704 gsl_qrng_get(quasiRandGen1D, &t);
2708 t = flattopTime * t;
2712 double funcAmp = 0.0;
2715 if (quasiRandGen2D != NULL) {
2716 double randNums[2] = {0.0, 0.0};
2717 gsl_qrng_get(quasiRandGen2D, randNums);
2718 t = randNums[0] * flattopTime;
2719 funcAmp = randNums[1];
2721 t = gsl_rng_uniform(
randGen_m)*flattopTime;
2725 double funcValue = (1.0 + modulationAmp
2729 allow = (funcAmp <= funcValue);
2738 if (saveProcessor >= numNodes)
2741 if (scalable || myNode == saveProcessor) {
2748 for (
size_t partIndex = 0; partIndex < numRise; partIndex++) {
2764 if (saveProcessor >= numNodes)
2767 if (scalable || myNode == saveProcessor) {
2773 gsl_qrng_free(quasiRandGen1D);
2774 gsl_qrng_free(quasiRandGen2D);
2780 gsl_matrix * corMat = gsl_matrix_alloc (4, 4);
2781 gsl_vector * rx = gsl_vector_alloc(4);
2782 gsl_vector * ry = gsl_vector_alloc(4);
2784 for (
unsigned int i = 0; i < 4; ++ i) {
2786 for (
unsigned int j = 0; j < i; ++ j) {
2792 int errcode = gsl_linalg_cholesky_decomp(corMat);
2794 if (errcode == GSL_EDOM) {
2795 throw OpalException(
"Distribution::GenerateTransverseGauss",
2796 "gsl_linalg_cholesky_decomp failed");
2799 for (
int i = 0; i < 3; ++ i) {
2800 for (
int j = i+1; j < 4 ; ++ j) {
2801 gsl_matrix_set (corMat, i, j, 0.0);
2805 int saveProcessor = -1;
2810 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2820 gsl_vector_set(rx, 0, gsl_ran_gaussian (
randGen_m,1.0));
2821 gsl_vector_set(rx, 1, gsl_ran_gaussian (
randGen_m,1.0));
2822 gsl_vector_set(rx, 2, gsl_ran_gaussian (
randGen_m,1.0));
2823 gsl_vector_set(rx, 3, gsl_ran_gaussian (
randGen_m,1.0));
2825 gsl_blas_dgemv(CblasNoTrans, 1.0, corMat, rx, 0.0, ry);
2826 x = gsl_vector_get(ry, 0);
2827 px = gsl_vector_get(ry, 1);
2828 y = gsl_vector_get(ry, 2);
2829 py = gsl_vector_get(ry, 3);
2831 bool xAndYOk =
false;
2841 bool pxAndPyOk =
false;
2851 allow = (xAndYOk && pxAndPyOk);
2861 if (saveProcessor >= numNodes)
2864 if (scalable || myNode == saveProcessor) {
2872 gsl_matrix_free(corMat);
2873 gsl_vector_free(rx);
2874 gsl_vector_free(ry);
2896 bool hasID1 = (id1.size() != 0);
2897 bool hasID2 = (id2.size() != 0);
2899 if (hasID1 || hasID2)
2900 *gmsg <<
"* Use special ID1 or ID2 particle in distribution" <<
endl;
2903 size_t numberOfParticles =
tOrZDist_m.size();
2904 beam->
create(numberOfParticles);
2905 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
2919 beam->
TriID[partIndex] = 0;
2923 beam->
Bin[partIndex] = binNumber;
2926 beam->
Bin[partIndex] = 0;
2929 if (beam->
ID[partIndex] == 1) {
2930 beam->
R[partIndex] =
Vector_t(id1[0],id1[1],id1[2]);
2931 beam->
P[partIndex] =
Vector_t(id1[3],id1[4],id1[5]);
2936 if (beam->
ID[partIndex] == 2) {
2937 beam->
R[partIndex] =
Vector_t(id2[0],id2[1],id2[2]);
2938 beam->
P[partIndex] =
Vector_t(id2[3],id2[4],id2[5]);
2965 double maxTOrZ = *longIt;
2966 for (++longIt; longIt !=
tOrZDist_m.end(); ++longIt) {
2967 if (maxTOrZ < *longIt)
2979 double minTOrZ = *longIt;
2980 for (++longIt; longIt !=
tOrZDist_m.end(); ++longIt) {
2981 if (minTOrZ > *longIt)
3036 if (numberOfParticles > 0) {
3039 os <<
"* Number of particles: "
3079 os <<
"* Distribution type: BINOMIAL" <<
endl;
3084 os <<
"* SIGMAT = " <<
sigmaR_m[2] <<
" [sec]" <<
endl;
3087 os <<
"* SIGMAPX = " <<
sigmaP_m[0] <<
" [Beta Gamma]" <<
endl;
3088 os <<
"* SIGMAPY = " <<
sigmaP_m[1] <<
" [Beta Gamma]" <<
endl;
3089 os <<
"* SIGMAPZ = " <<
sigmaP_m[2] <<
" [Beta Gamma]" <<
endl;
3110 os <<
"* Distribution type: ASTRAFLATTOPTH" <<
endl;
3114 os <<
"* Distribution type: GUNGAUSSFLATTOPTH" <<
endl;
3118 os <<
"* Distribution type: FLATTOP" <<
endl;
3126 os <<
"* Transverse profile determined by laser image: " << endl
3143 os <<
"* Time Rise = " <<
tRise_m
3144 <<
" [sec]" <<
endl;
3146 <<
" [sec]" <<
endl;
3150 <<
" [sec]" <<
endl;
3152 <<
" [sec]" <<
endl;
3154 <<
" [sec]" <<
endl;
3155 os <<
"* Longitudinal cutoff = " <<
cutoffR_m[2]
3156 <<
" [units of Sigma Time]" <<
endl;
3157 os <<
"* Flat top modulation amplitude = "
3159 <<
" [Percent of distribution amplitude]" <<
endl;
3160 os <<
"* Flat top modulation periods = "
3171 os <<
"* Distribution type: FROMFILE" <<
endl;
3173 os <<
"* Input file: "
3179 os <<
"* Distribution type: MATCHEDGAUSS" <<
endl;
3183 os <<
"* SIGMAPX = " <<
sigmaP_m[0] <<
" [Beta Gamma]" <<
endl;
3184 os <<
"* SIGMAPY = " <<
sigmaP_m[1] <<
" [Beta Gamma]" <<
endl;
3185 os <<
"* SIGMAPZ = " <<
sigmaP_m[2] <<
" [Beta Gamma]" <<
endl;
3186 os <<
"* AVRGPZ = " <<
avrgpz_m <<
" [Beta Gamma]" <<
endl;
3195 os <<
"* CUTOFFX = " <<
cutoffR_m[0] <<
" [units of SIGMAX]" <<
endl;
3196 os <<
"* CUTOFFY = " <<
cutoffR_m[1] <<
" [units of SIGMAY]" <<
endl;
3197 os <<
"* CUTOFFLONG = " <<
cutoffR_m[2] <<
" [units of SIGMAZ]" <<
endl;
3198 os <<
"* CUTOFFPX = " <<
cutoffP_m[0] <<
" [units of SIGMAPX]" <<
endl;
3199 os <<
"* CUTOFFPY = " <<
cutoffP_m[1] <<
" [units of SIGMAPY]" <<
endl;
3200 os <<
"* CUTOFFPZ = " <<
cutoffP_m[2] <<
" [units of SIGMAPY]" <<
endl;
3204 os <<
"* Distribution type: GAUSS" <<
endl;
3208 <<
" [sec]" <<
endl;
3210 <<
" [sec]" <<
endl;
3212 <<
" [sec]" <<
endl;
3213 os <<
"* Longitudinal cutoff = " <<
cutoffR_m[2]
3214 <<
" [units of Sigma Time]" <<
endl;
3215 os <<
"* Flat top modulation amplitude = "
3217 <<
" [Percent of distribution amplitude]" <<
endl;
3218 os <<
"* Flat top modulation periods = "
3223 os <<
"* SIGMAPX = " <<
sigmaP_m[0]
3224 <<
" [Beta Gamma]" <<
endl;
3225 os <<
"* SIGMAPY = " <<
sigmaP_m[1]
3226 <<
" [Beta Gamma]" <<
endl;
3230 <<
" [units of SIGMAX]" <<
endl;
3232 <<
" [units of SIGMAY]" <<
endl;
3234 <<
" [units of SIGMAPX]" <<
endl;
3236 <<
" [units of SIGMAPY]" <<
endl;
3241 os <<
"* SIGMAPX = " <<
sigmaP_m[0] <<
" [Beta Gamma]" <<
endl;
3242 os <<
"* SIGMAPY = " <<
sigmaP_m[1] <<
" [Beta Gamma]" <<
endl;
3243 os <<
"* SIGMAPZ = " <<
sigmaP_m[2] <<
" [Beta Gamma]" <<
endl;
3244 os <<
"* AVRGPZ = " <<
avrgpz_m <<
" [Beta Gamma]" <<
endl;
3253 os <<
"* CUTOFFX = " <<
cutoffR_m[0] <<
" [units of SIGMAX]" <<
endl;
3254 os <<
"* CUTOFFY = " <<
cutoffR_m[1] <<
" [units of SIGMAY]" <<
endl;
3255 os <<
"* CUTOFFLONG = " <<
cutoffR_m[2] <<
" [units of SIGMAZ]" <<
endl;
3256 os <<
"* CUTOFFPX = " <<
cutoffP_m[0] <<
" [units of SIGMAPX]" <<
endl;
3257 os <<
"* CUTOFFPY = " <<
cutoffP_m[1] <<
" [units of SIGMAPY]" <<
endl;
3258 os <<
"* CUTOFFPZ = " <<
cutoffP_m[2] <<
" [units of SIGMAPY]" <<
endl;
3264 os <<
"* Distribution type: SURFACEEMISION" <<
endl;
3266 os <<
"* * Number of electrons for surface emission "
3268 os <<
"* * Initialized electrons inward margin for surface emission "
3270 os <<
"* * E field threshold (MV), only in position r with E(r)>EINITHR that "
3271 <<
"particles will be initialized "
3273 os <<
"* * Field enhancement for surface emission "
3275 os <<
"* * Maximum number of electrons emitted from a single triangle for "
3276 <<
"Fowler-Nordheim emission "
3278 os <<
"* * Field Threshold for Fowler-Nordheim emission (MV/m) "
3280 os <<
"* * Empirical constant A for Fowler-Nordheim emission model "
3282 os <<
"* * Empirical constant B for Fowler-Nordheim emission model "
3284 os <<
"* * Constant for image charge effect parameter y(E) in Fowler-Nordheim "
3285 <<
"emission model "
3287 os <<
"* * Zero order constant for image charge effect parameter v(y) in "
3288 <<
"Fowler-Nordheim emission model "
3290 os <<
"* * Second order constant for image charge effect parameter v(y) in "
3291 <<
"Fowler-Nordheim emission model "
3293 os <<
"* * Select secondary model type(0:no secondary emission; 1:Furman-Pivi; "
3294 <<
"2 or larger: Vaughan's model "
3296 os <<
"* * Secondary emission mode type(true: emit n true secondaries; false: "
3297 <<
"emit one particle with n times charge "
3299 os <<
"* * Sey_0 in Vaughan's model "
3301 os <<
"* * Energy related to sey_0 in Vaughan's model in eV "
3303 os <<
"* * Sey max in Vaughan's model "
3305 os <<
"* * Emax in Vaughan's model in eV "
3307 os <<
"* * Fitting parameter denotes the roughness of surface for impact "
3308 <<
"energy in Vaughan's model "
3310 os <<
"* * Fitting parameter denotes the roughness of surface for impact angle "
3311 <<
"in Vaughan's model "
3313 os <<
"* * Thermal velocity of Maxwellian distribution of secondaries in "
3314 <<
"Vaughan's model "
3316 os <<
"* * VW denote the velocity scalar for Parallel plate benchmark "
3318 os <<
"* * Material type number of the cavity surface for Furman-Pivi's model, "
3319 <<
"0 for copper, 1 for stainless steel "
3325 os <<
"* Distribution type: SURFACERANDCREATE" <<
endl;
3327 os <<
"* * Number of electrons initialized on the surface as primaries "
3329 os <<
"* * Initialized electrons inward margin for surface emission "
3331 os <<
"* * E field threshold (MV), only in position r with E(r)>EINITHR that "
3332 <<
"particles will be initialized "
3338 os <<
"* ------------- THERMAL EMITTANCE MODEL --------------------------------------------" <<
endl;
3355 os <<
"* ----------------------------------------------------------------------------------" <<
endl;
3360 os <<
"* THERMAL EMITTANCE in ASTRA MODE" <<
endl;
3361 os <<
"* Kinetic energy (thermal emittance) = "
3363 <<
" [eV] " <<
endl;
3367 os <<
"* THERMAL EMITTANCE in NONE MODE" <<
endl;
3368 os <<
"* Kinetic energy added to longitudinal momentum = "
3370 <<
" [eV] " <<
endl;
3374 os <<
"* THERMAL EMITTANCE in NONEQUIL MODE" <<
endl;
3388 binIndex * numberOfSampleBins_m + sampleIndex);
3391 <<
" contains " << sum <<
" particles" <<
endl;
3416 for (
size_t partIndex = 0; partIndex < currentNumPart; partIndex++) {
3429 (numberOfParticles + 1) / 2 != numberOfParticles / 2) {
3451 for (
size_t particleIndex = 0; particleIndex <
tOrZDist_m.size(); ++ particleIndex) {
3452 xDist_m.at(particleIndex) *= xmult;
3453 pxDist_m.at(particleIndex) *= pxmult;
3454 yDist_m.at(particleIndex) *= ymult;
3455 pyDist_m.at(particleIndex) *= pymult;
3457 pzDist_m.at(particleIndex) *= pzmult;
3463 gsl_qrng *quasiRandGen =
nullptr;
3467 quasiRandGen = gsl_qrng_alloc(gsl_qrng_halton, dimension);
3469 quasiRandGen = gsl_qrng_alloc(gsl_qrng_sobol, dimension);
3471 quasiRandGen = gsl_qrng_alloc(gsl_qrng_niederreiter_2, dimension);
3474 quasiRandGen = gsl_qrng_alloc(gsl_qrng_halton, dimension);
3477 return quasiRandGen;
3488 "SURFACERANDCREATE, "
3489 "GUNGAUSSFLATTOPTH, "
3497 =
Attributes::makeReal(
"EX",
"Projected normalized emittance EX (m-rad), used to create matched distribution ", 1E-6);
3499 =
Attributes::makeReal(
"EY",
"Projected normalized emittance EY (m-rad) used to create matched distribution ", 1E-6);
3501 =
Attributes::makeReal(
"ET",
"Projected normalized emittance ET (m-rad) used to create matched distribution ", 1E-6);
3505 =
Attributes::makeReal(
"RESIDUUM",
"Residuum for the closed orbit finder and sigma matrix generator ", 1
e-8);
3514 " (false: using all sectors) (default: true)",
3517 =
Attributes::makeReal(
"NSTEPS",
"Number of integration steps of closed orbit finder (matched gauss)"
3518 " (default: 720)", 720);
3527 =
Attributes::makeReal(
"NSECTORS",
"Number of sectors to average field, for closed orbit finder ", 1);
3531 "coordinates.",
"");
3540 "distribution list.", 1.0);
3544 " Currently \"NONE\" or \"EV\".",
"");
3549 "an injected beam.",
false);
3555 "photocathode.",
"None");
3558 "model (eV). (Thermal energy added in with random "
3559 "number generator.)", 1.0);
3562 "emission. (Default 255 nm light.)", 4.86);
3565 " (Default atomically clean copper.)", 4.31);
3568 " (Default atomically clean copper.)", 7.0);
3571 " (Default 300 K.)", 300.0);
3574 "charge solve.", 0.0);
3622 "0.0 ... infinity.", 10001.0);
3625 "0.0 ... infinity.", 10001.0);
3628 "0.0 ... infinity.", 10001.0);
3631 "0.0 ... infinity.", 10001.0);
3634 "direction in units of sigma.", 3.0);
3636 "direction in units of sigma.", 3.0);
3638 "direction in units of sigma.", 3.0);
3641 "units of sigma.", 3.0);
3643 "dimension in units of sigma.", 3.0);
3645 "dimension in units of sigma.", 3.0);
3647 "dimension in units of sigma.", 3.0);
3651 "on flat top portion of emitted GAUSS "
3652 "distribtuion (in percent of flat top "
3656 "flat top portion of emitted GAUSS "
3657 "distribution", 0.0);
3696 "profile (x,y).",
"");
3701 "image profile, in % of max intensity.",
3708 =
Attributes::makeBool(
"ROTATE90",
"Rotate laser profile 90 degrees counter clockwise",
false);
3710 =
Attributes::makeBool(
"ROTATE180",
"Rotate laser profile 180 degrees counter clockwise",
false);
3712 =
Attributes::makeBool(
"ROTATE270",
"Rotate laser profile 270 degrees counter clockwise",
false);
3719 "current particle positions.", 0.001);
3722 "with E(r)>EINITHR that particles will be "
3723 "initialized.", 0.0);
3726 "emission model.", 1.54
e-6);
3729 "emission model.", 6.83e9);
3732 "in Fowler-Nordheim emission model.", 3.795
e-5);
3735 "Fowler-Nordheim emission model.", 0.9632);
3738 "in Fowler-Nordheim emission model.", 1.065);
3747 "emission (MV/m).", 30.0);
3750 "single triangle for Fowler-Nordheim "
3754 "secondary emission; 1:Furman-Pivi; "
3755 "2 or larger: Vaughan's model.", 0.0);
3758 "emit n true secondaries; false: emit "
3759 "one particle with n times charge.",
true);
3771 "surface for impact energy in Vaughan's "
3775 "surface for impact angle in Vaughan's "
3779 "of secondaries in Vaughan's model.", 7.268929821 * 1e5);
3785 "surface for Furman-Pivi's model, 0 "
3786 "for copper, 1 for stainless steel.", 0.0);
3800 "respect of number of particles and number of cores",
false);
3814 "when emitting a distribution.", 100.0);
3884 "The attribute DISTRIBUTION isn't supported any more, use TYPE instead");
3892 else if (
distT_m ==
"BINOMIAL")
3894 else if (
distT_m ==
"FLATTOP")
3896 else if (
distT_m ==
"GUNGAUSSFLATTOPTH")
3898 else if (
distT_m ==
"ASTRAFLATTOPTH")
3900 else if (
distT_m ==
"SURFACEEMISSION")
3902 else if (
distT_m ==
"SURFACERANDCREATE")
3904 else if (
distT_m ==
"GAUSSMATCHED")
3908 "The distribution \"" +
distT_m +
"\" isn't known.\n" +
3909 "Known distributions are:\n"
3914 "GUNGAUSSFLATTOPTH\n"
3917 "SURFACERANDCREATE\n"
3950 double deltaT = maxT - minT;
3951 maxT += deltaT * 0.0005;
3952 minT -= deltaT * 0.0005;
3964 double deltaT = maxT - minT;
3965 maxT += deltaT * 0.0005;
3966 minT -= deltaT * 0.0005;
3981 throw OpalException(
"Distribution::setDistParametersBinomial",
3982 "Attribute R is not supported for binomial distribution\n"
3983 "use CORR[X|Y|Z] and R51, R52, R61, R62 instead");
4012 WARNMSG(
"The attribute SIGMAPT may be removed in a future version\n"
4013 <<
"use SIGMAPZ instead" <<
endl;)
4093 double timeRatio =
sqrt(2.0 *
log(10.0)) -
sqrt(2.0 *
log(10.0 / 9.0));
4182 if (cr.size() == 15) {
4183 *gmsg <<
"* Use r to specify correlations" <<
endl;
4185 for (
unsigned int i = 0; i < 5; ++ i) {
4186 for (
unsigned int j = i + 1; j < 6; ++ j, ++ k) {
4194 "Inconsistent set of correlations specified, check manual");
4230 double timeRatio =
sqrt(2.0 *
log(10.0)) -
sqrt(2.0 *
log(10.0 / 9.0));
4269 if (model ==
"ASTRA")
4271 else if (model ==
"NONEQUIL")
4310 size_t numParticles =
pzDist_m.size();
4313 avgPz /= numParticles;
4360 "PT is obsolete. The moments of the beam is defined with OFFSETPZ");
4363 const double pz = beam->
getP()/beam->
getM();
4364 double gamma =
sqrt(
pow(pz, 2.0) + 1.0);
4409 double avgZ[] = {0.0, 1.0 *
tOrZDist_m.size()};
4416 for (
double& tOrZ : tOrZDist_m)
4430 size_t startIdx = 0;
4445 "Attribute T isn't supported anymore; use OFFSETZ instead");
4448 double deltaTOrZ = 0.0;
4458 WARNMSG(
"PT & PZ are obsolete and will be ignored. The moments of the beam is defined with PC" <<
endl);
4468 for (
size_t particleIndex = startIdx; particleIndex < endIdx; ++ particleIndex) {
4469 xDist_m.at(particleIndex) += deltaX;
4470 pxDist_m.at(particleIndex) += deltaPx;
4471 yDist_m.at(particleIndex) += deltaY;
4472 pyDist_m.at(particleIndex) += deltaPy;
4474 pzDist_m.at(particleIndex) += deltaPz;
4493 << std::left << std::setw(84) << std::setfill(
'*') <<
"* " <<
"\n"
4494 <<
"* Write initial distribution to file \"" << fname <<
"\"\n"
4495 << std::left << std::setw(84) << std::setfill(
'*') <<
"* "
4496 << std::setfill(
' ') <<
endl;
4498 std::ofstream outputFile(fname);
4499 if (outputFile.bad()) {
4500 *gmsg <<
"Unable to open output file \"" << fname <<
"\"" <<
endl;
4502 outputFile.
setf(std::ios::left);
4504 outputFile.width(17);
4505 outputFile <<
"x [m]";
4506 outputFile.width(17);
4507 outputFile <<
"px [betax gamma]";
4508 outputFile.width(17);
4509 outputFile <<
"y [m]";
4510 outputFile.width(17);
4511 outputFile <<
"py [betay gamma]";
4513 outputFile.width(17);
4514 outputFile <<
"t [s]";
4516 outputFile.width(17);
4517 outputFile <<
"z [m]";
4519 outputFile.width(17);
4520 outputFile <<
"pz [betaz gamma]" ;
4522 outputFile.width(17);
4523 outputFile <<
"Bin Number" <<
std::endl;
4526 outputFile.
width(17);
4527 outputFile <<
"Bin Number";
4531 outputFile <<
"# " << totalNum <<
std::endl;
4552 std::vector<char> msgbuf;
4553 const size_t bitsPerParticle = (6 *
sizeof(double) +
sizeof(
size_t));
4554 size_t totalSendBits =
xWrite_m.size() * bitsPerParticle;
4568 if (totalSendBits > 0) {
4569 msgbuf.reserve(totalSendBits);
4571 for (
size_t idx = 0; idx <
xWrite_m.size(); ++ idx) {
4572 buffer =
reinterpret_cast<const char*
>(&(
xWrite_m[idx]));
4573 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(double));
4574 buffer =
reinterpret_cast<const char*
>(&(
pxWrite_m[idx]));
4575 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(double));
4576 buffer =
reinterpret_cast<const char*
>(&(
yWrite_m[idx]));
4577 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(double));
4578 buffer =
reinterpret_cast<const char*
>(&(
pyWrite_m[idx]));
4579 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(double));
4580 buffer =
reinterpret_cast<const char*
>(&(
tOrZWrite_m[idx]));
4581 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(double));
4582 buffer =
reinterpret_cast<const char*
>(&(
pzWrite_m[idx]));
4583 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(double));
4584 buffer =
reinterpret_cast<const char*
>(&(
binWrite_m[idx]));
4585 msgbuf.insert(msgbuf.end(), buffer, buffer +
sizeof(size_t));
4592 std::ofstream outputFile(fname, std::fstream::app);
4593 if (outputFile.bad()) {
4596 if (numberOfBits[node] == 0)
continue;
4597 char *recvbuf =
new char[numberOfBits[node]];
4603 outputFile.precision(9);
4604 outputFile.setf(std::ios::scientific);
4605 outputFile.setf(std::ios::right);
4607 for (
size_t partIndex = 0; partIndex <
xWrite_m.size(); partIndex++) {
4609 outputFile << std::setw(17) <<
xWrite_m.at(partIndex)
4610 << std::setw(17) <<
pxWrite_m.at(partIndex)
4611 << std::setw(17) <<
yWrite_m.at(partIndex)
4612 << std::setw(17) <<
pyWrite_m.at(partIndex)
4614 << std::setw(17) <<
pzWrite_m.at(partIndex)
4620 if (numberOfBits[i] > 0) numSenders ++;
4623 for (
int i = 0; i < numSenders; ++ i) {
4629 while (j < bufsize) {
4630 const double *dbuffer =
reinterpret_cast<const double*
>(recvbuf + j);
4631 const size_t *sbuffer =
reinterpret_cast<const size_t*
>(recvbuf + j + 6 *
sizeof(double));
4632 outputFile << std::setw(17) << dbuffer[0]
4633 << std::setw(17) << dbuffer[1]
4634 << std::setw(17) << dbuffer[2]
4635 << std::setw(17) << dbuffer[3]
4636 << std::setw(17) << dbuffer[4]
4637 << std::setw(17) << dbuffer[5]
4638 << std::setw(17) << sbuffer[0]
4640 j += bitsPerParticle;
4669 for (
int nodeIndex = 0; nodeIndex <
Ippl::getNodes(); nodeIndex++) {
4672 size_t numberOfParticles = 0;
4674 std::ofstream outputFile(fname, std::fstream::app);
4675 if (outputFile.bad()) {
4676 *gmsg <<
"Node " <<
Ippl::myNode() <<
" unable to write"
4677 <<
"to file \"" << fname <<
"\"" <<
endl;
4681 outputFile.setf(std::ios::scientific);
4682 outputFile.setf(std::ios::right);
4685 for (
size_t partIndex = 0; partIndex < numberOfParticles; partIndex++) {
4687 outputFile.width(17);
4688 outputFile <<
xDist_m.at(partIndex);
4689 outputFile.width(17);
4690 outputFile <<
pxDist_m.at(partIndex);
4691 outputFile.width(17);
4692 outputFile <<
yDist_m.at(partIndex);
4693 outputFile.width(17);
4694 outputFile <<
pyDist_m.at(partIndex);
4695 outputFile.width(17);
4697 outputFile.width(17);
4698 outputFile <<
pzDist_m.at(partIndex);
4701 outputFile.width(17);
4702 outputFile << binNumber;
4721 return sqrt(-2.0 *
log(rand));
4743 for (
unsigned int i = 0; i <
pzDist_m.size(); ++ i) {
4749 allreduce(&(avrg[0]), 6, std::plus<double>());
4755 for (
unsigned int i = 0; i <
pzDist_m.size(); ++ i) {
int seed
The current random seed.
Vector_t pmean_m
Total thermal momentum.
double getEmissionDeltaT()
std::vector< double > & getBGxDist()
void doRestartOpalCycl(PartBunchBase< double, 3 > *p, size_t Np, int restartStep, const int specifiedNumBunch, H5PartWrapper *h5wrapper)
virtual double get(double rand)
ParticleAttrib< Vector_t > P
void printDist(Inform &os, size_t numberOfParticles) const
EmissionModelT::EmissionModelT emissionModel_m
Emission Model.
void applyEmissionModel(double lowEnergyLimit, double &px, double &py, double &pz, std::vector< double > &additionalRNs)
void chooseInputMomentumUnits(InputMomentumUnitsT::InputMomentumUnitsT inputMoUnits)
const PartData & getReference() const
Return the embedded CLASSIC PartData.
virtual void update()
Update this object.
std::vector< double > yWrite_m
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
void getXY(double &x, double &y)
void doRestartOpalE(EnvelopeBunch *p, size_t Np, int restartStep, H5PartWrapper *h5wrapper)
std::vector< size_t > particlesPerDist_m
constexpr double kB
Boltzman's constant in eV/K.
IpplTimings::TimerRef distrCreate_m
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
constexpr double e
The value of .
ParticleAttrib< Vector_t > Ef
size_t darkCurrentParts_m
void setRinit(double rinit)
std::vector< double > tOrZWrite_m
void adjustPhaseSpace(double massIneV)
void initializeBeam(PartBunchBase< double, 3 > *beam)
void define(Object *newObject)
Define a new object.
std::vector< double > xDist_m
The base class for all OPAL definitions.
Finds a closed orbit of a cyclotron for a given energy.
double pTotThermal_m
Random number generator.
long long getLocalTrackStep() const
std::vector< double > tOrZDist_m
core of the envelope tracker based on Rene Bakkers BET implementation
std::vector< double > pxWrite_m
double getMass() const
Return Particle's rest mass in GeV.
int getNumberOfEnergyBins()
void createOpalCycl(PartBunchBase< double, 3 > *beam, size_t numberOfParticles, double current, const Beamline &bl)
Interface for a Cyclotron.
virtual bool canReplaceBy(Object *object)
Distribution can only be replaced by another distribution.
void createDistributionFromFile(size_t numberOfParticles, double massIneV)
Vector_t getCooridinate(size_t i)
size_t getNumberOfSlices()
Return the number of slices.
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
void setCharge(double _Q)
set the charge of the bunch
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
virtual double getPHIinit() const
double tEmission_m
Emission parameters.
double darkInwardMargin_m
Number of dark current particles.
The base class for all OPAL exceptions.
Tps< T > sin(const Tps< T > &x)
Sine.
virtual double get(double rand)
std::string laserProfileFileName_m
std::vector< std::vector< double > > additionalRNs_m
Upper limit on emission energy distribution (eV).
PETE_TBTree< FnCopysign, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > copysign(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
ParticleAttrib< double > Q
constexpr double two_pi
The value of .
void shiftBeam(double &maxTOrZ, double &minTOrZ)
double getCurrent() const
Return the beam current in A.
void calcPartPerDist(size_t numberOfParticles)
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
std::vector< double > & getBGzDist()
Tps< T > exp(const Tps< T > &x)
Exponential.
void initialize(int sli, double charge, double energy, double width, double te, double frac, double current, double center, double bX, double bY, double mX, double mY, double Bz, int nbin)
void generateBinomial(size_t numberOfParticles)
virtual int raw_probe_receive(char *&, int &, int &)
InputMomentumUnitsT::InputMomentumUnitsT inputMoUnits_m
std::string toUpper(const std::string &str)
double emitEnergyUpperLimit_m
Cathode temperature (K).
void createDistributionGauss(size_t numberOfParticles, double massIneV)
void createBunch()
create and initialize local num slices
void setGamma(double gamma)
double getEmissionTimeShift() const
static Distribution * find(const std::string &name)
double getEnergyBinDeltaT()
void writeOutFileEmission()
void setFieldEmissionParameters()
virtual bool predecessorIsSameFlavour() const =0
std::vector< double > xWrite_m
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
void createBoundaryGeometry(PartBunchBase< double, 3 > *p, BoundaryGeometry &bg)
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
std::vector< double > & getYDist()
virtual bool raw_send(void *, int, int, int)
void scaleDistCoordinates()
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
size_t totalNumberParticles_m
size_t getTotalNum() const
Tps< T > log(const Tps< T > &x)
Natural logarithm.
std::vector< Distribution * > addedDistributions_m
Vector of distributions to be added to this distribution.
void generateFlattopZ(size_t numberOfParticles)
int next_tag(int t, int s=1000)
size_t emitParticles(PartBunchBase< double, 3 > *beam, double eZ)
bool cZero
if true create symmetric distribution
Inform & printInfo(Inform &os) const
bool getBool(const Attribute &attr)
Return logical value.
constexpr double m_e
The electron rest mass in GeV.
Inform & level2(Inform &inf)
constexpr double alpha
The fine structure constant, no dimension.
void setupEmissionModelNonEquil()
void setupEnergyBins(double maxTOrZ, double minTOrZ)
virtual double getFMHighE() const
IpplTimings::TimerRef distrReload_m
timer for IC, can not be in Distribution.h
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
void setDistParametersBinomial(double massIneV)
virtual double getCyclHarm() const
static OpalData * getInstance()
void generateGaussZ(size_t numberOfParticles)
void printDistSurfEmission(Inform &os) const
unsigned int numberOfDistributions_m
and list type for switch statements.
void printEmissionModelNonEquil(Inform &os) const
const std::string & getOpalName() const
Return object name.
size_t getNumberOfEmissionSteps()
double getCharge() const
Return the charge number in elementary charge.
static BeamSequence * find(const std::string &name)
Find a BeamSequence by name.
void createDistributionFlattop(size_t numberOfParticles, double massIneV)
std::vector< double > pzWrite_m
void injectBeam(PartBunchBase< double, 3 > *beam)
void create(size_t &numberOfParticles, double massIneV)
void createPriPart(PartBunchBase< double, 3 > *beam, BoundaryGeometry &bg)
ParticleAttrib< short > PType
double getGlobalPhaseShift()
units: (sec)
void setupEmissionModelAstra(PartBunchBase< double, 3 > *beam)
constexpr double pi
The value of .
void printDistGauss(Inform &os) const
void printDistFromFile(Inform &os) const
LaserProfile * laserProfile_m
void printDistMatchedGauss(Inform &os) const
void fill(std::vector< double > &p)
Add a particle to the temporary container.
virtual void execute()
Execute the command.
void setPRinit(double prinit)
void printEnergyBins(Inform &os) const
ParticleAttrib< int > TriID
Defines a structure to hold energy bins and their associated data.
void generateFlattopLaserProfile(size_t numberOfParticles)
void allreduce(const T *input, T *output, int count, Op op)
constexpr double c
The velocity of light in m/s.
void addProblemCharacteristicValue(const std::string &name, unsigned int value)
std::string rngtype
random number generator
void setEnergyBins(int numberOfEnergyBins)
void checkEmissionParameters()
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
virtual Beamline * fetchLine() const =0
Return the embedded CLASSIC beam line.
static void startTimer(TimerRef t)
double getChargePerParticle() const
get the macro particle charge
void setTEmission(double t)
Vector_t getMomenta(size_t i)
size_t findEBin(double tOrZ)
virtual void execute()
Execute the algorithm on the attached beam line.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
void generateAstraFlattopT(size_t numberOfParticles)
constexpr double SMALLESTCUTOFF
PartData particleRefData_m
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
size_t mySliceEndOffset()
void setupEmissionModel(PartBunchBase< double, 3 > *beam)
std::vector< double > & getTOrZDist()
double cathodeTemp_m
Cathode material Fermi energy (eV).
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
double getInitialGamma() const
Vektor< double, 3 > Vector_t
virtual double getFMLowE() const
An abstract sequence of beam line components.
static MPI_Comm getComm()
size_t getLocalNum() const
double converteVToBetaGamma(double valueIneV, double massIneV)
double laserEnergy_m
Cathode material work function (eV).
Tps< T > sqrt(const Tps< T > &x)
Square root.
std::string laserImageName_m
void setupParticleBins(double massIneV, PartBunchBase< double, 3 > *beam)
ParticleAttrib< double > dt
std::vector< double > pyWrite_m
The base class for all OPAL beam lines and sequences.
short getNumBunch() const
void generateTransverseGauss(size_t numberOfParticles)
void applyEmissModelNone(double &pz)
void printDistSurfAndCreate(Inform &os) const
gsl_qrng * selectRandomGenerator(std::string, unsigned int dimension)
Select and allocate gsl random number generator.
void generateLongFlattopT(size_t numberOfParticles)
void writeOutFileHeader()
void printEmissionModelNone(Inform &os) const
void setupEmissionModelNone(PartBunchBase< double, 3 > *beam)
size_t getNumberOfParticlesInFile(std::ifstream &inputFile)
virtual void readStep(PartBunchBase< double, 3 > *, h5_ssize_t firstParticle, h5_ssize_t lastParticle)=0
double currentEmissionTime_m
Object * find(const std::string &name)
Find entry.
The base class for all OPAL objects.
Tps< T > cos(const Tps< T > &x)
Cosine.
double tRise_m
time binned distribution with thermal energy
void setNumBunch(short n)
void createMatchedGaussDistribution(size_t numberOfParticles, double massIneV)
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
virtual Distribution * clone(const std::string &name)
Return a clone.
constexpr double q_e
The elementary charge in As.
double getQ() const
Access to reference data.
void distributeSlices(int nSlice=101)
distributes nSlice amongst processors and initializes slices
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)
void writeOutFileInjection()
double getChargePerParticle()
returns charge per slice
size_t totalNumberEmittedParticles_m
void applyEmissModelAstra(double &px, double &py, double &pz, std::vector< double > &additionalRNs)
ParticleAttrib< int > Bin
virtual int raw_receive(char *, int, int &, int &)
std::vector< double > & getXDist()
void shiftDistCoordinates(double massIneV)
virtual void readHeader()=0
bool cloTuneOnly
Do closed orbit and tune calculation only.
constexpr double epsilon_0
The permittivity of vacuum in As/Vm.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
bool builtin
Built-in flag.
ParticleAttrib< Vector_t > Bf
void setDistParametersFlattop(double massIneV)
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
DistrTypeT::DistrTypeT distrTypeT_m
Distribution type. Declared as string.
double cathodeFermiEnergy_m
Laser photon energy (eV).
void applyEmissModelNonEquil(double eZ, double &px, double &py, double &pz, std::vector< double > &additionalRNs)
int getLastEmittedEnergyBin()
void iterateEmittedBin(int binNumber)
Inform & level3(Inform &inf)
std::string::iterator iterator
void createDistributionBinomial(size_t numberOfParticles, double massIneV)
void clearCooridinateArray()
double getReal(const Attribute &attr)
Return real value.
std::vector< double > & getBGyDist()
void setDistToEmitted(bool emitted)
static void stopTimer(TimerRef t)
bool ppdebug
ppdebug flag.
std::string getInputBasename()
get input file name without extension
double tPulseLengthFWHM_m
void printDistFlattop(Inform &os) const
size_t mySliceStartOffset()
std::vector< double > pzDist_m
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
std::vector< double > yDist_m
void setDistParametersGauss(double massIneV)
size_t getNumParticles() const
std::vector< double > pyDist_m
static Communicate * Comm
void generateFlattopT(size_t numberOfParticles)
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Inform & level1(Inform &inf)
void checkParticleNumber(size_t &numberOfParticles)
void reflectDistribution(size_t &numberOfParticles)
void printDistBinomial(Inform &os) const
double laserIntensityCut_m
Defines a structure to hold energy bins and their associated data for multi-bunch tracking in cyclotr...
void createOpalT(PartBunchBase< double, 3 > *beam, std::vector< Distribution * > addedDistributions, size_t &numberOfParticles)
double fieldEnhancement_m
Work function of surface material (eV).
void printEmissionModel(Inform &os) const
void printEmissionModelAstra(Inform &os) const
void setEmissionTime(double &maxT, double &minT)
void setPBins(PartBins *pbin)
gsl_histogram * energyBinHist_m
Distribution energy bins.
std::vector< double > pxDist_m
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
double vVThermal_m
Velocity scalar for parallel plate benchmark.
Inform & endl(Inform &inf)
This class computes the matched distribution.
SymTenzor< double, 6 > correlationMatrix_m
std::string getString(const Attribute &attr)
Get string value.
long long getGlobalTrackStep() const
size_t getNumOfLocalParticlesToCreate(size_t n)
std::vector< size_t > binWrite_m