Import Geant4 9.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 15:37:50 +02:00
parent a8e9364cea
commit 96c8bcd0af
6923 changed files with 198390 additions and 41849 deletions
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4DiffuseElastic.cc,v 1.7 2007/06/12 14:46:26 grichine Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4DiffuseElastic.cc,v 1.18 2007/11/14 18:42:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// Physics model class G4DiffuseElastic
@@ -42,9 +42,11 @@
#include "G4QElasticCrossSection.hh"
#include "G4VQCrossSection.hh"
#include "G4ElasticHadrNucleusHE.hh"
#include "Randomize.hh"
#include "G4Integrator.hh"
#include "globals.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
@@ -52,10 +54,21 @@
#include "G4PionPlus.hh"
#include "G4PionMinus.hh"
#include "G4Element.hh"
#include "G4ElementTable.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsFreeVector.hh"
/////////////////////////////////////////////////////////////////////////
//
// Test Constructor. Just to check xsc
G4DiffuseElastic::G4DiffuseElastic()
: G4HadronicInteraction(), fParticle(0)
{
SetMinEnergy( 0.0*GeV );
SetMinEnergy( 0.01*GeV );
SetMaxEnergy( 100.*TeV );
verboseLevel = 0;
lowEnergyRecoilLimit = 100.*keV;
@@ -70,14 +83,193 @@ G4DiffuseElastic::G4DiffuseElastic()
theAlpha = G4Alpha::Alpha();
thePionPlus = G4PionPlus::PionPlus();
thePionMinus= G4PionMinus::PionMinus();
fEnergyBin = 200;
fAngleBin = 100;
fEnergyVector = 0;
fAngleTable = 0;
fParticle = 0;
fWaveVector = 0.;
fAtomicWeight = 0.;
fAtomicNumber = 0.;
fNuclearRadius = 0.;
fBeta = 0.;
fZommerfeld = 0.;
fAm = 0.;
fAddCoulomb = false;
}
//////////////////////////////////////////////////////////////////////////
//
// Constructor with initialisation
G4DiffuseElastic::G4DiffuseElastic(const G4ParticleDefinition* aParticle)
: G4HadronicInteraction(), fParticle(aParticle)
{
SetMinEnergy( 0.01*GeV );
SetMaxEnergy( 100.*TeV );
verboseLevel = 0;
lowEnergyRecoilLimit = 100.*keV;
lowEnergyLimitQ = 0.0*GeV;
lowEnergyLimitHE = 0.0*GeV;
lowestEnergyLimit= 0.0*keV;
plabLowLimit = 20.0*MeV;
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
theDeuteron = G4Deuteron::Deuteron();
theAlpha = G4Alpha::Alpha();
thePionPlus = G4PionPlus::PionPlus();
thePionMinus= G4PionMinus::PionMinus();
fEnergyBin = 200;
fAngleBin = 100;
// fEnergyVector = 0;
fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin );
fAngleTable = 0;
fParticle = aParticle;
fWaveVector = 0.;
fAtomicWeight = 0.;
fAtomicNumber = 0.;
fNuclearRadius = 0.;
fBeta = 0.;
fZommerfeld = 0.;
fAm = 0.;
fAddCoulomb = false;
// Initialise();
}
//////////////////////////////////////////////////////////////////////////////
//
// Destructor
G4DiffuseElastic::~G4DiffuseElastic()
{
if(fEnergyVector) delete fEnergyVector;
if( fAngleTable )
{
fAngleTable->clearAndDestroy();
delete fAngleTable ;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Initialisation for given particle using element table of application
void G4DiffuseElastic::Initialise()
{
// fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin );
const G4ElementTable* theElementTable = G4Element::GetElementTable();
size_t jEl, numOfEl = G4Element::GetNumberOfElements();
for(jEl = 0 ; jEl < numOfEl; ++jEl) // application element loop
{
fAtomicNumber = (*theElementTable)[jEl]->GetZ(); // atomic number
fAtomicWeight = (*theElementTable)[jEl]->GetN(); // number of nucleons
fNuclearRadius = CalculateNuclearRad(fAtomicWeight);
if(verboseLevel > 0)
G4cout<<"G4DiffuseElastic::Initialise() the element: "
<<(*theElementTable)[jEl]->GetName()<<G4endl;
fElementNumberVector.push_back(fAtomicNumber);
fElementNameVector.push_back((*theElementTable)[jEl]->GetName());
BuildAngleTable();
fAngleBank.push_back(fAngleTable);
}
return;
}
//////////////////////////////////////////////////////////////////////////////
//
// Initialisation for given particle on fly using new element number
void G4DiffuseElastic::InitialiseOnFly(G4double Z, G4double A)
{
fAtomicNumber = Z; // atomic number
fAtomicWeight = A; // number of nucleons
fNuclearRadius = CalculateNuclearRad(fAtomicWeight);
if(verboseLevel > 0)
G4cout<<"G4DiffuseElastic::Initialise() the element with Z = "
<<Z<<"; and A = "<<A<<G4endl;
fElementNumberVector.push_back(fAtomicNumber);
BuildAngleTable();
fAngleBank.push_back(fAngleTable);
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// Build for given particle and element table of momentum, angle probability.
// For the moment in lab system.
void G4DiffuseElastic::BuildAngleTable()
{
G4int i, j;
G4double partMom, kinE, a=0., z = fParticle->GetPDGCharge(), m1 = fParticle->GetPDGMass();
G4double theta1, theta2, thetaMax, thetaCoulomb, sum = 0.;
G4Integrator<G4DiffuseElastic,G4double(G4DiffuseElastic::*)(G4double)> integral;
fAngleTable = new G4PhysicsTable(fEnergyBin);
for(i = 0; i < fEnergyBin; i++)
{
kinE = fEnergyVector->GetLowEdgeEnergy(i);
partMom = std::sqrt( kinE*(kinE + 2*m1) );
fWaveVector = partMom/hbarc;
thetaMax = 10.174/fWaveVector/fNuclearRadius;
if (thetaMax > pi) thetaMax = pi;
thetaCoulomb = 0.2*thetaMax;
if(z)
{
a = partMom/m1;
fBeta = a/std::sqrt(1+a*a);
fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber);
fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
}
G4PhysicsFreeVector* angleVector = new G4PhysicsFreeVector(fAngleBin);
G4PhysicsLogVector* angleBins = new G4PhysicsLogVector( 0.01*thetaMax, thetaMax, fAngleBin );
for(j = 1; j < fAngleBin; j++)
{
theta1 = angleBins->GetLowEdgeEnergy(j-1);
theta2 = angleBins->GetLowEdgeEnergy(j);
if(theta2 > thetaCoulomb && z) fAddCoulomb = true;
sum += integral.Legendre10(this,&G4DiffuseElastic::GetIntegrandFunction, theta1,theta2);
angleVector->PutValue( j-1 , theta2, sum );
// G4cout<<"j-1 = "<<j-1<<"; theta2 = "<<theta2<<"; sum = "<<sum<<G4endl;
}
fAddCoulomb = false;
fAngleTable->insertAt(i,angleVector);
// delete[] angleVector;
// delete[] angleBins;
}
return;
}
////////////////////////////////////////////////////////////////////////////////
//
// Model analog of DoIt function
G4HadFinalState*
G4DiffuseElastic::ApplyYourself( const G4HadProjectile& aTrack,
@@ -153,7 +345,9 @@ G4DiffuseElastic::ApplyYourself( const G4HadProjectile& aTrack,
// Sample t
//
t = SampleT( theParticle, ptot, A);
// t = SampleT( theParticle, ptot, A);
t = SampleTableT( theParticle, ptot, Z, A); // use initialised table
// NaN finder
if(!(t < 0.0 || t >= 0.0))
@@ -261,17 +455,193 @@ G4DiffuseElastic::GetDiffuseElasticXsc( const G4ParticleDefinition* particle,
fParticle = particle;
fWaveVector = momentum/hbarc;
fAtomicWeight = A;
G4double r0;
if(A > 10.) r0 = 1.16*( 1 - std::pow(A, -2./3.) )*fermi; // 1.08*fermi;
else r0 = 1.1*fermi;
fNuclearRadius = r0*std::pow(A, 1./3.);
fAddCoulomb = false;
fNuclearRadius = CalculateNuclearRad(A);
G4double sigma = fNuclearRadius*fNuclearRadius*GetDiffElasticProb(theta);
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
// return invariant differential elastic cross section d(sigma)/d(tMand)
G4double
G4DiffuseElastic::GetInvElasticXsc( const G4ParticleDefinition* particle,
G4double tMand,
G4double plab,
G4double A, G4double Z )
{
G4double m1 = particle->GetPDGMass();
G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1));
G4int iZ = static_cast<G4int>(Z+0.5);
G4int iA = static_cast<G4int>(A+0.5);
G4ParticleDefinition * theDef = 0;
if (iZ == 1 && iA == 1) theDef = theProton;
else if (iZ == 1 && iA == 2) theDef = theDeuteron;
else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton();
else if (iZ == 2 && iA == 3) theDef = G4He3::He3();
else if (iZ == 2 && iA == 4) theDef = theAlpha;
else theDef = G4ParticleTable::GetParticleTable()->FindIon(iZ,iA,0,iZ);
G4double tmass = theDef->GetPDGMass();
G4LorentzVector lv(0.0,0.0,0.0,tmass);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double ptot2 = ptot*ptot;
G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
if( cost >= 1.0 ) cost = 1.0;
else if( cost <= -1.0) cost = -1.0;
G4double thetaCMS = std::acos(cost);
G4double sigma = GetDiffuseElasticXsc( particle, thetaCMS, ptot, A);
sigma *= pi/ptot2;
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
// return differential elastic cross section d(sigma)/d(omega) with Coulomb
// correction
G4double
G4DiffuseElastic::GetDiffuseElasticSumXsc( const G4ParticleDefinition* particle,
G4double theta,
G4double momentum,
G4double A, G4double Z )
{
fParticle = particle;
fWaveVector = momentum/hbarc;
fAtomicWeight = A;
fAtomicNumber = Z;
G4double z = particle->GetPDGCharge();
if(z)
{
fAddCoulomb = true;
fBeta = CalculateParticleBeta( particle, momentum);
fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber);
fAm = CalculateAm( momentum, fZommerfeld, fAtomicNumber);
}
fNuclearRadius = CalculateNuclearRad(A);
G4double sigma = fNuclearRadius*fNuclearRadius*GetDiffElasticSumProb(theta);
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
// return invariant differential elastic cross section d(sigma)/d(tMand) with Coulomb
// correction
G4double
G4DiffuseElastic::GetInvElasticSumXsc( const G4ParticleDefinition* particle,
G4double tMand,
G4double plab,
G4double A, G4double Z )
{
G4double m1 = particle->GetPDGMass();
G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1));
G4int iZ = static_cast<G4int>(Z+0.5);
G4int iA = static_cast<G4int>(A+0.5);
G4ParticleDefinition * theDef = 0;
if (iZ == 1 && iA == 1) theDef = theProton;
else if (iZ == 1 && iA == 2) theDef = theDeuteron;
else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton();
else if (iZ == 2 && iA == 3) theDef = G4He3::He3();
else if (iZ == 2 && iA == 4) theDef = theAlpha;
else theDef = G4ParticleTable::GetParticleTable()->FindIon(iZ,iA,0,iZ);
G4double tmass = theDef->GetPDGMass();
G4LorentzVector lv(0.0,0.0,0.0,tmass);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double ptot2 = ptot*ptot;
G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
if( cost >= 1.0 ) cost = 1.0;
else if( cost <= -1.0) cost = -1.0;
G4double thetaCMS = std::acos(cost);
G4double sigma = GetDiffuseElasticSumXsc( particle, thetaCMS, ptot, A, Z );
sigma *= pi/ptot2;
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
// return invariant differential elastic cross section d(sigma)/d(tMand) with Coulomb
// correction
G4double
G4DiffuseElastic::GetInvCoulombElasticXsc( const G4ParticleDefinition* particle,
G4double tMand,
G4double plab,
G4double A, G4double Z )
{
G4double m1 = particle->GetPDGMass();
G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1));
G4int iZ = static_cast<G4int>(Z+0.5);
G4int iA = static_cast<G4int>(A+0.5);
G4ParticleDefinition * theDef = 0;
if (iZ == 1 && iA == 1) theDef = theProton;
else if (iZ == 1 && iA == 2) theDef = theDeuteron;
else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton();
else if (iZ == 2 && iA == 3) theDef = G4He3::He3();
else if (iZ == 2 && iA == 4) theDef = theAlpha;
else theDef = G4ParticleTable::GetParticleTable()->FindIon(iZ,iA,0,iZ);
G4double tmass = theDef->GetPDGMass();
G4LorentzVector lv(0.0,0.0,0.0,tmass);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double ptot2 = ptot*ptot;
G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
if( cost >= 1.0 ) cost = 1.0;
else if( cost <= -1.0) cost = -1.0;
G4double thetaCMS = std::acos(cost);
G4double sigma = GetCoulombElasticXsc( particle, thetaCMS, ptot, Z );
sigma *= pi/ptot2;
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
// return differential elastic probability d(probability)/d(omega)
@@ -317,20 +687,24 @@ G4DiffuseElastic::GetDiffElasticProb( // G4ParticleDefinition* particle,
e1 = 0.3*fermi;
e2 = 0.35*fermi;
}
G4double kg = fWaveVector*gamma; // wavek*delta;
G4double lambda = 15.; // 15 ok
// G4double kg = fWaveVector*gamma; // wavek*delta;
G4double kg = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta;
G4double kg2 = kg*kg;
G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta;
G4double dk2t2 = dk2t*dk2t;
G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta;
// G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta;
// G4double dk2t2 = dk2t*dk2t;
// G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta;
G4double pikdt = lambda*(1.-std::exp(-pi*fWaveVector*diffuse*theta/lambda)); // wavek*delta;
damp = DampFactor(pikdt);
damp2 = damp*damp;
G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector;
G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
damp = DampFactor(pikdt);
damp2 = damp*damp;
sigma = kg2 + dk2t2;
sigma = kg2;
// sigma += dk2t2;
sigma *= bzero2;
sigma += mode2k2*bone2 + e2dk3t*bzero*bone;
sigma += kr2*bonebyarg2;
@@ -339,6 +713,100 @@ G4DiffuseElastic::GetDiffElasticProb( // G4ParticleDefinition* particle,
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
// return differential elastic probability d(probability)/d(omega) with
// Coulomb correction
G4double
G4DiffuseElastic::GetDiffElasticSumProb( // G4ParticleDefinition* particle,
G4double theta
// G4double momentum,
// G4double A
)
{
G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
G4double delta, diffuse, gamma;
G4double e1, e2, bone, bone2;
// G4double wavek = momentum/hbarc; // wave vector
// G4double r0 = 1.08*fermi;
// G4double rad = r0*std::pow(A, 1./3.);
G4double kr = fWaveVector*fNuclearRadius; // wavek*rad;
G4double kr2 = kr*kr;
G4double krt = kr*theta;
bzero = BesselJzero(krt);
bzero2 = bzero*bzero;
bone = BesselJone(krt);
bone2 = bone*bone;
bonebyarg = BesselOneByArg(krt);
bonebyarg2 = bonebyarg*bonebyarg;
if (fParticle == theProton)
{
diffuse = 0.63*fermi;
// diffuse = 0.6*fermi;
gamma = 0.3*fermi;
delta = 0.1*fermi*fermi;
e1 = 0.3*fermi;
e2 = 0.35*fermi;
}
else // as proton, if were not defined
{
diffuse = 0.63*fermi;
gamma = 0.3*fermi;
delta = 0.1*fermi*fermi;
e1 = 0.3*fermi;
e2 = 0.35*fermi;
}
G4double lambda = 15.; // 15 ok
// G4double kg = fWaveVector*gamma; // wavek*delta;
G4double kg = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta;
// G4cout<<"kg = "<<kg<<G4endl;
if(fAddCoulomb) // add Coulomb correction
{
G4double sinHalfTheta = std::sin(0.5*theta);
G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
kg += 0.5*fZommerfeld/kr/(sinHalfTheta2+fAm); // correction at J0()
// kg += 0.65*fZommerfeld/kr/(sinHalfTheta2+fAm); // correction at J0()
}
G4double kg2 = kg*kg;
// G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta;
// G4cout<<"dk2t = "<<dk2t<<G4endl;
// G4double dk2t2 = dk2t*dk2t;
// G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta;
G4double pikdt = lambda*(1.-std::exp(-pi*fWaveVector*diffuse*theta/lambda)); // wavek*delta;
// G4cout<<"pikdt = "<<pikdt<<G4endl;
damp = DampFactor(pikdt);
damp2 = damp*damp;
G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector;
G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
sigma = kg2;
// sigma += dk2t2;
sigma *= bzero2;
sigma += mode2k2*bone2;
sigma += e2dk3t*bzero*bone;
// sigma += kr2*(1 + 8.*fZommerfeld*fZommerfeld/kr2)*bonebyarg2; // correction at J1()/()
sigma += kr2*bonebyarg2; // correction at J1()/()
sigma *= damp2; // *rad*rad;
return sigma;
}
////////////////////////////////////////////////////////////////////////////
//
@@ -350,7 +818,7 @@ G4DiffuseElastic::GetIntegrandFunction( G4double theta )
G4double result;
result = 2*pi*std::sin(theta);
result *= GetDiffElasticProb(theta);
result *= GetDiffElasticSumProb(theta);
return result;
}
@@ -368,10 +836,8 @@ G4DiffuseElastic::IntegralElasticProb( const G4ParticleDefinition* particle,
fParticle = particle;
fWaveVector = momentum/hbarc;
fAtomicWeight = A;
G4double r0;
if(A > 10.) r0 = 1.16*( 1 - std::pow(A, -2./3.) )*fermi; // 1.08*fermi;
else r0 = 1.1*fermi;
fNuclearRadius = r0*std::pow(A, 1./3.);
fNuclearRadius = CalculateNuclearRad(A);
G4Integrator<G4DiffuseElastic,G4double(G4DiffuseElastic::*)(G4double)> integral;
@@ -393,6 +859,18 @@ G4double G4DiffuseElastic::SampleT( const G4ParticleDefinition* aParticle, G4dou
return t;
}
////////////////////////////////////////////////////////////////////////////
//
// Return inv momentum transfer -t > 0 from initialisation table
G4double G4DiffuseElastic::SampleTableT( const G4ParticleDefinition* aParticle, G4double p,
G4double Z, G4double A)
{
G4double theta = SampleTableThetaCMS( aParticle, p, Z, A); // sample theta in cms
G4double t = 2*p*p*( 1 - std::cos(theta) ); // -t !!!
return t;
}
////////////////////////////////////////////////////////////////////////////
//
// Return scattering angle sampled in cms
@@ -403,18 +881,16 @@ G4DiffuseElastic::SampleThetaCMS(const G4ParticleDefinition* particle,
G4double momentum, G4double A)
{
G4int i, iMax = 100;
G4double r0, norm, result, theta1, theta2, thetaMax, sum = 0.;
G4double norm, result, theta1, theta2, thetaMax, sum = 0.;
fParticle = particle;
fWaveVector = momentum/hbarc;
fAtomicWeight = A;
if(A > 10.) r0 = 1.16*( 1 - std::pow(A, -2./3.) )*fermi; // 1.08*fermi;
else r0 = 1.1*fermi;
fNuclearRadius = r0*std::pow(A, 1./3.);
fNuclearRadius = CalculateNuclearRad(A);
thetaMax = 10.174/fWaveVector/fNuclearRadius;
if (thetaMax > pi) thetaMax = pi;
G4Integrator<G4DiffuseElastic,G4double(G4DiffuseElastic::*)(G4double)> integral;
@@ -437,9 +913,155 @@ G4DiffuseElastic::SampleThetaCMS(const G4ParticleDefinition* particle,
}
}
if (i > iMax ) result = 0.5*(theta1 + theta2);
G4double sigma = pi*thetaMax/iMax;
result += G4RandGauss::shoot(0.,sigma);
if(result < 0.) result = 0.;
if(result > thetaMax) result = thetaMax;
return result;
}
////////////////////////////////////////////////////////////////////////////
//
// Return scattering angle sampled in cms according to precalculated table.
G4double
G4DiffuseElastic::SampleTableThetaCMS(const G4ParticleDefinition* particle,
G4double momentum, G4double Z, G4double A)
{
size_t iElement;
G4int iMomentum, iAngle;
G4double randAngle, position, theta1, theta2, E1, E2, W1, W2, W;
G4double m1 = particle->GetPDGMass();
for(iElement = 0; iElement < fElementNumberVector.size(); iElement++)
{
if( std::fabs(Z - fElementNumberVector[iElement]) < 0.5) break;
}
if ( iElement == fElementNumberVector.size() )
{
InitialiseOnFly(Z,A);
// iElement--;
// G4cout << "G4DiffuseElastic: Element with atomic number " << Z
// << " is not found, return zero angle" << G4endl;
// return 0.; // no table for this element
}
// G4cout<<"iElement = "<<iElement<<G4endl;
fAngleTable = fAngleBank[iElement];
G4double kinE = std::sqrt(momentum*momentum + m1*m1) - m1;
for(iMomentum = 0; iMomentum < fEnergyBin; iMomentum++)
{
if( kinE < fEnergyVector->GetLowEdgeEnergy(iMomentum) ) break;
}
if ( iMomentum == fEnergyBin ) iMomentum--; // kinE is more then theMaxEnergy
if ( iMomentum < 0 ) iMomentum = 0; // against negative index, kinE < theMinEnergy
// G4cout<<"iMomentum = "<<iMomentum<<G4endl;
if (iMomentum == fEnergyBin -1 || iMomentum == 0 ) // the table edges
{
position = (*(*fAngleTable)(iMomentum))(fAngleBin-2)*G4UniformRand();
// G4cout<<"position = "<<position<<G4endl;
for(iAngle = 0; iAngle < fAngleBin; iAngle++)
{
if( position < (*(*fAngleTable)(iMomentum))(iAngle) ) break;
}
if (iAngle == fAngleBin) iAngle--;
// G4cout<<"iAngle = "<<iAngle<<G4endl;
randAngle = GetScatteringAngle(iMomentum, iAngle, position);
// G4cout<<"randAngle = "<<randAngle<<G4endl;
}
else
{
position = (*(*fAngleTable)(iMomentum))(fAngleBin-2)*G4UniformRand();
// G4cout<<"position = "<<position<<G4endl;
for(iAngle = 0; iAngle < fAngleBin; iAngle++)
{
if( position < (*(*fAngleTable)(iMomentum))(iAngle) ) break;
}
if (iAngle == fAngleBin) iAngle--;
// G4cout<<"iAngle = "<<iAngle<<G4endl;
theta2 = GetScatteringAngle(iMomentum, iAngle, position);
// G4cout<<"theta2 = "<<theta2<<G4endl;
E2 = fEnergyVector->GetLowEdgeEnergy(iMomentum);
// G4cout<<"E2 = "<<E2<<G4endl;
iMomentum--;
position = (*(*fAngleTable)(iMomentum))(fAngleBin-2)*G4UniformRand();
// G4cout<<"position = "<<position<<G4endl;
for(iAngle = 0; iAngle < fAngleBin; iAngle++)
{
if( position < (*(*fAngleTable)(iMomentum))(iAngle) ) break;
}
if (iAngle == fAngleBin) iAngle--;
theta1 = GetScatteringAngle(iMomentum, iAngle, position);
// G4cout<<"theta1 = "<<theta1<<G4endl;
E1 = fEnergyVector->GetLowEdgeEnergy(iMomentum);
// G4cout<<"E1 = "<<E1<<G4endl;
W = 1.0/(E2 - E1);
W1 = (E2 - kinE)*W;
W2 = (kinE - E1)*W;
randAngle = W1*theta1 + W2*theta2;
// G4cout<<"randAngle = "<<randAngle<<G4endl;
}
return randAngle;
}
/////////////////////////////////////////////////////////////////////////////////
//
//
G4double
G4DiffuseElastic:: GetScatteringAngle(G4int iMomentum, G4int iAngle, G4double position)
{
G4double x1, x2, y1, y2, randAngle;
if( iAngle == 0 )
{
randAngle = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle);
}
else
{
if ( iAngle >= G4int((*fAngleTable)(iMomentum)->GetVectorLength()) )
{
iAngle = (*fAngleTable)(iMomentum)->GetVectorLength() - 1;
}
y1 = (*(*fAngleTable)(iMomentum))(iAngle-1);
y2 = (*(*fAngleTable)(iMomentum))(iAngle);
x1 = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle-1);
x2 = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle);
if ( x1 == x2 ) randAngle = x2;
else
{
if ( y1 == y2 ) randAngle = x1 + (x2 - x1)*G4UniformRand();
else
{
randAngle = x1 + (position - y1)*(x2 - x1)/(y2 - y1);
}
}
}
return randAngle;
}
////////////////////////////////////////////////////////////////////////////
//
@@ -462,9 +1084,9 @@ G4DiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double tmax = 4.0*ptot*ptot;
G4double t = 0.0;
G4double ptot = p1.mag();
G4double tmax = 4.0*ptot*ptot;
G4double t = 0.0;
//
@@ -528,3 +1150,128 @@ G4DiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
return theta;
}
////////////////////////////////////////////////////////////////////////////
//
// Return scattering angle in lab system (target at rest) knowing theta in CMS
G4double
G4DiffuseElastic::ThetaCMStoThetaLab( const G4DynamicParticle* aParticle,
G4double tmass, G4double thetaCMS)
{
const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
G4double m1 = theParticle->GetPDGMass();
// G4double plab = aParticle->GetTotalMomentum();
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv(0.0,0.0,0.0,tmass);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double phi = G4UniformRand()*twopi;
G4double cost = std::cos(thetaCMS);
G4double sint;
if( cost >= 1.0 )
{
cost = 1.0;
sint = 0.0;
}
else if( cost <= -1.0)
{
cost = -1.0;
sint = 0.0;
}
else
{
sint = std::sqrt((1.0-cost)*(1.0+cost));
}
if (verboseLevel>1)
{
G4cout << "cos(tcms)=" << cost << " std::sin(tcms)=" << sint << G4endl;
}
G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
v1 *= ptot;
G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(ptot*ptot + m1*m1));
nlv1.boost(bst);
G4ThreeVector np1 = nlv1.vect();
G4double thetaLab = np1.theta();
return thetaLab;
}
////////////////////////////////////////////////////////////////////////////
//
// Return scattering angle in CMS system (target at rest) knowing theta in Lab
G4double
G4DiffuseElastic::ThetaLabToThetaCMS( const G4DynamicParticle* aParticle,
G4double tmass, G4double thetaLab)
{
const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
G4double m1 = theParticle->GetPDGMass();
G4double plab = aParticle->GetTotalMomentum();
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv(0.0,0.0,0.0,tmass);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
// lv1.boost(-bst);
// G4ThreeVector p1 = lv1.vect();
// G4double ptot = p1.mag();
G4double phi = G4UniformRand()*twopi;
G4double cost = std::cos(thetaLab);
G4double sint;
if( cost >= 1.0 )
{
cost = 1.0;
sint = 0.0;
}
else if( cost <= -1.0)
{
cost = -1.0;
sint = 0.0;
}
else
{
sint = std::sqrt((1.0-cost)*(1.0+cost));
}
if (verboseLevel>1)
{
G4cout << "cos(tlab)=" << cost << " std::sin(tlab)=" << sint << G4endl;
}
G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
v1 *= plab;
G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(plab*plab + m1*m1));
nlv1.boost(-bst);
G4ThreeVector np1 = nlv1.vect();
G4double thetaCMS = np1.theta();
return thetaCMS;
}
//
//
/////////////////////////////////////////////////////////////////////////////////