97static const G4int nzdat = 5;
98static const G4int zdat[5] = {1, 4, 13, 29, 92};
101{ 0.0198550717512320, 0.1016667612931865, 0.2372337950418355, 0.4082826787521750,
102 0.5917173212478250, 0.7627662049581645, 0.8983332387068135, 0.9801449282487680 };
105{ 0.0506142681451880, 0.1111905172266870, 0.1568533229389435, 0.1813418916891810,
106 0.1813418916891810, 0.1568533229389435, 0.1111905172266870, 0.0506142681451880 };
116 factorForCross(4.*fine_structure_const*fine_structure_const
117 *classic_electr_radius*classic_electr_radius/(3.*pi)),
118 sqrte(sqrt(
G4Exp(1.))),
120 fParticleChange(nullptr),
121 minPairEnergy(4.*electron_mass_c2),
122 lowestKinEnergy(1.0*GeV),
187 if(dataFile) { dataFile = RetrieveTables(); }
188 if(!dataFile) { MakeSamplingTables(); }
219 const G4double* theAtomicNumDensityVector =
224 G4double Z = (*theElementVector)[i]->GetZ();
227 dedx += loss*theAtomicNumDensityVector[i];
229 dedx = std::max(dedx, 0.0);
242 G4double cut = std::min(cutEnergy,tmax);
251 if (kkk > 8) { kkk = 8; }
252 else if (kkk < 1) { kkk = 1; }
257 for (
G4int l=0 ; l<kkk; ++l) {
258 for (
G4int ll=0; ll<8; ++ll)
266 loss = std::max(loss, 0.0);
280 if (tmax <= cut) {
return cross; }
287 if(kkk > 8) { kkk = 8; }
288 else if (kkk < 1) { kkk = 1; }
293 for(
G4int l=0; l<kkk; ++l)
295 for(
G4int i=0; i<8; ++i)
304 cross = std::max(cross, 0.0);
319 static const G4double bbbh = 202.4 ;
320 static const G4double g1tf = 1.95e-5 ;
321 static const G4double g2tf = 5.3e-5 ;
322 static const G4double g1h = 4.4e-5 ;
323 static const G4double g2h = 4.8e-5 ;
325 if (pairEnergy <= 4.0 * electron_mass_c2)
329 G4double residEnergy = totalEnergy - pairEnergy;
334 G4double a0 = 1.0 / (totalEnergy * residEnergy);
335 G4double alf = 4.0 * electron_mass_c2 / pairEnergy;
338 G4double tmnexp = alf/(1.0 + rt) + delta*rt;
340 if(tmnexp >= 1.0) {
return 0.0; }
345 G4double massratio2 = massratio*massratio;
346 G4double inv_massratio2 = 1.0 / massratio2;
350 if( Z < 1.5 ) { bbb = bbbh ; g1 = g1h ; g2 = g2h ; }
351 else { bbb = bbbtf; g1 = g1tf; g2 = g2tf; }
358 if (z1exp > 35.221047195922)
361 zeta = (0.073 *
G4Log(z1exp) - 0.26) / (0.058 *
G4Log(z2exp) - 0.14);
376 for (
G4int i = 0; i < 8; ++i)
378 rho[i] =
G4Exp(tmn*xgi[i]) - 1.0;
379 rho2[i] = rho[i] * rho[i];
380 xi[i] = xi0*(1.0-rho2[i]);
381 xi1[i] = 1.0 + xi[i];
382 xii[i] = 1.0 / xi[i];
391 for (
G4int i = 0; i < 8; ++i)
393 G4double yeu = (b40 + 5.0) + (b40 - 1.0) * rho2[i];
394 G4double yed = b62 *
G4Log(3.0 + xii[i]) + (2.0 * beta - 1.0) * rho2[i] - b40;
396 G4double ymu = b62 * (1.0 + rho2[i]) + 6.0;
397 G4double ymd = (b40 + 3.0) * (1.0 + rho2[i]) *
G4Log(3.0 + xi[i]) + 2.0 - 3.0 * rho2[i];
399 ye1[i] = 1.0 + yeu / yed;
400 ym1[i] = 1.0 + ymu / ymd;
406 for(
G4int i = 0; i < 8; ++i)
408 if(xi[i] <= 1000.0) {
409 be[i] = ((2.0 + rho2[i]) * (1.0 + beta) + xi[i] * (3.0 + rho2[i])) *
410 G4Log(1.0 + xii[i]) + (1.0 - rho2[i] - beta) / xi1[i] - (3.0 + rho2[i]);
412 be[i] = 0.5 * (3.0 - rho2[i] + 2.0 * beta * (1.0 + rho2[i])) * xii[i];
416 G4double a10 = (1.0 + 2.0 * beta) * (1.0 - rho2[i]);
417 bm[i] = ((1.0 + rho2[i]) * (1.0 + 1.5 * beta) - a10 * xii[i]) *
G4Log(xi1[i]) +
418 xi[i] * (1.0 - rho2[i] - beta) / xi1[i] + a10;
420 bm[i] = 0.5 * (5.0 - rho2[i] + beta * (3.0 + rho2[i])) * xi[i];
426 for (
G4int i = 0; i < 8; ++i)
428 G4double screen = screen0*xi1[i]/(1.0-rho2[i]) ;
437 fm *= (fm > 0.0) * inv_massratio2;
439 sum += wgi[i]*(1.0 + rho[i])*(
fe+fm);
442 return -tmn*sum*
factorForCross*z2*residEnergy/(totalEnergy*pairEnergy);
458 G4double tmax = std::min(maxEnergy, maxPairEnergy);
460 if (cut >= tmax) {
return cross; }
463 if(tmax < kineticEnergy) {
471void G4MuPairProductionModel::MakeSamplingTables()
475 for (
G4int iz=0; iz<nzdat; ++iz) {
481 for (
size_t it=0; it<=
nbine; ++it) {
494 size_t imax = (size_t)fac;
508 for (
size_t i=0; i<
nbiny; ++i) {
510 if(0 == it) { pv->
PutX(i, x); }
522 }
else if(i == imax) {
529 kinEnergy *= factore;
541 std::vector<G4DynamicParticle*>* vdp,
563 G4double maxEnergy = std::min(tmax, maxPairEnergy);
566 if(minEnergy >= maxEnergy) {
return; }
585 G4int iz1(0), iz2(0);
586 for(
G4int iz=0; iz<nzdat; ++iz) {
592 if(iz > 0) { iz1 = zdat[iz-1]; }
597 if(0 == iz1) { iz1 = iz2 = zdat[nzdat-1]; }
607 G4double x = FindScaledEnergy(iz1, rand, logTkin, yymin, yymax);
609 G4double x2 = FindScaledEnergy(iz2, rand, logTkin, yymin, yymax);
614 x += (x2 - x)*(
lnZ - lz1)/(lz2 - lz1);
617 pairEnergy = kinEnergy*
G4Exp(x*coeff);
620 }
while((pairEnergy < minEnergy || pairEnergy > maxEnergy) && 10 > count);
632 G4double eEnergy = (1.-r)*pairEnergy*0.5;
633 G4double pEnergy = pairEnergy - eEnergy;
640 eDirection, pDirection);
642 eEnergy = std::max(eEnergy - CLHEP::electron_mass_c2, 0.0);
643 pEnergy = std::max(pEnergy - CLHEP::electron_mass_c2, 0.0);
649 vdp->push_back(aParticle1);
650 vdp->push_back(aParticle2);
653 kinEnergy -= pairEnergy;
654 partDirection *= totalMomentum;
656 partDirection = partDirection.
unit();
665 vdp->push_back(newdp);
675void G4MuPairProductionModel::DataCorrupted(
G4int Z,
G4double logTkin)
const
678 ed <<
"G4ElementData is not properly initialized Z= " << Z
679 <<
" Ekin(MeV)= " <<
G4Exp(logTkin)
680 <<
" IsMasterThread= " <<
IsMaster()
688void G4MuPairProductionModel::StoreTables()
const
690 for (
G4int iz=0; iz<nzdat; ++iz) {
694 DataCorrupted(Z, 1.0);
697 std::ostringstream ss;
699 std::ofstream outfile(ss.str());
706G4bool G4MuPairProductionModel::RetrieveTables()
708 char* path = std::getenv(
"G4LEDATA");
711 std::ostringstream ost;
712 ost << path <<
"/mupair/";
718 for (
G4int iz=0; iz<nzdat; ++iz) {
721 std::ostringstream ss;
723 std::ifstream infile(ss.str(), std::ios::in);
std::vector< G4Element * > G4ElementVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4ThreeVector GetMomentum() const
static G4Electron * Electron()
void InitialiseForElement(G4int Z, G4PhysicsVector *v)
G4Physics2DVector * GetElement2DData(G4int Z)
static G4EmParameters * Instance()
G4bool RetrieveMuDataFromFile() const
const G4ElementVector * GetElementVector() const
size_t GetNumberOfElements() const
const G4double * GetAtomicNumDensityVector() const
G4double ComputeMicroscopicCrossSection(G4double tkin, G4double Z, G4double cut)
void SetParticle(const G4ParticleDefinition *)
G4ParticleDefinition * thePositron
G4double ComputMuPairLoss(G4double Z, G4double tkin, G4double cut, G4double tmax)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kineticEnergy, G4double Z, G4double A, G4double cutEnergy, G4double maxEnergy) override
G4MuPairProductionModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="muPairProd")
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
virtual G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy) override
virtual void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
virtual G4double ComputeDMicroscopicCrossSection(G4double tkin, G4double Z, G4double pairEnergy)
const G4ParticleDefinition * particle
virtual G4double MinPrimaryEnergy(const G4Material *, const G4ParticleDefinition *, G4double) override
G4ParticleChangeForLoss * fParticleChange
G4double MaxSecondaryEnergyForElement(G4double kineticEnergy, G4double Z)
virtual ~G4MuPairProductionModel()
G4ParticleDefinition * theElectron
G4double GetLOGZ(G4int Z) const
static G4NistManager * Instance()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void SetProposedMomentumDirection(const G4ThreeVector &dir)
G4double GetPDGMass() const
const G4String & GetParticleName() const
G4bool Retrieve(std::ifstream &fIn)
void PutY(std::size_t idy, G4double value)
void Store(std::ofstream &fOut) const
void PutValue(std::size_t idx, std::size_t idy, G4double value)
void PutX(std::size_t idx, G4double value)
static G4Positron * Positron()
virtual void SamplePairDirections(const G4DynamicParticle *dp, G4double elecKinEnergy, G4double posiKinEnergy, G4ThreeVector &dirElectron, G4ThreeVector &dirPositron, G4int Z=0, const G4Material *mat=nullptr)
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
G4VEmAngularDistribution * GetAngularDistribution()
G4double LowEnergyLimit() const
std::vector< G4EmElementSelector * > * GetElementSelectors()
G4double HighEnergyLimit() const
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
G4ElementData * fElementData
void SetAngularDistribution(G4VEmAngularDistribution *)
const G4String & GetName() const
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
G4double SecondaryThreshold() const
G4ElementData * GetElementData()
G4ParticleChangeForLoss * GetParticleChangeForLoss()
void ProposeTrackStatus(G4TrackStatus status)