Import Geant4 9.5.0 source tree
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+47
-256
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user