double Propagation::ExtractPhotonEnergyMC(double z, Process &proc) const { double esoft = 0; //double snew = 0; double emin = proc.GetMin(); Particle pi = proc.GetIncidentParticle(); Particle pb = proc.GetTargetParticle(); double Epi = pi.GetEnergy(); double m = pi.GetMass(); esoft = ShootPhotonEnergyMC(emin / (4.0 * Epi), z); //snew = 4 * Epi * esoft + m * m; pb.SetEnergy(esoft); proc.SetTargetParticle(pb); proc.SetCMEnergy(); return esoft; }
void Propagation::Propagate(Particle &curr_particle, std::vector<Particle> &ParticleAtMatrix, std::vector<Particle> &ParticleAtGround, bool dropParticlesBelowEnergyThreshold ) const { double theta_deflBF = 0.0; double BNorm = magneticFieldStrength; double zin = curr_particle.Getz(); double Ein = curr_particle.GetEnergy(); int type = curr_particle.GetType(); int wi_last = curr_particle.GetWeigth(); double z_curr = zin; double Ecurr = Ein; bool interacted = 0; double min_dist = 1e12; double walkdone = 0; double E1 = 0; double E2 = 0; double E3 = 0; double stepsize = 0; double Elast = 0; double R = Uniform(0.0, 1.0); double R2 = Uniform(0.0, 1.0); Process proc; proc.SetIncidentParticle(curr_particle); proc.SetBackground(Bkg); double Ethr2 = std::max(fEthr, std::max(ElectronMass,ElectronMass*ElectronMass/proc.feps_sup)); if (Ecurr < Ethr2) { if (!dropParticlesBelowEnergyThreshold) ParticleAtGround.push_back(curr_particle); return; } std::vector<double> EtargetAll = GetEtarget(proc, curr_particle); min_dist = ExtractMinDist(proc, curr_particle.GetType(), R, R2, EtargetAll); interacted = 0; double dz = 0; double zpos = zin; double corrB_factor = 0; double realpath = 0; double min_dist_last = min_dist; while (!interacted) { proc.SetInteractionAngle(cPI); theta_deflBF = 0; realpath = 0.1 * min_dist; theta_deflBF = GetMeanThetaBFDeflection(BNorm, curr_particle.GetEnergy(), curr_particle.GetType(), min_dist); corrB_factor = cos(theta_deflBF); stepsize = realpath * corrB_factor; dz = Mpc2z(stepsize); if ((walkdone + realpath) > min_dist) { interacted = 1; } if (zpos - dz <= 0) { dz = zpos; stepsize = z2Mpc(dz); realpath = stepsize / corrB_factor; } zpos -= dz; walkdone += realpath; Elast = Ecurr; if (type == 0 || type == 22) Ecurr = EnergyLoss1D(Ecurr, zpos + Mpc2z(realpath), zpos, 0); else Ecurr = EnergyLoss1D(Ecurr, zpos + Mpc2z(realpath), zpos, BNorm); z_curr = zpos; curr_particle.Setz(z_curr); curr_particle.SetEnergy(Ecurr); if (z_curr <= 0) { ParticleAtGround.push_back(curr_particle); return; } if (Ecurr <= Ethr2) { if (!dropParticlesBelowEnergyThreshold) { ParticleAtGround.push_back(curr_particle); } return; } proc.SetIncidentParticle(curr_particle); proc.SetCMEnergy(); proc.SetLimits(); // std::vector<double> EtargetAll=GetEtarget(proc,curr_particle); min_dist = ExtractMinDist(proc, curr_particle.GetType(), R, R2, EtargetAll); } //end while if (interacted == 1) { if (proc.GetName() == Process::PP) { E1 = ExtractPPSecondariesEnergy(proc); if (E1 == 0 || E1 == Ecurr) std::cerr << "ERROR in PP process: E : " << Ecurr << " " << E1 << " " << std::endl; Particle pp(11, E1, z_curr,curr_particle.Generation()+1); pp.SetWeigth(wi_last); ParticleAtMatrix.push_back(pp); Particle pe(-11, Ecurr - E1, z_curr,curr_particle.Generation()+1); pe.SetWeigth(wi_last); ParticleAtMatrix.push_back(pe); return; } //if PP else if (proc.GetName() == Process::DPP) { E1 = (Ecurr - 2 * ElectronMass) / 2.0; if (E1 == 0) std::cerr << "ERROR in DPP process E : " << E1 << std::endl; Particle pp(11, E1, z_curr,curr_particle.Generation()+1); pp.SetWeigth(wi_last); ParticleAtMatrix.push_back(pp); Particle pe(-11, E1, z_curr,curr_particle.Generation()+1); pe.SetWeigth(wi_last); ParticleAtMatrix.push_back(pe); return; } //end if DPP else if (proc.GetName() == Process::ICS) { E1 = ExtractICSSecondariesEnergy(proc); E2 = Ecurr - E1; if (E1 == 0 || E2 == 0) std::cerr << "ERROR in ICS process E : " << E1 << " " << E2 << std::endl; Particle pp(curr_particle.GetType(), E1, z_curr,curr_particle.Generation()+1); pp.SetWeigth(wi_last); ParticleAtMatrix.push_back(pp); Particle pg(22, E2, z_curr,curr_particle.Generation()+1); pg.SetWeigth(wi_last); ParticleAtMatrix.push_back(pg); return; } //end if ics else if (proc.GetName() == Process::TPP) { E1 = E2 = ExtractTPPSecondariesEnergy(proc); E3 = Ecurr - E1 - E2; if (E1 == 0 || E2 == 0 || E3 == 0) std::cerr << "ERROR in TPP process E : " << E1 << " " << E2 << std::endl; Particle pp(11, E1, z_curr,curr_particle.Generation()+1); pp.SetWeigth(wi_last); ParticleAtMatrix.push_back(pp); Particle pe(-11, E1, z_curr,curr_particle.Generation()+1); pe.SetWeigth(wi_last); ParticleAtMatrix.push_back(pe); Particle psc(curr_particle.GetType(), E3, z_curr,curr_particle.Generation()+1); psc.SetWeigth(wi_last); ParticleAtMatrix.push_back(psc); return; } } return; }
double Propagation::ExtractMinDist(Process &proc, int type, double R, double R2, std::vector<double> &Etarget) const { double min_dist1 = 0; double min_dist2 = 0; Process proc1(proc); Process proc2(proc); double tmp_lambda1 = 0; double tmp_lambda2 = 0; Particle pt; pt.SetType(0); pt.Setz(proc.GetIncidentParticle().Getz()); if (type == 22) { if (Etarget[0]) { proc1.SetName(Process::PP); pt.SetEnergy(Etarget[0]); proc1.SetTargetParticle(pt); proc1.SetCMEnergy(); tmp_lambda1 = GetLambdaTab(proc1, Process::PP); min_dist1 = -tmp_lambda1 * log(R); } if (Etarget[1]) { pt.SetEnergy(Etarget[1]); proc2.SetTargetParticle(pt); proc2.SetCMEnergy(); tmp_lambda2 = GetLambdaTab(proc2, Process::DPP); min_dist2 = -tmp_lambda2 * log(R2); } #ifdef DEBUG_ELECA std::cerr << "comparing 2 mindists: " << min_dist1 << "(" << tmp_lambda1 << ") vs " << min_dist2 << " ( " << tmp_lambda2 << ") " << std::endl; #endif if (min_dist2 < min_dist1) { min_dist1 = min_dist2; proc.SetName(Process::DPP); pt.SetEnergy(Etarget[1]); proc.SetTargetParticle(pt); proc.SetCMEnergy(); } else { proc.SetName(Process::PP); pt.SetEnergy(Etarget[0]); proc.SetTargetParticle(pt); proc.SetCMEnergy(); } } //end if type 0 else if (abs(type) == 11) { proc1.SetName(Process::ICS); pt.SetEnergy(Etarget[0]); proc1.SetTargetParticle(pt); tmp_lambda1 = GetLambdaTab(proc1, Process::ICS); min_dist1 = -tmp_lambda1 * log(R); proc2.SetName(Process::TPP); pt.SetEnergy(Etarget[1]); proc2.SetTargetParticle(pt); tmp_lambda2 = GetLambdaTab(proc2, Process::TPP); min_dist2 = -tmp_lambda2 * log(R2); #ifdef DEBUG_ELECA std::cerr << "comparing 2 mindists: " << min_dist1 << "(" << tmp_lambda1 << ") vs " << min_dist2 << " ( " << tmp_lambda2 << ") " << std::endl; #endif if (min_dist2 < min_dist1) { min_dist1 = min_dist2; proc.SetName(Process::TPP); pt.SetEnergy(Etarget[1]); proc.SetTargetParticle(pt); proc.SetCMEnergy(); } else { proc.SetName(Process::ICS); pt.SetEnergy(Etarget[0]); proc.SetTargetParticle(pt); proc.SetCMEnergy(); } } //else e+/e- else std::cerr << "something wrong in particle type ( " << type << ". Propagation of photons and e+/e- is the only allowed.)" << std::endl; return min_dist1; }