Import Geant4 9.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 16:46:55 +02:00
parent 89a9605df1
commit b1eb5424d2
10957 changed files with 888481 additions and 160139 deletions
@@ -0,0 +1,660 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4AntiNuclElastic.cc - A.Galoyan 02.05.2011
// GEANT4 tag $Name: not supported by cvs2svn $
//
// Geant4 Header : G4AntiNuclElastic
//
//
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4IonTable.hh"
#include "Randomize.hh"
#include "G4AntiProton.hh"
#include "G4AntiNeutron.hh"
#include "G4AntiDeuteron.hh"
#include "G4AntiAlpha.hh"
#include "G4AntiTriton.hh"
#include "G4AntiHe3.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
#include "G4Alpha.hh"
#include "G4Pow.hh"
#include "G4AntiNuclElastic.hh"
#include "G4NucleiProperties.hh"
G4AntiNuclElastic::G4AntiNuclElastic()
: G4HadronElastic("AntiAElastic")
{
//V.Ivanchenko commented out
//SetMinEnergy( 0.1*GeV );
//SetMaxEnergy( 10.*TeV );
theAProton = G4AntiProton::AntiProton();
theANeutron = G4AntiNeutron::AntiNeutron();
theADeuteron = G4AntiDeuteron::AntiDeuteron();
theATriton = G4AntiTriton::AntiTriton();
theAAlpha = G4AntiAlpha::AntiAlpha();
theAHe3 = G4AntiHe3::AntiHe3();
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
theDeuteron = G4Deuteron::Deuteron();
theAlpha = G4Alpha::Alpha();
cs = new G4ComponentAntiNuclNuclearXS();
fParticle = 0;
fWaveVector = 0.;
fBeta = 0.;
fZommerfeld = 0.;
fAm = 0.;
fTetaCMS = 0.;
fRa = 0.;
fRef = 0.;
fceff = 0.;
fptot = 0.;
fTmax = 0.;
fThetaLab = 0.;
}
/////////////////////////////////////////////////////////////////////////
G4AntiNuclElastic::~G4AntiNuclElastic()
{
delete cs;
}
////////////////////////////////////////////////////////////////////////
// sample momentum transfer in the CMS system
G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particle,
G4double Plab, G4int Z, G4int A)
{
G4double T;
G4double Mproj = particle->GetPDGMass();
G4LorentzVector Pproj(0.,0.,Plab,std::sqrt(Plab*Plab+Mproj*Mproj));
G4double ctet1 = GetcosTeta1(Plab, A);
G4double energy=Pproj.e()-Mproj;
const G4ParticleDefinition* theParticle = particle;
G4ParticleDefinition * theDef = 0;
if(Z == 1 && A == 1) theDef = theProton;
else if (Z == 1 && A == 2) theDef = theDeuteron;
else if (Z == 1 && A == 3) theDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theDef = G4He3::He3();
else if (Z == 2 && A == 4) theDef = theAlpha;
G4double TargMass =G4NucleiProperties::GetNuclearMass(A,Z);
//transform to CMS
G4LorentzVector lv(0.0,0.0,0.0,TargMass);
lv += Pproj;
G4double S = lv.mag2()/GeV/GeV;
G4ThreeVector bst = lv.boostVector();
Pproj.boost(-bst);
G4ThreeVector p1 = Pproj.vect();
G4double ptot = p1.mag();
fbst = bst;
fptot= ptot;
fTmax = 4.0*ptot*ptot;
if(Plab/std::abs(particle->GetBaryonNumber()) < 100.*MeV) // Uzhi 24 Nov. 2011
{return fTmax*G4UniformRand();} // Uzhi 24 Nov. 2011
G4double Z1 = particle->GetPDGCharge();
G4double Z2 = Z;
G4double beta = CalculateParticleBeta(particle, ptot);
G4double n = CalculateZommerfeld( beta, Z1, Z2 );
G4double Am = CalculateAm( ptot, n, Z2 );
fWaveVector = ptot; // /hbarc;
G4LorentzVector Fproj(0.,0.,0.,0.);
G4double XsCoulomb = sqr(n/fWaveVector)*pi*(1+ctet1)/(1.+Am)/(1.+2.*Am-ctet1);
XsCoulomb=XsCoulomb*0.38938e+6;
G4double XsElastHad =cs->GetElasticElementCrossSection(particle, energy, Z, (G4double)A);
G4double XstotalHad =cs->GetTotalElementCrossSection(particle, energy, Z, (G4double)A);
XsElastHad/=millibarn; XstotalHad/=millibarn;
G4double CoulombProb = XsCoulomb/(XsCoulomb+XsElastHad);
// G4cout<<" XselastHadron " << XsElastHad << " XsCol "<< XsCoulomb <<G4endl;
// G4cout <<" XsTotal" << XstotalHad <<G4endl;
// G4cout<<"XsInel"<< XstotalHad-XsElastHad<<G4endl;
if(G4UniformRand() < CoulombProb)
{ // Simulation of Coulomb scattering
G4double phi = twopi * G4UniformRand();
G4double Ksi = G4UniformRand();
G4double par1 = 2.*(1.+Am)/(1.+ctet1);
// ////sample ThetaCMS in Coulomb part
G4double cosThetaCMS = (par1*ctet1- Ksi*(1.+2.*Am))/(par1-Ksi);
G4double PtZ=ptot*cosThetaCMS;
Fproj.setPz(PtZ);
G4double PtProjCMS = ptot*std::sqrt(1.0 - cosThetaCMS*cosThetaCMS);
G4double PtX= PtProjCMS * std::cos(phi);
G4double PtY= PtProjCMS * std::sin(phi);
Fproj.setPx(PtX);
Fproj.setPy(PtY);
Fproj.setE(std::sqrt(PtX*PtX+PtY*PtY+PtZ*PtZ+Mproj*Mproj));
T = -(Pproj-Fproj).mag2();
} else
{
///////Simulation of strong interaction scattering////////////////////////////
// G4double Qmax = 2.*ptot*197.33; // in fm^-1
G4double Qmax = 2.*3.0*197.33; // in fm^-1
G4double Amag = 70*70; // A1 in Magora funct:A1*exp(-q*A2)
G4double SlopeMag = 2.*3.0; // A2 in Magora funct:A1*exp(-q*A2)
G4double sig_pbarp= cs->GetAntiHadronNucleonTotCrSc(particle,energy);
fRa = 1.113*G4Pow::GetInstance()->Z13(A) -
0.227/G4Pow::GetInstance()->Z13(A);
if(A == 3) fRa=1.81;
if(A == 4) fRa=1.37;
if((A>=12.) && (A<27) ) fRa=fRa*0.85;
if((A>=27.) && (A<48) ) fRa=fRa*0.90;
if((A>=48.) && (A<65) ) fRa=fRa*0.95;
G4double Ref2 = 0;
G4double ceff2 =0;
G4double rho = 0;
if ((theParticle == theAProton) || (theParticle == theANeutron))
{
if(theDef == theProton)
{
// G4double Mp2=sqr(theDef->GetPDGMass()/GeV );
// change 30 October
if(Plab < 610.)
{ rho = 1.3347-10.342*Plab/1000.+22.277*Plab/1000.*Plab/1000.-
13.634*Plab/1000.*Plab/1000.*Plab/1000. ;}
if((Plab < 5500.)&&(Plab >= 610.) )
{ rho = 0.22; }
if((Plab >= 5500.)&&(Plab < 12300.) )
{ rho = -0.32; }
if( Plab >= 12300.)
{ rho = 0.135-2.26/(std::sqrt(S)) ;}
Ref2 = 0.35 + 0.9/std::sqrt(std::sqrt(S-4.*0.88))+0.04*std::log(S) ;
ceff2 = 0.375 - 2./S + 0.44/(sqr(S-4.)+1.5) ;
/*
Ref2=0.8/std::sqrt(std::sqrt(S-4.*Mp2)) + 0.55;
if(S>1000.) Ref2=0.62+0.02*std::log(S) ;
ceff2 = 0.035/(sqr(S-4.3)+0.4) + 0.085 * std::log(S) ;
if(S>1000.) ceff2 = 0.005 * std::log(S) + 0.29;
*/
Ref2=Ref2*Ref2;
ceff2 = ceff2*ceff2;
SlopeMag = 0.5; // Uzhi
Amag= 1.; // Uzhi
}
if(Z>2)
{ Ref2 = fRa*fRa +2.48*0.01*sig_pbarp*fRa - 2.23e-6*sig_pbarp*sig_pbarp*fRa*fRa;
ceff2 = 0.16+3.3e-4*sig_pbarp+0.35*std::exp(-0.03*sig_pbarp);
}
if( (Z==2)&&(A==4) )
{ Ref2 = fRa*fRa -0.46 +0.03*sig_pbarp - 2.98e-6*sig_pbarp*sig_pbarp;
ceff2= 0.078 + 6.657e-4*sig_pbarp + 0.3359*std::exp(-0.03*sig_pbarp);
}
if( (Z==1)&&(A==3) )
{ Ref2 = fRa*fRa - 1.36 + 0.025 * sig_pbarp - 3.69e-7 * sig_pbarp*sig_pbarp;
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*std::exp(-0.03*sig_pbarp);
}
if( (Z==2)&&(A==3) )
{ Ref2 = fRa*fRa - 1.36 + 0.025 * sig_pbarp - 3.69e-7 * sig_pbarp*sig_pbarp;
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*std::exp(-0.03*sig_pbarp);
}
if( (Z==1)&&(A==2) )
{
Ref2 = fRa*fRa - 0.28 + 0.019 * sig_pbarp + 2.06e-6 * sig_pbarp*sig_pbarp;
ceff2 = 0.297 + 7.853e-04*sig_pbarp + 0.2899*std::exp(-0.03*sig_pbarp);
}
}
if (theParticle == theADeuteron)
{
sig_pbarp= cs->GetAntiHadronNucleonTotCrSc(particle,energy/2.);
Ref2 = XstotalHad/10./2./pi ;
if(Z>2)
{
ceff2 = 0.38 + 2.0e-4 *sig_pbarp + 0.5 * std::exp(-0.03*sig_pbarp);
}
if(theDef == theProton)
{
ceff2 = 0.297 + 7.853e-04*sig_pbarp + 0.2899*std::exp(-0.03*sig_pbarp);
}
if(theDef == theDeuteron)
{
ceff2 = 0.65 + 3.0e-4*sig_pbarp + 0.55 * std::exp(-0.03*sig_pbarp);
}
if( (theDef == G4Triton::Triton()) || (theDef == G4He3::He3() ) )
{
ceff2 = 0.57 + 2.5e-4*sig_pbarp + 0.65 * std::exp(-0.02*sig_pbarp);
}
if(theDef == theAlpha)
{
ceff2 = 0.40 + 3.5e-4 *sig_pbarp + 0.45 * std::exp(-0.02*sig_pbarp);
}
}
if( (theParticle ==theAHe3) || (theParticle ==theATriton) )
{
sig_pbarp = cs->GetAntiHadronNucleonTotCrSc(particle,energy/3.);
Ref2 = XstotalHad/10./2./pi ;
if(Z>2)
{
ceff2 = 0.26 + 2.2e-4*sig_pbarp + 0.33*std::exp(-0.03*sig_pbarp);
}
if(theDef == theProton)
{
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*std::exp(-0.03*sig_pbarp);
}
if(theDef == theDeuteron)
{
ceff2 = 0.57 + 2.5e-4*sig_pbarp + 0.65 * std::exp(-0.02*sig_pbarp);
}
if( (theDef == G4Triton::Triton()) || (theDef == G4He3::He3() ) )
{
ceff2 = 0.39 + 2.7e-4*sig_pbarp + 0.7 * std::exp(-0.02*sig_pbarp);
}
if(theDef == theAlpha)
{
ceff2 = 0.24 + 3.5e-4*sig_pbarp + 0.75 * std::exp(-0.03*sig_pbarp);
}
}
if (theParticle == theAAlpha)
{
sig_pbarp = cs->GetAntiHadronNucleonTotCrSc(particle,energy/3.);
Ref2 = XstotalHad/10./2./pi ;
if(Z>2)
{
ceff2 = 0.22 + 2.0e-4*sig_pbarp + 0.2 * std::exp(-0.03*sig_pbarp);
}
if(theDef == theProton)
{
ceff2= 0.078 + 6.657e-4*sig_pbarp + 0.3359*std::exp(-0.03*sig_pbarp);
}
if(theDef == theDeuteron)
{
ceff2 = 0.40 + 3.5e-4 *sig_pbarp + 0.45 * std::exp(-0.02*sig_pbarp);
}
if( (theDef == G4Triton::Triton()) || (theDef == G4He3::He3() ) )
{
ceff2 = 0.24 + 3.5e-4*sig_pbarp + 0.75 * std::exp(-0.03*sig_pbarp);
}
if(theDef == theAlpha)
{
ceff2 = 0.17 + 3.5e-4*sig_pbarp + 0.45 * std::exp(-0.03*sig_pbarp);
}
}
fRef=std::sqrt(Ref2);
fceff = std::sqrt(ceff2);
// G4cout<<" Ref "<<fRef<<" c_eff "<<fceff<< " rho "<< rho<<G4endl;
G4double Q = 0.0 ;
G4double BracFunct;
do
{
Q = -std::log(1.-(1.- std::exp(-SlopeMag * Qmax))* G4UniformRand() )/SlopeMag;
G4double x = fRef * Q;
BracFunct = ( ( sqr(BesselOneByArg(x))+sqr(rho/2. * BesselJzero(x)) )
* sqr(DampFactor(pi*fceff*Q))) /(Amag*std::exp(-SlopeMag*Q));
BracFunct = BracFunct * Q * sqr(sqr(fRef));
}
while (G4UniformRand()>BracFunct);
T= sqr(Q);
T*=3.893913e+4; // fm -> MeV^2
}
G4double cosTet=1.0-T/(2.*ptot*ptot);
fTetaCMS=std::acos(cosTet);
return T;
}
/////////////////////////////////////////////////////////////////////
// Sample of Theta in CMS
G4double G4AntiNuclElastic::SampleThetaCMS(const G4ParticleDefinition* p, G4double plab,
G4int Z, G4int A)
{
G4double T;
T = SampleInvariantT( p, plab, Z, A);
// NaN finder
if(!(T < 0.0 || T >= 0.0))
{
if (verboseLevel > 0)
{
G4cout << "G4DiffuseElastic:WARNING: A = " << A
<< " mom(GeV)= " << plab/GeV
<< " S-wave will be sampled"
<< G4endl;
}
T = G4UniformRand()*fTmax;
}
if(fptot > 0.) // Uzhi 24 Nov. 2011
{
G4double cosTet=1.0-T/(2.*fptot*fptot);
fTetaCMS=std::acos(cosTet);
return fTetaCMS;
} else // Uzhi 24 Nov. 2011
{ // Uzhi 24 Nov. 2011
return 2.*G4UniformRand()-1.; // Uzhi 24 Nov. 2011
} // Uzhi 24 Nov. 2011
}
/////////////////////////////////////////////////////////////////////
// Sample of Theta in Lab System
G4double G4AntiNuclElastic::SampleThetaLab(const G4ParticleDefinition* p, G4double plab,
G4int Z, G4int A)
{
G4double T;
T = SampleInvariantT( p, plab, Z, A);
// NaN finder
if(!(T < 0.0 || T >= 0.0))
{
if (verboseLevel > 0)
{
G4cout << "G4DiffuseElastic:WARNING: A = " << A
<< " mom(GeV)= " << plab/GeV
<< " S-wave will be sampled"
<< G4endl;
}
T = G4UniformRand()*fTmax;
}
G4double phi = G4UniformRand()*twopi;
G4double cost(1.);
if(fTmax > 0.) {cost = 1. - 2.0*T/fTmax;} // Uzhi 24 Nov. 2011
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));
}
G4double m1 = p->GetPDGMass();
G4ThreeVector v(sint*std::cos(phi),sint*std::sin(phi),cost);
v *= fptot;
G4LorentzVector nlv(v.x(),v.y(),v.z(),std::sqrt(fptot*fptot + m1*m1));
nlv.boost(fbst);
G4ThreeVector np = nlv.vect();
G4double theta = np.theta();
fThetaLab = theta;
return theta;
}
////////////////////////////////////////////////////////////////////
// Calculation of Damp factor
G4double G4AntiNuclElastic::DampFactor(G4double x)
{
G4double df;
G4double f3 = 6.; // first factorials
if( std::fabs(x) < 0.01 )
{
df=1./(1.+x*x/f3);
}
else
{
df = x/std::sinh(x);
}
return df;
}
/////////////////////////////////////////////////////////////////////////////////
// Calculation of particle velocity Beta
G4double G4AntiNuclElastic::CalculateParticleBeta( const G4ParticleDefinition* particle,
G4double momentum )
{
G4double mass = particle->GetPDGMass();
G4double a = momentum/mass;
fBeta = a/std::sqrt(1+a*a);
return fBeta;
}
///////////////////////////////////////////////////////////////////////////////////
// Calculation of parameter Zommerfeld
G4double G4AntiNuclElastic::CalculateZommerfeld( G4double beta, G4double Z1, G4double Z2 )
{
fZommerfeld = fine_structure_const*Z1*Z2/beta;
return fZommerfeld;
}
////////////////////////////////////////////////////////////////////////////////////
//
G4double G4AntiNuclElastic::CalculateAm( G4double momentum, G4double n, G4double Z)
{
G4double k = momentum/hbarc;
G4double ch = 1.13 + 3.76*n*n;
G4double zn = 1.77*k/G4Pow::GetInstance()->A13(Z)*Bohr_radius;
G4double zn2 = zn*zn;
fAm = ch/zn2;
return fAm;
}
/////////////////////////////////////////////////////////////
//
// Bessel J0 function based on rational approximation from
// J.F. Hart, Computer Approximations, New York, Willey 1968, p. 141
G4double G4AntiNuclElastic::BesselJzero(G4double value)
{
G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
modvalue = std::fabs(value);
if ( value < 8.0 && value > -8.0 )
{
value2 = value*value;
fact1 = 57568490574.0 + value2*(-13362590354.0
+ value2*( 651619640.7
+ value2*(-11214424.18
+ value2*( 77392.33017
+ value2*(-184.9052456 ) ) ) ) );
fact2 = 57568490411.0 + value2*( 1029532985.0
+ value2*( 9494680.718
+ value2*(59272.64853
+ value2*(267.8532712
+ value2*1.0 ) ) ) );
bessel = fact1/fact2;
}
else
{
arg = 8.0/modvalue;
value2 = arg*arg;
shift = modvalue-0.785398164;
fact1 = 1.0 + value2*(-0.1098628627e-2
+ value2*(0.2734510407e-4
+ value2*(-0.2073370639e-5
+ value2*0.2093887211e-6 ) ) );
fact2 = -0.1562499995e-1 + value2*(0.1430488765e-3
+ value2*(-0.6911147651e-5
+ value2*(0.7621095161e-6
- value2*0.934945152e-7 ) ) );
bessel = std::sqrt(0.636619772/modvalue)*(std::cos(shift)*fact1 - arg*std::sin(shift)*fact2);
}
return bessel;
}
//////////////////////////////////////////////////////////////////////////////
// Bessel J1 function based on rational approximation from
// J.F. Hart, Computer Approximations, New York, Willey 1968, p. 141
G4double G4AntiNuclElastic::BesselJone(G4double value)
{
G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
modvalue = std::fabs(value);
if ( modvalue < 8.0 )
{
value2 = value*value;
fact1 = value*(72362614232.0 + value2*(-7895059235.0
+ value2*( 242396853.1
+ value2*(-2972611.439
+ value2*( 15704.48260
+ value2*(-30.16036606 ) ) ) ) ) );
fact2 = 144725228442.0 + value2*(2300535178.0
+ value2*(18583304.74
+ value2*(99447.43394
+ value2*(376.9991397
+ value2*1.0 ) ) ) );
bessel = fact1/fact2;
}
else
{
arg = 8.0/modvalue;
value2 = arg*arg;
shift = modvalue - 2.356194491;
fact1 = 1.0 + value2*( 0.183105e-2
+ value2*(-0.3516396496e-4
+ value2*(0.2457520174e-5
+ value2*(-0.240337019e-6 ) ) ) );
fact2 = 0.04687499995 + value2*(-0.2002690873e-3
+ value2*( 0.8449199096e-5
+ value2*(-0.88228987e-6
+ value2*0.105787412e-6 ) ) );
bessel = std::sqrt( 0.636619772/modvalue)*(std::cos(shift)*fact1 - arg*std::sin(shift)*fact2);
if (value < 0.0) bessel = -bessel;
}
return bessel;
}
////////////////////////////////////////////////////////////////////////////////
// return J1(x)/x with special case for small x
G4double G4AntiNuclElastic::BesselOneByArg(G4double x)
{
G4double x2, result;
if( std::fabs(x) < 0.01 )
{
x *= 0.5;
x2 = x*x;
result = (2.- x2 + x2*x2/6.)/4.;
}
else
{
result = BesselJone(x)/x;
}
return result;
}
/////////////////////////////////////////////////////////////////////////////////
// return angle from which Coulomb scattering is calculated
G4double G4AntiNuclElastic::GetcosTeta1(G4double plab, G4int A)
{
// G4double p0 =G4LossTableManager::Instance()->FactorForAngleLimit()*CLHEP::hbarc/CLHEP::fermi;
G4double p0 = 1.*hbarc/fermi;
//G4double cteta1 = 1.0 - p0*p0/2.0 * pow(A,2./3.)/(plab*plab);
G4double cteta1 = 1.0 - p0*p0/2.0 * G4Pow::GetInstance()->Z23(A)/(plab*plab);
//////////////////
if(cteta1 < -1.) cteta1 = -1.0;
return cteta1;
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4CHIPSElastic.cc,v 1.4 2010/01/13 15:42:06 mkossov Exp $
// GEANT4 tag $Name: geant4-09-04-beta-01 $
// $Id: G4CHIPSElastic.cc,v 1.4 2010-01-13 15:42:06 mkossov Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
//---------------------------------------------------------------------
//
@@ -45,39 +45,97 @@
#include "G4QProtonElasticCrossSection.hh"
#include "G4QNeutronElasticCrossSection.hh"
#include "G4QAntiBaryonElasticCrossSection.hh" // Uzhi
#include "G4QPionPlusElasticCrossSection.hh" // Uzhi
#include "G4QPionMinusElasticCrossSection.hh" // Uzhi
#include "G4QKaonPlusElasticCrossSection.hh" // Uzhi
#include "G4QKaonMinusElasticCrossSection.hh" // Uzhi
#include <iostream>
G4VQCrossSection* G4CHIPSElastic::pxsManager = 0;
G4VQCrossSection* G4CHIPSElastic::nxsManager = 0;
G4CHIPSElastic::G4CHIPSElastic() : G4VHadronElastic("hElasticCHIPS")
G4VQCrossSection* G4CHIPSElastic::PBARxsManager = 0; // Uzhi
G4VQCrossSection* G4CHIPSElastic::PIPxsManager = 0;
G4VQCrossSection* G4CHIPSElastic::PIMxsManager = 0;
G4VQCrossSection* G4CHIPSElastic::KPxsManager = 0;
G4VQCrossSection* G4CHIPSElastic::KMxsManager = 0;
G4CHIPSElastic::G4CHIPSElastic() : G4HadronElastic("hElasticCHIPS")
{
if(!pxsManager)
{
pxsManager = G4QProtonElasticCrossSection::GetPointer();
nxsManager = G4QNeutronElasticCrossSection::GetPointer();
pxsManager = G4QProtonElasticCrossSection::GetPointer();
nxsManager = G4QNeutronElasticCrossSection::GetPointer();
PBARxsManager = G4QAntiBaryonElasticCrossSection::GetPointer(); // Uzhi
PIPxsManager = G4QPionPlusElasticCrossSection::GetPointer(); // Uzhi
PIMxsManager = G4QPionMinusElasticCrossSection::GetPointer(); // Uzhi
KPxsManager = G4QKaonPlusElasticCrossSection::GetPointer(); // Uzhi
KMxsManager = G4QKaonMinusElasticCrossSection::GetPointer(); // Uzhi
}
//Description();
}
G4CHIPSElastic::~G4CHIPSElastic()
{}
void G4CHIPSElastic::Description() const
{
char* dirName = getenv("G4PhysListDocDir");
if (dirName) {
std::ofstream outFile;
G4String outFileName = GetModelName() + ".html";
G4String pathName = G4String(dirName) + "/" + outFileName;
outFile.open(pathName);
outFile << "<html>\n";
outFile << "<head>\n";
outFile << "<title>Description of G4CHIPSElastic</title>\n";
outFile << "</head>\n";
outFile << "<body>\n";
outFile << "The G4CHIPSElastic model performs hadron-nucleus elastic\n"
<< "scattering using the parameterized elastic cross sections\n"
<< "of M. Kossov\n";
outFile << "</body>\n";
outFile << "</html>\n";
outFile.close();
}
}
G4double
G4CHIPSElastic::SampleInvariantT(const G4ParticleDefinition* p,
G4double plab, G4int Z, G4int A)
{
G4int N = A - Z;
if(Z == 1 && N == 2) N = 1;
else if(Z == 2 && N == 1) N = 2;
if(Z == 1 && N == 2) { N = 1; }
else if(Z == 2 && N == 1) { N = 2; }
G4int projPDG = p->GetPDGEncoding();
G4double cs = 0.;
if (projPDG==2212) cs = pxsManager->GetCrossSection(false,plab,Z,N,projPDG);
else if(projPDG==2112) cs = nxsManager->GetCrossSection(false,plab,Z,N,projPDG);
if (projPDG==2212) { cs = pxsManager->GetCrossSection(false,plab,Z,N,projPDG); }
else if(projPDG==2112) { cs = nxsManager->GetCrossSection(false,plab,Z,N,projPDG); }
else if(projPDG==-2212){ cs = PBARxsManager->GetCrossSection(false,plab,Z,N,projPDG); } //Pbar
else if(projPDG== 211) { cs = PIPxsManager->GetCrossSection(false,plab,Z,N,projPDG); } // Pi+
else if(projPDG==-211) { cs = PIMxsManager->GetCrossSection(false,plab,Z,N,projPDG); } // Pi-
else if(projPDG== 321) { cs = KPxsManager->GetCrossSection(false,plab,Z,N,projPDG); } // K+
else if(projPDG==-321) { cs = KMxsManager->GetCrossSection(false,plab,Z,N,projPDG); } // K-
G4double t = 0.0;
if(cs > 0.0)
{
if (projPDG==2212) t = pxsManager->GetExchangeT(Z,N,projPDG);
else if(projPDG==2112) t = nxsManager->GetExchangeT(Z,N,projPDG);
if (projPDG== 2212) { t = pxsManager->GetExchangeT(Z,N,projPDG); }
else if(projPDG== 2112) { t = nxsManager->GetExchangeT(Z,N,projPDG); }
else if(projPDG==-2212) { t = PBARxsManager->GetExchangeT(Z,N,projPDG); } // Pbar
else if(projPDG== 211) { t = PIPxsManager->GetExchangeT(Z,N,projPDG); } // Pi+
else if(projPDG== -211) { t = PIMxsManager->GetExchangeT(Z,N,projPDG); } // Pi-
else if(projPDG== 321) { t = KPxsManager->GetExchangeT(Z,N,projPDG); } // K+
else if(projPDG== -321) { t = KMxsManager->GetExchangeT(Z,N,projPDG); } // K-
}
else t = G4VHadronElastic::SampleInvariantT(p, plab, Z, A);
else { t = G4HadronElastic::SampleInvariantT(p, plab, Z, A); }
return t;
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4CHIPSElasticXS.cc,v 1.2 2010/09/24 13:56:00 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
// $Id: G4CHIPSElasticXS.cc,v 1.2 2010-09-24 13:56:00 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
// -------------------------------------------------------------------
//
@@ -36,9 +36,12 @@
// Author Ivantchenko, Geant4, 3-Aug-09
//
// Modifications:
// 31-05-2011 V.Uzhinsky added anti-baryons, Pi+, Pi-, K+, K- cross sections
// 23-08-2011 V.Ivanchenko migration to new design and cleanup
//
#include "G4CHIPSElasticXS.hh"
#include "G4HadronicException.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4Element.hh"
@@ -48,6 +51,12 @@
#include "G4QProtonElasticCrossSection.hh"
#include "G4QNeutronElasticCrossSection.hh"
#include "G4QAntiBaryonElasticCrossSection.hh" // Uzhi
#include "G4QPionMinusElasticCrossSection.hh" // Uzhi
#include "G4QPionPlusElasticCrossSection.hh" // Uzhi
#include "G4QKaonMinusElasticCrossSection.hh" // Uzhi
#include "G4QKaonPlusElasticCrossSection.hh" // Uzhi
G4CHIPSElasticXS::G4CHIPSElasticXS()
: G4VCrossSectionDataSet("CHIPSElasticXS"),
theProton(G4Proton::Proton()),
@@ -58,124 +67,114 @@ G4CHIPSElasticXS::G4CHIPSElasticXS()
// verboseLevel = 0;
pCManager = G4QProtonElasticCrossSection::GetPointer();
nCManager = G4QNeutronElasticCrossSection::GetPointer();
PBARxsManager = G4QAntiBaryonElasticCrossSection::GetPointer(); // Uzhi
PIPxsManager = G4QPionPlusElasticCrossSection::GetPointer(); // Uzhi
PIMxsManager = G4QPionMinusElasticCrossSection::GetPointer(); // Uzhi
KPxsManager = G4QKaonPlusElasticCrossSection::GetPointer(); // Uzhi
KMxsManager = G4QKaonMinusElasticCrossSection::GetPointer(); // Uzhi
//Description();
theParticle = 0;
}
G4CHIPSElasticXS::~G4CHIPSElasticXS()
{}
G4bool
G4CHIPSElasticXS::IsApplicable(const G4DynamicParticle* dyn,
const G4Element* elm)
{
return (elm->GetZ() < 2.5 && dyn->GetKineticEnergy() > thEnergy);
}
G4bool
G4CHIPSElasticXS::IsZAApplicable(const G4DynamicParticle* dyn,
G4double ZZ, G4double /*AA*/)
void G4CHIPSElasticXS::Description() const
{
return (ZZ < 2.5 && dyn->GetKineticEnergy() > thEnergy);
char* dirName = getenv("G4PhysListDocDir");
if (dirName) {
std::ofstream outFile;
G4String outFileName = GetName() + ".html";
G4String pathName = G4String(dirName) + "/" + outFileName;
outFile.open(pathName);
outFile << "<html>\n";
outFile << "<head>\n";
outFile << "<title>Description of CHIPS Elastic Cross Section</title>\n";
outFile << "</head>\n";
outFile << "<body>\n";
outFile << "G4CHIPSElasticXS provides hadron-nuclear elastic scattering\n"
<< "cross sections for protons and neutrons with incident energies\n"
<< "between 19 MeV and X GeV. These cross sections represent\n"
<< "parameterizations developed by M. Kossov. (more detail)\n";
outFile << "</body>\n";
outFile << "</html>\n";
outFile.close();
}
}
G4bool
G4CHIPSElasticXS::IsIsoApplicable(const G4DynamicParticle* dyn,
G4int Z, G4int /*N*/)
G4int Z, G4int /*A*/,
const G4Element*, const G4Material*)
{
return (Z <= 2 && dyn->GetKineticEnergy() > thEnergy);
}
G4double
G4CHIPSElasticXS::GetCrossSection(const G4DynamicParticle* aParticle,
const G4Element* elm,
G4double)
G4CHIPSElasticXS::GetIsoCrossSection(const G4DynamicParticle* dyn,
G4int Z, G4int A,
const G4Isotope*, const G4Element*,
const G4Material*)
{
G4double xs = 0.0;
G4int Z = G4int(elm->GetZ());
G4IsotopeVector* isv = elm->GetIsotopeVector();
G4int ni = 0;
if(isv) { ni = isv->size(); }
if(ni <= 1) {
G4int A = G4int(elm->GetN()+0.5);
xs = GetZandACrossSection(aParticle, Z, A);
} else {
G4double* ab = elm->GetRelativeAbundanceVector();
for(G4int j=0; j<ni; ++j) {
G4int A = (*isv)[j]->GetN();
xs += ab[j]*GetZandACrossSection(aParticle, Z, A);
}
}
if(verboseLevel > 1) {
G4cout << "G4CHIPSElasticXS::GetCrossSection for "
<< theParticle->GetParticleName()
<< " on " << elm->GetName()
<< " ekin(MeV)= " << aParticle->GetKineticEnergy()/CLHEP::MeV
<< ", XSel(bn)= " << xs/CLHEP::barn << G4endl;
}
return xs;
}
G4double
G4CHIPSElasticXS::GetIsoCrossSection(const G4DynamicParticle* p,
const G4Isotope* iso,
G4double)
{
return GetZandACrossSection(p, iso->GetZ(), iso->GetN());
}
G4double
G4CHIPSElasticXS::GetIsoZACrossSection(const G4DynamicParticle* p,
G4double ZZ,
G4double AA,
G4double)
{
return GetZandACrossSection(p, G4int(ZZ), G4int(AA));
}
G4double
G4CHIPSElasticXS::GetZandACrossSection(const G4DynamicParticle* dyn,
G4int Z, G4int A, G4double)
{
G4double momentum = dyn->GetTotalMomentum();
// only proton, deuteron and He4 x-sections
G4int N = A - Z;
if(Z == 1) {
if(N > 1) { N = 1; }
} else if(Z == 2) { N = 2; }
G4double x = 0.0;
if(theParticle == theProton) {
x = pCManager->GetCrossSection(false,momentum,Z,N,pPDG);
G4double momentum = dyn->GetTotalMomentum();
G4int uPDGcode = dyn->GetPDGcode();
G4VQCrossSection* CHIPSmanager = 0;
G4double cross = 0.0;
switch(uPDGcode) {
case 2212:
CHIPSmanager=pCManager;
break;
case 2112:
CHIPSmanager=nCManager;
break;
case -2212:
CHIPSmanager=PBARxsManager;
break;
case -2112:
CHIPSmanager=PBARxsManager;
break;
case 211:
CHIPSmanager=PIPxsManager;
break;
case -211:
CHIPSmanager=PIMxsManager;
break;
case 321:
CHIPSmanager=KPxsManager;
break;
case -321:
CHIPSmanager=KMxsManager;
break;
case 130:
break;
case 310:
break;
case 311:
break;
case -311:
break;
default:
throw G4HadronicException(__FILE__, __LINE__,
"G4CHIPSElasticXS: not applicable for a particle");
return cross;
}
if(CHIPSmanager) {
cross = CHIPSmanager->GetCrossSection(false,momentum,Z,N,uPDGcode);
} else {
x = nCManager->GetCrossSection(false,momentum,Z,N,pPDG);
cross = 0.5*(KPxsManager->GetCrossSection(false,momentum,Z,N,uPDGcode) +
KMxsManager->GetCrossSection(false,momentum,Z,N,uPDGcode));
}
return x;
return cross;
}
void
G4CHIPSElasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
{
if(isInitialized) { return; }
if(verboseLevel > 0){
G4cout << "G4CHIPSElasticXS::BuildPhysicsTable for "
<< p.GetParticleName()
<< " Elow(MeV)= " << thEnergy/MeV
<< G4endl;
}
isInitialized = true;
theParticle = &p;
if(theParticle != theProton && theParticle != theNeutron) {
G4cout << "G4CHIPSElasticXS::BuildPhysicsTable ERROR for "
<< p.GetParticleName()
<< G4endl;
G4Exception("G4CHIPSElasticXS", "", FatalException,"Not applicable");
}
pPDG = theParticle->GetPDGEncoding();
}
void
G4CHIPSElasticXS::DumpPhysicsTable(const G4ParticleDefinition&)
{}
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4ChargeExchange.cc,v 1.18 2010/11/19 18:50:03 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
// $Id: G4ChargeExchange.cc,v 1.18 2010-11-19 18:50:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
//
// G4 Model: Charge and strangness exchange based on G4LightMedia model
@@ -79,7 +79,7 @@ G4ChargeExchange::G4ChargeExchange() : G4HadronicInteraction("Charge Exchange")
theD = G4Deuteron::Deuteron();
theT = G4Triton::Triton();
theA = G4Alpha::Alpha();
theA = G4He3::He3();
theHe3 = G4He3::He3();
}
G4ChargeExchange::~G4ChargeExchange()
@@ -227,10 +227,12 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
theDef =
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(Z,A,0.0);
}
if(!theSecondary) { return &theParticleChange; }
G4double m11 = theSecondary->GetPDGMass();
G4double m21 = theDef->GetPDGMass();
if(theRecoil) m21 += theRecoil->GetPDGMass();
else theRecoil = theDef;
if(theRecoil) { m21 += theRecoil->GetPDGMass(); }
else { theRecoil = theDef; }
G4double etot = lv0.e() + lv1.e();
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4ChargeExchangeProcess.cc,v 1.15 2008/11/27 16:43:00 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4ChargeExchangeProcess.cc,v 1.15 2008-11-27 16:43:00 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
//
// Geant4 Hadron Charge Exchange Process -- source file
@@ -56,6 +56,7 @@ G4ChargeExchangeProcess::G4ChargeExchangeProcess(const G4String& procName)
{
SetProcessSubType(fChargeExchange);
thEnergy = 20.*MeV;
pPDG = 0;
verboseLevel= 1;
AddDataSet(new G4HadronElasticDataSet);
theProton = G4Proton::Proton();
@@ -86,7 +87,7 @@ G4ChargeExchangeProcess::G4ChargeExchangeProcess(const G4String& procName)
theD = G4Deuteron::Deuteron();
theT = G4Triton::Triton();
theA = G4Alpha::Alpha();
theA = G4He3::He3();
theHe3 = G4He3::He3();
}
G4ChargeExchangeProcess::~G4ChargeExchangeProcess()
@@ -129,10 +130,10 @@ BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
G4HadronicProcess::BuildPhysicsTable(aParticleType);
}
G4double G4ChargeExchangeProcess::GetMicroscopicCrossSection(
G4double G4ChargeExchangeProcess::GetElementCrossSection(
const G4DynamicParticle* dp,
const G4Element* elm,
G4double temp)
const G4Material* mat)
{
// gives the microscopic cross section in GEANT4 internal units
G4double Z = elm->GetZ();
@@ -146,7 +147,7 @@ G4double G4ChargeExchangeProcess::GetMicroscopicCrossSection(
G4cout << "G4ChargeExchangeProcess compute GHAD CS for element "
<< elm->GetName()
<< G4endl;
x = store->GetCrossSection(dp, elm, temp);
x = store->GetCrossSection(dp, elm, mat);
if(verboseLevel>1)
G4cout << "G4ChargeExchangeProcess cross(mb)= " << x/millibarn
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4DiffuseElastic.cc,v 1.25 2009/09/22 16:21:46 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4DiffuseElastic.cc,v 1.25 2009-09-22 16:21:46 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
//
// Physics model class G4DiffuseElastic
@@ -39,6 +39,7 @@
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4IonTable.hh"
#include "G4NucleiProperties.hh"
#include "Randomize.hh"
#include "G4Integrator.hh"
@@ -63,7 +64,7 @@
G4DiffuseElastic::G4DiffuseElastic()
: G4HadronicInteraction(), fParticle(0)
: G4HadronElastic("DiffuseElastic"), fParticle(0)
{
SetMinEnergy( 0.01*GeV );
SetMaxEnergy( 1.*TeV );
@@ -98,48 +99,6 @@ G4DiffuseElastic::G4DiffuseElastic()
fAddCoulomb = false;
}
//////////////////////////////////////////////////////////////////////////
//
// Constructor with initialisation
G4DiffuseElastic::G4DiffuseElastic(const G4ParticleDefinition* aParticle)
: G4HadronicInteraction(), fParticle(aParticle)
{
SetMinEnergy( 0.01*GeV );
SetMaxEnergy( 1.*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; // 200; // 100;
fAngleBin = 400; // 200; // 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
@@ -188,181 +147,6 @@ void G4DiffuseElastic::Initialise()
return;
}
////////////////////////////////////////////////////////////////////////////////
//
// Model analog of DoIt function
G4HadFinalState*
G4DiffuseElastic::ApplyYourself( const G4HadProjectile& aTrack,
G4Nucleus& targetNucleus )
{
theParticleChange.Clear();
const G4HadProjectile* aParticle = &aTrack;
G4double ekin = aParticle->GetKineticEnergy();
if(ekin <= lowestEnergyLimit)
{
theParticleChange.SetEnergyChange(ekin);
theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
return &theParticleChange;
}
G4double aTarget = targetNucleus.GetN();
G4double zTarget = targetNucleus.GetZ();
G4double plab = aParticle->GetTotalMomentum();
if (verboseLevel >1)
{
G4cout << "G4DiffuseElastic::DoIt: Incident particle plab="
<< plab/GeV << " GeV/c "
<< " ekin(MeV) = " << ekin/MeV << " "
<< aParticle->GetDefinition()->GetParticleName() << G4endl;
}
// Scattered particle referred to axis of incident particle
const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
G4double m1 = theParticle->GetPDGMass();
G4int Z = static_cast<G4int>(zTarget+0.5);
G4int A = static_cast<G4int>(aTarget+0.5);
G4int N = A - Z;
G4int projPDG = theParticle->GetPDGEncoding();
if (verboseLevel>1)
{
G4cout << "G4DiffuseElastic for " << theParticle->GetParticleName()
<< " PDGcode= " << projPDG << " on nucleus Z= " << Z
<< " A= " << A << " N= " << N
<< G4endl;
}
G4ParticleDefinition * theDef = 0;
if(Z == 1 && A == 1) theDef = theProton;
else if (Z == 1 && A == 2) theDef = theDeuteron;
else if (Z == 1 && A == 3) theDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theDef = G4He3::He3();
else if (Z == 2 && A == 4) theDef = theAlpha;
else theDef = G4ParticleTable::GetParticleTable()->FindIon(Z,A,0,Z);
G4double m2 = theDef->GetPDGMass();
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv(0.0,0.0,0.0,m2);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double tmax = 4.0*ptot*ptot;
G4double t = 0.0;
//
// Sample t
//
// t = SampleT( theParticle, ptot, A);
t = SampleTableT( theParticle, ptot, Z, A); // use initialised table
// NaN finder
if(!(t < 0.0 || t >= 0.0))
{
if (verboseLevel > 0)
{
G4cout << "G4DiffuseElastic:WARNING: Z= " << Z << " N= "
<< N << " pdg= " << projPDG
<< " mom(GeV)= " << plab/GeV
<< " S-wave will be sampled"
<< G4endl;
}
t = G4UniformRand()*tmax;
}
if(verboseLevel>1)
{
G4cout <<" t= " << t << " tmax= " << tmax
<< " ptot= " << ptot << G4endl;
}
// Sampling of angles in CM system
G4double phi = G4UniformRand()*twopi;
G4double cost = 1. - 2.0*t/tmax;
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(t)=" << cost << " std::sin(t)=" << 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);
G4double eFinal = nlv1.e() - m1;
if (verboseLevel > 1)
{
G4cout << "Scattered: "
<< nlv1<<" m= " << m1 << " ekin(MeV)= " << eFinal
<< " Proj: 4-mom " << lv1
<<G4endl;
}
if(eFinal < 0.0)
{
G4cout << "G4DiffuseElastic WARNING ekin= " << eFinal
<< " after scattering of "
<< aParticle->GetDefinition()->GetParticleName()
<< " p(GeV/c)= " << plab
<< " on " << theDef->GetParticleName()
<< G4endl;
eFinal = 0.0;
nlv1.setE(m1);
}
theParticleChange.SetMomentumChange(nlv1.vect().unit());
theParticleChange.SetEnergyChange(eFinal);
G4LorentzVector nlv0 = lv - nlv1;
G4double erec = nlv0.e() - m2;
if (verboseLevel > 1)
{
G4cout << "Recoil: "
<< nlv0<<" m= " << m2 << " ekin(MeV)= " << erec
<<G4endl;
}
if(erec > lowEnergyRecoilLimit)
{
G4DynamicParticle * aSec = new G4DynamicParticle(theDef, nlv0);
theParticleChange.AddSecondary(aSec);
} else {
if(erec < 0.0) erec = 0.0;
theParticleChange.SetLocalEnergyDeposit(erec);
}
return &theParticleChange;
}
////////////////////////////////////////////////////////////////////////////
//
// return differential elastic cross section d(sigma)/d(omega)
@@ -950,6 +734,31 @@ G4DiffuseElastic::SampleThetaCMS(const G4ParticleDefinition* particle,
//
// Return inv momentum transfer -t > 0 from initialisation table
G4double G4DiffuseElastic::SampleInvariantT( const G4ParticleDefinition* aParticle, G4double p,
G4int Z, G4int A)
{
fParticle = aParticle;
G4double m1 = fParticle->GetPDGMass();
G4double totElab = std::sqrt(m1*m1+p*p);
G4double m2 = G4NucleiProperties::GetNuclearMass(A, Z);
G4LorentzVector lv1(p,0.0,0.0,totElab);
G4LorentzVector lv(0.0,0.0,0.0,m2);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double momentumCMS = p1.mag();
G4double t = SampleTableT( aParticle, momentumCMS, G4double(Z), G4double(A) ); // sample theta2 in cms
return t;
}
////////////////////////////////////////////////////////////////////////////
//
// Return inv momentum transfer -t > 0 from initialisation table
G4double G4DiffuseElastic::SampleTableT( const G4ParticleDefinition* aParticle, G4double p,
G4double Z, G4double A)
{
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4ElasticHadrNucleusHE.cc,v 1.82 2010/11/18 22:49:57 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
// $Id: G4ElasticHadrNucleusHE.cc,v 1.82 2010-11-18 22:49:57 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
//
// The generator of high energy hadron-nucleus elastic scattering
@@ -218,13 +218,19 @@ void G4ElasticData::DefineNucleusParameters(G4double A)
// The constructor for the generating of events
//
G4ElasticHadrNucleusHE::G4ElasticHadrNucleusHE()
: G4VHadronElastic("hElasticGlauber")
// :G4HadronicInteraction("G4ElasticHadrNucleusHE")
G4ElasticHadrNucleusHE::G4ElasticHadrNucleusHE(const G4String& name)
: G4HadronElastic(name)
{
dQ2 = hMass = hMass2 = hLabMomentum = hLabMomentum2 = MomentumCM = HadrEnergy
= R1 = R2 = Pnucl = Aeff = HadrTot = HadrSlope = HadrReIm = TotP = DDSect2
= DDSect3 = ConstU = FmaxT = Slope1 = Slope2 = Coeff1 = Coeff2 = MaxTR
= Slope0 = Coeff0 = aAIm = aDIm = Dtot11 = 0.0;
NumbN = iHadrCode = iHadron = 0;
verboseLevel = 0;
plabLowLimit = 20.0*MeV;
lowestEnergyLimit = 0.0;
//Description();
MbToGeV2 = 2.568;
sqMbToGeV = 1.602;
@@ -233,13 +239,13 @@ G4ElasticHadrNucleusHE::G4ElasticHadrNucleusHE()
protonM = proton_mass_c2/GeV;
protonM2 = protonM*protonM;
BoundaryP[0]=9.0;BoundaryTG[0]=5.0;BoundaryTL[0]=0.;
BoundaryP[1]=20.0;BoundaryTG[1]=1.5;BoundaryTL[1]=0.;
BoundaryP[2]=5.0; BoundaryTG[2]=1.0;BoundaryTL[2]=1.5;
BoundaryP[3]=8.0; BoundaryTG[3]=3.0;BoundaryTL[3]=0.;
BoundaryP[4]=7.0; BoundaryTG[4]=3.0;BoundaryTL[4]=0.;
BoundaryP[5]=5.0; BoundaryTG[5]=2.0;BoundaryTL[5]=0.;
BoundaryP[6]=5.0; BoundaryTG[6]=1.5;BoundaryTL[6]=3.0;
BoundaryP[0]=9.0;BoundaryTG[0]=5.0;BoundaryTL[0]=0.;
BoundaryP[1]=20.0;BoundaryTG[1]=1.5;BoundaryTL[1]=0.;
BoundaryP[2]=5.0; BoundaryTG[2]=1.0;BoundaryTL[2]=1.5;
BoundaryP[3]=8.0; BoundaryTG[3]=3.0;BoundaryTL[3]=0.;
BoundaryP[4]=7.0; BoundaryTG[4]=3.0;BoundaryTL[4]=0.;
BoundaryP[5]=5.0; BoundaryTG[5]=2.0;BoundaryTL[5]=0.;
BoundaryP[6]=5.0; BoundaryTG[6]=1.5;BoundaryTL[6]=3.0;
Binom();
// energy in GeV
@@ -277,10 +283,38 @@ G4ElasticHadrNucleusHE::G4ElasticHadrNucleusHE()
HadronType[j] = id[j];
HadronType1[j] = id1[j];
for(G4int k = 0; k < 93; k++) SetOfElasticData[j][k] = 0;
for(G4int k = 0; k < 93; k++) { SetOfElasticData[j][k] = 0; }
}
}
void G4ElasticHadrNucleusHE::Description() const
{
char* dirName = getenv("G4PhysListDocDir");
if (dirName) {
std::ofstream outFile;
G4String outFileName = GetModelName() + ".html";
G4String pathName = G4String(dirName) + "/" + outFileName;
outFile.open(pathName);
outFile << "<html>\n";
outFile << "<head>\n";
outFile << "<title>Description of G4ElasticHadrNucleusHE Model</title>\n";
outFile << "</head>\n";
outFile << "<body>\n";
outFile << "G4ElasticHadrNucleusHE is a hadron-nucleus elastic scattering\n"
<< "model developed by N. Starkov which uses a Glauber model\n"
<< "parameterization to calculate the final state. It is valid\n"
<< "for all hadrons with incident energies above 1 GeV.\n";
outFile << "</body>\n";
outFile << "</html>\n";
outFile.close();
}
}
///////////////////////////////////////////////////////////////////
//
//
@@ -451,7 +485,7 @@ G4double G4ElasticHadrNucleusHE::
<<Pnucl<<G4endl;
}
pElD->CrossSecMaxQ2[NumbOnE] = 1.0;
//pElD->CrossSecMaxQ2[NumbOnE] = 1.0;
if(verboseLevel > 1)
G4cout<<" HadrNucleusQ2_2: NumbOnE= " << NumbOnE
@@ -663,7 +697,7 @@ G4double G4ElasticHadrNucleusHE::GetLightFq2(G4int Z, G4int Nucleus,
G4double Prod0 = 0;
G4double N1 = -1.0;
G4double Tot0 = 0;
//G4double Tot0 = 0;
G4double exp1;
G4double Prod3 ;
@@ -675,7 +709,7 @@ G4double G4ElasticHadrNucleusHE::GetLightFq2(G4int Z, G4int Nucleus,
{
N1 = -N1*Unucl*(Nucleus-i1+1)/i1*Rho2;
Prod1 = 0;
Tot0 = 0;
//Tot0 = 0;
N2 = -1;
for(i2 = 1; i2<=Nucleus; i2++) ////+++++++++ i2
@@ -23,111 +23,72 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4HadronElastic.cc,v 1.68 2010/11/19 18:50:03 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
// $Id: G4HadronElastic.cc,v 1.6 2010-11-19 18:50:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
// Geant4 Header : G4HadronElastic
//
// Physics model class G4HadronElastic (derived from G4LElastic)
//
//
// G4 Model: Low-energy Elastic scattering with 4-momentum balance
// F.W. Jones, TRIUMF, 04-JUN-96
// Uses G4ElasticHadrNucleusHE and G4VQCrossSection
//
//
// 25-JUN-98 FWJ: replaced missing Initialize for ParticleChange.
// 09-Set-05 V.Ivanchenko HARP version of the model: fix scattering
// on hydrogen, use relativistic Lorentz transformation
// 24-Nov-05 V.Ivanchenko sample cost in center of mass reference system
// 03-Dec-05 V.Ivanchenko add protection to initial momentum 20 MeV/c in
// center of mass system (before it was in lab system)
// below model is not valid
// 14-Dec-05 V.Ivanchenko change protection to cos(theta) < -1 and
// rename the class
// 13-Apr-06 V.Ivanchenko move to coherent_elastic subdirectory; remove
// charge exchange; remove limitation on incident momentum;
// add s-wave regim below some momentum
// 24-Apr-06 V.Ivanchenko add neutron scattering on hydrogen from CHIPS
// 07-Jun-06 V.Ivanchenko fix problem of rotation
// 25-Jul-06 V.Ivanchenko add 19 MeV low energy, below which S-wave is sampled
// 02-Aug-06 V.Ivanchenko introduce energy cut on the aria of S-wave for pions
// 24-Aug-06 V.Ivanchenko switch on G4ElasticHadrNucleusHE
// 31-Aug-06 V.Ivanchenko do not sample sacttering for particles with kinetic
// energy below 10 keV
// 16-Nov-06 V.Ivanchenko Simplify logic of choosing of the model for sampling
// 30-Mar-07 V.Ivanchenko lowEnergyLimitQ=0, lowEnergyLimitHE = 1.0*GeV,
// lowestEnergyLimit= 0
// 04-May-07 V.Ivanchenko do not use HE model for hydrogen target to avoid NaN;
// use QElastic for p, n incident for any energy for
// p and He targets only
// 11-May-07 V.Ivanchenko remove unused method Defs1
// 13.01.10: M.Kosov: Use G4Q(Pr/Neut)ElasticCS instead of G4QElasticCS
//
// Author : V.Ivanchenko 29 June 2009 (redesign old elastic model)
//
#include "G4HadronElastic.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4IonTable.hh"
#include "G4QProtonElasticCrossSection.hh"
#include "G4QNeutronElasticCrossSection.hh"
#include "G4VQCrossSection.hh"
#include "G4ElasticHadrNucleusHE.hh"
#include "Randomize.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
#include "G4Alpha.hh"
#include "G4PionPlus.hh"
#include "G4PionMinus.hh"
#include "G4Pow.hh"
G4VQCrossSection* G4HadronElastic::pCManager = 0;
G4VQCrossSection* G4HadronElastic::nCManager = 0;
G4HadronElastic::G4HadronElastic(G4ElasticHadrNucleusHE* HModel)
: G4HadronicInteraction("G4HadronElastic"), hElastic(HModel)
G4HadronElastic::G4HadronElastic(const G4String& name)
: G4HadronicInteraction(name)
{
SetMinEnergy( 0.0*GeV );
SetMaxEnergy( 100.*TeV );
verboseLevel= 0;
lowEnergyRecoilLimit = 100.*keV;
lowEnergyLimitQ = 0.0*GeV;
lowEnergyLimitHE = 1.0*GeV;
lowestEnergyLimit= 1.e-6*eV;
plabLowLimit = 20.0*MeV;
if(!pCManager)
{
pCManager = G4QProtonElasticCrossSection::GetPointer();
nCManager = G4QNeutronElasticCrossSection::GetPointer();
}
if(!hElastic) hElastic = new G4ElasticHadrNucleusHE();
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
theDeuteron = G4Deuteron::Deuteron();
theAlpha = G4Alpha::Alpha();
thePionPlus = G4PionPlus::PionPlus();
thePionMinus= G4PionMinus::PionMinus();
//Description();
}
G4HadronElastic::~G4HadronElastic()
{}
void G4HadronElastic::Description() const
{
delete hElastic;
char* dirName = getenv("G4PhysListDocDir");
if (dirName) {
std::ofstream outFile;
G4String outFileName = GetModelName() + ".html";
G4String pathName = G4String(dirName) + "/" + outFileName;
outFile.open(pathName);
outFile << "<html>\n";
outFile << "<head>\n";
outFile << "<title>Description of G4HadronElastic Model</title>\n";
outFile << "</head>\n";
outFile << "<body>\n";
outFile << "G4HadronElastic is a hadron-nucleus elastic scattering\n"
<< "model which uses the Gheisha two-exponential momentum\n"
<< "transfer parameterization. The model is fully relativistic\n"
<< "as opposed to the original Gheisha model which was not.\n"
<< "This model may be used for all long-lived hadrons at all\n"
<< "incident energies.\n";
outFile << "</body>\n";
outFile << "</html>\n";
outFile.close();
}
}
G4VQCrossSection* G4HadronElastic::GetCS()
{
return pCManager;
//if (PDG==2212) return pCManager;
//else if(PDG==2112) return nCManager;
//return 0;
}
G4ElasticHadrNucleusHE* G4HadronElastic::GetHElastic()
{
return hElastic;
}
G4HadFinalState* G4HadronElastic::ApplyYourself(
const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
@@ -146,34 +107,22 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
G4int Z = targetNucleus.GetZ_asInt();
G4double plab = aParticle->GetTotalMomentum();
if (verboseLevel >1) {
G4cout << "G4HadronElastic::DoIt: Incident particle plab="
<< plab/GeV << " GeV/c "
<< " ekin(MeV) = " << ekin/MeV << " "
<< aParticle->GetDefinition()->GetParticleName() << G4endl;
}
// Scattered particle referred to axis of incident particle
const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
G4double m1 = theParticle->GetPDGMass();
G4int N = A - Z;
G4int projPDG = theParticle->GetPDGEncoding();
if (verboseLevel>1) {
G4cout << "G4HadronElastic for " << theParticle->GetParticleName()
<< " PDGcode= " << projPDG << " on nucleus Z= " << Z
<< " A= " << A << " N= " << N
G4cout << "G4HadronElastic: "
<< aParticle->GetDefinition()->GetParticleName()
<< " Plab(GeV/c)= " << plab/GeV
<< " Ekin(MeV) = " << ekin/MeV
<< " scattered off Z= " << Z
<< " A= " << A
<< G4endl;
}
G4ParticleDefinition * theDef = 0;
if(Z == 1 && A == 1) theDef = theProton;
else if (Z == 1 && A == 2) theDef = theDeuteron;
else if (Z == 1 && A == 3) theDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theDef = G4He3::He3();
else if (Z == 2 && A == 4) theDef = theAlpha;
else theDef = G4ParticleTable::GetParticleTable()->GetIon(Z,A,0.0);
G4double m2 = theDef->GetPDGMass();
G4double m2 = G4NucleiProperties::GetNuclearMass(A, Z);
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv(0.0,0.0,0.0,m2);
lv += lv1;
@@ -182,84 +131,25 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double tmax = 4.0*ptot*ptot;
G4double t = 0.0;
G4double momentumCMS = p1.mag();
G4double tmax = 4.0*momentumCMS*momentumCMS;
// Choose generator
G4ElasticGenerator gtype = fLElastic;
// Q-elastic for p,n scattering on H and He
if (theParticle == theProton || theParticle == theNeutron) {
// && Z <= 2 && ekin >= lowEnergyLimitQ)
gtype = fQElastic;
} else {
// S-wave for very low energy
if(plab < plabLowLimit) gtype = fSWave;
// HE-elastic for energetic projectile mesons
else if(ekin >= lowEnergyLimitHE && theParticle->GetBaryonNumber() == 0)
{ gtype = fHElastic; }
}
//
// Sample t
//
if(gtype == fQElastic) {
if (verboseLevel >1) {
G4cout << "G4HadronElastic: Z= " << Z << " N= " << N << " pdg= " << projPDG
<< " mom(GeV)= " << plab/GeV<<", pC="<<pCManager<<", nC="<<nCManager<<G4endl;
}
if(Z == 1 && N == 2) N = 1;
else if(Z == 2 && N == 1) N = 2;
G4double cs = 0.;
if (projPDG==2212) cs = pCManager->GetCrossSection(false,plab,Z,N,projPDG);
else if(projPDG==2112) cs = nCManager->GetCrossSection(false,plab,Z,N,projPDG);
// check if cross section is reasonable
if(cs > 0.0)
{
if (projPDG==2212) t = pCManager->GetExchangeT(Z,N,projPDG);
else if(projPDG==2112) t = nCManager->GetExchangeT(Z,N,projPDG);
}
else if(plab > plabLowLimit) gtype = fLElastic;
else gtype = fSWave;
}
if(gtype == fLElastic) {
G4double g2 = GeV*GeV;
t = g2*SampleT(tmax/g2,m1,m2, A);
}
// use mean atomic number
if(gtype == fHElastic) {
t = hElastic->SampleT(theParticle,plab, Z, A);
}
if(gtype == fSWave) t = G4UniformRand()*tmax;
if(verboseLevel>1) {
G4cout <<"type= " << gtype <<" t= " << t << " tmax= " << tmax
<< " ptot= " << ptot << G4endl;
}
// Sampling in CM system
G4double phi = G4UniformRand()*twopi;
G4double t = SampleInvariantT(theParticle, plab, Z, A);
G4double phi = G4UniformRand()*CLHEP::twopi;
G4double cost = 1. - 2.0*t/tmax;
G4double sint;
// problem in sampling
if(cost > 1.0 || cost < -1.0) {
if(verboseLevel > 0) {
G4cout << "G4HadronElastic:WARNING: Z= " << Z << " N= "
<< N << " " << aParticle->GetDefinition()->GetParticleName()
<< " mom(GeV)= " << plab/GeV
<< " the model type " << gtype;
if(gtype == fQElastic) G4cout << " CHIPS ";
else if(gtype == fLElastic) G4cout << " LElastic ";
else if(gtype == fHElastic) G4cout << " HElastic ";
G4cout << " cost= " << cost
<< G4endl;
}
//if(verboseLevel > 0) {
G4cout << "G4HadronElastic WARNING (1 - cost)= " << 1 - cost
<< " after scattering of "
<< aParticle->GetDefinition()->GetParticleName()
<< " p(GeV/c)= " << plab
<< " on an ion Z= " << Z << " A= " << A
<< G4endl;
//}
cost = 1.0;
sint = 0.0;
@@ -268,28 +158,30 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
sint = std::sqrt((1.0-cost)*(1.0+cost));
}
if (verboseLevel>1) {
G4cout << "cos(t)=" << cost << " std::sin(t)=" << sint << G4endl;
G4cout << " t= " << t << " tmax= " << tmax
<< " Pcms= " << momentumCMS << " cos(t)=" << cost
<< " sin(t)=" << 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));
v1 *= momentumCMS;
G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),
std::sqrt(momentumCMS*momentumCMS + m1*m1));
nlv1.boost(bst);
G4double eFinal = nlv1.e() - m1;
if (verboseLevel > 1) {
G4cout << "Scattered: "
<< nlv1<<" m= " << m1 << " ekin(MeV)= " << eFinal
<< " Proj: 4-mom " << lv1
<<G4endl;
G4cout <<" m= " << m1 << " Efin(MeV)= " << eFinal
<< " Proj: 4-mom " << lv1 << " Final: " << nlv1
<< G4endl;
}
if(eFinal <= lowestEnergyLimit) {
if(eFinal < 0.0 && verboseLevel > 0) {
G4cout << "G4HadronElastic WARNING ekin= " << eFinal
G4cout << "G4HadronElastic WARNING Efinal= " << eFinal
<< " after scattering of "
<< aParticle->GetDefinition()->GetParticleName()
<< " p(GeV/c)= " << plab
<< " on " << theDef->GetParticleName()
<< " on an ion Z= " << Z << " A= " << A
<< G4endl;
}
theParticleChange.SetEnergyChange(0.0);
@@ -300,211 +192,63 @@ G4HadFinalState* G4HadronElastic::ApplyYourself(
theParticleChange.SetEnergyChange(eFinal);
}
G4LorentzVector nlv0 = lv - nlv1;
G4double erec = nlv0.e() - m2;
lv -= nlv1;
G4double erec = lv.e() - m2;
if (verboseLevel > 1) {
G4cout << "Recoil: "
<< nlv0<<" m= " << m2 << " ekin(MeV)= " << erec
<<G4endl;
G4cout << "Recoil: " <<" m= " << m2 << " Erec(MeV)= " << erec
<< " 4-mom: " << lv
<< G4endl;
}
if(erec > lowEnergyRecoilLimit) {
G4DynamicParticle * aSec = new G4DynamicParticle(theDef, nlv0);
if(erec > GetRecoilEnergyThreshold()) {
G4ParticleDefinition * theDef = 0;
if(Z == 1 && A == 1) { theDef = theProton; }
else if (Z == 1 && A == 2) { theDef = theDeuteron; }
else if (Z == 1 && A == 3) { theDef = G4Triton::Triton(); }
else if (Z == 2 && A == 3) { theDef = G4He3::He3(); }
else if (Z == 2 && A == 4) { theDef = theAlpha; }
else {
theDef =
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(Z,A,0.0);
}
G4DynamicParticle * aSec = new G4DynamicParticle(theDef, lv);
theParticleChange.AddSecondary(aSec);
} else {
if(erec < 0.0) erec = 0.0;
} else if(erec > 0.0) {
theParticleChange.SetLocalEnergyDeposit(erec);
}
return &theParticleChange;
}
// sample momentum transfer in the CMS system
G4double
G4HadronElastic::SampleT(G4double tmax, G4double, G4double, G4double atno2)
G4HadronElastic::SampleInvariantT(const G4ParticleDefinition* p,
G4double plab,
G4int Z, G4int A)
{
// G4cout << "Entering elastic scattering 2"<<G4endl;
// Compute the direction of elastic scattering.
// It is planned to replace this code with a method based on
// parameterized functions and a Monte Carlo method to invert the CDF.
// G4double ran = G4UniformRand();
G4double aa, bb, cc, dd, rr;
if (atno2 <= 62.) {
aa = std::pow(atno2, 1.63);
bb = 14.5*std::pow(atno2, 0.66);
cc = 1.4*std::pow(atno2, 0.33);
dd = 10.;
static const G4double GeV2 = GeV*GeV;
G4double momentumCMS = ComputeMomentumCMS(p,plab,Z,A);
G4double tmax = 4.0*momentumCMS*momentumCMS/GeV2;
G4double aa, bb, cc;
G4double dd = 10.;
G4Pow* g4pow = G4Pow::GetInstance();
if (A <= 62) {
bb = 14.5*g4pow->Z23(A);
aa = g4pow->powZ(A, 1.63)/bb;
cc = 1.4*g4pow->Z13(A)/dd;
} else {
aa = std::pow(atno2, 1.33);
bb = 60.*std::pow(atno2, 0.33);
cc = 0.4*std::pow(atno2, 0.40);
dd = 10.;
bb = 60.*g4pow->Z13(A);
aa = g4pow->powZ(A, 1.33)/bb;
cc = 0.4*g4pow->powZ(A, 0.4)/dd;
}
aa = aa/bb;
cc = cc/dd;
G4double ran, t1, t2;
do {
ran = G4UniformRand();
t1 = -std::log(ran)/bb;
t2 = -std::log(ran)/dd;
} while(t1 > tmax || t2 > tmax);
rr = (aa + cc)*ran;
if (verboseLevel > 1) {
G4cout << "DoIt: aa,bb,cc,dd,rr" << G4endl;
G4cout << aa << " " << bb << " " << cc << " " << dd << " " << rr << G4endl;
G4cout << "t1,Fctcos " << t1 << " " << Fctcos(t1, aa, bb, cc, dd, rr) << G4endl;
G4cout << "t2,Fctcos " << t2 << " " << Fctcos(t2, aa, bb, cc, dd, rr) << G4endl;
G4double q1 = 1.0 - std::exp(-bb*tmax);
G4double q2 = 1.0 - std::exp(-dd*tmax);
G4double s1 = q1*aa;
G4double s2 = q2*cc;
if((s1 + s2)*G4UniformRand() < s2) {
q1 = q2;
bb = dd;
}
G4double eps = 0.001;
G4int ind1 = 10;
G4double t = 0.0;
G4int ier1;
ier1 = Rtmi(&t, t1, t2, eps, ind1,
aa, bb, cc, dd, rr);
if (verboseLevel > 1) {
G4cout << "From Rtmi, ier1=" << ier1 << " t= " << t << G4endl;
G4cout << "t, Fctcos " << t << " " << Fctcos(t, aa, bb, cc, dd, rr) << G4endl;
}
if (ier1 != 0) t = 0.25*(3.*t1 + t2);
if (verboseLevel > 1) {
G4cout << "t, Fctcos " << t << " " << Fctcos(t, aa, bb, cc, dd, rr) <<
G4endl;
}
return t;
return -GeV2*std::log(1.0 - G4UniformRand()*q1)/bb;
}
// The following is a "translation" of a root-finding routine
// from GEANT3.21/GHEISHA. Some of the labelled block structure has
// been retained for clarity. This routine will not be needed after
// the planned revisions to DoIt().
G4int
G4HadronElastic::Rtmi(G4double* x, G4double xli, G4double xri, G4double eps,
G4int iend,
G4double aa, G4double bb, G4double cc, G4double dd,
G4double rr)
{
G4int ier = 0;
G4double xl = xli;
G4double xr = xri;
*x = xl;
G4double tol = *x;
G4double f = Fctcos(tol, aa, bb, cc, dd, rr);
if (f == 0.) return ier;
G4double fl, fr;
fl = f;
*x = xr;
tol = *x;
f = Fctcos(tol, aa, bb, cc, dd, rr);
if (f == 0.) return ier;
fr = f;
// Error return in case of wrong input data
if (fl*fr >= 0.) {
ier = 2;
return ier;
}
// Basic assumption fl*fr less than 0 is satisfied.
// Generate tolerance for function values.
G4int i = 0;
G4double tolf = 100.*eps;
// Start iteration loop
label4:
i++;
// Start bisection loop
for (G4int k = 1; k <= iend; k++) {
*x = 0.5*(xl + xr);
tol = *x;
f = Fctcos(tol, aa, bb, cc, dd, rr);
if (f == 0.) return 0;
if (f*fr < 0.) { // Interchange xl and xr in order to get the
tol = xl; // same Sign in f and fr
xl = xr;
xr = tol;
tol = fl;
fl = fr;
fr = tol;
}
tol = f - fl;
G4double a = f*tol;
a = a + a;
if (a < fr*(fr - fl) && i <= iend) goto label17;
xr = *x;
fr = f;
// Test on satisfactory accuracy in bisection loop
tol = eps;
a = std::abs(xr);
if (a > 1.) tol = tol*a;
if (std::abs(xr - xl) <= tol && std::abs(fr - fl) <= tolf) goto label14;
}
// End of bisection loop
// No convergence after iend iteration steps followed by iend
// successive steps of bisection or steadily increasing function
// values at right bounds. Error return.
ier = 1;
label14:
if (std::abs(fr) > std::abs(fl)) {
*x = xl;
f = fl;
}
return ier;
// Computation of iterated x-value by inverse parabolic interp
label17:
G4double a = fr - f;
G4double dx = (*x - xl)*fl*(1. + f*(a - tol)/(a*(fr - fl)))/tol;
G4double xm = *x;
G4double fm = f;
*x = xl - dx;
tol = *x;
f = Fctcos(tol, aa, bb, cc, dd, rr);
if (f == 0.) return ier;
// Test on satisfactory accuracy in iteration loop
tol = eps;
a = std::abs(*x);
if (a > 1) tol = tol*a;
if (std::abs(dx) <= tol && std::abs(f) <= tolf) return ier;
// Preparation of next bisection loop
if (f*fl < 0.) {
xr = *x;
fr = f;
}
else {
xl = *x;
fl = f;
xr = xm;
fr = fm;
}
goto label4;
}
// Test function for root-finder
G4double
G4HadronElastic::Fctcos(G4double t,
G4double aa, G4double bb, G4double cc, G4double dd,
G4double rr)
{
const G4double expxl = -82.;
const G4double expxu = 82.;
G4double test1 = -bb*t;
if (test1 > expxu) test1 = expxu;
if (test1 < expxl) test1 = expxl;
G4double test2 = -dd*t;
if (test2 > expxu) test2 = expxu;
if (test2 < expxl) test2 = expxl;
return aa*std::exp(test1) + cc*std::exp(test2) - rr;
}
@@ -29,6 +29,7 @@
// 11-OCT-2007 F.W. Jones: removed erroneous code for identity
// exchange of particles.
// FWJ 27-AUG-2010: extended to 5 GeV by Tony Kwan TRIUMF
#include "G4LEnp.hh"
#include "Randomize.hh"
@@ -46,7 +47,7 @@ G4LEnp::G4LEnp():G4HadronicInteraction("G4LEnp")
// SetMinEnergy(10.*MeV);
// SetMaxEnergy(1200.*MeV);
SetMinEnergy(0.);
SetMaxEnergy(1200.*GeV);
SetMaxEnergy(5.*GeV);
}
G4LEnp::~G4LEnp()
@@ -71,8 +72,8 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
G4double E = aParticle->GetTotalEnergy();
G4double E0 = aParticle->GetDefinition()->GetPDGMass();
G4double Q = aParticle->GetDefinition()->GetPDGCharge();
G4double N = targetNucleus.GetN();
G4double Z = targetNucleus.GetZ();
G4int A = targetNucleus.GetA_asInt();
G4int Z = targetNucleus.GetZ_asInt();
G4cout << "G4LEnp:ApplyYourself: incident particle: "
<< aParticle->GetDefinition()->GetParticleName() << G4endl;
G4cout << "P = " << P/GeV << " GeV/c"
@@ -84,7 +85,7 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
<< ", mass = " << E0/GeV << " GeV"
<< ", charge = " << Q << G4endl;
G4cout << "G4LEnp:ApplyYourself: material:" << G4endl;
G4cout << "A = " << N
G4cout << "A = " << A
<< ", Z = " << Z
<< ", atomic mass "
<< G4Proton::Proton()->GetPDGMass()/GeV << "GeV"
@@ -92,7 +93,7 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
//
// GHEISHA ADD operation to get total energy, mass, charge
//
E += G4Proton::Proton()->GetPDGMass();
E += proton_mass_c2;
G4double E02 = E*E - P*P;
E0 = std::sqrt(std::abs(E02));
if (E02 < 0)E0 *= -1;
@@ -115,8 +116,6 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
else
je1 = midBin;
} while (je2 - je1 > 1);
// G4int j;
//std::abs(ek-elab[je1]) < std::abs(ek-elab[je2]) ? j = je1 : j = je2;
G4double delab = elab[je2] - elab[je1];
// Sample the angle
@@ -130,10 +129,11 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
G4double sigint1 = rc*ek + b;
G4double sigint2 = 0.;
if (verboseLevel > 1) G4cout << "sample=" << sample << G4endl
<< ke1 << " " << ke2 << " "
<< sigint1 << " " << sigint2 << G4endl;
if (verboseLevel > 1) {
G4cout << "sample=" << sample << G4endl
<< ke1 << " " << ke2 << " "
<< sigint1 << " " << sigint2 << G4endl;
}
do {
G4int midBin = (ke1 + ke2)/2;
dsig = sig[je2][midBin] - sig[je1][midBin];
@@ -148,38 +148,23 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
ke1 = midBin;
sigint1 = sigint;
}
if (verboseLevel > 1)G4cout << ke1 << " " << ke2 << " "
<< sigint1 << " " << sigint2 << G4endl;
if (verboseLevel > 1) {
G4cout << ke1 << " " << ke2 << " "
<< sigint1 << " " << sigint2 << G4endl;
}
} while (ke2 - ke1 > 1);
// sigint1 and sigint2 should be recoverable from above loop
// G4double dsig = sig[je2][ke1] - sig[je1][ke1];
// G4double rc = dsig/delab;
// G4double b = sig[je1][ke1] - rc*elab[je1];
// G4double sigint1 = rc*ek + b;
// G4double dsig = sig[je2][ke2] - sig[je1][ke2];
// G4double rc = dsig/delab;
// G4double b = sig[je1][ke2] - rc*elab[je1];
// G4double sigint2 = rc*ek + b;
dsig = sigint2 - sigint1;
rc = 1./dsig;
b = ke1 - rc*sigint1;
G4double kint = rc*sample + b;
G4double theta = (0.5 + kint)*pi/180.;
// G4int k;
//std::abs(sample-sig[j][ke1]) < std::abs(sample-sig[j][ke2]) ? k = ke1 : k = ke2;
// G4double theta = (0.5 + k)*pi/180.;
if (verboseLevel > 1) {
G4cout << " energy bin " << je1 << " energy=" << elab[je1] << G4endl;
G4cout << " angle bin " << kint << " angle=" << theta/degree << G4endl;
}
// Get the target particle
G4DynamicParticle* targetParticle = targetNucleus.ReturnTargetParticle();
@@ -190,7 +175,6 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
G4double M2 = targetParticle->GetDefinition()->GetPDGMass();
G4double totalEnergy = E1 + E2;
G4double pseudoMass = std::sqrt(totalEnergy*totalEnergy - P*P);
// pseudoMass also = std::sqrt(M1*M1 + M2*M2 + 2*M2*E1)
// Transform into centre of mass system
@@ -216,7 +200,7 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
if (px*px + py*py > 0) {
G4double cost, sint, ph, cosp, sinp;
cost = pz/p;
sint = (std::sqrt(std::abs((1-cost)*(1+cost))) + std::sqrt(px*px+py*py)/p)/2;
sint = (std::sqrt(std::fabs((1-cost)*(1+cost))) + std::sqrt(px*px+py*py)/p)/2;
py < 0 ? ph = 3*halfpi : ph = halfpi;
if (std::abs(px) > 0.000001*GeV) ph = std::atan2(py,px);
cosp = std::cos(ph);
@@ -224,10 +208,6 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
px = (cost*cosp*pxnew - sinp*pynew + sint*cosp*pznew);
py = (cost*sinp*pxnew + cosp*pynew + sint*sinp*pznew);
pz = (-sint*pxnew + cost*pznew);
// G4ThreeVector it(a,b,c);
// p0->SetMomentum(it);
// G4ThreeVector aTargetMom = theInitial - it;
// targetParticle->SetMomentum(aTargetMom);
}
else {
px = pxnew;
@@ -317,10 +297,7 @@ G4LEnp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
theParticleChange.SetMomentumChange(newP->GetMomentumDirection());
theParticleChange.SetEnergyChange(newP->GetKineticEnergy());
delete newP;
G4DynamicParticle* p1 = new G4DynamicParticle;
p1->SetDefinition(targetParticle->GetDefinition());
p1->SetMomentum(targetParticle->GetMomentum());
theParticleChange.AddSecondary(p1);
theParticleChange.AddSecondary(targetParticle);
return &theParticleChange;
}
@@ -27,6 +27,7 @@
// G4 Low energy model: n-n or p-p scattering
// F.W. Jones, L.G. Greeniaus, H.P. Wellisch
// FWJ 27-AUG-2010: extended Coulomb-suppressed data to 5 GeV
#include "G4LEpp.hh"
#include "Randomize.hh"
@@ -44,7 +45,7 @@ G4LEpp::G4LEpp():G4HadronicInteraction("G4LEpp")
SetCoulombEffects(0);
SetMinEnergy(0.);
SetMaxEnergy(1200.*GeV);
SetMaxEnergy(5.*GeV);
}
G4LEpp::~G4LEpp()
@@ -62,6 +63,7 @@ G4LEpp::SetCoulombEffects(G4int State)
sig[i] = SigCoul[i];
}
elab = ElabCoul;
SetMaxEnergy(1.2*GeV);
}
else {
for(G4int i=0; i<NANGLE; i++)
@@ -69,6 +71,7 @@ G4LEpp::SetCoulombEffects(G4int State)
sig[i] = Sig[i];
}
elab = Elab;
SetMaxEnergy(5.*GeV);
}
}
@@ -86,13 +89,12 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
G4double ek = aParticle->GetKineticEnergy();
G4ThreeVector theInitial = aParticle->Get4Momentum().vect();
// if (verboseLevel > 1)
{
if (verboseLevel > 1) {
G4double E = aParticle->GetTotalEnergy();
G4double E0 = aParticle->GetDefinition()->GetPDGMass();
G4double Q = aParticle->GetDefinition()->GetPDGCharge();
G4double N = targetNucleus.GetN();
G4double Z = targetNucleus.GetZ();
G4int A = targetNucleus.GetA_asInt();
G4int Z = targetNucleus.GetZ_asInt();
G4cout << "G4LEpp:ApplyYourself: incident particle: "
<< aParticle->GetDefinition()->GetParticleName() << G4endl;
G4cout << "P = " << P/GeV << " GeV/c"
@@ -104,7 +106,7 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
<< ", mass = " << E0/GeV << " GeV"
<< ", charge = " << Q << G4endl;
G4cout << "G4LEpp:ApplyYourself: material:" << G4endl;
G4cout << "A = " << N
G4cout << "A = " << A
<< ", Z = " << Z
<< ", atomic mass "
<< G4Proton::Proton()->GetPDGMass()/GeV << "GeV"
@@ -112,9 +114,9 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
//
// GHEISHA ADD operation to get total energy, mass, charge
//
E += G4Proton::Proton()->GetPDGMass();
E += proton_mass_c2;
G4double E02 = E*E - P*P;
E0 = std::sqrt(std::abs(E02));
E0 = std::sqrt(std::fabs(E02));
if (E02 < 0)E0 *= -1;
Q += Z;
G4cout << "G4LEpp:ApplyYourself: total:" << G4endl;
@@ -135,8 +137,6 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
else
je1 = midBin;
} while (je2 - je1 > 1);
// G4int j;
//std::abs(ek-elab[je1]) < std::abs(ek-elab[je2]) ? j = je1 : j = je2;
G4double delab = elab[je2] - elab[je1];
// Sample the angle
@@ -172,37 +172,19 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
<< sigint1 << " " << sigint2 << G4endl;
} while (ke2 - ke1 > 1);
// sigint1 and sigint2 should be recoverable from above loop
// G4double dsig = sig[je2][ke1] - sig[je1][ke1];
// G4double rc = dsig/delab;
// G4double b = sig[je1][ke1] - rc*elab[je1];
// G4double sigint1 = rc*ek + b;
// G4double dsig = sig[je2][ke2] - sig[je1][ke2];
// G4double rc = dsig/delab;
// G4double b = sig[je1][ke2] - rc*elab[je1];
// G4double sigint2 = rc*ek + b;
dsig = sigint2 - sigint1;
rc = 1./dsig;
b = ke1 - rc*sigint1;
G4double kint = rc*sample + b;
G4double theta = (0.5 + kint)*pi/180.;
if (theta < 0.) theta = 0.;
// G4int k;
//std::abs(sample-sig[j][ke1]) < std::abs(sample-sig[j][ke2]) ? k = ke1 : k = ke2;
// G4double theta = (0.5 + k)*pi/180.;
if (theta < 0.) { theta = 0.; }
if (verboseLevel > 1) {
G4cout << " energy bin " << je1 << " energy=" << elab[je1] << G4endl;
G4cout << " angle bin " << kint << " angle=" << theta/degree << G4endl;
}
// Get the target particle
G4DynamicParticle* targetParticle = targetNucleus.ReturnTargetParticle();
G4double E1 = aParticle->GetTotalEnergy();
@@ -211,7 +193,6 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
G4double M2 = targetParticle->GetDefinition()->GetPDGMass();
G4double totalEnergy = E1 + E2;
G4double pseudoMass = std::sqrt(totalEnergy*totalEnergy - P*P);
// pseudoMass also = std::sqrt(M1*M1 + M2*M2 + 2*M2*E1)
// Transform into centre of mass system
@@ -224,7 +205,7 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
G4cout << " E1, M1 (GeV) " << E1/GeV << " " << M1/GeV << G4endl;
G4cout << " E2, M2 (GeV) " << E2/GeV << " " << M2/GeV << G4endl;
G4cout << " particle 1 momentum in CM " << px/GeV << " " << py/GeV << " "
<< pz/GeV << " " << p/GeV << G4endl;
<< pz/GeV << " " << p/GeV << G4endl;
}
// First scatter w.r.t. Z axis
@@ -237,18 +218,14 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
if (px*px + py*py > 0) {
G4double cost, sint, ph, cosp, sinp;
cost = pz/p;
sint = (std::sqrt(std::abs((1-cost)*(1+cost))) + std::sqrt(px*px+py*py)/p)/2;
sint = (std::sqrt(std::fabs((1-cost)*(1+cost))) + std::sqrt(px*px+py*py)/p)/2;
py < 0 ? ph = 3*halfpi : ph = halfpi;
if (std::abs(px) > 0.000001*GeV) ph = std::atan2(py,px);
if (std::fabs(px) > 0.000001*GeV) ph = std::atan2(py,px);
cosp = std::cos(ph);
sinp = std::sin(ph);
px = (cost*cosp*pxnew - sinp*pynew + sint*cosp*pznew);
py = (cost*sinp*pxnew + cosp*pynew + sint*sinp*pznew);
pz = (-sint*pxnew + cost*pznew);
// G4ThreeVector it(a,b,c);
// p0->SetMomentum(it);
// G4ThreeVector aTargetMom = theInitial - it;
// targetParticle->SetMomentum(aTargetMom);
}
else {
px = pxnew;
@@ -304,7 +281,6 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
newP->SetDefinition(const_cast<G4ParticleDefinition *>(aParticle->GetDefinition()) );
newP->SetMomentum(G4ThreeVector(PB[1], PB[2], PB[3]));
//The target particle...
PA[1] = -px;
@@ -322,51 +298,26 @@ G4LEpp::ApplyYourself(const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
targetParticle->SetMomentum(G4ThreeVector(PB[1], PB[2], PB[3]));
// G4double ektotal = newP->GetKineticEnergy() +
// targetParticle->GetKineticEnergy();
if (verboseLevel > 1) {
G4cout << " particle 1 momentum in LAB "
<< newP->GetMomentum()*(1./GeV)
<< newP->GetMomentum()/GeV
<< " " << newP->GetTotalMomentum()/GeV << G4endl;
G4cout << " particle 2 momentum in LAB "
<< targetParticle->GetMomentum()*(1./GeV)
<< targetParticle->GetMomentum()/GeV
<< " " << targetParticle->GetTotalMomentum()/GeV << G4endl;
G4cout << " TOTAL momentum in LAB "
<< (newP->GetMomentum()+targetParticle->GetMomentum())*(1./GeV)
<< (newP->GetMomentum()+targetParticle->GetMomentum())/GeV
<< " "
<< (newP->GetMomentum()+targetParticle->GetMomentum()).mag()/GeV
<< G4endl;
}
// if (theta < pi/2.) {
// G4double p = newP->GetMomentum().mag();
// G4ThreeVector m = newP->GetMomentum();
// if (p > DBL_MIN)
// theParticleChange.SetMomentumChange(m.x()/p, m.y()/p, m.z()/p);
// else
// theParticleChange.SetMomentumChange(0., 0., 0.);
theParticleChange.SetMomentumChange( newP->GetMomentumDirection());
theParticleChange.SetEnergyChange(newP->GetKineticEnergy());
delete newP;
// }
// else {
// // charge exchange
// theParticleChange.SetNumberOfSecondaries(2);
// theParticleChange.AddSecondary(newP);
// theParticleChange.SetStatusChange(fStopAndKill);
// // theParticleChange.SetEnergyChange(0.0);
// }
theParticleChange.SetMomentumChange( newP->GetMomentumDirection());
theParticleChange.SetEnergyChange(newP->GetKineticEnergy());
delete newP;
// Recoil particle
G4DynamicParticle* p1 = new G4DynamicParticle;
p1->SetDefinition(targetParticle->GetDefinition());
p1->SetMomentum(targetParticle->GetMomentum());
theParticleChange.AddSecondary(p1);
theParticleChange.AddSecondary(targetParticle);
return &theParticleChange;
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4NuclNuclDiffuseElastic.cc,v 1.5 2010/11/09 09:04:29 grichine Exp $
// GEANT4 tag $Name: geant4-09-04 $
// $Id: G4NuclNuclDiffuseElastic.cc,v 1.5 2010-11-09 09:04:29 grichine Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
//
// Physics model class G4NuclNuclDiffuseElastic
@@ -39,6 +39,7 @@
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4IonTable.hh"
#include "G4NucleiProperties.hh"
#include "Randomize.hh"
#include "G4Integrator.hh"
@@ -63,7 +64,7 @@
G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseElastic()
: G4HadronicInteraction(), fParticle(0)
: G4HadronElastic("NNDiffuseElastic"), fParticle(0)
{
SetMinEnergy( 50*MeV );
SetMaxEnergy( 1.*TeV );
@@ -98,63 +99,24 @@ G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseElastic()
fAddCoulomb = false;
// Ranges of angle table relative to current Rutherford (Coulomb grazing) angle
fCofAlphaMax = 1.5;
fCofAlphaCoulomb = 0.5;
fProfileDelta = 1.;
fProfileAlpha = 0.5;
}
//////////////////////////////////////////////////////////////////////////
//
// Constructor with initialisation
G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseElastic(const G4ParticleDefinition* aParticle)
: G4HadronicInteraction(), fParticle(aParticle)
{
SetMinEnergy( 50.*MeV); // 0.01*GeV );
SetMaxEnergy( 1.*TeV); // 1.*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; //200; // 200; // 100;
fAngleBin = 400; // 400; // 200; // 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;
// Ranges of angle table relative to current Rutherford (Coulomb grazing) angle
// Empirical parameters
fCofAlphaMax = 1.5;
fCofAlphaCoulomb = 0.5;
fProfileDelta = 1.;
fProfileAlpha = 0.5;
fProfileAlpha = 0.5;
fCofLambda = 1.0;
fCofDelta = 0.04;
fCofAlpha = 0.095;
fNuclearRadius1 = fNuclearRadius2 = fNuclearRadiusSquare = fNuclearRadiusCof
= fRutherfordRatio = fCoulombPhase0 = fHalfRutThetaTg = fHalfRutThetaTg2
= fRutherfordTheta = fProfileLambda = fCofPhase = fCofFar = fCofAlphaMax
= fCofAlphaCoulomb = fSumSigma = fEtaRatio = fReZ = 0.0;
fMaxL = 0;
// Initialise();
}
//////////////////////////////////////////////////////////////////////////////
@@ -208,181 +170,6 @@ void G4NuclNuclDiffuseElastic::Initialise()
BuildAngleTable();
fAngleBank.push_back(fAngleTable);
}
return;
}
////////////////////////////////////////////////////////////////////////////////
//
// Model analog of DoIt function
G4HadFinalState*
G4NuclNuclDiffuseElastic::ApplyYourself( const G4HadProjectile& aTrack,
G4Nucleus& targetNucleus )
{
theParticleChange.Clear();
const G4HadProjectile* aParticle = &aTrack;
G4double ekin = aParticle->GetKineticEnergy();
if(ekin <= lowestEnergyLimit)
{
theParticleChange.SetEnergyChange(ekin);
theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
return &theParticleChange;
}
G4double aTarget = targetNucleus.GetN();
G4double zTarget = targetNucleus.GetZ();
G4double plab = aParticle->GetTotalMomentum();
if (verboseLevel >1)
{
G4cout << "G4NuclNuclDiffuseElastic::DoIt: Incident particle plab="
<< plab/GeV << " GeV/c "
<< " ekin(MeV) = " << ekin/MeV << " "
<< aParticle->GetDefinition()->GetParticleName() << G4endl;
}
// Scattered particle referred to axis of incident particle
const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
G4double m1 = theParticle->GetPDGMass();
G4int Z = static_cast<G4int>(zTarget+0.5);
G4int A = static_cast<G4int>(aTarget+0.5);
G4int N = A - Z;
G4int projPDG = theParticle->GetPDGEncoding();
if (verboseLevel>1)
{
G4cout << "G4NuclNuclDiffuseElastic for " << theParticle->GetParticleName()
<< " PDGcode= " << projPDG << " on nucleus Z= " << Z
<< " A= " << A << " N= " << N
<< G4endl;
}
G4ParticleDefinition * theDef = 0;
if(Z == 1 && A == 1) theDef = theProton;
else if (Z == 1 && A == 2) theDef = theDeuteron;
else if (Z == 1 && A == 3) theDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theDef = G4He3::He3();
else if (Z == 2 && A == 4) theDef = theAlpha;
else theDef = G4ParticleTable::GetParticleTable()->FindIon(Z,A,0,Z);
G4double m2 = theDef->GetPDGMass();
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv(0.0,0.0,0.0,m2);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
G4double tmax = 4.0*ptot*ptot;
G4double t = 0.0;
//
// Sample t
//
// t = SampleT( theParticle, ptot, A);
t = SampleTableT( theParticle, ptot, Z, A); // use initialised table
// NaN finder
if(!(t < 0.0 || t >= 0.0))
{
if (verboseLevel > 0)
{
G4cout << "G4NuclNuclDiffuseElastic:WARNING: Z= " << Z << " N= "
<< N << " pdg= " << projPDG
<< " mom(GeV)= " << plab/GeV
<< " S-wave will be sampled"
<< G4endl;
}
t = G4UniformRand()*tmax;
}
if(verboseLevel>1)
{
G4cout <<" t= " << t << " tmax= " << tmax
<< " ptot= " << ptot << G4endl;
}
// Sampling of angles in CM system
G4double phi = G4UniformRand()*twopi;
G4double cost = 1. - 2.0*t/tmax;
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(t)=" << cost << " std::sin(t)=" << 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);
G4double eFinal = nlv1.e() - m1;
if (verboseLevel > 1)
{
G4cout << "Scattered: "
<< nlv1<<" m= " << m1 << " ekin(MeV)= " << eFinal
<< " Proj: 4-mom " << lv1
<<G4endl;
}
if(eFinal < 0.0)
{
G4cout << "G4NuclNuclDiffuseElastic WARNING ekin= " << eFinal
<< " after scattering of "
<< aParticle->GetDefinition()->GetParticleName()
<< " p(GeV/c)= " << plab
<< " on " << theDef->GetParticleName()
<< G4endl;
eFinal = 0.0;
nlv1.setE(m1);
}
theParticleChange.SetMomentumChange(nlv1.vect().unit());
theParticleChange.SetEnergyChange(eFinal);
G4LorentzVector nlv0 = lv - nlv1;
G4double erec = nlv0.e() - m2;
if (verboseLevel > 1)
{
G4cout << "Recoil: "
<< nlv0<<" m= " << m2 << " ekin(MeV)= " << erec
<<G4endl;
}
if(erec > lowEnergyRecoilLimit)
{
G4DynamicParticle * aSec = new G4DynamicParticle(theDef, nlv0);
theParticleChange.AddSecondary(aSec);
} else {
if(erec < 0.0) erec = 0.0;
theParticleChange.SetLocalEnergyDeposit(erec);
}
return &theParticleChange;
}
@@ -907,7 +694,8 @@ G4NuclNuclDiffuseElastic::IntegralElasticProb( const G4ParticleDefinition* part
//
// Return inv momentum transfer -t > 0
G4double G4NuclNuclDiffuseElastic::SampleT( const G4ParticleDefinition* aParticle, G4double p, G4double A)
G4double G4NuclNuclDiffuseElastic::SampleT( const G4ParticleDefinition* aParticle,
G4double p, G4double A)
{
G4double theta = SampleThetaCMS( aParticle, p, A); // sample theta in cms
G4double t = 2*p*p*( 1 - std::cos(theta) ); // -t !!!
@@ -969,6 +757,32 @@ G4NuclNuclDiffuseElastic::SampleThetaCMS(const G4ParticleDefinition* particle,
/////////////////////////////////////////////////////////////////////////////
///////////////////// Table preparation and reading ////////////////////////
////////////////////////////////////////////////////////////////////////////
//
// Return inv momentum transfer -t > 0 from initialisation table
G4double G4NuclNuclDiffuseElastic::SampleInvariantT( const G4ParticleDefinition* aParticle, G4double p,
G4int Z, G4int A)
{
fParticle = aParticle;
G4double m1 = fParticle->GetPDGMass();
G4double totElab = std::sqrt(m1*m1+p*p);
G4double m2 = G4NucleiProperties::GetNuclearMass(A, Z);
G4LorentzVector lv1(p,0.0,0.0,totElab);
G4LorentzVector lv(0.0,0.0,0.0,m2);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double momentumCMS = p1.mag();
G4double t = SampleTableT( aParticle, momentumCMS, G4double(Z), G4double(A) ); // sample theta2 in cms
return t;
}
////////////////////////////////////////////////////////////////////////////
//
// Return inv momentum transfer -t > 0 from initialisation table
@@ -1143,7 +957,7 @@ void G4NuclNuclDiffuseElastic::InitialiseOnFly(G4double Z, G4double A)
void G4NuclNuclDiffuseElastic::BuildAngleTable()
{
G4int i, j;
G4double partMom, kinE, a = 0., z = fParticle->GetPDGCharge(), m1 = fParticle->GetPDGMass();
G4double partMom, kinE, m1 = fParticle->GetPDGMass();
G4double alpha1, alpha2, alphaMax, alphaCoulomb, delta = 0., sum = 0.;
// G4cout<<"particle z = "<<z<<"; particle m1 = "<<m1/GeV<<" GeV"<<G4endl;
@@ -1161,30 +975,7 @@ void G4NuclNuclDiffuseElastic::BuildAngleTable()
partMom = std::sqrt( kinE*(kinE + 2*m1) );
fWaveVector = partMom/hbarc;
G4double kR = fWaveVector*fNuclearRadius;
if( z )
{
a = partMom/m1; // beta*gamma for m1
fBeta = a/std::sqrt(1+a*a);
fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber);
fRutherfordRatio = fZommerfeld/fWaveVector;
fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
}
// G4cout<<"fZommerfeld = "<<fZommerfeld<<G4endl;
fProfileLambda = kR; // *std::sqrt(1.-2*fZommerfeld/kR);
// G4cout<<"fProfileLambda = "<<fProfileLambda<<G4endl;
fProfileDelta = fCofDelta*fProfileLambda;
fProfileAlpha = fCofAlpha*fProfileLambda;
// CalculateCoulombPhaseZero();
CalculateRutherfordAnglePar();
InitDynParameters(fParticle, partMom);
alphaMax = fRutherfordTheta*fCofAlphaMax;
@@ -1219,7 +1010,7 @@ void G4NuclNuclDiffuseElastic::BuildAngleTable()
// if(alpha1 < kRlim2) alpha1 = kRlim2;
alpha2 = alpha1 + delth;
delta = integral.Legendre10(this, &G4NuclNuclDiffuseElastic::GetFresnelDiffuseXsc, alpha1, alpha2);
delta = integral.Legendre10(this, &G4NuclNuclDiffuseElastic::GetFresnelIntegrandXsc, alpha1, alpha2);
// delta = integral.Legendre96(this, &G4NuclNuclDiffuseElastic::GetIntegrandFunction, alpha1, alpha2);
sum += delta;
@@ -1,412 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4UHadronElasticProcess.cc,v 1.42 2010/06/15 15:24:34 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04-beta-01 $
//
// Geant4 Hadron Elastic Scattering Process -- header file
//
// Created 21 April 2006 V.Ivanchenko
//
// Modified:
// 24.04.06 V.Ivanchenko add neutron scattering on hydrogen from CHIPS
// 07.06.06 V.Ivanchenko fix problem of rotation of final state
// 25.07.06 V.Ivanchenko add 19 MeV low energy for CHIPS
// 26.09.06 V.Ivanchenko add lowestEnergy
// 20.10.06 V.Ivanchenko initialise lowestEnergy=0 for neitrals, eV for charged
// 23.01.07 V.Ivanchnko add cross section interfaces with Z and A
// 02.05.07 V.Ivanchnko add He3
// 13.01.10: M.Kosov: Use G4Q(Pr/Neut)ElasticCS instead of G4QElasticCS
//
#include "G4UHadronElasticProcess.hh"
#include "globals.hh"
#include "G4CrossSectionDataStore.hh"
#include "G4HadronElasticDataSet.hh"
#include "G4VQCrossSection.hh"
#include "G4QProtonElasticCrossSection.hh"
#include "G4QNeutronElasticCrossSection.hh"
#include "G4QCHIPSWorld.hh"
#include "G4Element.hh"
#include "G4ElementVector.hh"
#include "G4IsotopeVector.hh"
#include "G4Neutron.hh"
#include "G4Proton.hh"
#include "G4HadronElastic.hh"
G4UHadronElasticProcess::G4UHadronElasticProcess(const G4String& pName, G4double)
: G4HadronicProcess(pName), lowestEnergy(0.0), first(true)
{
SetProcessSubType(fHadronElastic);
AddDataSet(new G4HadronElasticDataSet);
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
thEnergy = 19.0*MeV;
verboseLevel= 1;
pCManager = G4QProtonElasticCrossSection::GetPointer();
nCManager = G4QNeutronElasticCrossSection::GetPointer();
}
G4UHadronElasticProcess::~G4UHadronElasticProcess()
{
}
void G4UHadronElasticProcess::SetQElasticCrossSection(G4VQCrossSection* p)
{
pCManager = p;
}
void G4UHadronElasticProcess::
BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
{
if(first) {
first = false;
theParticle = &aParticleType;
pPDG = theParticle->GetPDGEncoding();
store = G4HadronicProcess::GetCrossSectionDataStore();
// defined lowest threshold for the projectile
if(theParticle->GetPDGCharge() != 0.0) lowestEnergy = eV;
// if(verboseLevel>1 ||
// (verboseLevel==1 && theParticle == theNeutron)) {
if(verboseLevel>1 && theParticle == theNeutron) {
// G4cout << G4endl;
G4cout << "G4UHadronElasticProcess for "
<< theParticle->GetParticleName()
<< " PDGcode= " << pPDG
<< " Elow(MeV)= " << thEnergy/MeV
<< " Elowest(eV)= " << lowestEnergy/eV
<< G4endl;
}
}
G4HadronicProcess::BuildPhysicsTable(aParticleType);
//store->BuildPhysicsTable(aParticleType);
}
G4double G4UHadronElasticProcess::GetMeanFreePath(const G4Track& track,
G4double,
G4ForceCondition* cond)
{
*cond = NotForced;
const G4DynamicParticle* dp = track.GetDynamicParticle();
cross = 0.0;
G4double x = DBL_MAX;
// Compute cross sesctions
const G4Material* material = track.GetMaterial();
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
G4double temp = material->GetTemperature();
G4int nelm = material->GetNumberOfElements();
#ifdef G4VERBOSE
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess get mfp for "
<< theParticle->GetParticleName()
<< " p(GeV)= " << dp->GetTotalMomentum()/GeV
<< " in " << material->GetName()
<< G4endl;
#endif
for (G4int i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
G4double x = GetMicroscopicCrossSection(dp, elm, temp);
cross += theAtomNumDensityVector[i]*x;
xsec[i] = cross;
}
#ifdef G4VERBOSE
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess cross(1/mm)= " << cross
<< " E(MeV)= " << dp->GetKineticEnergy()
<< " " << theParticle->GetParticleName()
<< " in " << material->GetName()
<< G4endl;
#endif
if(cross > DBL_MIN) x = 1./cross;
return x;
}
G4double G4UHadronElasticProcess::GetMicroscopicCrossSection(
const G4DynamicParticle* dp,
const G4Element* elm,
G4double temp)
{
// gives the microscopic cross section in GEANT4 internal units
G4int iz = G4int(elm->GetZ());
G4double x = 0.0;
// CHIPS cross sections
if(iz <= 2 && dp->GetKineticEnergy() > thEnergy &&
(theParticle == theProton || theParticle == theNeutron)) {
G4double momentum = dp->GetTotalMomentum();
G4IsotopeVector* isv = elm->GetIsotopeVector();
G4int ni = 0;
if(isv) ni = isv->size();
x = 0.0;
if(ni == 0) {
G4int N = G4int(elm->GetN()+0.5) - iz;
#ifdef G4VERBOSE
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess compute CHIPS CS for Z= " << iz
<< " N= " << N << " pdg= " << pPDG
<< " mom(GeV)= " << momentum/GeV
<< ", pC=" << pCManager << ", nC=" << nCManager << G4endl;
#endif
x = 0.;
if (pPDG==2212) x = pCManager->GetCrossSection(false,momentum,iz,N,pPDG);
else if(pPDG==2112) x = nCManager->GetCrossSection(false,momentum,iz,N,pPDG);
xsecH[0] = x;
} else {
G4double* ab = elm->GetRelativeAbundanceVector();
for(G4int j=0; j<ni; j++) {
G4int N = (*isv)[j]->GetN() - iz;
if(iz == 1) {
if(N > 1) N = 1;
} else {
N = 2;
}
#ifdef G4VERBOSE
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess compute CHIPS CS for Z= " << iz
<< " N= " << N << " pdg= " << pPDG
<< " mom(GeV)= " << momentum/GeV
<< ", pC=" << pCManager << ", nC=" << pCManager << G4endl;
#endif
G4double qxs=0.;
if (pPDG==2212) qxs=pCManager->GetCrossSection(false,momentum,iz,N,pPDG);
else if(pPDG==2112) qxs=nCManager->GetCrossSection(false,momentum,iz,N,pPDG);
G4double y = ab[j]*qxs;
x += y;
xsecH[j] = x;
}
}
// GHAD cross section
} else {
#ifdef G4VERBOSE
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess compute GHAD CS for element "
<< elm->GetName()
<< G4endl;
#endif
x = store->GetCrossSection(dp, elm, temp);
}
// NaN finder
if(!(x < 0.0 || x >= 0.0)) {
if (verboseLevel > 1) {
G4cout << "G4UHadronElasticProcess:WARNING: Z= " << iz
<< " pdg= " << pPDG
<< " mom(GeV)= " << dp->GetTotalMomentum()/GeV
<< " cross= " << x
<< " set to zero"
<< G4endl;
}
x = 0.0;
}
#ifdef G4VERBOSE
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess cross(mb)= " << x/millibarn
<< " E(MeV)= " << dp->GetKineticEnergy()
<< " " << theParticle->GetParticleName()
<< " in Z= " << iz
<< G4endl;
#endif
return x;
}
G4VParticleChange* G4UHadronElasticProcess::PostStepDoIt(
const G4Track& track,
const G4Step& step)
{
G4ForceCondition cn;
aParticleChange.Initialize(track);
G4double kineticEnergy = track.GetKineticEnergy();
if(kineticEnergy <= lowestEnergy)
return G4VDiscreteProcess::PostStepDoIt(track,step);
G4double mfp = GetMeanFreePath(track, 0.0, &cn);
if(mfp == DBL_MAX)
return G4VDiscreteProcess::PostStepDoIt(track,step);
G4Material* material = track.GetMaterial();
// Select element
const G4ElementVector* theElementVector = material->GetElementVector();
G4Element* elm = (*theElementVector)[0];
G4int nelm = material->GetNumberOfElements() - 1;
if (nelm > 0) {
G4double x = G4UniformRand()*cross;
G4int i = -1;
do {i++;} while (x > xsec[i] && i < nelm);
elm = (*theElementVector)[i];
}
G4double Z = elm->GetZ();
G4double A = G4double(G4int(elm->GetN()+0.5));
G4int iz = G4int(Z);
// Select isotope
G4IsotopeVector* isv = elm->GetIsotopeVector();
G4int ni = 0;
if(isv) ni = isv->size();
if(ni == 1) {
A = G4double((*isv)[0]->GetN());
} else if(ni > 1) {
G4double* ab = elm->GetRelativeAbundanceVector();
G4int j = -1;
ni--;
// Special treatment of hydrogen and helium for CHIPS
if(iz <= 2 && kineticEnergy > thEnergy &&
(theParticle == theProton || theParticle == theNeutron)) {
G4double x = G4UniformRand()*xsecH[ni];
do {j++;} while (x > xsecH[j] && j < ni);
// GHAD cross sections
} else {
G4double y = G4UniformRand();
do {
j++;
y -= ab[j];
} while (y > 0.0 && j < ni);
}
A = G4double((*isv)[j]->GetN());
} else {
G4int nIso = theDefaultIsotopes.GetNumberOfIsotopes(iz);
G4int idxIso = theDefaultIsotopes.GetFirstIsotope(iz);
A = theDefaultIsotopes.GetIsotopeNucleonCount(idxIso);
if(1 < nIso) {
G4double cross = 0.0;
G4int i = 0;
for (; i<nIso; ++i) {
cross += theDefaultIsotopes.GetAbundance(idxIso+i);
xsec[i] = cross;
}
cross *= G4UniformRand();
for (i = 0; i<nIso; ++i) {
if(cross <= xsec[i]) {
A = theDefaultIsotopes.GetIsotopeNucleonCount(idxIso+i);
break;
}
}
}
}
G4HadronicInteraction* hadi =
ChooseHadronicInteraction( kineticEnergy, material, elm);
// Initialize the hadronic projectile from the track
// G4cout << "track " << track.GetDynamicParticle()->Get4Momentum()<<G4endl;
G4HadProjectile thePro(track);
if(verboseLevel>1)
G4cout << "G4UHadronElasticProcess::PostStepDoIt for "
<< theParticle->GetParticleName()
<< " Target Z= " << Z
<< " A= " << A << G4endl;
targetNucleus.SetParameters(A, Z);
aParticleChange.Initialize(track);
G4HadFinalState* result = hadi->ApplyYourself(thePro, targetNucleus);
G4ThreeVector indir = track.GetMomentumDirection();
G4ThreeVector outdir = (result->GetMomentumChange()).rotateUz(indir);
if(verboseLevel>1)
G4cout << "Efin= " << result->GetEnergyChange()
<< " de= " << result->GetLocalEnergyDeposit()
<< " nsec= " << result->GetNumberOfSecondaries()
<< " dir= " << outdir
<< G4endl;
aParticleChange.ProposeEnergy(result->GetEnergyChange());
aParticleChange.ProposeMomentumDirection(outdir);
if(result->GetNumberOfSecondaries() > 0) {
aParticleChange.SetNumberOfSecondaries(1);
G4DynamicParticle* p = result->GetSecondary(0)->GetParticle();
G4ThreeVector pdir = p->GetMomentumDirection();
// G4cout << "recoil " << pdir << G4endl;
pdir = pdir.rotateUz(indir);
// G4cout << "recoil rotated " << pdir << G4endl;
p->SetMomentumDirection(pdir);
aParticleChange.AddSecondary(p);
} else {
aParticleChange.SetNumberOfSecondaries(0);
aParticleChange.ProposeLocalEnergyDeposit(result->GetLocalEnergyDeposit());
}
result->Clear();
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
G4bool G4UHadronElasticProcess::
IsApplicable(const G4ParticleDefinition& aParticleType)
{
return (aParticleType == *(G4PionPlus::PionPlus()) ||
aParticleType == *(G4PionMinus::PionMinus()) ||
aParticleType == *(G4KaonPlus::KaonPlus()) ||
aParticleType == *(G4KaonZeroShort::KaonZeroShort()) ||
aParticleType == *(G4KaonZeroLong::KaonZeroLong()) ||
aParticleType == *(G4KaonMinus::KaonMinus()) ||
aParticleType == *(G4Proton::Proton()) ||
aParticleType == *(G4AntiProton::AntiProton()) ||
aParticleType == *(G4Neutron::Neutron()) ||
aParticleType == *(G4AntiNeutron::AntiNeutron()) ||
aParticleType == *(G4Lambda::Lambda()) ||
aParticleType == *(G4AntiLambda::AntiLambda()) ||
aParticleType == *(G4SigmaPlus::SigmaPlus()) ||
aParticleType == *(G4SigmaZero::SigmaZero()) ||
aParticleType == *(G4SigmaMinus::SigmaMinus()) ||
aParticleType == *(G4AntiSigmaPlus::AntiSigmaPlus()) ||
aParticleType == *(G4AntiSigmaZero::AntiSigmaZero()) ||
aParticleType == *(G4AntiSigmaMinus::AntiSigmaMinus()) ||
aParticleType == *(G4XiZero::XiZero()) ||
aParticleType == *(G4XiMinus::XiMinus()) ||
aParticleType == *(G4AntiXiZero::AntiXiZero()) ||
aParticleType == *(G4AntiXiMinus::AntiXiMinus()) ||
aParticleType == *(G4Deuteron::Deuteron()) ||
aParticleType == *(G4Triton::Triton()) ||
aParticleType == *(G4He3::He3()) ||
aParticleType == *(G4Alpha::Alpha()) ||
aParticleType == *(G4OmegaMinus::OmegaMinus()) ||
aParticleType == *(G4AntiOmegaMinus::AntiOmegaMinus()));
}
void G4UHadronElasticProcess::
DumpPhysicsTable(const G4ParticleDefinition& aParticleType)
{
store->DumpPhysicsTable(aParticleType);
}
@@ -1,224 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VHadronElastic.cc,v 1.6 2010/11/19 18:50:03 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// Geant4 Header : G4VHadronElastic
//
// Author : V.Ivanchenko 29 June 2009 (redesign old elastic model)
//
// Modified:
//
//
#include "G4VHadronElastic.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4IonTable.hh"
#include "Randomize.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
#include "G4Alpha.hh"
#include "G4Pow.hh"
G4VHadronElastic::G4VHadronElastic(const G4String& name)
: G4HadronicInteraction(name)
{
SetMinEnergy( 0.0*GeV );
SetMaxEnergy( 100.*TeV );
lowestEnergyLimit= 1.e-6*eV;
theProton = G4Proton::Proton();
theNeutron = G4Neutron::Neutron();
theDeuteron = G4Deuteron::Deuteron();
theAlpha = G4Alpha::Alpha();
}
G4VHadronElastic::~G4VHadronElastic()
{}
G4HadFinalState* G4VHadronElastic::ApplyYourself(
const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
{
theParticleChange.Clear();
const G4HadProjectile* aParticle = &aTrack;
G4double ekin = aParticle->GetKineticEnergy();
if(ekin <= lowestEnergyLimit) {
theParticleChange.SetEnergyChange(ekin);
theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
return &theParticleChange;
}
G4int A = targetNucleus.GetA_asInt();
G4int Z = targetNucleus.GetZ_asInt();
G4double plab = aParticle->GetTotalMomentum();
// Scattered particle referred to axis of incident particle
const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
G4double m1 = theParticle->GetPDGMass();
if (verboseLevel>1) {
G4cout << "G4VHadronElastic: "
<< aParticle->GetDefinition()->GetParticleName()
<< " Plab(GeV/c)= " << plab/GeV
<< " Ekin(MeV) = " << ekin/MeV
<< " scattered off Z= " << Z
<< " A= " << A
<< G4endl;
}
G4ParticleDefinition * theDef = 0;
if(Z == 1 && A == 1) theDef = theProton;
else if (Z == 1 && A == 2) theDef = theDeuteron;
else if (Z == 1 && A == 3) theDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theDef = G4He3::He3();
else if (Z == 2 && A == 4) theDef = theAlpha;
else {
theDef =
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(Z,A,0.0);
}
G4double m2 = theDef->GetPDGMass();
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv(0.0,0.0,0.0,m2);
lv += lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
G4ThreeVector p1 = lv1.vect();
momentumCMS = p1.mag();
G4double tmax = 4.0*momentumCMS*momentumCMS;
// Sampling in CM system
G4double t = SampleInvariantT(theParticle, plab, Z, A);
G4double phi = G4UniformRand()*CLHEP::twopi;
G4double cost = 1. - 2.0*t/tmax;
G4double sint;
// problem in sampling
if(cost > 1.0 || cost < -1.0) {
if(verboseLevel > 0) {
G4cout << "G4VHadronElastic WARNING cost= " << cost
<< " after scattering of "
<< aParticle->GetDefinition()->GetParticleName()
<< " p(GeV/c)= " << plab
<< " on " << theDef->GetParticleName()
<< G4endl;
}
cost = 1.0;
sint = 0.0;
// normal situation
} else {
sint = std::sqrt((1.0-cost)*(1.0+cost));
}
if (verboseLevel>1) {
G4cout << " t= " << t << " tmax= " << tmax
<< " Pcms= " << momentumCMS << "cos(t)=" << cost
<< " std::sin(t)=" << sint << G4endl;
}
G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
v1 *= momentumCMS;
G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),
std::sqrt(momentumCMS*momentumCMS + m1*m1));
nlv1.boost(bst);
G4double eFinal = nlv1.e() - m1;
if (verboseLevel > 1) {
G4cout <<" m= " << m1 << " Efin(MeV)= " << eFinal
<< " Proj: 4-mom " << lv1 << " Final: " << nlv1
<< G4endl;
}
if(eFinal <= lowestEnergyLimit) {
if(eFinal < 0.0 && verboseLevel > 0) {
G4cout << "G4VHadronElastic WARNING Efinal= " << eFinal
<< " after scattering of "
<< aParticle->GetDefinition()->GetParticleName()
<< " p(GeV/c)= " << plab
<< " on " << theDef->GetParticleName()
<< G4endl;
}
theParticleChange.SetEnergyChange(0.0);
nlv1 = G4LorentzVector(0.0,0.0,0.0,m1);
} else {
theParticleChange.SetMomentumChange(nlv1.vect().unit());
theParticleChange.SetEnergyChange(eFinal);
}
G4LorentzVector nlv0 = lv - nlv1;
G4double erec = nlv0.e() - m2;
if (verboseLevel > 1) {
G4cout << "Recoil: " <<" m= " << m2 << " Erec(MeV)= " << erec
<< " 4-mom: " << nlv0
<< G4endl;
}
if(erec > GetRecoilEnergyThreshold()) {
G4DynamicParticle * aSec = new G4DynamicParticle(theDef, nlv0);
theParticleChange.AddSecondary(aSec);
} else if(erec > 0.0) {
theParticleChange.SetLocalEnergyDeposit(erec);
}
return &theParticleChange;
}
// sample momentum transfer in the CMS system
G4double
G4VHadronElastic::SampleInvariantT(const G4ParticleDefinition* /*p*/,
G4double /*ptot*/,
G4int /*Z*/, G4int A)
{
static const G4double GeV2 = GeV*GeV;
G4double tmax = 4.0*momentumCMS*momentumCMS/GeV2;
G4double aa, bb, cc;
G4double dd = 10.;
G4Pow* p = G4Pow::GetInstance();
if (A <= 62) {
bb = 14.5*p->Z23(A);
aa = p->powZ(A, 1.63)/bb;
cc = 1.4*p->Z13(A)/dd;
} else {
bb = 60.*p->Z13(A);
aa = p->powZ(A, 1.33)/bb;
cc = 0.4*p->powZ(A, 0.4)/dd;
}
G4double q1 = 1.0 - std::exp(-bb*tmax);
G4double q2 = 1.0 - std::exp(-dd*tmax);
G4double s1 = q1*aa;
G4double s2 = q2*cc;
if((s1 + s2)*G4UniformRand() < s2) {
q1 = q2;
bb = dd;
}
return -GeV2*std::log(1.0 - G4UniformRand()*q1)/bb;
}
@@ -1,179 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4WHadronElasticProcess.cc,v 1.5 2010/11/19 18:50:03 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// Geant4 Hadron Elastic Scattering Process
//
// Created 21 April 2006 V.Ivanchenko
//
// Modified:
// 24.04.06 V.Ivanchenko add neutron scattering on hydrogen from CHIPS
// 07.06.06 V.Ivanchenko fix problem of rotation of final state
// 25.07.06 V.Ivanchenko add 19 MeV low energy for CHIPS
// 26.09.06 V.Ivanchenko add lowestEnergy
// 20.10.06 V.Ivanchenko initialise lowestEnergy=0 for neitrals, eV for charged
// 23.01.07 V.Ivanchenko add cross section interfaces with Z and A
// 02.05.07 V.Ivanchenko add He3
// 13.01.10: M.Kosov: Commented not used G4QElasticCrossSection & G4QCHIPSWorld
//
#include "G4WHadronElasticProcess.hh"
#include "globals.hh"
#include "G4CrossSectionDataStore.hh"
#include "G4HadronElasticDataSet.hh"
#include "G4VQCrossSection.hh"
#include "G4Element.hh"
#include "G4ElementVector.hh"
#include "G4IsotopeVector.hh"
#include "G4Neutron.hh"
#include "G4ProductionCutsTable.hh"
G4WHadronElasticProcess::G4WHadronElasticProcess(const G4String& pName)
: G4HadronicProcess(pName)
{
SetProcessSubType(fHadronElastic);
AddDataSet(new G4HadronElasticDataSet);
theNeutron = G4Neutron::Neutron();
lowestEnergy = 1.*keV;
lowestEnergyNeutron = 1.e-6*eV;
}
G4WHadronElasticProcess::~G4WHadronElasticProcess()
{
}
G4VParticleChange* G4WHadronElasticProcess::PostStepDoIt(
const G4Track& track,
const G4Step& step)
{
aParticleChange.Initialize(track);
G4double kineticEnergy = track.GetKineticEnergy();
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
const G4ParticleDefinition* part = dynParticle->GetDefinition();
// protection against numerical problems
if(part == theNeutron) {
if(kineticEnergy <= lowestEnergyNeutron)
return G4VDiscreteProcess::PostStepDoIt(track,step);
} else {
if(kineticEnergy <= lowestEnergy)
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
G4Material* material = track.GetMaterial();
G4CrossSectionDataStore* store = GetCrossSectionDataStore();
G4double xsec = store->GetCrossSection(dynParticle,material);
if(xsec <= DBL_MIN) return G4VDiscreteProcess::PostStepDoIt(track,step);
// Select element
G4Element* elm = store->SampleZandA(dynParticle,material,targetNucleus);
G4HadronicInteraction* hadi =
ChooseHadronicInteraction( kineticEnergy, material, elm);
size_t idx = track.GetMaterialCutsCouple()->GetIndex();
G4double tcut =
(*(G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(3)))[idx];
hadi->SetRecoilEnergyThreshold(tcut);
// Initialize the hadronic projectile from the track
// G4cout << "track " << track.GetDynamicParticle()->Get4Momentum()<<G4endl;
G4HadProjectile thePro(track);
if(verboseLevel>1) {
G4cout << "G4WHadronElasticProcess::PostStepDoIt for "
<< part->GetParticleName()
<< " in " << material->GetName()
<< " Target Z= " << targetNucleus.GetZ_asInt()
<< " A= " << targetNucleus.GetA_asInt() << G4endl;
}
G4HadFinalState* result = hadi->ApplyYourself(thePro, targetNucleus);
G4ThreeVector indir = track.GetMomentumDirection();
G4ThreeVector outdir = (result->GetMomentumChange()).rotateUz(indir);
if(verboseLevel>1) {
G4cout << "Efin= " << result->GetEnergyChange()
<< " de= " << result->GetLocalEnergyDeposit()
<< " nsec= " << result->GetNumberOfSecondaries()
<< " dir= " << outdir
<< G4endl;
}
aParticleChange.ProposeEnergy(result->GetEnergyChange());
aParticleChange.ProposeMomentumDirection(outdir);
if(result->GetNumberOfSecondaries() > 0) {
aParticleChange.SetNumberOfSecondaries(1);
G4DynamicParticle* p = result->GetSecondary(0)->GetParticle();
G4ThreeVector pdir = p->GetMomentumDirection();
// G4cout << "recoil " << pdir << G4endl;
pdir = pdir.rotateUz(indir);
// G4cout << "recoil rotated " << pdir << G4endl;
p->SetMomentumDirection(pdir);
aParticleChange.AddSecondary(p);
} else {
aParticleChange.SetNumberOfSecondaries(0);
aParticleChange.ProposeLocalEnergyDeposit(result->GetLocalEnergyDeposit());
}
result->Clear();
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
G4bool G4WHadronElasticProcess::
IsApplicable(const G4ParticleDefinition& aParticleType)
{
return (&aParticleType == G4PionPlus::PionPlus() ||
&aParticleType == G4PionMinus::PionMinus() ||
&aParticleType == G4KaonPlus::KaonPlus() ||
&aParticleType == G4KaonZeroShort::KaonZeroShort() ||
&aParticleType == G4KaonZeroLong::KaonZeroLong() ||
&aParticleType == G4KaonMinus::KaonMinus() ||
&aParticleType == G4Proton::Proton() ||
&aParticleType == G4AntiProton::AntiProton() ||
&aParticleType == G4Neutron::Neutron() ||
&aParticleType == G4AntiNeutron::AntiNeutron() ||
&aParticleType == G4Lambda::Lambda() ||
&aParticleType == G4AntiLambda::AntiLambda() ||
&aParticleType == G4SigmaPlus::SigmaPlus() ||
&aParticleType == G4SigmaZero::SigmaZero() ||
&aParticleType == G4SigmaMinus::SigmaMinus() ||
&aParticleType == G4AntiSigmaPlus::AntiSigmaPlus() ||
&aParticleType == G4AntiSigmaZero::AntiSigmaZero() ||
&aParticleType == G4AntiSigmaMinus::AntiSigmaMinus() ||
&aParticleType == G4XiZero::XiZero() ||
&aParticleType == G4XiMinus::XiMinus() ||
&aParticleType == G4AntiXiZero::AntiXiZero() ||
&aParticleType == G4AntiXiMinus::AntiXiMinus() ||
&aParticleType == G4Deuteron::Deuteron() ||
&aParticleType == G4Triton::Triton() ||
&aParticleType == G4He3::He3() ||
&aParticleType == G4Alpha::Alpha() ||
&aParticleType == G4OmegaMinus::OmegaMinus() ||
&aParticleType == G4AntiOmegaMinus::AntiOmegaMinus() ||
&aParticleType == G4GenericIon::GenericIon());
}