10 #include <unordered_map>
13 using namespace Jetscape;
17 rng_engine.seed(ran_seed);
20 GWeight[0] = 0.0621766166553473; GWeight[1] = 0.0619360674206832; GWeight[2] = 0.0614558995903167; GWeight[3] = 0.0607379708417702; GWeight[4] = 0.0597850587042655;
21 GWeight[5] = 0.0586008498132224; GWeight[6] = 0.0571899256477284; GWeight[7] = 0.0555577448062125; GWeight[8] = 0.0537106218889962; GWeight[9] = 0.0516557030695811;
22 GWeight[10] = 0.0494009384494663; GWeight[11] = 0.0469550513039484; GWeight[12] = 0.0443275043388033; GWeight[13] = 0.0415284630901477; GWeight[14] = 0.0385687566125877;
23 GWeight[15] = 0.0354598356151462; GWeight[16] = 0.0322137282235780; GWeight[17] = 0.0288429935805352; GWeight[18] = 0.0253606735700124; GWeight[19] = 0.0217802431701248;
24 GWeight[20] = 0.0181155607134894; GWeight[21] = 0.0143808227614856; GWeight[22] = 0.0105905483836510; GWeight[23] = 0.0067597991957454; GWeight[24] = 0.0029086225531551;
25 GWeight[25] = 0.0621766166553473; GWeight[26] = 0.0619360674206832; GWeight[27] = 0.0614558995903167; GWeight[28] = 0.0607379708417702; GWeight[29] = 0.0597850587042655;
26 GWeight[30] = 0.0586008498132224; GWeight[31] = 0.0571899256477284; GWeight[32] = 0.0555577448062125; GWeight[33] = 0.0537106218889962; GWeight[34] = 0.0516557030695811;
27 GWeight[35] = 0.0494009384494663; GWeight[36] = 0.0469550513039484; GWeight[37] = 0.0443275043388033; GWeight[38] = 0.0415284630901477; GWeight[39] = 0.0385687566125877;
28 GWeight[40] = 0.0354598356151462; GWeight[41] = 0.0322137282235780; GWeight[42] = 0.0288429935805352; GWeight[43] = 0.0253606735700124; GWeight[44] = 0.0217802431701248;
29 GWeight[45] = 0.0181155607134894; GWeight[46] = 0.0143808227614856; GWeight[47] = 0.0105905483836510; GWeight[48] = 0.0067597991957454; GWeight[49] = 0.0029086225531551;
32 GAbs[0] = 0.0310983383271889; GAbs[1] = 0.0931747015600861; GAbs[2] = 0.1548905899981459; GAbs[3] = 0.2160072368760418; GAbs[4] = 0.2762881937795320;
33 GAbs[5] = 0.3355002454194373; GAbs[6] = 0.3934143118975651; GAbs[7] = 0.4498063349740388; GAbs[8] = 0.5044581449074642; GAbs[9] = 0.5571583045146501;
34 GAbs[10] = 0.6077029271849502; GAbs[11] = 0.6558964656854394; GAbs[12] = 0.7015524687068222; GAbs[13] = 0.7444943022260685; GAbs[14] = 0.7845558329003993;
35 GAbs[15] = 0.8215820708593360; GAbs[16] = 0.8554297694299461; GAbs[17] = 0.8859679795236131; GAbs[18] = 0.9130785566557919; GAbs[19] = 0.9366566189448780;
36 GAbs[20] = 0.9566109552428079; GAbs[21] = 0.9728643851066920; GAbs[22] = 0.9853540840480058; GAbs[23] = 0.9853540840480058; GAbs[24] = 0.9988664044200710;
37 GAbs[25] = -0.0310983383271889; GAbs[26] = -0.0931747015600861; GAbs[27] = -0.1548905899981459; GAbs[28] = -0.2160072368760418; GAbs[29] = -0.2762881937795320;
38 GAbs[30] = -0.3355002454194373; GAbs[31] = -0.3934143118975651; GAbs[32] = -0.4498063349740388; GAbs[33] = -0.5044581449074642; GAbs[34] = -0.5571583045146501;
39 GAbs[35] = -0.6077029271849502; GAbs[36] = -0.6558964656854394; GAbs[37] = -0.7015524687068222; GAbs[38] = -0.7444943022260685; GAbs[39] = -0.7845558329003993;
40 GAbs[40] = -0.8215820708593360; GAbs[41] = -0.8554297694299461; GAbs[42] = -0.8859679795236131; GAbs[43] = -0.9130785566557919; GAbs[44] = -0.9366566189448780;
41 GAbs[45] = -0.9566109552428079; GAbs[46] = -0.9728643851066920; GAbs[47] = -0.9853540840480058; GAbs[48] = -0.9853540840480058; GAbs[49] = -0.9988664044200710;
50 CellDX = 0.2; CellDY = 0.2; CellDZ = 0.2; CellDT = 0.1;
54 SetNumLight = 1000000;
69 num_ud = 0; num_s = 0;
71 for(
int iCDF=0; iCDF<NUMSTEP; ++iCDF){
72 std::vector<double> temp = {0., 0.};
73 CDFTabLight.push_back(temp);
74 CDFTabStrange.push_back(temp);
80 return 1./( exp( (sqrt(M*M + P*P) - mu)/T ) + 1. );
84 std::vector<std::vector<double>>& CDFTab = (quark == 1) ? CDFTabLight : CDFTabStrange;
86 int TargetPoint = ((floor + ceiling) / 2);
87 double TargetVal = CDFTab[TargetPoint][1];
89 return (goal > TargetVal);
94 double PMax = 10. * Temp;
95 PStep = PMax / (NUMSTEP - 1);
97 std::vector<std::vector<double>> CDFTab;
100 }
else if (quark == 2) {
101 CDFTab = CDFTabStrange;
103 JSWARN <<
"This is not a valid quark input for CDFGenerator()";
115 for (
int i = 1;
i < NUMSTEP;
i++) {
116 CDFTab[
i][0] = CDFTab[
i - 1][0] + PStep;
117 double Fermi0 = FermiPDF(CDFTab[
i - 1][0], M, Temp, muPi0);
118 double Fermi1 = FermiPDF(CDFTab[
i][0], M, Temp, muPi0);
119 CDFTab[
i][1] = CDFTab[i - 1][1] + (PStep / 2) * (Fermi0 * CDFTab[i - 1][0] * CDFTab[i - 1][0] + Fermi1 * CDFTab[i][0] * CDFTab[i][0]);
123 for (
int i = 0;
i < NUMSTEP;
i++) {
124 CDFTab[
i][1] = CDFTab[
i][1] / CDFTab[NUMSTEP - 1][1];
128 CDFTabLight = CDFTab;
129 }
else if (quark == 2) {
130 CDFTabStrange = CDFTab;
135 double PMag, CosT, Phi, PStep;
136 double PMax = 10. * Temp;
137 PStep = PMax / (NUMSTEP - 1);
139 std::vector<std::vector<double>>& CDFTab = (quark == 1) ? CDFTabLight : CDFTabStrange;
142 int ceiling = NUMSTEP - 1;
151 for (
int i = 0;
i < 25;
i++) {
152 if (SplitSort(PRoll, floor, ceiling, quark)) {
153 floor = ((floor + ceiling) / 2);
155 ceiling = ((floor + ceiling) / 2);
159 denominator = CDFTab[ceiling][1] - CDFTab[floor][1];
160 if (std::fabs(denominator) > 1
e-16) {
161 PMag = PStep * (PRoll - CDFTab[floor][1]) / denominator + CDFTab[floor][0];
166 CosT = (
ran() - 0.5) * 2.0;
167 Phi =
ran() * 2 * PI;
169 NewX = PMag * sqrt(1 - CosT * CosT) * cos(Phi);
170 NewY = PMag * sqrt(1 - CosT * CosT) * sin(Phi);
178 if(
L < 0.){
L = -
L;
JSWARN <<
"Negative brick length - setting to positive " <<
L <<
" fm.";}
179 if(W < 0.){W = -W;
JSWARN <<
"Negative brick width - setting to positive " << W <<
" fm.";}
190 double UDDeg = 4.*6.;
191 double OddDeg = 2.*6.;
198 double LorBoost[4][4];
199 int GeneratedParticles;
200 double new_quark_energy;
216 double vsquare = Vel[1]*Vel[1] + Vel[2]*Vel[2] + Vel[3]*Vel[3];
219 JSWARN <<
"v^2 = " << vsquare;
220 JSWARN <<
"Unphysical velocity (brick flow)! Set to \"No Flow\" case";
226 Vel[0] = 1. / std::sqrt(1.-vsquare);
230 LorBoost[0][0]= Vel[0];
231 LorBoost[0][1]= Vel[0]*Vel[1];
232 LorBoost[0][2]= Vel[0]*Vel[2];
233 LorBoost[0][3]= Vel[0]*Vel[3];
234 LorBoost[1][0]= Vel[0]*Vel[1];
238 LorBoost[2][0]= Vel[0]*Vel[2];
242 LorBoost[3][0]= Vel[0]*Vel[3];
247 LorBoost[0][0]= Vel[0];
248 LorBoost[0][1]= Vel[0]*Vel[1];
249 LorBoost[0][2]= Vel[0]*Vel[2];
250 LorBoost[0][3]= Vel[0]*Vel[3];
251 LorBoost[1][0]= Vel[0]*Vel[1];
252 LorBoost[1][1]= (Vel[0] - 1.)*Vel[1]*Vel[1]/vsquare + 1.;
253 LorBoost[1][2]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
254 LorBoost[1][3]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
255 LorBoost[2][0]= Vel[0]*Vel[2];
256 LorBoost[2][1]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
257 LorBoost[2][2]= (Vel[0] - 1.)*Vel[2]*Vel[2]/vsquare + 1.;
258 LorBoost[2][3]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
259 LorBoost[3][0]= Vel[0]*Vel[3];
260 LorBoost[3][1]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
261 LorBoost[3][2]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
262 LorBoost[3][3]= (Vel[0] - 1.)*Vel[3]*Vel[3]/vsquare + 1.;
268 CMSigma[0] = (LorBoost[0][0]*LFSigma[0] + LorBoost[0][1]*LFSigma[1] + LorBoost[0][2]*LFSigma[2] + LorBoost[0][3]*LFSigma[3]);
269 CMSigma[1] = (LorBoost[1][0]*LFSigma[0] + LorBoost[1][1]*LFSigma[1] + LorBoost[1][2]*LFSigma[2] + LorBoost[1][3]*LFSigma[3]);
270 CMSigma[2] = (LorBoost[2][0]*LFSigma[0] + LorBoost[2][1]*LFSigma[1] + LorBoost[2][2]*LFSigma[2] + LorBoost[2][3]*LFSigma[3]);
271 CMSigma[3] = (LorBoost[3][0]*LFSigma[0] + LorBoost[3][1]*LFSigma[1] + LorBoost[3][2]*LFSigma[2] + LorBoost[3][3]*LFSigma[3]);
279 double pSpatialdSigma;
285 auto computeEnergy = [](
double mass,
double cut,
double GAbsL,
double GAbsM,
double GAbsK) {
286 return sqrt(mass * mass + (cut * GAbsL) * (cut * GAbsL) + (cut * GAbsM) * (cut * GAbsM) + (cut * GAbsK) * (cut * GAbsK));
290 auto FermiDistribution = [](
double energy,
double temperature) {
291 return 1. / (exp(energy / temperature) + 1.);
295 for (
int l=0; l<GPoints; l++){
296 for (
int m=0;
m<GPoints;
m++){
297 for(
int k=0;
k<GPoints;
k++){
298 GWeightProd = GWeight[l] * GWeight[
m] * GWeight[
k];
299 pSpatialdSigma = (cut * GAbs[l]) * CMSigma[1] + (cut * GAbs[
m]) * CMSigma[2] + (cut * GAbs[
k]) * CMSigma[3];
302 E_light = computeEnergy(xmq, cut, GAbs[l], GAbs[m], GAbs[
k]);
303 NumLight += GWeightProd * FermiDistribution(E_light,
T) *
304 (E_light * CMSigma[0] + pSpatialdSigma) / E_light;
307 E_strange = computeEnergy(xms, cut, GAbs[l], GAbs[m], GAbs[k]);
308 NumStrange += GWeightProd * FermiDistribution(E_strange,
T) *
309 (E_strange * CMSigma[0] + pSpatialdSigma) / E_strange;
315 NumLight *= UDDeg*cut*cut*cut/(8.*PI*PI*PI);
316 NumStrange *= OddDeg*cut*cut*cut/(8.*PI*PI*PI);
319 CDFGenerator(
T, xmq, 1);
320 CDFGenerator(
T, xms, 2);
324 double NumHere = NumLight*
L*W*W;
328 double NumOddHere = NumStrange*
L*W*W;
330 std::poisson_distribution<int> poisson_ud(NumHere);
331 std::poisson_distribution<int> poisson_s(NumOddHere);
335 NumHere = SetNumLight;
336 NumOddHere = SetNumStrange;
340 GeneratedParticles = poisson_ud(getRandomGenerator());
343 for(
int partic = 0; partic < GeneratedParticles; partic++){
345 std::vector<double> temp = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
346 Plist.push_back(temp);
349 double SpecRoll =
ran();
350 if (SpecRoll <= 0.25) {
351 Plist[PartCount][1] = -2;
352 }
else if (SpecRoll <= 0.50) {
353 Plist[PartCount][1] = -1;
354 }
else if (SpecRoll <= 0.75) {
355 Plist[PartCount][1] = 1;
357 Plist[PartCount][1] = 2;
362 double XRoll =
ran()-0.5;
363 double YRoll =
ran()-0.5;
364 double ZRoll =
ran()-0.5;
366 Plist[PartCount][7] = XRoll*
L;
367 Plist[PartCount][8] = YRoll*W;
368 Plist[PartCount][9] = ZRoll*W;
371 Plist[PartCount][10] = Time;
380 new_quark_energy = sqrt(xmq*xmq + NewP*NewP);
381 Plist[PartCount][6]= (LorBoost[0][0]*new_quark_energy + LorBoost[0][1]*NewX + LorBoost[0][2]*NewY + LorBoost[0][3]*NewZ)*GEVFM;
382 Plist[PartCount][3]= (LorBoost[1][0]*new_quark_energy + LorBoost[1][1]*NewX + LorBoost[1][2]*NewY + LorBoost[1][3]*NewZ)*GEVFM;
383 Plist[PartCount][4]= (LorBoost[2][0]*new_quark_energy + LorBoost[2][1]*NewX + LorBoost[2][2]*NewY + LorBoost[2][3]*NewZ)*GEVFM;
384 Plist[PartCount][5]= (LorBoost[3][0]*new_quark_energy + LorBoost[3][1]*NewX + LorBoost[3][2]*NewY + LorBoost[3][3]*NewZ)*GEVFM;
386 Plist[PartCount][0] = 1;
387 Plist[PartCount][2] = 0;
388 Plist[PartCount][11] = 0;
392 nL_tot += GeneratedParticles;
395 GeneratedParticles = poisson_s(getRandomGenerator());
397 nS_tot += GeneratedParticles;
399 for(
int partic = 0; partic < GeneratedParticles; partic++){
401 std::vector<double> temp = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
402 Plist.push_back(temp);
405 double SpecRoll =
ran();
407 Plist[PartCount][1] = -3;
409 Plist[PartCount][1] = 3;
414 double XRoll =
ran()-0.5;
415 double YRoll =
ran()-0.5;
416 double ZRoll =
ran()-0.5;
418 Plist[PartCount][7] = XRoll*
L;
419 Plist[PartCount][8] = YRoll*W;
420 Plist[PartCount][9] = ZRoll*W;
423 Plist[PartCount][10] = Time;
432 new_quark_energy = sqrt(xms*xms + NewP*NewP);
433 Plist[PartCount][6]= (LorBoost[0][0]*new_quark_energy + LorBoost[0][1]*NewX + LorBoost[0][2]*NewY + LorBoost[0][3]*NewZ)*GEVFM;
434 Plist[PartCount][3]= (LorBoost[1][0]*new_quark_energy + LorBoost[1][1]*NewX + LorBoost[1][2]*NewY + LorBoost[1][3]*NewZ)*GEVFM;
435 Plist[PartCount][4]= (LorBoost[2][0]*new_quark_energy + LorBoost[2][1]*NewX + LorBoost[2][2]*NewY + LorBoost[2][3]*NewZ)*GEVFM;
436 Plist[PartCount][5]= (LorBoost[3][0]*new_quark_energy + LorBoost[3][1]*NewX + LorBoost[3][2]*NewY + LorBoost[3][3]*NewZ)*GEVFM;
439 Plist[PartCount][0] = 1;
440 Plist[PartCount][2] = 0;
441 Plist[PartCount][11] = 0;
445 JSDEBUG <<
"Light particles: " << nL_tot;
446 JSDEBUG <<
"Strange particles: " << nS_tot;
454 std::shuffle(&Plist[0], &Plist[PartCount], getRandomGenerator());
488 double UDDeg = 4.*6.;
489 double OddDeg = 2.*6.;
492 double LorBoost[4][4];
493 int GeneratedParticles;
500 double pSpatialdSigma;
504 GeneratedParticles = 0;
505 double new_quark_energy;
512 const double accuracyRange = 0.003 / GEVFM;
514 std::unordered_map<double, std::vector<std::vector<double>>> cdfLightCache;
515 std::unordered_map<double, std::vector<std::vector<double>>> cdfStrangeCache;
518 auto withinAccuracyRange = [accuracyRange](
double targetTemp,
double cachedTemp) {
519 return std::fabs(targetTemp - cachedTemp) <= accuracyRange;
523 auto getClosestCachedTemp = [](
const std::unordered_map<double, std::vector<std::vector<double>>>& cache,
double targetTemp) {
524 double closestTemp = -1.0;
525 double minDistance = std::numeric_limits<double>::max();
526 for (
const auto&
entry : cache) {
527 double cachedTemp =
entry.first;
528 double distance = std::fabs(targetTemp - cachedTemp);
529 if (distance < minDistance) {
531 closestTemp = cachedTemp;
538 auto computeEnergy = [](
double mass,
double cut,
double GAbsL,
double GAbsM,
double GAbsK) {
539 return sqrt(mass * mass + (cut * GAbsL) * (cut * GAbsL) + (cut * GAbsM) * (cut * GAbsM) + (cut * GAbsK) * (cut * GAbsK));
543 auto FermiDistribution = [](
double energy,
double temperature) {
544 return 1. / (exp(energy / temperature) + 1.);
547 for(
int iS=0; iS<
surface.size(); ++iS){
557 TRead =
surface[iS][8] / GEVFM;
565 auto cdfLightIter = cdfLightCache.find(TRead);
566 if (cdfLightIter == cdfLightCache.end()) {
568 double closestTemp = getClosestCachedTemp(cdfLightCache,TRead);
570 if (closestTemp >= 0. && withinAccuracyRange(TRead, closestTemp)) {
572 CDFTabLight = cdfLightCache[closestTemp];
577 CDFGenerator(TRead, xmq, 1);
578 cdfLightCache[TRead] = CDFTabLight;
582 CDFTabLight = cdfLightIter->second;
586 auto cdfStrangeIter = cdfStrangeCache.find(TRead);
587 if (cdfStrangeIter == cdfStrangeCache.end()) {
589 double closestTemp = getClosestCachedTemp(cdfStrangeCache,TRead);
591 if (closestTemp >= 0 && withinAccuracyRange(TRead, closestTemp)) {
593 CDFTabStrange = cdfStrangeCache[closestTemp];
598 CDFGenerator(TRead, xms, 2);
599 cdfStrangeCache[TRead] = CDFTabStrange;
603 CDFTabStrange = cdfStrangeIter->second;
606 if (Cartesian_hydro ==
false){
608 CPos[0] = tau_pos*std::cosh(eta_pos);
609 CPos[3] = tau_pos*std::sinh(eta_pos);
611 double cosh_eta_pos = std::cosh(eta_pos);
612 double sinh_eta_pos = std::sinh(eta_pos);
613 LFSigma[0] = cosh_eta_pos*tau_sur - (sinh_eta_pos / tau_pos) * eta_sur;
614 LFSigma[3] = -sinh_eta_pos*tau_sur + (cosh_eta_pos / tau_pos) * eta_sur;
618 LFSigma[0] = tau_sur;
619 LFSigma[3] = eta_sur;
622 double vsquare = Vel[1]*Vel[1] + Vel[2]*Vel[2] + Vel[3]*Vel[3];
623 if(vsquare < 10
e-16){
628 Vel[0] = 1. / sqrt(1-vsquare);
631 LorBoost[0][0]= Vel[0];
632 LorBoost[0][1]= Vel[0]*Vel[1];
633 LorBoost[0][2]= Vel[0]*Vel[2];
634 LorBoost[0][3]= Vel[0]*Vel[3];
635 LorBoost[1][0]= Vel[0]*Vel[1];
636 LorBoost[1][1]= (Vel[0] - 1.)*Vel[1]*Vel[1]/vsquare + 1.;
637 LorBoost[1][2]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
638 LorBoost[1][3]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
639 LorBoost[2][0]= Vel[0]*Vel[2];
640 LorBoost[2][1]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
641 LorBoost[2][2]= (Vel[0] - 1.)*Vel[2]*Vel[2]/vsquare + 1.;
642 LorBoost[2][3]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
643 LorBoost[3][0]= Vel[0]*Vel[3];
644 LorBoost[3][1]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
645 LorBoost[3][2]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
646 LorBoost[3][3]= (Vel[0] - 1.)*Vel[3]*Vel[3]/vsquare + 1.;
660 CMSigma[0] = (LorBoost[0][0]*LFSigma[0] + LorBoost[0][1]*LFSigma[1] + LorBoost[0][2]*LFSigma[2] + LorBoost[0][3]*LFSigma[3]);
661 CMSigma[1] = (LorBoost[1][0]*LFSigma[0] + LorBoost[1][1]*LFSigma[1] + LorBoost[1][2]*LFSigma[2] + LorBoost[1][3]*LFSigma[3]);
662 CMSigma[2] = (LorBoost[2][0]*LFSigma[0] + LorBoost[2][1]*LFSigma[1] + LorBoost[2][2]*LFSigma[2] + LorBoost[2][3]*LFSigma[3]);
663 CMSigma[3] = (LorBoost[3][0]*LFSigma[0] + LorBoost[3][1]*LFSigma[1] + LorBoost[3][2]*LFSigma[2] + LorBoost[3][3]*LFSigma[3]);
669 for (
int l = 0; l < GPoints; l++) {
670 for (
int m = 0;
m < GPoints;
m++) {
671 for (
int k = 0;
k < GPoints;
k++) {
672 GWeightProd = GWeight[l] * GWeight[
m] * GWeight[
k];
673 pSpatialdSigma = (cut * GAbs[l]) * CMSigma[1] + (cut * GAbs[
m]) * CMSigma[2] + (cut * GAbs[
k]) * CMSigma[3];
676 E_light = computeEnergy(xmq, cut, GAbs[l], GAbs[m], GAbs[
k]);
677 NumLight += GWeightProd * FermiDistribution(E_light, TRead) *
678 (E_light * CMSigma[0] + pSpatialdSigma) / E_light;
681 E_strange = computeEnergy(xms, cut, GAbs[l], GAbs[m], GAbs[k]);
682 NumStrange += GWeightProd * FermiDistribution(E_strange, TRead) *
683 (E_strange * CMSigma[0] + pSpatialdSigma) / E_strange;
690 double NumHere = NumLight*UDDeg*cut*cut*cut/(8.*PI*PI*PI);
691 std::poisson_distribution<int> poisson_ud(NumHere);
694 GeneratedParticles = poisson_ud(getRandomGenerator());
697 for(
int partic = 0; partic < GeneratedParticles; partic++){
699 std::vector<double> temp = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
700 Plist.push_back(temp);
703 double SpecRoll =
ran();
704 if (SpecRoll <= 0.25) {
705 Plist[PartCount][1] = -2;
706 }
else if (SpecRoll <= 0.50) {
707 Plist[PartCount][1] = -1;
708 }
else if (SpecRoll <= 0.75) {
709 Plist[PartCount][1] = 1;
711 Plist[PartCount][1] = 2;
716 Plist[PartCount][10] = CPos[0] + (
ran() - 0.5)*CellDT;
717 Plist[PartCount][7] = CPos[1] + (
ran() - 0.5)*CellDX;
718 Plist[PartCount][8] = CPos[2] + (
ran() - 0.5)*CellDY;
719 Plist[PartCount][9] = CPos[3] + (
ran() - 0.5)*CellDZ;
728 new_quark_energy = sqrt(xmq*xmq + NewP*NewP);
729 Plist[PartCount][6] = (LorBoost[0][0]*new_quark_energy + LorBoost[0][1]*NewX + LorBoost[0][2]*NewY + LorBoost[0][3]*NewZ)*GEVFM;
730 Plist[PartCount][3] = (LorBoost[1][0]*new_quark_energy + LorBoost[1][1]*NewX + LorBoost[1][2]*NewY + LorBoost[1][3]*NewZ)*GEVFM;
731 Plist[PartCount][4] = (LorBoost[2][0]*new_quark_energy + LorBoost[2][1]*NewX + LorBoost[2][2]*NewY + LorBoost[2][3]*NewZ)*GEVFM;
732 Plist[PartCount][5] = (LorBoost[3][0]*new_quark_energy + LorBoost[3][1]*NewX + LorBoost[3][2]*NewY + LorBoost[3][3]*NewZ)*GEVFM;
735 Plist[PartCount][0] = 1;
736 Plist[PartCount][2] = 0;
737 Plist[PartCount][11] = 0;
743 double NumOddHere = NumStrange*OddDeg*cut*cut*cut/(8.*PI*PI*PI);
744 std::poisson_distribution<int> poisson_s(NumOddHere);
747 int nL = GeneratedParticles;
750 GeneratedParticles = poisson_s(getRandomGenerator());
752 int nS = GeneratedParticles;
755 for(
int partic = 0; partic < GeneratedParticles; partic++){
757 std::vector<double> temp = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
758 Plist.push_back(temp);
761 double SpecRoll =
ran();
763 Plist[PartCount][1] = -3;
765 Plist[PartCount][1] = 3;
770 Plist[PartCount][10] = CPos[0] + (
ran() - 0.5)*CellDT;
771 Plist[PartCount][7] = CPos[1] + (
ran() - 0.5)*CellDX;
772 Plist[PartCount][8] = CPos[2] + (
ran() - 0.5)*CellDY;
773 Plist[PartCount][9] = CPos[3] + (
ran() - 0.5)*CellDZ;
782 new_quark_energy = sqrt(xms*xms + NewP*NewP);
783 Plist[PartCount][6] = (LorBoost[0][0]*new_quark_energy + LorBoost[0][1]*NewX + LorBoost[0][2]*NewY + LorBoost[0][3]*NewZ)*GEVFM;
784 Plist[PartCount][3] = (LorBoost[1][0]*new_quark_energy + LorBoost[1][1]*NewX + LorBoost[1][2]*NewY + LorBoost[1][3]*NewZ)*GEVFM;
785 Plist[PartCount][4] = (LorBoost[2][0]*new_quark_energy + LorBoost[2][1]*NewX + LorBoost[2][2]*NewY + LorBoost[2][3]*NewZ)*GEVFM;
786 Plist[PartCount][5] = (LorBoost[3][0]*new_quark_energy + LorBoost[3][1]*NewX + LorBoost[3][2]*NewY + LorBoost[3][3]*NewZ)*GEVFM;
789 Plist[PartCount][0] = 1;
790 Plist[PartCount][2] = 0;
791 Plist[PartCount][11] = 0;
796 JSDEBUG <<
"Light particles: " << nL_tot;
797 JSDEBUG <<
"Strange particles: " << nS_tot;
805 std::shuffle(&Plist[0], &Plist[PartCount], getRandomGenerator());
839 double UDDeg = 4.*6.;
840 double OddDeg = 2.*6.;
843 double LorBoost[4][4];
844 int GeneratedParticles;
851 double pSpatialdSigma;
855 GeneratedParticles = 0;
856 double new_quark_energy;
863 const double accuracyRange = 0.003 / GEVFM;
865 std::unordered_map<double, std::vector<std::vector<double>>> cdfLightCache;
866 std::unordered_map<double, std::vector<std::vector<double>>> cdfStrangeCache;
869 auto withinAccuracyRange = [accuracyRange](
double targetTemp,
double cachedTemp) {
870 return std::fabs(targetTemp - cachedTemp) <= accuracyRange;
874 auto getClosestCachedTemp = [](
const std::unordered_map<double, std::vector<std::vector<double>>>& cache,
double targetTemp) {
875 double closestTemp = -1.0;
876 double minDistance = std::numeric_limits<double>::max();
877 for (
const auto&
entry : cache) {
878 double cachedTemp =
entry.first;
879 double distance = std::fabs(targetTemp - cachedTemp);
880 if (distance < minDistance) {
882 closestTemp = cachedTemp;
889 auto computeEnergy = [](
double mass,
double cut,
double GAbsL,
double GAbsM,
double GAbsK) {
890 return sqrt(mass * mass + (cut * GAbsL) * (cut * GAbsL) + (cut * GAbsM) * (cut * GAbsM) + (cut * GAbsK) * (cut * GAbsK));
894 auto FermiDistribution = [](
double energy,
double temperature) {
895 return 1. / (exp(energy / temperature) + 1.);
898 std::vector<double> NumLightList;
899 std::vector<double> NumStrangeList;
901 double d_eta = CellDZ;
903 int N_slices = std::floor((eta_max / d_eta)-0.5)+1;
904 for(
int slice=1; slice <= (2*N_slices+1); slice++){
905 double eta_slice = (slice-N_slices-1)*d_eta;
907 JSINFO <<
"Sampling thermal partons for pseudorapidity slice " << slice
908 <<
" (eta_min = " << eta_slice-(d_eta/2.) <<
", eta_max = "
909 << eta_slice+(d_eta/2.) <<
")";
911 for(
int iS=0; iS<
surface.size(); ++iS){
921 TRead =
surface[iS][8] / GEVFM;
929 auto cdfLightIter = cdfLightCache.find(TRead);
930 if (cdfLightIter == cdfLightCache.end()) {
932 double closestTemp = getClosestCachedTemp(cdfLightCache,TRead);
934 if (closestTemp >= 0. && withinAccuracyRange(TRead, closestTemp)) {
936 CDFTabLight = cdfLightCache[closestTemp];
941 CDFGenerator(TRead, xmq, 1);
942 cdfLightCache[TRead] = CDFTabLight;
946 CDFTabLight = cdfLightIter->second;
950 auto cdfStrangeIter = cdfStrangeCache.find(TRead);
951 if (cdfStrangeIter == cdfStrangeCache.end()) {
953 double closestTemp = getClosestCachedTemp(cdfStrangeCache,TRead);
955 if (closestTemp >= 0 && withinAccuracyRange(TRead, closestTemp)) {
957 CDFTabStrange = cdfStrangeCache[closestTemp];
962 CDFGenerator(TRead, xms, 2);
963 cdfStrangeCache[TRead] = CDFTabStrange;
967 CDFTabStrange = cdfStrangeIter->second;
971 CPos[0] = tau_pos*std::cosh(eta_pos);
972 CPos[3] = tau_pos*std::sinh(eta_pos);
974 double cosh_eta_pos = std::cosh(eta_pos);
975 double sinh_eta_pos = std::sinh(eta_pos);
976 LFSigma[0] = cosh_eta_pos*tau_sur - (sinh_eta_pos / tau_pos) * eta_sur;
977 LFSigma[3] = -sinh_eta_pos*tau_sur + (cosh_eta_pos / tau_pos) * eta_sur;
979 CellDZ = CPos[0] * 2. * std::sinh(d_eta/2.);
981 double vsquare = Vel[1]*Vel[1] + Vel[2]*Vel[2] + Vel[3]*Vel[3];
982 if(vsquare < 10
e-16){
987 Vel[0] = 1. / sqrt(1-vsquare);
990 LorBoost[0][0]= Vel[0];
991 LorBoost[0][1]= Vel[0]*Vel[1];
992 LorBoost[0][2]= Vel[0]*Vel[2];
993 LorBoost[0][3]= Vel[0]*Vel[3];
994 LorBoost[1][0]= Vel[0]*Vel[1];
995 LorBoost[1][1]= (Vel[0] - 1.)*Vel[1]*Vel[1]/vsquare + 1.;
996 LorBoost[1][2]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
997 LorBoost[1][3]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
998 LorBoost[2][0]= Vel[0]*Vel[2];
999 LorBoost[2][1]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
1000 LorBoost[2][2]= (Vel[0] - 1.)*Vel[2]*Vel[2]/vsquare + 1.;
1001 LorBoost[2][3]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
1002 LorBoost[3][0]= Vel[0]*Vel[3];
1003 LorBoost[3][1]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
1004 LorBoost[3][2]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
1005 LorBoost[3][3]= (Vel[0] - 1.)*Vel[3]*Vel[3]/vsquare + 1.;
1023 CMSigma[0] = (LorBoost[0][0]*LFSigma[0] + LorBoost[0][1]*LFSigma[1] + LorBoost[0][2]*LFSigma[2] + LorBoost[0][3]*LFSigma[3]);
1024 CMSigma[1] = (LorBoost[1][0]*LFSigma[0] + LorBoost[1][1]*LFSigma[1] + LorBoost[1][2]*LFSigma[2] + LorBoost[1][3]*LFSigma[3]);
1025 CMSigma[2] = (LorBoost[2][0]*LFSigma[0] + LorBoost[2][1]*LFSigma[1] + LorBoost[2][2]*LFSigma[2] + LorBoost[2][3]*LFSigma[3]);
1026 CMSigma[3] = (LorBoost[3][0]*LFSigma[0] + LorBoost[3][1]*LFSigma[1] + LorBoost[3][2]*LFSigma[2] + LorBoost[3][3]*LFSigma[3]);
1032 for (
int l = 0; l < GPoints; l++) {
1033 for (
int m = 0;
m < GPoints;
m++) {
1034 for (
int k = 0;
k < GPoints;
k++) {
1035 GWeightProd = GWeight[l] * GWeight[
m] * GWeight[
k];
1036 pSpatialdSigma = (cut * GAbs[l]) * CMSigma[1] + (cut * GAbs[
m]) * CMSigma[2] + (cut * GAbs[
k]) * CMSigma[3];
1039 E_light = computeEnergy(xmq, cut, GAbs[l], GAbs[m], GAbs[
k]);
1040 NumLight += GWeightProd * FermiDistribution(E_light, TRead) *
1041 (E_light * CMSigma[0] + pSpatialdSigma) / E_light;
1044 E_strange = computeEnergy(xms, cut, GAbs[l], GAbs[m], GAbs[k]);
1045 NumStrange += GWeightProd * FermiDistribution(E_strange, TRead) *
1046 (E_strange * CMSigma[0] + pSpatialdSigma) / E_strange;
1052 NumHere = NumLight*UDDeg*cut*cut*cut/(8.*PI*PI*PI);
1056 NumOddHere = NumStrange*OddDeg*cut*cut*cut/(8.*PI*PI*PI);
1058 NumLightList.push_back(NumHere);
1059 NumStrangeList.push_back(NumOddHere);
1061 NumHere = NumLightList[iS];
1062 NumOddHere = NumStrangeList[iS];
1065 std::poisson_distribution<int> poisson_ud(NumHere);
1068 GeneratedParticles = poisson_ud(getRandomGenerator());
1071 for(
int partic = 0; partic < GeneratedParticles; partic++){
1073 std::vector<double> temp = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
1074 Plist.push_back(temp);
1077 double SpecRoll =
ran();
1078 if (SpecRoll <= 0.25) {
1079 Plist[PartCount][1] = -2;
1080 }
else if (SpecRoll <= 0.50) {
1081 Plist[PartCount][1] = -1;
1082 }
else if (SpecRoll <= 0.75) {
1083 Plist[PartCount][1] = 1;
1085 Plist[PartCount][1] = 2;
1090 Plist[PartCount][10] = CPos[0] + (
ran() - 0.5)*CellDT;
1091 Plist[PartCount][7] = CPos[1] + (
ran() - 0.5)*CellDX;
1092 Plist[PartCount][8] = CPos[2] + (
ran() - 0.5)*CellDY;
1093 Plist[PartCount][9] = CPos[3] + (
ran() - 0.5)*CellDZ;
1095 if(std::abs(Plist[PartCount][9]) >= std::abs(Plist[PartCount][10])) {
1096 Plist[PartCount][10] = std::abs(Plist[PartCount][9]) + 10
e-3;
1098 double temp_t = std::sqrt(Plist[PartCount][10]*Plist[PartCount][10]-Plist[PartCount][9]*Plist[PartCount][9])
1099 * std::cosh(eta_slice+0.5*std::log((Plist[PartCount][10]+Plist[PartCount][9])/(Plist[PartCount][10]-Plist[PartCount][9])));
1100 double temp_z = std::sqrt(Plist[PartCount][10]*Plist[PartCount][10]-Plist[PartCount][9]*Plist[PartCount][9])
1101 * std::sinh(eta_slice+0.5*std::log((Plist[PartCount][10]+Plist[PartCount][9])/(Plist[PartCount][10]-Plist[PartCount][9])));
1102 Plist[PartCount][10] = temp_t;
1103 Plist[PartCount][9] = temp_z;
1107 MCSampler(TRead, 1);
1109 Vel[3] = tanh(eta_slice);
1110 double vsquare = Vel[1]*Vel[1] + Vel[2]*Vel[2] + Vel[3]*Vel[3];
1111 if(vsquare < 10
e-16){
1116 Vel[0] = 1. / sqrt(1-vsquare);
1119 LorBoost[0][0]= Vel[0];
1120 LorBoost[0][1]= Vel[0]*Vel[1];
1121 LorBoost[0][2]= Vel[0]*Vel[2];
1122 LorBoost[0][3]= Vel[0]*Vel[3];
1123 LorBoost[1][0]= Vel[0]*Vel[1];
1124 LorBoost[1][1]= (Vel[0] - 1.)*Vel[1]*Vel[1]/vsquare + 1.;
1125 LorBoost[1][2]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
1126 LorBoost[1][3]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
1127 LorBoost[2][0]= Vel[0]*Vel[2];
1128 LorBoost[2][1]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
1129 LorBoost[2][2]= (Vel[0] - 1.)*Vel[2]*Vel[2]/vsquare + 1.;
1130 LorBoost[2][3]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
1131 LorBoost[3][0]= Vel[0]*Vel[3];
1132 LorBoost[3][1]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
1133 LorBoost[3][2]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
1134 LorBoost[3][3]= (Vel[0] - 1.)*Vel[3]*Vel[3]/vsquare + 1.;
1151 new_quark_energy = sqrt(xmq*xmq + NewP*NewP);
1152 Plist[PartCount][6] = (LorBoost[0][0]*new_quark_energy + LorBoost[0][1]*NewX + LorBoost[0][2]*NewY + LorBoost[0][3]*NewZ)*GEVFM;
1153 Plist[PartCount][3] = (LorBoost[1][0]*new_quark_energy + LorBoost[1][1]*NewX + LorBoost[1][2]*NewY + LorBoost[1][3]*NewZ)*GEVFM;
1154 Plist[PartCount][4] = (LorBoost[2][0]*new_quark_energy + LorBoost[2][1]*NewX + LorBoost[2][2]*NewY + LorBoost[2][3]*NewZ)*GEVFM;
1155 Plist[PartCount][5] = (LorBoost[3][0]*new_quark_energy + LorBoost[3][1]*NewX + LorBoost[3][2]*NewY + LorBoost[3][3]*NewZ)*GEVFM;
1158 Plist[PartCount][0] = 1;
1159 Plist[PartCount][2] = 0;
1160 Plist[PartCount][11] = 0;
1164 std::poisson_distribution<int> poisson_s(NumOddHere);
1167 int nL = GeneratedParticles;
1170 GeneratedParticles = poisson_s(getRandomGenerator());
1172 int nS = GeneratedParticles;
1175 for(
int partic = 0; partic < GeneratedParticles; partic++){
1177 std::vector<double> temp = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
1178 Plist.push_back(temp);
1181 double SpecRoll =
ran();
1182 if(SpecRoll <= 0.5){
1183 Plist[PartCount][1] = -3;
1185 Plist[PartCount][1] = 3;
1190 Plist[PartCount][10] = CPos[0] + (
ran() - 0.5)*CellDT;
1191 Plist[PartCount][7] = CPos[1] + (
ran() - 0.5)*CellDX;
1192 Plist[PartCount][8] = CPos[2] + (
ran() - 0.5)*CellDY;
1193 Plist[PartCount][9] = CPos[3] + (
ran() - 0.5)*CellDZ;
1195 if(std::abs(Plist[PartCount][9]) >= std::abs(Plist[PartCount][10])) {
1196 Plist[PartCount][10] = std::abs(Plist[PartCount][9]) + 10
e-3;
1198 double temp_t = std::sqrt(Plist[PartCount][10]*Plist[PartCount][10]-Plist[PartCount][9]*Plist[PartCount][9])
1199 * std::cosh(eta_slice+0.5*std::log((Plist[PartCount][10]+Plist[PartCount][9])/(Plist[PartCount][10]-Plist[PartCount][9])));
1200 double temp_z = std::sqrt(Plist[PartCount][10]*Plist[PartCount][10]-Plist[PartCount][9]*Plist[PartCount][9])
1201 * std::sinh(eta_slice+0.5*std::log((Plist[PartCount][10]+Plist[PartCount][9])/(Plist[PartCount][10]-Plist[PartCount][9])));
1202 Plist[PartCount][10] = temp_t;
1203 Plist[PartCount][9] = temp_z;
1207 MCSampler(TRead, 2);
1209 Vel[3] = tanh(eta_slice);
1210 double vsquare = Vel[1]*Vel[1] + Vel[2]*Vel[2] + Vel[3]*Vel[3];
1211 if(vsquare < 10
e-16){
1216 Vel[0] = 1. / sqrt(1-vsquare);
1219 LorBoost[0][0]= Vel[0];
1220 LorBoost[0][1]= Vel[0]*Vel[1];
1221 LorBoost[0][2]= Vel[0]*Vel[2];
1222 LorBoost[0][3]= Vel[0]*Vel[3];
1223 LorBoost[1][0]= Vel[0]*Vel[1];
1224 LorBoost[1][1]= (Vel[0] - 1.)*Vel[1]*Vel[1]/vsquare + 1.;
1225 LorBoost[1][2]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
1226 LorBoost[1][3]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
1227 LorBoost[2][0]= Vel[0]*Vel[2];
1228 LorBoost[2][1]= (Vel[0] - 1.)*Vel[1]*Vel[2]/vsquare;
1229 LorBoost[2][2]= (Vel[0] - 1.)*Vel[2]*Vel[2]/vsquare + 1.;
1230 LorBoost[2][3]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
1231 LorBoost[3][0]= Vel[0]*Vel[3];
1232 LorBoost[3][1]= (Vel[0] - 1.)*Vel[1]*Vel[3]/vsquare;
1233 LorBoost[3][2]= (Vel[0] - 1.)*Vel[2]*Vel[3]/vsquare;
1234 LorBoost[3][3]= (Vel[0] - 1.)*Vel[3]*Vel[3]/vsquare + 1.;
1251 new_quark_energy = sqrt(xms*xms + NewP*NewP);
1252 Plist[PartCount][6] = (LorBoost[0][0]*new_quark_energy + LorBoost[0][1]*NewX + LorBoost[0][2]*NewY + LorBoost[0][3]*NewZ)*GEVFM;
1253 Plist[PartCount][3] = (LorBoost[1][0]*new_quark_energy + LorBoost[1][1]*NewX + LorBoost[1][2]*NewY + LorBoost[1][3]*NewZ)*GEVFM;
1254 Plist[PartCount][4] = (LorBoost[2][0]*new_quark_energy + LorBoost[2][1]*NewX + LorBoost[2][2]*NewY + LorBoost[2][3]*NewZ)*GEVFM;
1255 Plist[PartCount][5] = (LorBoost[3][0]*new_quark_energy + LorBoost[3][1]*NewX + LorBoost[3][2]*NewY + LorBoost[3][3]*NewZ)*GEVFM;
1258 Plist[PartCount][0] = 1;
1259 Plist[PartCount][2] = 0;
1260 Plist[PartCount][11] = 0;
1267 JSDEBUG <<
"Light particles: " << nL_tot;
1268 JSDEBUG <<
"Strange particles: " << nS_tot;
1276 std::shuffle(&Plist[0], &Plist[PartCount], getRandomGenerator());