Import Geant4 9.6.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 17:01:34 +02:00
parent b1eb5424d2
commit e2d2f9810a
10384 changed files with 698580 additions and 628834 deletions
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4KleinNishinaModel.cc,v 1.5 2011-01-02 19:58:54 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -47,6 +46,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4KleinNishinaModel.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
#include "Randomize.hh"
@@ -62,7 +63,7 @@
using namespace std;
G4KleinNishinaModel::G4KleinNishinaModel(const G4String& nam)
: G4VEmModel(nam),isInitialized(false)
: G4VEmModel(nam)
{
theGamma = G4Gamma::Gamma();
theElectron = G4Electron::Electron();
@@ -86,10 +87,7 @@ void G4KleinNishinaModel::Initialise(const G4ParticleDefinition* p,
{
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
InitialiseElementSelectors(p, cuts);
if (isInitialized) { return; }
fParticleChange = GetParticleChangeForGamma();
isInitialized = true;
if(!fParticleChange) { fParticleChange = GetParticleChangeForGamma(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -100,8 +98,8 @@ G4KleinNishinaModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
G4double Z, G4double,
G4double, G4double)
{
G4double CrossSection = 0.0 ;
if ( Z < 0.9999 || GammaEnergy < 0.1*keV) { return CrossSection; }
G4double xSection = 0.0 ;
if ( Z < 0.9999 || GammaEnergy < 0.1*keV) { return xSection; }
static const G4double a = 20.0 , b = 230.0 , c = 440.0;
@@ -117,7 +115,7 @@ G4KleinNishinaModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
if (Z < 1.5) { T0 = 40.0*keV; }
G4double X = max(GammaEnergy, T0) / electron_mass_c2;
CrossSection = p1Z*std::log(1.+2.*X)/X
xSection = p1Z*std::log(1.+2.*X)/X
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
// modification for low energy. (special case for Hydrogen)
@@ -126,23 +124,17 @@ G4KleinNishinaModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
X = (T0+dT0) / electron_mass_c2 ;
G4double sigma = p1Z*log(1.+2*X)/X
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
G4double c1 = -T0*(sigma-CrossSection)/(CrossSection*dT0);
G4double c1 = -T0*(sigma-xSection)/(xSection*dT0);
G4double c2 = 0.150;
if (Z > 1.5) { c2 = 0.375-0.0556*log(Z); }
G4double y = log(GammaEnergy/T0);
CrossSection *= exp(-y*(c1+c2*y));
xSection *= exp(-y*(c1+c2*y));
}
G4int iz = G4int(Z);
G4int nShells = G4AtomicShells::GetNumberOfShells(iz);
//G4cout << "Z= " << Z << " Nshells=" << nShells << G4endl;
G4double bindingEnergy = G4AtomicShells::GetBindingEnergy(iz,nShells-1);
G4double eth = sqrt(bindingEnergy*(bindingEnergy + electron_mass_c2)) -
0.5*(sqrt(bindingEnergy*(bindingEnergy + 2*electron_mass_c2)) - bindingEnergy);
CrossSection *= (1.0 - eth/GammaEnergy);
if(CrossSection < 0.0) { CrossSection = 0.0; }
if(xSection < 0.0) { xSection = 0.0; }
// G4cout << "e= " << GammaEnergy << " Z= " << Z
// << " cross= " << CrossSection << G4endl;
return CrossSection;
// << " cross= " << xSection << G4endl;
return xSection;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -167,44 +159,32 @@ void G4KleinNishinaModel::SampleSecondaries(
G4double totprob = 0.0;
G4int i;
for(i=0; i<nShells; ++i) {
G4double bindingEnergy = elm->GetAtomicShell(i);
G4double eth = sqrt(bindingEnergy*(bindingEnergy + electron_mass_c2)) -
0.5*(sqrt(bindingEnergy*(bindingEnergy + 2*electron_mass_c2)) - bindingEnergy);
G4double prob = 1.0 - eth/energy;
if(prob > 0.0) { totprob += prob*elm->GetNbOfShellElectrons(i); }
//G4double bindingEnergy = elm->GetAtomicShell(i);
totprob += elm->GetNbOfShellElectrons(i);
//totprob += elm->GetNbOfShellElectrons(i)/(bindingEnergy*bindingEnergy);
fProbabilities[i] = totprob;
}
if(totprob == 0.0) { return; }
//if(totprob == 0.0) { return; }
// Loop on sampling
G4double eKinEnergy;
const G4int nlooplim = 100;
G4int nloop = 0;
// const G4int nlooplim = 100;
//G4int nloop = 0;
G4double bindingEnergy, ePotEnergy, eKinEnergy;
G4double gamEnergy0, gamEnergy1;
//static const G4double eminus2 = 1.0 - exp(-2.0);
do {
++nloop;
//++nloop;
G4double xprob = totprob*G4UniformRand();
// select shell
for(i=0; i<nShells; ++i) { if(xprob <= fProbabilities[i]) {break;} }
for(i=0; i<nShells; ++i) { if(xprob <= fProbabilities[i]) { break; } }
G4double bindingEnergy = elm->GetAtomicShell(i);
// shortcut if the loop is too long
if(nloop >= nlooplim) {
lv1.set(0.0,0.0,0.0,0.0);
eKinEnergy = energy - bindingEnergy;
if(eKinEnergy < 0.0) { eKinEnergy = 0.0; }
G4double eTotMomentum = sqrt(eKinEnergy*(eKinEnergy + 2*electron_mass_c2));
G4double phi = G4UniformRand()*twopi;
G4double costet = 2*G4UniformRand() - 1;
G4double sintet = sqrt((1 - costet)*(1 + costet));
lv2.set(eTotMomentum*sintet*cos(phi),eTotMomentum*sintet*sin(phi),
eTotMomentum*costet,eKinEnergy + electron_mass_c2);
break;
}
G4double limitEnergy = limitFactor*bindingEnergy;
G4double gamEnergy0 = energy;
bindingEnergy = elm->GetAtomicShell(i);
// ePotEnergy = bindingEnergy;
// gamEnergy0 = energy;
lv1.set(0.0,0.0,energy,energy);
//G4cout << "nShells= " << nShells << " i= " << i
@@ -212,24 +192,27 @@ void G4KleinNishinaModel::SampleSecondaries(
// << " Elim= " << limitEnergy
// << G4endl;
// for low energy rest frame of the electron
if(energy < limitEnergy) {
G4double eTotMomentum = sqrt(bindingEnergy*(bindingEnergy + 2*electron_mass_c2));
G4double phi = G4UniformRand()*twopi;
G4double costet = 2*G4UniformRand() - 1;
G4double sintet = sqrt((1 - costet)*(1 + costet));
lv2.set(eTotMomentum*sintet*cos(phi),eTotMomentum*sintet*sin(phi),
eTotMomentum*costet,bindingEnergy + electron_mass_c2);
bst = lv2.boostVector();
lv1.boost(-bst);
gamEnergy0 = lv1.e();
}
// for rest frame of the electron
G4double x = -log(G4UniformRand());
eKinEnergy = bindingEnergy*x;
ePotEnergy = bindingEnergy*(1.0 + x);
// for rest frame of the electron
G4double eTotMomentum = sqrt(eKinEnergy*(eKinEnergy + 2*electron_mass_c2));
G4double phi = G4UniformRand()*twopi;
G4double costet = 2*G4UniformRand() - 1;
G4double sintet = sqrt((1 - costet)*(1 + costet));
lv2.set(eTotMomentum*sintet*cos(phi),eTotMomentum*sintet*sin(phi),
eTotMomentum*costet,eKinEnergy + electron_mass_c2);
bst = lv2.boostVector();
lv1.boost(-bst);
gamEnergy0 = lv1.e();
// In the rest frame of the electron
// The scattered gamma energy is sampled according to Klein - Nishina formula.
// The scattered gamma energy is sampled according to Klein-Nishina formula
// The random number techniques of Butcher & Messel are used
// (Nuc Phys 20(1960),15).
// (Nuc Phys 20(1960),15).
G4double E0_m = gamEnergy0/electron_mass_c2;
//
@@ -238,9 +221,9 @@ void G4KleinNishinaModel::SampleSecondaries(
G4double epsilon, epsilonsq, onecost, sint2, greject ;
G4double epsilon0 = 1./(1 + 2*E0_m);
G4double epsilon0sq = epsilon0*epsilon0;
G4double alpha1 = - log(epsilon0);
G4double eps0 = 1./(1 + 2*E0_m);
G4double epsilon0sq = eps0*eps0;
G4double alpha1 = - log(eps0);
G4double alpha2 = 0.5*(1 - epsilon0sq);
do {
@@ -251,14 +234,14 @@ void G4KleinNishinaModel::SampleSecondaries(
} else {
epsilonsq = epsilon0sq + (1.- epsilon0sq)*G4UniformRand();
epsilon = sqrt(epsilonsq);
};
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sint2 = onecost*(2.-onecost);
greject = 1. - epsilon*sint2/(1.+ epsilonsq);
} while (greject < G4UniformRand());
G4double gamEnergy1 = epsilon*gamEnergy0;
gamEnergy1 = epsilon*gamEnergy0;
// before scattering total 4-momentum in e- system
lv2.set(0.0,0.0,0.0,electron_mass_c2);
@@ -268,31 +251,21 @@ void G4KleinNishinaModel::SampleSecondaries(
// scattered gamma angles. ( Z - axis along the parent gamma)
//
if(sint2 < 0.0) { sint2 = 0.0; }
G4double cosTeta = 1. - onecost;
G4double sinTeta = sqrt(sint2);
G4double Phi = twopi * G4UniformRand();
costet = 1. - onecost;
sintet = sqrt(sint2);
phi = twopi * G4UniformRand();
// e- recoil
//
// in rest frame of the electron
if(energy < limitEnergy) {
G4ThreeVector gamDir = lv1.vect().unit();
G4ThreeVector v = G4ThreeVector(sinTeta*cos(Phi),sinTeta*sin(Phi),cosTeta);
v.rotateUz(gamDir);
lv1.set(gamEnergy1*v.x(),gamEnergy1*v.y(),gamEnergy1*v.z(),gamEnergy1);
lv2 -= lv1;
//G4cout << "Egam= " << lv1.e() << " Ee= " << lv2.e()-electron_mass_c2 << G4endl;
lv2.boost(bst);
lv1.boost(bst);
eKinEnergy = lv2.e() - electron_mass_c2 - 2*bindingEnergy;
} else {
lv1.set(gamEnergy1*sinTeta*cos(Phi),gamEnergy1*sinTeta*sin(Phi),
gamEnergy1*cosTeta,gamEnergy1);
lv2 -= lv1;
eKinEnergy = lv2.e() - electron_mass_c2 - bindingEnergy;
}
G4ThreeVector gamDir = lv1.vect().unit();
G4ThreeVector v = G4ThreeVector(sintet*cos(phi),sintet*sin(phi),costet);
v.rotateUz(gamDir);
lv1.set(gamEnergy1*v.x(),gamEnergy1*v.y(),gamEnergy1*v.z(),gamEnergy1);
lv2 -= lv1;
//G4cout<<"Egam= "<<lv1.e()<<" Ee= "<< lv2.e()-electron_mass_c2 << G4endl;
lv2.boost(bst);
eKinEnergy = lv2.e() - electron_mass_c2 - ePotEnergy;
//G4cout << "eKinEnergy= " << eKinEnergy << G4endl;
} while ( eKinEnergy < 0.0 );
@@ -301,7 +274,8 @@ void G4KleinNishinaModel::SampleSecondaries(
// update G4VParticleChange for the scattered gamma
//
G4double gamEnergy1 = lv1.e();
lv1.boost(bst);
gamEnergy1 = lv1.e();
if(gamEnergy1 > lowestGammaEnergy) {
G4ThreeVector gamDirection1 = lv1.vect().unit();
gamDirection1.rotateUz(direction);
@@ -319,7 +293,8 @@ void G4KleinNishinaModel::SampleSecondaries(
if(eKinEnergy > lowestGammaEnergy) {
G4ThreeVector eDirection = lv2.vect().unit();
eDirection.rotateUz(direction);
G4DynamicParticle* dp = new G4DynamicParticle(theElectron,eDirection,eKinEnergy);
G4DynamicParticle* dp =
new G4DynamicParticle(theElectron,eDirection,eKinEnergy);
fvect->push_back(dp);
} else { eKinEnergy = 0.0; }
@@ -330,9 +305,9 @@ void G4KleinNishinaModel::SampleSecondaries(
if(fAtomDeexcitation) {
G4int index = couple->GetIndex();
if(fAtomDeexcitation->CheckDeexcitationActiveRegion(index)) {
G4int Z = (G4int)elm->GetZ();
G4int Z = G4lrint(elm->GetZ());
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(i);
const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
size_t nbefore = fvect->size();
fAtomDeexcitation->GenerateParticles(fvect, shell, Z, index);
size_t nafter = fvect->size();