Import Geant4 9.4.0 source tree
This commit is contained in:
+644
@@ -0,0 +1,644 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4AnalyticalEcpssrKCrossSection.cc,v 1.5 2010/12/15 07:39:10 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4AnalyticalEcpssrKCrossSection.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include "G4SemiLogInterpolation.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4AnalyticalEcpssrKCrossSection::G4AnalyticalEcpssrKCrossSection()
|
||||
{
|
||||
// Storing FK data needed for medium velocities region
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
G4Exception("G4AnalyticalEcpssrKCrossSection::G4AnalyticalEcpssrKCrossSection() G4LEDATA environment variable not set");
|
||||
|
||||
std::ostringstream fileName;
|
||||
fileName << path << "/pixe/uf/FK.dat";
|
||||
std::ifstream FK(fileName.str().c_str());
|
||||
|
||||
if (!FK) G4Exception("G4AnalyticalEcpssrKCrossSection::G4AnalyticalEcpssrKCrossSection() error opening FK data file");
|
||||
|
||||
dummyVec.push_back(0.);
|
||||
|
||||
while(!FK.eof())
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
FK>>x>>y;
|
||||
|
||||
// Mandatory vector initialization
|
||||
if (x != dummyVec.back())
|
||||
{
|
||||
dummyVec.push_back(x);
|
||||
aVecMap[x].push_back(-1.);
|
||||
}
|
||||
|
||||
FK>>FKData[x][y];
|
||||
|
||||
if (y != aVecMap[x].back()) aVecMap[x].push_back(y);
|
||||
|
||||
}
|
||||
|
||||
// Storing C coefficients for high velocity formula
|
||||
|
||||
G4String fileC1("pixe/uf/c1");
|
||||
tableC1 = new G4DNACrossSectionDataSet(new G4SemiLogInterpolation, 1.,1.);
|
||||
tableC1->LoadData(fileC1);
|
||||
|
||||
G4String fileC2("pixe/uf/c2");
|
||||
tableC2 = new G4DNACrossSectionDataSet(new G4SemiLogInterpolation, 1.,1.);
|
||||
tableC2->LoadData(fileC2);
|
||||
|
||||
G4String fileC3("pixe/uf/c3");
|
||||
tableC3 = new G4DNACrossSectionDataSet(new G4SemiLogInterpolation, 1.,1.);
|
||||
tableC3->LoadData(fileC3);
|
||||
|
||||
//
|
||||
|
||||
verboseLevel=0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void print (G4double elem)
|
||||
{
|
||||
G4cout << elem << " ";
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4AnalyticalEcpssrKCrossSection::~G4AnalyticalEcpssrKCrossSection()
|
||||
{
|
||||
|
||||
delete tableC1;
|
||||
delete tableC2;
|
||||
delete tableC3;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrKCrossSection::ExpIntFunction(G4int n,G4double x)
|
||||
|
||||
{
|
||||
// this "ExpIntFunction" function allows fast evaluation of the n order exponential integral function En(x)
|
||||
|
||||
G4int i;
|
||||
G4int ii;
|
||||
G4int nm1;
|
||||
G4double a;
|
||||
G4double b;
|
||||
G4double c;
|
||||
G4double d;
|
||||
G4double del;
|
||||
G4double fact;
|
||||
G4double h;
|
||||
G4double psi;
|
||||
G4double ans = 0;
|
||||
const G4double euler= 0.5772156649;
|
||||
const G4int maxit= 100;
|
||||
const G4double fpmin = 1.0e-30;
|
||||
const G4double eps = 1.0e-7;
|
||||
nm1=n-1;
|
||||
if (n<0 || x<0.0 || (x==0.0 && (n==0 || n==1))) {
|
||||
G4cout << "G4AnalyticalEcpssrKCrossSection::ExpIntFunction: VERY Bad arguments in ExpIntFunction" << G4endl;
|
||||
G4cout << n << ", " << x << G4endl;
|
||||
}
|
||||
else {
|
||||
if (n==0) ans=std::exp(-x)/x;
|
||||
else {
|
||||
if (x==0.0) ans=1.0/nm1;
|
||||
else {
|
||||
if (x > 1.0) {
|
||||
b=x+n;
|
||||
c=1.0/fpmin;
|
||||
d=1.0/b;
|
||||
h=d;
|
||||
for (i=1;i<=maxit;i++) {
|
||||
a=-i*(nm1+i);
|
||||
b +=2.0;
|
||||
d=1.0/(a*d+b);
|
||||
c=b+a/c;
|
||||
del=c*d;
|
||||
h *=del;
|
||||
if (std::fabs(del-1.0) < eps) {
|
||||
ans=h*std::exp(-x);
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ans = (nm1!=0 ? 1.0/nm1 : -std::log(x)-euler);
|
||||
fact=1.0;
|
||||
for (i=1;i<=maxit;i++) {
|
||||
fact *=-x/i;
|
||||
if (i !=nm1) del = -fact/(i-nm1);
|
||||
else {
|
||||
psi = -euler;
|
||||
for (ii=1;ii<=nm1;ii++) psi +=1.0/ii;
|
||||
del=fact*(-std::log(x)+psi);
|
||||
}
|
||||
ans += del;
|
||||
if (std::fabs(del) < std::fabs(ans)*eps) return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4AnalyticalEcpssrKCrossSection::CalculateCrossSection(G4int zTarget,G4double massIncident, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
// this K-CrossSection calculation method is done according to W.Brandt and G.Lapicki, Phys.Rev.A23(1981)//
|
||||
|
||||
G4NistManager* massManager = G4NistManager::Instance();
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double zIncident = 0;
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
if (massIncident == aProtone->GetPDGMass() )
|
||||
{
|
||||
zIncident = (aProtone->GetPDGCharge())/eplus;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (massIncident == aAlpha->GetPDGMass())
|
||||
{
|
||||
zIncident = (aAlpha->GetPDGCharge())/eplus;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "*** WARNING in G4AnalyticalEcpssrKCrossSection::CalculateCrossSection : we can treat only Proton or Alpha incident particles " << G4endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel>0) G4cout << " massIncident=" << massIncident<< G4endl;
|
||||
|
||||
G4double kBindingEnergy = transitionManager->Shell(zTarget,0)->BindingEnergy();
|
||||
|
||||
if (verboseLevel>0) G4cout << " kBindingEnergy=" << kBindingEnergy/eV<< G4endl;
|
||||
|
||||
G4double massTarget = (massManager->GetAtomicMassAmu(zTarget))*amu_c2;
|
||||
|
||||
if (verboseLevel>0) G4cout << " massTarget=" << massTarget<< G4endl;
|
||||
|
||||
G4double systemMass =((massIncident*massTarget)/(massIncident+massTarget))/electron_mass_c2; //the mass of the system (projectile, target)
|
||||
|
||||
if (verboseLevel>0) G4cout << " systemMass=" << systemMass<< G4endl;
|
||||
|
||||
const G4double zkshell= 0.3;
|
||||
|
||||
G4double screenedzTarget = zTarget-zkshell; // screenedzTarget is the screened nuclear charge of the target
|
||||
|
||||
const G4double rydbergMeV= 13.6056923e-6;
|
||||
|
||||
G4double tetaK = kBindingEnergy/((screenedzTarget*screenedzTarget)*rydbergMeV); //tetaK denotes the reduced binding energy of the electron
|
||||
|
||||
if (verboseLevel>0) G4cout << " tetaK=" << tetaK<< G4endl;
|
||||
|
||||
G4double velocity =(2./(tetaK*screenedzTarget))*std::pow(((energyIncident*electron_mass_c2)/(massIncident*rydbergMeV)),0.5);
|
||||
|
||||
if (verboseLevel>0) G4cout << " velocity=" << velocity<< G4endl;
|
||||
|
||||
const G4double bohrPow2Barn=(Bohr_radius*Bohr_radius)/barn ;
|
||||
|
||||
if (verboseLevel>0) G4cout << " bohrPow2Barn=" << bohrPow2Barn<< G4endl;
|
||||
|
||||
G4double sigma0 = 8.*pi*(zIncident*zIncident)*bohrPow2Barn*std::pow(screenedzTarget,-4.); //sigma0 is the initial cross section of K shell at stable state
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigma0=" << sigma0<< G4endl;
|
||||
|
||||
const G4double kAnalyticalApproximation= 1.5;
|
||||
|
||||
G4double x = kAnalyticalApproximation/velocity;
|
||||
|
||||
if (verboseLevel>0) G4cout << " x=" << x<< G4endl;
|
||||
|
||||
G4double electrIonizationEnergy;
|
||||
|
||||
if ((0.< x) && (x <= 0.035))
|
||||
{
|
||||
electrIonizationEnergy= 0.75*pi*(std::log(1./(x*x))-1.);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (0.035 < x) && (x <=3.))
|
||||
{
|
||||
electrIonizationEnergy =std::exp(-2.*x)/(0.031+(0.213*std::pow(x,0.5))+(0.005*x)-(0.069*std::pow(x,3./2.))+(0.324*x*x));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( (3.< x) && (x<=11.))
|
||||
{
|
||||
electrIonizationEnergy =2.*std::exp(-2.*x)/std::pow(x,1.6);
|
||||
}
|
||||
|
||||
else electrIonizationEnergy =0.;
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel>0) G4cout << " electrIonizationEnergy=" << electrIonizationEnergy<< G4endl;
|
||||
|
||||
G4double hFunction =(electrIonizationEnergy*2.)/(tetaK*std::pow(velocity,3)); //hFunction represents the correction for polarization effet
|
||||
|
||||
if (verboseLevel>0) G4cout << " hFunction=" << hFunction<< G4endl;
|
||||
|
||||
G4double gFunction = (1.+(9.*velocity)+(31.*velocity*velocity)+(98.*std::pow(velocity,3.))+(12.*std::pow(velocity,4.))+(25.*std::pow(velocity,5.))
|
||||
+(4.2*std::pow(velocity,6.))+(0.515*std::pow(velocity,7.)))/std::pow(1.+velocity,9.); //gFunction represents the correction for binding effet
|
||||
if (verboseLevel>0) G4cout << " gFunction=" << gFunction<< G4endl;
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double sigmaPSS = 1.+(((2.*zIncident)/(screenedzTarget*tetaK))*(gFunction-hFunction)); //describes the perturbed stationnairy state of the affected atomic electon
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigmaPSS=" << sigmaPSS<< G4endl;
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigmaPSS*tetaK=" << sigmaPSS*tetaK<< G4endl;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const G4double cNaturalUnit= 1/fine_structure_const; // it's the speed of light according to Atomic-Unit-System
|
||||
|
||||
if (verboseLevel>0) G4cout << " cNaturalUnit=" << cNaturalUnit<< G4endl;
|
||||
|
||||
G4double ykFormula=0.4*(screenedzTarget/cNaturalUnit)*(screenedzTarget/cNaturalUnit)/(velocity/sigmaPSS);
|
||||
|
||||
if (verboseLevel>0) G4cout << " ykFormula=" << ykFormula<< G4endl;
|
||||
|
||||
G4double relativityCorrection = std::pow((1.+(1.1*ykFormula*ykFormula)),0.5)+ykFormula;// the relativistic correction parameter
|
||||
|
||||
if (verboseLevel>0) G4cout << " relativityCorrection=" << relativityCorrection<< G4endl;
|
||||
|
||||
G4double reducedVelocity = velocity*std::pow(relativityCorrection,0.5); // presents the reduced collision velocity parameter
|
||||
|
||||
if (verboseLevel>0) G4cout << " reducedVelocity=" << reducedVelocity<< G4endl;
|
||||
|
||||
G4double etaOverTheta2 = (energyIncident*electron_mass_c2)/(massIncident*rydbergMeV*screenedzTarget*screenedzTarget)
|
||||
/(sigmaPSS*tetaK)/(sigmaPSS*tetaK);
|
||||
|
||||
if (verboseLevel>0) G4cout << " etaOverTheta2=" << etaOverTheta2<< G4endl;
|
||||
|
||||
G4double universalFunction = 0;
|
||||
|
||||
// low velocity formula
|
||||
|
||||
if ( velocity < 1. )
|
||||
{
|
||||
if (verboseLevel>0) G4cout << " Notice : FK is computed from low velocity formula" << G4endl;
|
||||
|
||||
universalFunction = (std::pow(2.,9.)/45.)*std::pow(reducedVelocity/sigmaPSS,8.)*std::pow((1.+(1.72*(reducedVelocity/sigmaPSS)*(reducedVelocity/sigmaPSS))),-4.);// is the reduced universal cross section
|
||||
|
||||
|
||||
if (verboseLevel>0) G4cout << " universalFunction by Brandt 1981 =" << universalFunction<< G4endl;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
if ( etaOverTheta2 > 86.6 && (sigmaPSS*tetaK) > 0.4 && (sigmaPSS*tetaK) < 2.9996 )
|
||||
{
|
||||
// High and medium energies. Method from Rice 1977 on tabvles from Benka 1978
|
||||
|
||||
if (verboseLevel>0) G4cout << " Notice : FK is computed from high velocity formula" << G4endl;
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigmaPSS*tetaK=" << sigmaPSS*tetaK << G4endl;
|
||||
|
||||
G4double C1= tableC1->FindValue(sigmaPSS*tetaK);
|
||||
G4double C2= tableC2->FindValue(sigmaPSS*tetaK);
|
||||
G4double C3= tableC3->FindValue(sigmaPSS*tetaK);
|
||||
|
||||
if (verboseLevel>0) G4cout << " C1=" << C1 << G4endl;
|
||||
if (verboseLevel>0) G4cout << " C2=" << C2 << G4endl;
|
||||
if (verboseLevel>0) G4cout << " C3=" << C3 << G4endl;
|
||||
|
||||
G4double etaK = (energyIncident*electron_mass_c2)/(massIncident*rydbergMeV*screenedzTarget*screenedzTarget);
|
||||
|
||||
if (verboseLevel>0) G4cout << " etaK=" << etaK << G4endl;
|
||||
|
||||
G4double etaT = (sigmaPSS*tetaK)*(sigmaPSS*tetaK)*(86.6); // at any theta, the largest tabulated etaOverTheta2 is 86.6
|
||||
|
||||
if (verboseLevel>0) G4cout << " etaT=" << etaT << G4endl;
|
||||
|
||||
G4double fKT = FunctionFK((sigmaPSS*tetaK),86.6)*(etaT/(sigmaPSS*tetaK));
|
||||
|
||||
if (FunctionFK((sigmaPSS*tetaK),86.6)<=0.)
|
||||
{
|
||||
G4cout <<
|
||||
"*** WARNING in G4AnalyticalEcpssrKCrossSection::CalculateCrossSection : unable to interpolate FK function in high velocity region ! ***" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verboseLevel>0) G4cout << " FunctionFK=" << FunctionFK((sigmaPSS*tetaK),86.6) << G4endl;
|
||||
|
||||
if (verboseLevel>0) G4cout << " fKT=" << fKT << G4endl;
|
||||
|
||||
G4double GK = C2/(4*etaK) + C3/(32*etaK*etaK);
|
||||
|
||||
if (verboseLevel>0) G4cout << " GK=" << GK << G4endl;
|
||||
|
||||
G4double GT = C2/(4*etaT) + C3/(32*etaT*etaT);
|
||||
|
||||
if (verboseLevel>0) G4cout << " GT=" << GT << G4endl;
|
||||
|
||||
G4double DT = fKT - C1*std::log(etaT) + GT;
|
||||
|
||||
if (verboseLevel>0) G4cout << " DT=" << DT << G4endl;
|
||||
|
||||
G4double fKK = C1*std::log(etaK) + DT - GK;
|
||||
|
||||
if (verboseLevel>0) G4cout << " fKK=" << fKK << G4endl;
|
||||
|
||||
G4double universalFunction3= fKK/(etaK/tetaK);
|
||||
|
||||
if (verboseLevel>0) G4cout << " universalFunction3=" << universalFunction3 << G4endl;
|
||||
|
||||
universalFunction=universalFunction3;
|
||||
|
||||
}
|
||||
|
||||
else if ( etaOverTheta2 >= 1.e-3 && etaOverTheta2 <= 86.6 && (sigmaPSS*tetaK) >= 0.4 && (sigmaPSS*tetaK) <= 2.9996 )
|
||||
|
||||
{
|
||||
// From Benka 1978
|
||||
|
||||
if (verboseLevel>0) G4cout << " Notice : FK is computed from INTERPOLATED data" << G4endl;
|
||||
|
||||
G4double universalFunction2 = FunctionFK((sigmaPSS*tetaK),etaOverTheta2);
|
||||
|
||||
if (universalFunction2<=0)
|
||||
{
|
||||
G4cout <<
|
||||
"*** WARNING : G4AnalyticalEcpssrKCrossSection::CalculateCrossSection is unable to interpolate FK function in medium velocity region ! ***" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verboseLevel>0) G4cout << " universalFunction2=" << universalFunction2 << " for theta=" << sigmaPSS*tetaK << " and etaOverTheta2=" << etaOverTheta2 << G4endl;
|
||||
|
||||
universalFunction=universalFunction2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double sigmaPSSR = (sigma0/(sigmaPSS*tetaK))*universalFunction; //sigmaPSSR is the straight-line K-shell ionization cross section
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigmaPSSR=" << sigmaPSSR<< G4endl;
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double pssDeltaK = (4./(systemMass*sigmaPSS*tetaK))*(sigmaPSS/velocity)*(sigmaPSS/velocity);
|
||||
|
||||
if (verboseLevel>0) G4cout << " pssDeltaK=" << pssDeltaK<< G4endl;
|
||||
|
||||
G4double energyLoss = std::pow(1-pssDeltaK,0.5); //energyLoss incorporates the straight-line energy-loss
|
||||
|
||||
if (verboseLevel>0) G4cout << " energyLoss=" << energyLoss<< G4endl;
|
||||
|
||||
G4double energyLossFunction = (std::pow(2.,-9)/8.)*((((9.*energyLoss)-1.)*std::pow(1.+energyLoss,9.))+(((9.*energyLoss)+1.)*std::pow(1.-energyLoss,9.)));//energy loss function
|
||||
|
||||
if (verboseLevel>0) G4cout << " energyLossFunction=" << energyLossFunction<< G4endl;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double coulombDeflection = (4.*pi*zIncident/systemMass)*std::pow(tetaK*sigmaPSS,-2.)*std::pow(velocity/sigmaPSS,-3.)*(zTarget/screenedzTarget); //incorporates Coulomb deflection parameter
|
||||
|
||||
if (verboseLevel>0) G4cout << " cParameter-short=" << coulombDeflection<< G4endl;
|
||||
|
||||
G4double cParameter = 2.*coulombDeflection/(energyLoss*(energyLoss+1.));
|
||||
|
||||
if (verboseLevel>0) G4cout << " cParameter-full=" << cParameter<< G4endl;
|
||||
|
||||
G4double coulombDeflectionFunction = 9.*ExpIntFunction(10,cParameter); //this function describes Coulomb-deflection effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " ExpIntFunction(10,cParameter) =" << ExpIntFunction(10,cParameter) << G4endl;
|
||||
|
||||
if (verboseLevel>0) G4cout << " coulombDeflectionFunction =" << coulombDeflectionFunction << G4endl;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double crossSection = 0;
|
||||
|
||||
crossSection = energyLossFunction* coulombDeflectionFunction*sigmaPSSR; //this ECPSSR cross section is estimated at perturbed-stationnairy-state(PSS)
|
||||
//and it's reduced by the energy-loss(E),the Coulomb deflection(C),
|
||||
//and the relativity(R) effects
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
if (crossSection >= 0) {
|
||||
return crossSection * barn;
|
||||
}
|
||||
else {return 0;}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrKCrossSection::FunctionFK(G4double k, G4double theta)
|
||||
{
|
||||
|
||||
G4double sigma = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
|
||||
// PROTECTION TO ALLOW INTERPOLATION AT MINIMUM AND MAXIMUM EtaK/Theta2 values
|
||||
// (in particular for FK computation at 8.66EXX for high velocity formula)
|
||||
|
||||
if (
|
||||
theta==8.66e-3 ||
|
||||
theta==8.66e-2 ||
|
||||
theta==8.66e-1 ||
|
||||
theta==8.66e+0 ||
|
||||
theta==8.66e+1
|
||||
) theta=theta-1e-12;
|
||||
|
||||
if (
|
||||
theta==1.e-3 ||
|
||||
theta==1.e-2 ||
|
||||
theta==1.e-1 ||
|
||||
theta==1.e+00 ||
|
||||
theta==1.e+01
|
||||
) theta=theta+1e-12;
|
||||
|
||||
// END PROTECTION
|
||||
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec.begin(),dummyVec.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap[(*t1)].begin(),aVecMap[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap[(*t2)].begin(),aVecMap[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
|
||||
xs11 = FKData[valueT1][valueE11];
|
||||
xs12 = FKData[valueT1][valueE12];
|
||||
xs21 = FKData[valueT2][valueE21];
|
||||
xs22 = FKData[valueT2][valueE22];
|
||||
|
||||
/*
|
||||
if (verboseLevel>0)
|
||||
{
|
||||
G4cout << "x1= " << valueT1 << G4endl;
|
||||
G4cout << " vector of y for x1" << G4endl;
|
||||
std::for_each (aVecMap[(*t1)].begin(),aVecMap[(*t1)].end(), print);
|
||||
G4cout << G4endl;
|
||||
G4cout << "x2= " << valueT2 << G4endl;
|
||||
G4cout << " vector of y for x2" << G4endl;
|
||||
std::for_each (aVecMap[(*t2)].begin(),aVecMap[(*t2)].end(), print);
|
||||
|
||||
G4cout << G4endl;
|
||||
G4cout
|
||||
<< " "
|
||||
<< valueT1 << " "
|
||||
<< valueT2 << " "
|
||||
<< valueE11 << " "
|
||||
<< valueE12 << " "
|
||||
<< valueE21<< " "
|
||||
<< valueE22 << " "
|
||||
<< xs11 << " "
|
||||
<< xs12 << " "
|
||||
<< xs21 << " "
|
||||
<< xs22 << " "
|
||||
<< G4endl;
|
||||
}
|
||||
*/
|
||||
|
||||
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
|
||||
|
||||
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
|
||||
|
||||
if (xsProduct != 0.)
|
||||
{
|
||||
sigma = QuadInterpolator( valueE11, valueE12,
|
||||
valueE21, valueE22,
|
||||
xs11, xs12,
|
||||
xs21, xs22,
|
||||
valueT1, valueT2,
|
||||
k, theta );
|
||||
}
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrKCrossSection::LinLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double d1 = std::log(xs1);
|
||||
G4double d2 = std::log(xs2);
|
||||
G4double value = std::exp(d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrKCrossSection::LogLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a*std::log10(e2);
|
||||
G4double sigma = a*std::log10(e) + b;
|
||||
G4double value = (std::pow(10.,sigma));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrKCrossSection::QuadInterpolator(G4double e11, G4double e12,
|
||||
G4double e21, G4double e22,
|
||||
G4double xs11, G4double xs12,
|
||||
G4double xs21, G4double xs22,
|
||||
G4double t1, G4double t2,
|
||||
G4double t, G4double e)
|
||||
{
|
||||
// Log-Log
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
/*
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+983
@@ -0,0 +1,983 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4AnalyticalEcpssrLiCrossSection.cc,v 1.4 2010/11/22 17:25:45 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4AnalyticalEcpssrLiCrossSection.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include "G4LinLogInterpolation.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4AnalyticalEcpssrLiCrossSection::G4AnalyticalEcpssrLiCrossSection()
|
||||
{
|
||||
|
||||
// Storing FLi data needed for 0.2 to 3.0 velocities region
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
G4Exception("G4ecpssrLCrossSection::G4AnalyticalEcpssrLiCrossSection() G4LEDDATA environment variable not set");
|
||||
|
||||
std::ostringstream fileName1;
|
||||
std::ostringstream fileName2;
|
||||
|
||||
fileName1 << path << "/pixe/uf/FL1.dat";
|
||||
fileName2 << path << "/pixe/uf/FL2.dat";
|
||||
|
||||
// Reading of FL1.dat
|
||||
|
||||
std::ifstream FL1(fileName1.str().c_str());
|
||||
if (!FL1) G4Exception("G4ecpssrLCrossSection::G4AnalyticalEcpssrLiCrossSection() error opening FL1 data file");
|
||||
|
||||
dummyVec1.push_back(0.);
|
||||
|
||||
while(!FL1.eof())
|
||||
{
|
||||
double x1;
|
||||
double y1;
|
||||
|
||||
FL1>>x1>>y1;
|
||||
|
||||
// Mandatory vector initialization
|
||||
if (x1 != dummyVec1.back())
|
||||
{
|
||||
dummyVec1.push_back(x1);
|
||||
aVecMap1[x1].push_back(-1.);
|
||||
}
|
||||
|
||||
FL1>>FL1Data[x1][y1];
|
||||
|
||||
if (y1 != aVecMap1[x1].back()) aVecMap1[x1].push_back(y1);
|
||||
}
|
||||
|
||||
// Reading of FL2.dat
|
||||
|
||||
std::ifstream FL2(fileName2.str().c_str());
|
||||
if (!FL2) G4Exception("G4ecpssrLCrossSection::G4AnalyticalEcpssrLiCrossSection() error opening FL2 data file");
|
||||
|
||||
dummyVec2.push_back(0.);
|
||||
|
||||
while(!FL2.eof())
|
||||
{
|
||||
double x2;
|
||||
double y2;
|
||||
|
||||
FL2>>x2>>y2;
|
||||
|
||||
// Mandatory vector initialization
|
||||
if (x2 != dummyVec2.back())
|
||||
{
|
||||
dummyVec2.push_back(x2);
|
||||
aVecMap2[x2].push_back(-1.);
|
||||
}
|
||||
|
||||
FL2>>FL2Data[x2][y2];
|
||||
|
||||
if (y2 != aVecMap2[x2].back()) aVecMap2[x2].push_back(y2);
|
||||
}
|
||||
|
||||
// Verbose level
|
||||
verboseLevel=0;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4AnalyticalEcpssrLiCrossSection::~G4AnalyticalEcpssrLiCrossSection()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::ExpIntFunction(G4int n,G4double x)
|
||||
|
||||
{
|
||||
// this function allows fast evaluation of the n order exponential integral function En(x)
|
||||
|
||||
G4int i;
|
||||
G4int ii;
|
||||
G4int nm1;
|
||||
G4double a;
|
||||
G4double b;
|
||||
G4double c;
|
||||
G4double d;
|
||||
G4double del;
|
||||
G4double fact;
|
||||
G4double h;
|
||||
G4double psi;
|
||||
G4double ans = 0;
|
||||
const G4double euler= 0.5772156649;
|
||||
const G4int maxit= 100;
|
||||
const G4double fpmin = 1.0e-30;
|
||||
const G4double eps = 1.0e-7;
|
||||
nm1=n-1;
|
||||
if (n<0 || x<0.0 || (x==0.0 && (n==0 || n==1)))
|
||||
G4cout << "bad arguments in ExpIntFunction" << G4endl;
|
||||
else {
|
||||
if (n==0) ans=std::exp(-x)/x;
|
||||
else {
|
||||
if (x==0.0) ans=1.0/nm1;
|
||||
else {
|
||||
if (x > 1.0) {
|
||||
b=x+n;
|
||||
c=1.0/fpmin;
|
||||
d=1.0/b;
|
||||
h=d;
|
||||
for (i=1;i<=maxit;i++) {
|
||||
a=-i*(nm1+i);
|
||||
b +=2.0;
|
||||
d=1.0/(a*d+b);
|
||||
c=b+a/c;
|
||||
del=c*d;
|
||||
h *=del;
|
||||
if (std::fabs(del-1.0) < eps) {
|
||||
ans=h*std::exp(-x);
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ans = (nm1!=0 ? 1.0/nm1 : -std::log(x)-euler);
|
||||
fact=1.0;
|
||||
for (i=1;i<=maxit;i++) {
|
||||
fact *=-x/i;
|
||||
if (i !=nm1) del = -fact/(i-nm1);
|
||||
else {
|
||||
psi = -euler;
|
||||
for (ii=1;ii<=nm1;ii++) psi +=1.0/ii;
|
||||
del=fact*(-std::log(x)+psi);
|
||||
}
|
||||
ans += del;
|
||||
if (std::fabs(del) < std::fabs(ans)*eps) return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::CalculateL1CrossSection(G4int zTarget,G4double massIncident, G4double energyIncident)
|
||||
{
|
||||
|
||||
//this L1-CrossSection calculation method is done according to Werner Brandt and Grzegorz Lapicki, Phys.Rev.A20 N2 (1979),
|
||||
//and using data tables of O. Benka et al. At.Data Nucl.Data Tables Vol.22 No.3 (1978).
|
||||
|
||||
G4NistManager* massManager = G4NistManager::Instance();
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double zIncident = 0;
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
if (massIncident == aProtone->GetPDGMass() )
|
||||
|
||||
zIncident = (aProtone->GetPDGCharge())/eplus;
|
||||
|
||||
else
|
||||
{
|
||||
if (massIncident == aAlpha->GetPDGMass())
|
||||
|
||||
zIncident = (aAlpha->GetPDGCharge())/eplus;
|
||||
|
||||
else
|
||||
{
|
||||
G4cout << "*** WARNING in G4AnalyticalEcpssrLiCrossSection::CalculateL1CrossSection : Proton or Alpha incident particles only. " << G4endl;
|
||||
G4cout << massIncident << ", " << aAlpha->GetPDGMass() << " (alpha)" << aProtone->GetPDGMass() << " (proton)" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4double l1BindingEnergy = transitionManager->Shell(zTarget,1)->BindingEnergy(); //Observed binding energy of L1-subshell
|
||||
|
||||
G4double massTarget = (massManager->GetAtomicMassAmu(zTarget))*amu_c2;
|
||||
|
||||
G4double systemMass =((massIncident*massTarget)/(massIncident+massTarget))/electron_mass_c2; //Mass of the system (projectile, target)
|
||||
|
||||
const G4double zlshell= 4.15;
|
||||
|
||||
G4double screenedzTarget = zTarget-zlshell; //Effective nuclear charge as seen by electrons in L1-sub shell
|
||||
|
||||
const G4double rydbergMeV= 13.6056923e-6;
|
||||
|
||||
const G4double nl= 2.;
|
||||
|
||||
G4double tetal1 = (l1BindingEnergy*nl*nl)/((screenedzTarget*screenedzTarget)*rydbergMeV); //Screening parameter
|
||||
|
||||
if (verboseLevel>0) G4cout << " tetal1=" << tetal1<< G4endl;
|
||||
|
||||
G4double reducedEnergy = (energyIncident*electron_mass_c2)/(massIncident*rydbergMeV*screenedzTarget*screenedzTarget);
|
||||
|
||||
const G4double bohrPow2Barn=(Bohr_radius*Bohr_radius)/barn ; //Bohr radius of hydrogen
|
||||
|
||||
G4double sigma0 = 8.*pi*(zIncident*zIncident)*bohrPow2Barn*std::pow(screenedzTarget,-4.);
|
||||
|
||||
G4double velocityl1 = CalculateVelocity(1, zTarget, massIncident, energyIncident); // Scaled velocity
|
||||
|
||||
if (verboseLevel>0) G4cout << " velocityl1=" << velocityl1<< G4endl;
|
||||
|
||||
const G4double l1AnalyticalApproximation= 1.5;
|
||||
|
||||
G4double x1 =(nl*l1AnalyticalApproximation)/velocityl1;
|
||||
|
||||
if (verboseLevel>0) G4cout << " x1=" << x1<< G4endl;
|
||||
|
||||
G4double electrIonizationEnergyl1=0.;
|
||||
|
||||
if ( x1<=0.035) electrIonizationEnergyl1= 0.75*pi*(std::log(1./(x1*x1))-1.);
|
||||
else
|
||||
{
|
||||
if ( x1<=3.)
|
||||
electrIonizationEnergyl1 =std::exp(-2.*x1)/(0.031+(0.213*std::pow(x1,0.5))+(0.005*x1)-(0.069*std::pow(x1,3./2.))+(0.324*x1*x1));
|
||||
else
|
||||
{if ( x1<=11.) electrIonizationEnergyl1 =2.*std::exp(-2.*x1)/std::pow(x1,1.6);}
|
||||
}
|
||||
|
||||
G4double hFunctionl1 =(electrIonizationEnergyl1*2.*nl)/(tetal1*std::pow(velocityl1,3)); //takes into account the polarization effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " hFunctionl1=" << hFunctionl1<< G4endl;
|
||||
|
||||
G4double gFunctionl1 = (1.+(9.*velocityl1)+(31.*velocityl1*velocityl1)+(49.*std::pow(velocityl1,3.))+(162.*std::pow(velocityl1,4.))+(63.*std::pow(velocityl1,5.))+(18.*std::pow(velocityl1,6.))+(1.97*std::pow(velocityl1,7.)))/std::pow(1.+velocityl1,9.);//takes into account the reduced binding effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " gFunctionl1=" << gFunctionl1<< G4endl;
|
||||
|
||||
G4double sigmaPSS_l1 = 1.+(((2.*zIncident)/(screenedzTarget*tetal1))*(gFunctionl1-hFunctionl1)); //Binding-polarization factor
|
||||
|
||||
if (verboseLevel>0) G4cout << "sigmaPSS_l1 =" << sigmaPSS_l1<< G4endl;
|
||||
|
||||
const G4double cNaturalUnit= 137.;
|
||||
|
||||
G4double yl1Formula=0.4*(screenedzTarget/cNaturalUnit)*(screenedzTarget/cNaturalUnit)/(nl*velocityl1/sigmaPSS_l1);
|
||||
|
||||
G4double l1relativityCorrection = std::pow((1.+(1.1*yl1Formula*yl1Formula)),0.5)+yl1Formula; // Relativistic correction parameter
|
||||
|
||||
//G4double reducedVelocity_l1 = velocityl1*std::pow(l1relativityCorrection,0.5); //Reduced velocity parameter
|
||||
|
||||
|
||||
G4double L1etaOverTheta2;
|
||||
|
||||
G4double universalFunction_l1 = 0.;
|
||||
|
||||
G4double sigmaPSSR_l1;
|
||||
|
||||
if ( velocityl1 <5. )
|
||||
{
|
||||
|
||||
L1etaOverTheta2 =(reducedEnergy* l1relativityCorrection)/((tetal1*sigmaPSS_l1)*(tetal1*sigmaPSS_l1));
|
||||
|
||||
if ( ((tetal1*sigmaPSS_l1) >=0.2) && ((tetal1*sigmaPSS_l1) <=2.6670) && (L1etaOverTheta2>=0.1e-3) && (L1etaOverTheta2<=0.866e2) )
|
||||
|
||||
universalFunction_l1 = FunctionFL1((tetal1*sigmaPSS_l1),L1etaOverTheta2);
|
||||
|
||||
if (verboseLevel>0) G4cout << "at low velocity range, universalFunction_l1 =" << universalFunction_l1 << G4endl;
|
||||
|
||||
sigmaPSSR_l1 = (sigma0/(tetal1*sigmaPSS_l1))*universalFunction_l1;// Plane-wave Born -Aproximation L1-subshell ionisation Cross Section
|
||||
|
||||
if (verboseLevel>0) G4cout << " at low velocity range, sigma PWBA L1 CS = " << sigmaPSSR_l1<< G4endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
L1etaOverTheta2 = reducedEnergy/(tetal1*tetal1);
|
||||
|
||||
if ( (tetal1 >=0.2) && (tetal1 <=2.6670) && (L1etaOverTheta2>=0.1e-3) && (L1etaOverTheta2<=0.866e2) )
|
||||
|
||||
universalFunction_l1 = FunctionFL1(tetal1,L1etaOverTheta2);
|
||||
|
||||
if (verboseLevel>0) G4cout << "at medium and high velocity range, universalFunction_l1 =" << universalFunction_l1 << G4endl;
|
||||
|
||||
sigmaPSSR_l1 = (sigma0/tetal1)*universalFunction_l1;// Plane-wave Born -Aproximation L1-subshell ionisation Cross Section
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigma PWBA L1 CS at medium and high velocity range = " << sigmaPSSR_l1<< G4endl;
|
||||
}
|
||||
|
||||
G4double pssDeltal1 = (4./(systemMass *sigmaPSS_l1*tetal1))*(sigmaPSS_l1/velocityl1)*(sigmaPSS_l1/velocityl1);
|
||||
|
||||
if (verboseLevel>0) G4cout << " pssDeltal1=" << pssDeltal1<< G4endl;
|
||||
|
||||
G4double energyLossl1 = std::pow(1-pssDeltal1,0.5);
|
||||
|
||||
if (verboseLevel>0) G4cout << " energyLossl1=" << energyLossl1<< G4endl;
|
||||
|
||||
G4double coulombDeflectionl1 =
|
||||
(8.*pi*zIncident/systemMass)*std::pow(tetal1*sigmaPSS_l1,-2.)*std::pow(velocityl1/sigmaPSS_l1,-3.)*(zTarget/screenedzTarget);
|
||||
|
||||
G4double cParameterl1 =2.* coulombDeflectionl1/(energyLossl1*(energyLossl1+1.));
|
||||
|
||||
G4double coulombDeflectionFunction_l1 = 9.*ExpIntFunction(10,cParameterl1); //Coulomb-deflection effect correction
|
||||
|
||||
if (verboseLevel>0) G4cout << " coulombDeflectionFunction_l1 =" << coulombDeflectionFunction_l1 << G4endl;
|
||||
|
||||
G4double crossSection_L1 = coulombDeflectionFunction_l1 * sigmaPSSR_l1;
|
||||
|
||||
//ECPSSR L1 -subshell cross section is estimated at perturbed-stationnairy-state(PSS)
|
||||
//and reduced by the energy-loss(E),the Coulomb deflection(C),and the relativity(R) effects
|
||||
|
||||
if (verboseLevel>0) G4cout << " crossSection_L1 =" << crossSection_L1 << G4endl;
|
||||
|
||||
if (crossSection_L1 >= 0) {
|
||||
|
||||
return crossSection_L1 * barn;
|
||||
}
|
||||
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::CalculateL2CrossSection(G4int zTarget,G4double massIncident, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
// this L2-CrossSection calculation method is done according to Werner Brandt and Grzegorz Lapicki, Phys.Rev.A20 N2 (1979),
|
||||
// and using data tables of O. Benka et al. At.Data Nucl.Data Tables Vol.22 No.3 (1978).
|
||||
|
||||
G4NistManager* massManager = G4NistManager::Instance();
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double zIncident = 0;
|
||||
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
if (massIncident == aProtone->GetPDGMass() )
|
||||
|
||||
zIncident = (aProtone->GetPDGCharge())/eplus;
|
||||
|
||||
else
|
||||
{
|
||||
if (massIncident == aAlpha->GetPDGMass())
|
||||
|
||||
zIncident = (aAlpha->GetPDGCharge())/eplus;
|
||||
|
||||
else
|
||||
{
|
||||
G4cout << "*** WARNING in G4AnalyticalEcpssrLiCrossSection::CalculateL2CrossSection : Proton or Alpha incident particles only. " << G4endl;
|
||||
G4cout << massIncident << ", " << aAlpha->GetPDGMass() << " (alpha)" << aProtone->GetPDGMass() << " (proton)" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4double l2BindingEnergy = transitionManager->Shell(zTarget,2)->BindingEnergy(); //Observed binding energy of L2-subshell
|
||||
|
||||
G4double massTarget = (massManager->GetAtomicMassAmu(zTarget))*amu_c2;
|
||||
|
||||
G4double systemMass =((massIncident*massTarget)/(massIncident+massTarget))/electron_mass_c2; //Mass of the system (projectile, target)
|
||||
|
||||
const G4double zlshell= 4.15;
|
||||
|
||||
G4double screenedzTarget = zTarget-zlshell; //Effective nuclear charge as seen by electrons in L2-subshell
|
||||
|
||||
const G4double rydbergMeV= 13.6056923e-6;
|
||||
|
||||
const G4double nl= 2.;
|
||||
|
||||
G4double tetal2 = (l2BindingEnergy*nl*nl)/((screenedzTarget*screenedzTarget)*rydbergMeV); //Screening parameter
|
||||
|
||||
if (verboseLevel>0) G4cout << " tetal2=" << tetal2<< G4endl;
|
||||
|
||||
G4double reducedEnergy = (energyIncident*electron_mass_c2)/(massIncident*rydbergMeV*screenedzTarget*screenedzTarget);
|
||||
|
||||
const G4double bohrPow2Barn=(Bohr_radius*Bohr_radius)/barn ; //Bohr radius of hydrogen
|
||||
|
||||
G4double sigma0 = 8.*pi*(zIncident*zIncident)*bohrPow2Barn*std::pow(screenedzTarget,-4.);
|
||||
|
||||
G4double velocityl2 = CalculateVelocity(2, zTarget, massIncident, energyIncident); // Scaled velocity
|
||||
|
||||
if (verboseLevel>0) G4cout << " velocityl2=" << velocityl2<< G4endl;
|
||||
|
||||
const G4double l23AnalyticalApproximation= 1.25;
|
||||
|
||||
G4double x2 = (nl*l23AnalyticalApproximation)/velocityl2;
|
||||
|
||||
if (verboseLevel>0) G4cout << " x2=" << x2<< G4endl;
|
||||
|
||||
G4double electrIonizationEnergyl2=0.;
|
||||
|
||||
if ( x2<=0.035) electrIonizationEnergyl2= 0.75*pi*(std::log(1./(x2*x2))-1.);
|
||||
else
|
||||
{
|
||||
if ( x2<=3.)
|
||||
electrIonizationEnergyl2 =std::exp(-2.*x2)/(0.031+(0.210*std::pow(x2,0.5))+(0.005*x2)-(0.069*std::pow(x2,3./2.))+(0.324*x2*x2));
|
||||
else
|
||||
{if ( x2<=11.) electrIonizationEnergyl2 =2.*std::exp(-2.*x2)/std::pow(x2,1.6); }
|
||||
}
|
||||
|
||||
G4double hFunctionl2 =(electrIonizationEnergyl2*2.*nl)/(tetal2*std::pow(velocityl2,3)); //takes into account the polarization effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " hFunctionl2=" << hFunctionl2<< G4endl;
|
||||
|
||||
G4double gFunctionl2 = (1.+(10.*velocityl2)+(45.*velocityl2*velocityl2)+(102.*std::pow(velocityl2,3.))+(331.*std::pow(velocityl2,4.))+(6.7*std::pow(velocityl2,5.))+(58.*std::pow(velocityl2,6.))+(7.8*std::pow(velocityl2,7.))+ (0.888*std::pow(velocityl2,8.)) )/std::pow(1.+velocityl2,10.);
|
||||
//takes into account the reduced binding effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " gFunctionl2=" << gFunctionl2<< G4endl;
|
||||
|
||||
G4double sigmaPSS_l2 = 1.+(((2.*zIncident)/(screenedzTarget*tetal2))*(gFunctionl2-hFunctionl2)); //Binding-polarization factor
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigmaPSS_l2=" << sigmaPSS_l2<< G4endl;
|
||||
|
||||
const G4double cNaturalUnit= 137.;
|
||||
|
||||
G4double yl2Formula=0.15*(screenedzTarget/cNaturalUnit)*(screenedzTarget/cNaturalUnit)/(velocityl2/sigmaPSS_l2);
|
||||
|
||||
G4double l2relativityCorrection = std::pow((1.+(1.1*yl2Formula*yl2Formula)),0.5)+yl2Formula; // Relativistic correction parameter
|
||||
|
||||
|
||||
G4double L2etaOverTheta2;
|
||||
|
||||
G4double universalFunction_l2 = 0.;
|
||||
|
||||
G4double sigmaPSSR_l2 ;
|
||||
|
||||
if ( velocityl2 < 5. )
|
||||
{
|
||||
|
||||
L2etaOverTheta2 = (reducedEnergy*l2relativityCorrection)/((sigmaPSS_l2*tetal2)*(sigmaPSS_l2*tetal2));
|
||||
|
||||
if ( (tetal2*sigmaPSS_l2>=0.2) && (tetal2*sigmaPSS_l2<=2.6670) && (L2etaOverTheta2>=0.1e-3) && (L2etaOverTheta2<=0.866e2) )
|
||||
|
||||
universalFunction_l2 = FunctionFL2((tetal2*sigmaPSS_l2),L2etaOverTheta2);
|
||||
|
||||
sigmaPSSR_l2 = (sigma0/(tetal2*sigmaPSS_l2))*universalFunction_l2;
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigma PWBA L2 CS at low velocity range = " << sigmaPSSR_l2<< G4endl;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
L2etaOverTheta2 = reducedEnergy /(tetal2*tetal2);
|
||||
|
||||
if ( (tetal2>=0.2) && (tetal2<=2.6670) && (L2etaOverTheta2>=0.1e-3) && (L2etaOverTheta2<=0.866e2) )
|
||||
|
||||
universalFunction_l2 = FunctionFL2((tetal2),L2etaOverTheta2);
|
||||
|
||||
sigmaPSSR_l2 = (sigma0/tetal2)*universalFunction_l2;
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigma PWBA L2 CS at medium and high velocity range = " << sigmaPSSR_l2<< G4endl;
|
||||
|
||||
}
|
||||
|
||||
G4double pssDeltal2 = (4./(systemMass*sigmaPSS_l2*tetal2))*(sigmaPSS_l2/velocityl2)*(sigmaPSS_l2/velocityl2);
|
||||
|
||||
G4double energyLossl2 = std::pow(1-pssDeltal2,0.5);
|
||||
|
||||
if (verboseLevel>0) G4cout << " energyLossl2=" << energyLossl2<< G4endl;
|
||||
|
||||
G4double coulombDeflectionl2
|
||||
=(8.*pi*zIncident/systemMass)*std::pow(tetal2*sigmaPSS_l2,-2.)*std::pow(velocityl2/sigmaPSS_l2,-3.)*(zTarget/screenedzTarget);
|
||||
|
||||
G4double cParameterl2 = 2.*coulombDeflectionl2/(energyLossl2*(energyLossl2+1.));
|
||||
|
||||
G4double coulombDeflectionFunction_l2 = 11.*ExpIntFunction(12,cParameterl2); //Coulomb-deflection effect correction
|
||||
|
||||
if (verboseLevel>0) G4cout << " coulombDeflectionFunction_l2 =" << coulombDeflectionFunction_l2 << G4endl;
|
||||
|
||||
G4double crossSection_L2 = coulombDeflectionFunction_l2 * sigmaPSSR_l2;
|
||||
//ECPSSR L2 -subshell cross section is estimated at perturbed-stationnairy-state(PSS)
|
||||
//and reduced by the energy-loss(E),the Coulomb deflection(C),and the relativity(R) effects
|
||||
|
||||
if (verboseLevel>0) G4cout << " crossSection_L2 =" << crossSection_L2 << G4endl;
|
||||
|
||||
if (crossSection_L2 >= 0) {
|
||||
return crossSection_L2 * barn;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::CalculateL3CrossSection(G4int zTarget,G4double massIncident, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
//this L3-CrossSection calculation method is done according to Werner Brandt and Grzegorz Lapicki, Phys.Rev.A20 N2 (1979),
|
||||
//and using data tables of O. Benka et al. At.Data Nucl.Data Tables Vol.22 No.3 (1978).
|
||||
|
||||
G4NistManager* massManager = G4NistManager::Instance();
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double zIncident = 0;
|
||||
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
if (massIncident == aProtone->GetPDGMass() )
|
||||
|
||||
zIncident = (aProtone->GetPDGCharge())/eplus;
|
||||
|
||||
else
|
||||
{
|
||||
if (massIncident == aAlpha->GetPDGMass())
|
||||
|
||||
zIncident = (aAlpha->GetPDGCharge())/eplus;
|
||||
|
||||
else
|
||||
{
|
||||
G4cout << "*** WARNING in G4AnalyticalEcpssrLiCrossSection::CalculateL3CrossSection : Proton or Alpha incident particles only. " << G4endl;
|
||||
G4cout << massIncident << ", " << aAlpha->GetPDGMass() << " (alpha)" << aProtone->GetPDGMass() << " (proton)" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4double l3BindingEnergy = transitionManager->Shell(zTarget,3)->BindingEnergy();
|
||||
|
||||
G4double massTarget = (massManager->GetAtomicMassAmu(zTarget))*amu_c2;
|
||||
|
||||
G4double systemMass =((massIncident*massTarget)/(massIncident+massTarget))/electron_mass_c2;//Mass of the system (projectile, target)
|
||||
|
||||
const G4double zlshell= 4.15;
|
||||
|
||||
G4double screenedzTarget = zTarget-zlshell;//Effective nuclear charge as seen by electrons in L3-subshell
|
||||
|
||||
const G4double rydbergMeV= 13.6056923e-6;
|
||||
|
||||
const G4double nl= 2.;
|
||||
|
||||
G4double tetal3 = (l3BindingEnergy*nl*nl)/((screenedzTarget*screenedzTarget)*rydbergMeV);//Screening parameter
|
||||
|
||||
if (verboseLevel>0) G4cout << " tetal3=" << tetal3<< G4endl;
|
||||
|
||||
G4double reducedEnergy = (energyIncident*electron_mass_c2)/(massIncident*rydbergMeV*screenedzTarget*screenedzTarget);
|
||||
|
||||
const G4double bohrPow2Barn=(Bohr_radius*Bohr_radius)/barn ;//Bohr radius of hydrogen
|
||||
|
||||
G4double sigma0 = 8.*pi*(zIncident*zIncident)*bohrPow2Barn*std::pow(screenedzTarget,-4.);
|
||||
|
||||
G4double velocityl3 = CalculateVelocity(3, zTarget, massIncident, energyIncident);// Scaled velocity
|
||||
|
||||
if (verboseLevel>0) G4cout << " velocityl3=" << velocityl3<< G4endl;
|
||||
|
||||
const G4double l23AnalyticalApproximation= 1.25;
|
||||
|
||||
G4double x3 = (nl*l23AnalyticalApproximation)/velocityl3;
|
||||
|
||||
if (verboseLevel>0) G4cout << " x3=" << x3<< G4endl;
|
||||
|
||||
G4double electrIonizationEnergyl3=0.;
|
||||
|
||||
if ( x3<=0.035) electrIonizationEnergyl3= 0.75*pi*(std::log(1./(x3*x3))-1.);
|
||||
else
|
||||
{
|
||||
if ( x3<=3.) electrIonizationEnergyl3 =std::exp(-2.*x3)/(0.031+(0.210*std::pow(x3,0.5))+(0.005*x3)-(0.069*std::pow(x3,3./2.))+(0.324*x3*x3));
|
||||
else
|
||||
{
|
||||
if ( x3<=11.) electrIonizationEnergyl3 =2.*std::exp(-2.*x3)/std::pow(x3,1.6);}
|
||||
}
|
||||
|
||||
G4double hFunctionl3 =(electrIonizationEnergyl3*2.*nl)/(tetal3*std::pow(velocityl3,3));//takes into account the polarization effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " hFunctionl3=" << hFunctionl3<< G4endl;
|
||||
|
||||
G4double gFunctionl3 = (1.+(10.*velocityl3)+(45.*velocityl3*velocityl3)+(102.*std::pow(velocityl3,3.))+(331.*std::pow(velocityl3,4.))+(6.7*std::pow(velocityl3,5.))+(58.*std::pow(velocityl3,6.))+(7.8*std::pow(velocityl3,7.))+ (0.888*std::pow(velocityl3,8.)) )/std::pow(1.+velocityl3,10.);
|
||||
//takes into account the reduced binding effect
|
||||
|
||||
if (verboseLevel>0) G4cout << " gFunctionl3=" << gFunctionl3<< G4endl;
|
||||
|
||||
G4double sigmaPSS_l3 = 1.+(((2.*zIncident)/(screenedzTarget*tetal3))*(gFunctionl3-hFunctionl3));//Binding-polarization factor
|
||||
|
||||
if (verboseLevel>0) G4cout << "sigmaPSS_l3 =" << sigmaPSS_l3<< G4endl;
|
||||
|
||||
const G4double cNaturalUnit= 137.;
|
||||
|
||||
G4double yl3Formula=0.15*(screenedzTarget/cNaturalUnit)*(screenedzTarget/cNaturalUnit)/(velocityl3/sigmaPSS_l3);
|
||||
|
||||
G4double l3relativityCorrection = std::pow((1.+(1.1*yl3Formula*yl3Formula)),0.5)+yl3Formula; // Relativistic correction parameter
|
||||
|
||||
G4double L3etaOverTheta2;
|
||||
|
||||
G4double universalFunction_l3 = 0.;
|
||||
|
||||
G4double sigmaPSSR_l3;
|
||||
|
||||
if ( velocityl3 < 5. )
|
||||
{
|
||||
|
||||
L3etaOverTheta2 = (reducedEnergy* l3relativityCorrection)/((sigmaPSS_l3*tetal3)*(sigmaPSS_l3*tetal3));
|
||||
|
||||
if ( (tetal3*sigmaPSS_l3>=0.2) && (tetal3*sigmaPSS_l3<=2.6670) && (L3etaOverTheta2>=0.1e-3) && (L3etaOverTheta2<=0.866e2) )
|
||||
|
||||
universalFunction_l3 = 2.*FunctionFL2((tetal3*sigmaPSS_l3), L3etaOverTheta2 );
|
||||
|
||||
sigmaPSSR_l3 = (sigma0/(tetal3*sigmaPSS_l3))*universalFunction_l3;
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigma PWBA L3 CS at low velocity range = " << sigmaPSSR_l3<< G4endl;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
|
||||
L3etaOverTheta2 = reducedEnergy/(tetal3*tetal3);
|
||||
|
||||
if ( (tetal3>=0.2) && (tetal3<=2.6670) && (L3etaOverTheta2>=0.1e-3) && (L3etaOverTheta2<=0.866e2) )
|
||||
|
||||
universalFunction_l3 = 2.*FunctionFL2(tetal3, L3etaOverTheta2 );
|
||||
|
||||
sigmaPSSR_l3 = (sigma0/tetal3)*universalFunction_l3;
|
||||
|
||||
if (verboseLevel>0) G4cout << " sigma PWBA L3 CS at medium and high velocity range = " << sigmaPSSR_l3<< G4endl;
|
||||
|
||||
}
|
||||
|
||||
G4double pssDeltal3 = (4./(systemMass*sigmaPSS_l3*tetal3))*(sigmaPSS_l3/velocityl3)*(sigmaPSS_l3/velocityl3);
|
||||
|
||||
if (verboseLevel>0) G4cout << " pssDeltal3=" << pssDeltal3<< G4endl;
|
||||
|
||||
G4double energyLossl3 = std::pow(1-pssDeltal3,0.5);
|
||||
|
||||
if (verboseLevel>0) G4cout << " energyLossl3=" << energyLossl3<< G4endl;
|
||||
|
||||
G4double coulombDeflectionl3 =
|
||||
(8.*pi*zIncident/systemMass)*std::pow(tetal3*sigmaPSS_l3,-2.)*std::pow(velocityl3/sigmaPSS_l3,-3.)*(zTarget/screenedzTarget);
|
||||
|
||||
G4double cParameterl3 = 2.*coulombDeflectionl3/(energyLossl3*(energyLossl3+1.));
|
||||
|
||||
G4double coulombDeflectionFunction_l3 = 11.*ExpIntFunction(12,cParameterl3);//Coulomb-deflection effect correction
|
||||
|
||||
if (verboseLevel>0) G4cout << " coulombDeflectionFunction_l3 =" << coulombDeflectionFunction_l3 << G4endl;
|
||||
|
||||
G4double crossSection_L3 = coulombDeflectionFunction_l3 * sigmaPSSR_l3;
|
||||
//ECPSSR L3 -subshell cross section is estimated at perturbed-stationnairy-state(PSS)
|
||||
//and reduced by the energy-loss(E),the Coulomb deflection(C),and the relativity(R) effects
|
||||
|
||||
if (verboseLevel>0) G4cout << " crossSection_L3 =" << crossSection_L3 << G4endl;
|
||||
|
||||
if (crossSection_L3 >= 0) {
|
||||
return crossSection_L3 * barn;
|
||||
}
|
||||
else {return 0;}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::CalculateVelocity(G4int subShell, G4int zTarget, G4double massIncident, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double liBindingEnergy = transitionManager->Shell(zTarget,subShell)->BindingEnergy();
|
||||
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
if (!((massIncident == aProtone->GetPDGMass()) || (massIncident == aAlpha->GetPDGMass())))
|
||||
{
|
||||
G4cout << "*** WARNING in G4AnalyticalEcpssrLiCrossSection::CalculateVelocity : Proton or Alpha incident particles only. " << G4endl;
|
||||
G4cout << massIncident << ", " << aAlpha->GetPDGMass() << " (alpha)" << aProtone->GetPDGMass() << " (proton)" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const G4double zlshell= 4.15;
|
||||
|
||||
G4double screenedzTarget = zTarget- zlshell;
|
||||
|
||||
const G4double rydbergMeV= 13.6056923e-6;
|
||||
|
||||
const G4double nl= 2.;
|
||||
|
||||
G4double tetali = (liBindingEnergy*nl*nl)/(screenedzTarget*screenedzTarget*rydbergMeV);
|
||||
|
||||
G4double reducedEnergy = (energyIncident*electron_mass_c2)/(massIncident*rydbergMeV*screenedzTarget*screenedzTarget);
|
||||
|
||||
G4double velocity = 2.*nl*std::pow(reducedEnergy,0.5)/tetali;
|
||||
|
||||
return velocity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::FunctionFL1(G4double k, G4double theta)
|
||||
{
|
||||
|
||||
G4double sigma = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
|
||||
// PROTECTION TO ALLOW INTERPOLATION AT MINIMUM AND MAXIMUM Eta/Theta2 values
|
||||
|
||||
if (
|
||||
theta==8.66e-4 ||
|
||||
theta==8.66e-3 ||
|
||||
theta==8.66e-2 ||
|
||||
theta==8.66e-1 ||
|
||||
theta==8.66e+00 ||
|
||||
theta==8.66e+01
|
||||
) theta=theta-1e-12;
|
||||
|
||||
if (
|
||||
theta==1.e-4 ||
|
||||
theta==1.e-3 ||
|
||||
theta==1.e-2 ||
|
||||
theta==1.e-1 ||
|
||||
theta==1.e+00 ||
|
||||
theta==1.e+01
|
||||
) theta=theta+1e-12;
|
||||
|
||||
// END PROTECTION
|
||||
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec1.begin(),dummyVec1.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap1[(*t1)].begin(),aVecMap1[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap1[(*t2)].begin(),aVecMap1[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
|
||||
xs11 = FL1Data[valueT1][valueE11];
|
||||
xs12 = FL1Data[valueT1][valueE12];
|
||||
xs21 = FL1Data[valueT2][valueE21];
|
||||
xs22 = FL1Data[valueT2][valueE22];
|
||||
|
||||
if (verboseLevel>0)
|
||||
G4cout
|
||||
<< valueT1 << " "
|
||||
<< valueT2 << " "
|
||||
<< valueE11 << " "
|
||||
<< valueE12 << " "
|
||||
<< valueE21 << " "
|
||||
<< valueE22 << " "
|
||||
<< xs11 << " "
|
||||
<< xs12 << " "
|
||||
<< xs21 << " "
|
||||
<< xs22 << " "
|
||||
<< G4endl;
|
||||
|
||||
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
|
||||
|
||||
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
|
||||
|
||||
if (xsProduct != 0.)
|
||||
{
|
||||
sigma = QuadInterpolator( valueE11, valueE12,
|
||||
valueE21, valueE22,
|
||||
xs11, xs12,
|
||||
xs21, xs22,
|
||||
valueT1, valueT2,
|
||||
k, theta );
|
||||
}
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::FunctionFL2(G4double k, G4double theta)
|
||||
{
|
||||
|
||||
G4double sigma = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
|
||||
// PROTECTION TO ALLOW INTERPOLATION AT MINIMUM AND MAXIMUM Eta/Theta2 values
|
||||
|
||||
if (
|
||||
theta==8.66e-4 ||
|
||||
theta==8.66e-3 ||
|
||||
theta==8.66e-2 ||
|
||||
theta==8.66e-1 ||
|
||||
theta==8.66e+00 ||
|
||||
theta==8.66e+01
|
||||
) theta=theta-1e-12;
|
||||
|
||||
if (
|
||||
theta==1.e-4 ||
|
||||
theta==1.e-3 ||
|
||||
theta==1.e-2 ||
|
||||
theta==1.e-1 ||
|
||||
theta==1.e+00 ||
|
||||
theta==1.e+01
|
||||
) theta=theta+1e-12;
|
||||
|
||||
// END PROTECTION
|
||||
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec2.begin(),dummyVec2.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap2[(*t1)].begin(),aVecMap2[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap2[(*t2)].begin(),aVecMap2[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
|
||||
xs11 = FL2Data[valueT1][valueE11];
|
||||
xs12 = FL2Data[valueT1][valueE12];
|
||||
xs21 = FL2Data[valueT2][valueE21];
|
||||
xs22 = FL2Data[valueT2][valueE22];
|
||||
|
||||
if (verboseLevel>0)
|
||||
G4cout
|
||||
<< valueT1 << " "
|
||||
<< valueT2 << " "
|
||||
<< valueE11 << " "
|
||||
<< valueE12 << " "
|
||||
<< valueE21 << " "
|
||||
<< valueE22 << " "
|
||||
<< xs11 << " "
|
||||
<< xs12 << " "
|
||||
<< xs21 << " "
|
||||
<< xs22 << " "
|
||||
<< G4endl;
|
||||
|
||||
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
|
||||
|
||||
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
|
||||
|
||||
if (xsProduct != 0.)
|
||||
{
|
||||
sigma = QuadInterpolator( valueE11, valueE12,
|
||||
valueE21, valueE22,
|
||||
xs11, xs12,
|
||||
xs21, xs22,
|
||||
valueT1, valueT2,
|
||||
k, theta );
|
||||
}
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::LinLinInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double value = xs1 + (xs2 - xs1)*(e - e1)/ (e2 - e1);
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::LinLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double d1 = std::log(xs1);
|
||||
G4double d2 = std::log(xs2);
|
||||
G4double value = std::exp(d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::LogLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a*std::log10(e2);
|
||||
G4double sigma = a*std::log10(e) + b;
|
||||
G4double value = (std::pow(10.,sigma));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4AnalyticalEcpssrLiCrossSection::QuadInterpolator(G4double e11, G4double e12,
|
||||
G4double e21, G4double e22,
|
||||
G4double xs11, G4double xs12,
|
||||
G4double xs21, G4double xs22,
|
||||
G4double t1, G4double t2,
|
||||
G4double t, G4double e)
|
||||
{
|
||||
// Log-Log
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
/*
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
|
||||
/*
|
||||
// Lin-Lin
|
||||
G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicDeexcitation.cc,v 1.11
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
@@ -58,8 +58,8 @@ std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z
|
||||
{
|
||||
|
||||
std::vector<G4DynamicParticle*>* vectorOfParticles;
|
||||
|
||||
vectorOfParticles = new std::vector<G4DynamicParticle*>;
|
||||
|
||||
G4DynamicParticle* aParticle;
|
||||
G4int provShellId = 0;
|
||||
G4int counter = 0;
|
||||
@@ -112,7 +112,12 @@ std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z
|
||||
|
||||
// Look this in a particular way: only one auger emitted! // ????
|
||||
while (provShellId > -2);
|
||||
|
||||
|
||||
// debug
|
||||
// if (vectorOfParticles->size() > 0) {
|
||||
// G4cout << " DEEXCITATION!" << G4endl;
|
||||
// }
|
||||
|
||||
return vectorOfParticles;
|
||||
}
|
||||
|
||||
@@ -383,9 +388,7 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
// G4int augerOriginatingShellId = 0;
|
||||
|
||||
G4int numberOfPossibleAuger = 0;
|
||||
numberOfPossibleAuger = anAugerTransition->AugerTransitionProbabilities(transitionRandomShellId)->size();
|
||||
|
||||
|
||||
|
||||
G4bool foundFlag = false;
|
||||
|
||||
while (transitionRandomShellIndex < transitionSize) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransitionManager.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
|
||||
@@ -96,19 +96,37 @@ const std::vector<G4int>* G4AugerTransition::TransitionOriginatingShellIds() con
|
||||
const G4DataVector* G4AugerTransition::AugerTransitionEnergies(G4int startShellId) const
|
||||
{
|
||||
std::map<G4int,G4DataVector,std::less<G4int> >::const_iterator shellId = augerTransitionEnergiesMap.find(startShellId);
|
||||
|
||||
if (shellId == augerTransitionEnergiesMap.end() )
|
||||
{G4Exception("G4AugerTransition: corresponding map element not found");}
|
||||
|
||||
const G4DataVector* dataSet = &(*shellId).second;
|
||||
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
// Returns the emission probabilities of the auger electrons, given th shell
|
||||
// Returns the emission probabilities of the auger electrons, given the shell
|
||||
// from wich the transition electron cames from.
|
||||
|
||||
const G4DataVector* G4AugerTransition::AugerTransitionProbabilities(G4int startShellId) const
|
||||
{
|
||||
|
||||
//debugging
|
||||
//if (startShellId == 1){G4cout <<"OI!!!"<< G4endl;}
|
||||
|
||||
std::map<G4int,G4DataVector,std::less<G4int> >::const_iterator shellId = augerTransitionProbabilitiesMap.find(startShellId);
|
||||
|
||||
if (shellId == augerTransitionProbabilitiesMap.end() )
|
||||
{G4Exception("G4AugerTransition: corresponding map element not found");}
|
||||
|
||||
const G4DataVector* dataSet = &(*shellId).second;
|
||||
// debugging purpose:
|
||||
/* G4cout << "id: " << shellId->first << G4endl;
|
||||
G4cout << "size:" << dataSet->size() << G4endl;
|
||||
for (G4int i = 0; i < dataSet->size(); i++){
|
||||
G4cout << (dataSet[0])[i] << G4endl;
|
||||
}*/
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4BoldyshevTripletModel.cc,v 1.2 2010/11/12 16:48:13 flongo Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
//
|
||||
// Author: Gerardo Depaola & Francesco Longo
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 23-06-2010 First implementation as model
|
||||
|
||||
|
||||
#include "G4BoldyshevTripletModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BoldyshevTripletModel::G4BoldyshevTripletModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),smallEnergy(4.*MeV),isInitialised(false),
|
||||
crossSectionHandler(0),meanFreePathTable(0)
|
||||
{
|
||||
lowEnergyLimit = 4.0*electron_mass_c2;
|
||||
highEnergyLimit = 100 * GeV;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Triplet Gamma conversion is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / MeV << " MeV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BoldyshevTripletModel::~G4BoldyshevTripletModel()
|
||||
{
|
||||
if (crossSectionHandler) delete crossSectionHandler;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void
|
||||
G4BoldyshevTripletModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4BoldyshevTripletModel::Initialise()" << G4endl;
|
||||
|
||||
if (crossSectionHandler)
|
||||
{
|
||||
crossSectionHandler->Clear();
|
||||
delete crossSectionHandler;
|
||||
}
|
||||
|
||||
// Read data tables for all materials
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
crossSectionHandler->Initialise(0,lowEnergyLimit,100.*GeV,400);
|
||||
G4String crossSectionFile = "tripdata/pp-trip-cs-"; // here only pair in electron field cs should be used
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
//
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Loaded cross section files for Livermore GammaConversion" << G4endl;
|
||||
G4cout << "To obtain the total cross section this should be used only " << G4endl
|
||||
<< "in connection with G4NuclearGammaConversion " << G4endl;
|
||||
}
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Livermore Electron Gamma Conversion model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / MeV << " MeV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(isInitialised) return;
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4BoldyshevTripletModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
|
||||
G4double GammaEnergy,
|
||||
G4double Z, G4double,
|
||||
G4double, G4double)
|
||||
{
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling ComputeCrossSectionPerAtom() of G4BoldyshevTripletModel"
|
||||
<< G4endl;
|
||||
}
|
||||
if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit) return 0;
|
||||
|
||||
G4double cs = crossSectionHandler->FindValue(G4int(Z), GammaEnergy);
|
||||
return cs;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BoldyshevTripletModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* ,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
// The energies of the secondary particles are sampled using
|
||||
// a modified Wheeler-Lamb model (see PhysRevD 7 (1973), 26)
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4BoldyshevTripletModel" << G4endl;
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
G4double epsilon ;
|
||||
G4double p0 = electron_mass_c2;
|
||||
|
||||
G4double positronTotEnergy, electronTotEnergy, thetaEle, thetaPos;
|
||||
G4double ener_re=0., theta_re, phi_re, phi;
|
||||
|
||||
// Calculo de theta - elecron de recoil
|
||||
|
||||
G4double energyThreshold = sqrt(2.)*electron_mass_c2; // -> momentumThreshold_N = 1
|
||||
energyThreshold = 1.1*electron_mass_c2;
|
||||
// G4cout << energyThreshold << G4endl;
|
||||
|
||||
G4double momentumThreshold_c = sqrt(energyThreshold * energyThreshold - electron_mass_c2*electron_mass_c2); // momentun in MeV/c unit
|
||||
G4double momentumThreshold_N = momentumThreshold_c/electron_mass_c2; // momentun in mc unit
|
||||
|
||||
// Calculation of recoil electron production
|
||||
|
||||
G4double SigmaTot = (28./9.) * std::log ( 2.* photonEnergy / electron_mass_c2 ) - 218. / 27. ;
|
||||
G4double X_0 = 2. * ( sqrt(momentumThreshold_N*momentumThreshold_N + 1) -1 );
|
||||
G4double SigmaQ = (82./27. - (14./9.) * log (X_0) + 4./15.*X_0 - 0.0348 * X_0 * X_0);
|
||||
G4double recoilProb = G4UniformRand();
|
||||
//G4cout << "SIGMA TOT " << SigmaTot << " " << "SigmaQ " << SigmaQ << " " << SigmaQ/SigmaTot << " " << recoilProb << G4endl;
|
||||
|
||||
if (recoilProb >= SigmaQ/SigmaTot) // create electron recoil
|
||||
{
|
||||
|
||||
G4double cosThetaMax = ( ( energyThreshold - electron_mass_c2 ) / (momentumThreshold_c) + electron_mass_c2*
|
||||
( energyThreshold + electron_mass_c2 ) / (photonEnergy*momentumThreshold_c) );
|
||||
|
||||
if (cosThetaMax > 1) G4cout << "ERRORE " << G4endl;
|
||||
|
||||
G4double r1;
|
||||
G4double r2;
|
||||
G4double are, bre, loga, f1_re, greject, cost;
|
||||
|
||||
do {
|
||||
r1 = G4UniformRand();
|
||||
r2 = G4UniformRand();
|
||||
// cost = (pow(4./enern,0.5*r1)) ;
|
||||
cost = pow(cosThetaMax,r1);
|
||||
theta_re = acos(cost);
|
||||
are = 1./(14.*cost*cost);
|
||||
bre = (1.-5.*cost*cost)/(2.*cost);
|
||||
loga = log((1.+ cost)/(1.- cost));
|
||||
f1_re = 1. - bre*loga;
|
||||
|
||||
if ( theta_re >= 4.47*CLHEP::pi/180.)
|
||||
{
|
||||
greject = are*f1_re;
|
||||
} else {
|
||||
greject = 1. ;
|
||||
}
|
||||
} while(greject < r2);
|
||||
|
||||
// Calculo de phi - elecron de recoil
|
||||
|
||||
G4double r3, r4, rt;
|
||||
|
||||
do {
|
||||
|
||||
r3 = G4UniformRand();
|
||||
r4 = G4UniformRand();
|
||||
phi_re = twopi*r3 ;
|
||||
G4double sint2 = 1. - cost*cost ;
|
||||
G4double fp = 1. - sint2*loga/(2.*cost) ;
|
||||
rt = (1.-cos(2.*phi_re)*fp/f1_re)/(2.*pi) ;
|
||||
|
||||
} while(rt < r4);
|
||||
|
||||
// Calculo de la energia - elecron de recoil - relacion momento maximo <-> angulo
|
||||
|
||||
G4double S = electron_mass_c2*(2.* photonEnergy + electron_mass_c2);
|
||||
G4double D2 = 4.*S * electron_mass_c2*electron_mass_c2
|
||||
+ (S - electron_mass_c2*electron_mass_c2)
|
||||
*(S - electron_mass_c2*electron_mass_c2)*sin(theta_re)*sin(theta_re);
|
||||
ener_re = electron_mass_c2 * (S + electron_mass_c2*electron_mass_c2)/sqrt(D2);
|
||||
|
||||
// G4cout << "electron de retroceso " << ener_re << " " << theta_re << " " << phi_re << G4endl;
|
||||
|
||||
// Recoil electron creation
|
||||
G4double dxEle_re=sin(theta_re)*std::cos(phi_re),dyEle_re=sin(theta_re)*std::sin(phi_re), dzEle_re=cos(theta_re);
|
||||
|
||||
G4double electronRKineEnergy = std::max(0.,ener_re - electron_mass_c2) ;
|
||||
|
||||
G4ThreeVector electronRDirection (dxEle_re, dyEle_re, dzEle_re);
|
||||
electronRDirection.rotateUz(photonDirection);
|
||||
|
||||
G4DynamicParticle* particle3 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronRDirection,
|
||||
electronRKineEnergy);
|
||||
fvect->push_back(particle3);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// deposito la energia ener_re - electron_mass_c2
|
||||
// G4cout << "electron de retroceso " << ener_re << G4endl;
|
||||
fParticleChange->ProposeLocalEnergyDeposit(ener_re - electron_mass_c2);
|
||||
}
|
||||
|
||||
// Depaola (2004) suggested distribution for e+e- energy
|
||||
|
||||
// G4double t = 0.5*asinh(momentumThreshold_N);
|
||||
G4double t = 0.5*log(momentumThreshold_N + sqrt(momentumThreshold_N*momentumThreshold_N+1));
|
||||
|
||||
G4double J1 = 0.5*(t*cosh(t)/sinh(t) - log(2.*sinh(t)));
|
||||
G4double J2 = (-2./3.)*log(2.*sinh(t)) + t*cosh(t)/sinh(t) + (sinh(t)-t*pow(cosh(t),3))/(3.*pow(sinh(t),2));
|
||||
G4double b = 2.*(J2-J1)/J1;
|
||||
|
||||
G4double n = 1 - b/6.;
|
||||
G4double re=0.;
|
||||
re = G4UniformRand();
|
||||
G4double a = 0.;
|
||||
G4double b1 = 16. - 3.*b - 36.*b*re*n + 36.*b*pow(re,2.)*pow(n,2.) +
|
||||
6.*pow(b,2.)*re*n;
|
||||
a = pow((b1/b),0.5);
|
||||
G4double c1 = (-6. + 12.*re*n + b + 2*a)*pow(b,2.);
|
||||
epsilon = (pow(c1,1./3.))/(2.*b) + (b-4.)/(2.*pow(c1,1./3.))+0.5;
|
||||
|
||||
G4double photonEnergy1 = photonEnergy - ener_re ; // resto al foton la energia del electron de retro.
|
||||
positronTotEnergy = epsilon*photonEnergy1;
|
||||
electronTotEnergy = photonEnergy1 - positronTotEnergy; // temporarly
|
||||
|
||||
G4double momento_e = sqrt(electronTotEnergy*electronTotEnergy -
|
||||
electron_mass_c2*electron_mass_c2) ;
|
||||
G4double momento_p = sqrt(positronTotEnergy*positronTotEnergy -
|
||||
electron_mass_c2*electron_mass_c2) ;
|
||||
|
||||
thetaEle = acos((sqrt(p0*p0/(momento_e*momento_e) +1.)- p0/momento_e)) ;
|
||||
thetaPos = acos((sqrt(p0*p0/(momento_p*momento_p) +1.)- p0/momento_p)) ;
|
||||
phi = twopi * G4UniformRand();
|
||||
|
||||
G4double dxEle= std::sin(thetaEle)*std::cos(phi),dyEle= std::sin(thetaEle)*std::sin(phi),dzEle=std::cos(thetaEle);
|
||||
G4double dxPos=-std::sin(thetaPos)*std::cos(phi),dyPos=-std::sin(thetaPos)*std::sin(phi),dzPos=std::cos(thetaPos);
|
||||
|
||||
|
||||
// Kinematics of the created pair:
|
||||
// the electron and positron are assumed to have a symetric angular
|
||||
// distribution with respect to the Z axis along the parent photon
|
||||
|
||||
G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
|
||||
|
||||
G4ThreeVector electronDirection (dxEle, dyEle, dzEle);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
|
||||
// The e+ is always created (even with kinetic energy = 0) for further annihilation
|
||||
G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
|
||||
|
||||
G4ThreeVector positronDirection (dxPos, dyPos, dzPos);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
// Fill output vector
|
||||
|
||||
|
||||
fvect->push_back(particle1);
|
||||
fvect->push_back(particle2);
|
||||
|
||||
|
||||
|
||||
|
||||
// kill incident photon
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4CompositeEMDataSet.cc,v 1.15 2009/09/25 07:41:34 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4CompositeEMDataSet.cc,v 1.16 2010/11/26 11:51:11 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
@@ -195,6 +195,7 @@ G4bool G4CompositeEMDataSet::SaveData(const G4String& argFileName) const
|
||||
std::ostringstream message;
|
||||
message << "G4CompositeEMDataSet::SaveData - component " << (z-minZ) << " not found";
|
||||
G4Exception(message.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!component->SaveData(argFileName))
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4DNAAttachment.cc,v 1.1 2010/09/08 13:46:45 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "G4DNAAttachment.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4DNAAttachment::G4DNAAttachment(const G4String& processName,
|
||||
G4ProcessType type):G4VEmProcess (processName, type),
|
||||
isInitialised(false)
|
||||
{
|
||||
SetProcessSubType(51);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4DNAAttachment::~G4DNAAttachment()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4DNAAttachment::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
return (&p == G4Electron::Electron());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAAttachment::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!isInitialised)
|
||||
{
|
||||
isInitialised = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
|
||||
if(name == "e-")
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNAMeltonAttachmentModel);
|
||||
Model()->SetLowEnergyLimit(4.*eV);
|
||||
Model()->SetHighEnergyLimit(13.*eV);
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4DNAAttachment::PrintInfo()
|
||||
{
|
||||
G4cout
|
||||
<< " Total cross sections computed from "
|
||||
<< Model()->GetName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNABornExcitationModel.cc,v 1.7 2009/08/31 14:03:29 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNABornExcitationModel.cc,v 1.10 2010/08/24 13:51:06 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
#include "G4DNABornExcitationModel.hh"
|
||||
@@ -39,12 +39,6 @@ G4DNABornExcitationModel::G4DNABornExcitationModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
{
|
||||
|
||||
lowEnergyLimit = 500 * keV;
|
||||
highEnergyLimit = 100 * MeV;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
@@ -53,19 +47,9 @@ G4DNABornExcitationModel::G4DNABornExcitationModel(const G4ParticleDefinition*,
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
//
|
||||
|
||||
table = 0;
|
||||
|
||||
//
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "Born excitation model is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / MeV << " MeV"
|
||||
<< G4endl;
|
||||
G4cout << "Born excitation model is constructed " << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,50 +59,103 @@ G4DNABornExcitationModel::G4DNABornExcitationModel(const G4ParticleDefinition*,
|
||||
G4DNABornExcitationModel::~G4DNABornExcitationModel()
|
||||
{
|
||||
// Cross section
|
||||
delete table;
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
for (pos = tableData.begin(); pos != tableData.end(); ++pos)
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
delete table;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNABornExcitationModel::Initialise(const G4ParticleDefinition* /*particle*/,
|
||||
void G4DNABornExcitationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNABornExcitationModel::Initialise()" << G4endl;
|
||||
|
||||
// Energy limits
|
||||
G4String fileElectron("dna/sigma_excitation_e_born");
|
||||
G4String fileProton("dna/sigma_excitation_p_born");
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
|
||||
|
||||
G4String electron;
|
||||
G4String proton;
|
||||
|
||||
if (LowEnergyLimit() < lowEnergyLimit)
|
||||
G4double scaleFactor = (1.e-22 / 3.343) * m*m;
|
||||
|
||||
if (electronDef != 0)
|
||||
{
|
||||
G4cout << "G4DNABornExcitationModel: low energy limit increased from " <<
|
||||
LowEnergyLimit()/keV << " keV to " << lowEnergyLimit/keV << " keV" << G4endl;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
electron = electronDef->GetParticleName();
|
||||
|
||||
tableFile[electron] = fileElectron;
|
||||
|
||||
lowEnergyLimit[electron] = 9. * eV;
|
||||
highEnergyLimit[electron] = 1. * MeV;
|
||||
|
||||
// Cross section
|
||||
|
||||
G4DNACrossSectionDataSet* tableE = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
|
||||
tableE->LoadData(fileElectron);
|
||||
|
||||
tableData[electron] = tableE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNABornExcitationModel::Initialise(): electron is not defined");
|
||||
}
|
||||
|
||||
if (HighEnergyLimit() > highEnergyLimit)
|
||||
if (protonDef != 0)
|
||||
{
|
||||
G4cout << "G4DNABornExcitationModel: high energy limit decreased from " <<
|
||||
HighEnergyLimit()/MeV << " MeV to " << highEnergyLimit/MeV << " MeV" << G4endl;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
proton = protonDef->GetParticleName();
|
||||
|
||||
tableFile[proton] = fileProton;
|
||||
|
||||
lowEnergyLimit[proton] = 500. * keV;
|
||||
highEnergyLimit[proton] = 100. * MeV;
|
||||
|
||||
// Cross section
|
||||
|
||||
G4DNACrossSectionDataSet* tableP = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
|
||||
tableP->LoadData(fileProton);
|
||||
|
||||
tableData[proton] = tableP;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNABornExcitationModel::Initialise(): proton is not defined");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if (table == 0)
|
||||
if (particle==electronDef)
|
||||
{
|
||||
table = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV,(1e-22/3.343)*m*m );
|
||||
table->LoadData("dna/sigma_excitation_p_born");
|
||||
SetLowEnergyLimit(lowEnergyLimit[electron]);
|
||||
SetHighEnergyLimit(highEnergyLimit[electron]);
|
||||
}
|
||||
|
||||
if (particle==protonDef)
|
||||
{
|
||||
SetLowEnergyLimit(lowEnergyLimit[proton]);
|
||||
SetHighEnergyLimit(highEnergyLimit[proton]);
|
||||
}
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "Born excitation model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / keV << " keV - "
|
||||
<< HighEnergyLimit() / MeV << " MeV " << G4endl;
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
if(!isInitialised)
|
||||
{
|
||||
isInitialised = true;
|
||||
@@ -130,77 +167,82 @@ void G4DNABornExcitationModel::Initialise(const G4ParticleDefinition* /*particle
|
||||
}
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNABornExcitationModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNABornExcitationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double k,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNABornExcitationModel" << G4endl;
|
||||
|
||||
if (
|
||||
particleDefinition != G4Proton::ProtonDefinition()
|
||||
&&
|
||||
particleDefinition != G4Electron::ElectronDefinition()
|
||||
)
|
||||
|
||||
return 0;
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4double crossSection=0;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
G4double lowLim = 0;
|
||||
G4double highLim = 0;
|
||||
G4double sigma=0;
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
if (particleDefinition == G4Proton::ProtonDefinition())
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
|
||||
pos1 = lowEnergyLimit.find(particleName);
|
||||
if (pos1 != lowEnergyLimit.end())
|
||||
{
|
||||
if (k >= lowEnergyLimit && k < highEnergyLimit)
|
||||
{
|
||||
crossSection = table->FindValue(k);
|
||||
}
|
||||
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Kinetic energy(keV)=" << k/keV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << crossSection/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << crossSection*densityWater/(1./cm) << G4endl;
|
||||
}
|
||||
lowLim = pos1->second;
|
||||
}
|
||||
|
||||
std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
|
||||
pos2 = highEnergyLimit.find(particleName);
|
||||
if (pos2 != highEnergyLimit.end())
|
||||
{
|
||||
highLim = pos2->second;
|
||||
}
|
||||
} // if (flagMaterialIsWater)
|
||||
|
||||
return crossSection*densityWater;
|
||||
if (ekin >= lowLim && ekin < highLim)
|
||||
{
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = tableData.find(particleName);
|
||||
|
||||
if (pos != tableData.end())
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != 0)
|
||||
{
|
||||
sigma = table->FindValue(ekin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNABornExcitationModel::CrossSectionPerVolume: attempting to calculate cross section for wrong particle");
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (waterMaterial)
|
||||
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -218,7 +260,9 @@ void G4DNABornExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
|
||||
G4double k = aDynamicParticle->GetKineticEnergy();
|
||||
|
||||
G4int level = RandomSelect(k);
|
||||
const G4String& particleName = aDynamicParticle->GetDefinition()->GetParticleName();
|
||||
|
||||
G4int level = RandomSelect(k,particleName);
|
||||
G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
@@ -233,41 +277,55 @@ void G4DNABornExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int G4DNABornExcitationModel::RandomSelect(G4double k)
|
||||
G4int G4DNABornExcitationModel::RandomSelect(G4double k, const G4String& particle)
|
||||
{
|
||||
G4int level = 0;
|
||||
|
||||
G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = tableData.find(particle);
|
||||
|
||||
const size_t n(table->NumberOfComponents());
|
||||
size_t i(n);
|
||||
G4double value = 0.;
|
||||
|
||||
while (i>0)
|
||||
{
|
||||
i--;
|
||||
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
i = n;
|
||||
|
||||
while (i > 0)
|
||||
if (pos != tableData.end())
|
||||
{
|
||||
i--;
|
||||
|
||||
if (valuesBuffer[i] > value)
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
|
||||
if (table != 0)
|
||||
{
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
|
||||
const size_t n(table->NumberOfComponents());
|
||||
size_t i(n);
|
||||
G4double value = 0.;
|
||||
|
||||
while (i>0)
|
||||
{
|
||||
i--;
|
||||
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
i = n;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
if (valuesBuffer[i] > value)
|
||||
{
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
|
||||
if (valuesBuffer) delete[] valuesBuffer;
|
||||
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
|
||||
if (valuesBuffer) delete[] valuesBuffer;
|
||||
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNABornExcitationModel::RandomSelect attempting to calculate cross section for wrong particle");
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNABornIonisationModel.cc,v 1.14 2009/11/12 03:08:58 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNABornIonisationModel.cc,v 1.18 2010/11/03 12:22:36 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
#include "G4DNABornIonisationModel.hh"
|
||||
@@ -238,45 +238,11 @@ void G4DNABornIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNABornIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNABornIonisationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
@@ -299,7 +265,7 @@ G4double G4DNABornIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double highLim = 0;
|
||||
G4double sigma=0;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
@@ -340,12 +306,12 @@ G4double G4DNABornIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (waterMaterial)
|
||||
|
||||
return sigma*densityWater;
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
}
|
||||
|
||||
@@ -409,49 +375,32 @@ void G4DNABornIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
G4ThreeVector deltaDirection(dirX,dirY,dirZ);
|
||||
deltaDirection.rotateUz(primaryDirection);
|
||||
|
||||
G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
|
||||
if (particle->GetDefinition() == G4Electron::ElectronDefinition())
|
||||
{
|
||||
G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
|
||||
|
||||
G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
|
||||
G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
|
||||
G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
|
||||
G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
|
||||
finalPx /= finalMomentum;
|
||||
finalPy /= finalMomentum;
|
||||
finalPz /= finalMomentum;
|
||||
G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
|
||||
G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
|
||||
G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
|
||||
G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
|
||||
finalPx /= finalMomentum;
|
||||
finalPy /= finalMomentum;
|
||||
finalPz /= finalMomentum;
|
||||
|
||||
G4ThreeVector direction;
|
||||
direction.set(finalPx,finalPy,finalPz);
|
||||
G4ThreeVector direction;
|
||||
direction.set(finalPx,finalPy,finalPz);
|
||||
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
|
||||
}
|
||||
|
||||
else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection) ;
|
||||
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(k-bindingEnergy-secondaryKinetic);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy);
|
||||
|
||||
G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic) ;
|
||||
fvect->push_back(dp);
|
||||
/*
|
||||
// creating neutral water molechule...
|
||||
|
||||
G4DNAGenericMoleculeManager *instance;
|
||||
instance = G4DNAGenericMoleculeManager::Instance();
|
||||
G4ParticleDefinition* waterDef = NULL;
|
||||
G4Molecule* water = instance->GetMolecule("H2O");
|
||||
waterDef = (G4ParticleDefinition*)water;
|
||||
|
||||
direction.set(0.,0.,0.);
|
||||
|
||||
//G4DynamicParticle* dynamicWater = new G4DynamicParticle(waterDef, direction, bindingEnergy);
|
||||
G4DynamicMolecule* dynamicWater = new G4DynamicMolecule(water, direction, bindingEnergy);
|
||||
|
||||
|
||||
//dynamicWater->RemoveElectron(ionizationShell, 1);
|
||||
|
||||
G4DynamicMolecule* dynamicWater2 = new G4DynamicMolecule(water, direction, bindingEnergy);
|
||||
G4DynamicMolecule* dynamicWater3 = new G4DynamicMolecule(water, direction, bindingEnergy);
|
||||
|
||||
fvect->push_back(dynamicWater);
|
||||
fvect->push_back(dynamicWater2);
|
||||
fvect->push_back(dynamicWater3);
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -511,7 +460,7 @@ G4double k, G4int shell)
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition())
|
||||
{
|
||||
G4double maximumKineticEnergyTransfer = 4.* (electron_mass_c2 / proton_mass_c2) * k - (waterStructure.IonisationEnergy(shell));
|
||||
G4double maximumKineticEnergyTransfer = 4.* (electron_mass_c2 / proton_mass_c2) * k;
|
||||
|
||||
G4double crossSectionMaximum = 0.;
|
||||
for (G4double value = waterStructure.IonisationEnergy(shell);
|
||||
@@ -563,7 +512,14 @@ void G4DNABornIonisationModel::RandomizeEjectedElectronDirection(G4ParticleDefin
|
||||
{
|
||||
G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
|
||||
phi = twopi * G4UniformRand();
|
||||
cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
|
||||
// cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
|
||||
// Restriction below 100 eV from Emfietzoglou (2000)
|
||||
|
||||
if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
else cosTheta = (2.*G4UniformRand())-1.;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAChampionElasticModel.cc,v 1.10 2009/11/03 15:04:25 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAChampionElasticModel.cc,v 1.16 2010/11/11 22:32:22 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
#include "G4DNAChampionElasticModel.hh"
|
||||
@@ -40,10 +40,9 @@ G4DNAChampionElasticModel::G4DNAChampionElasticModel(const G4ParticleDefinition*
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
{
|
||||
|
||||
killBelowEnergy = 8.23*eV; // Minimum e- energy for energy loss by excitation
|
||||
killBelowEnergy = 4*eV;
|
||||
lowEnergyLimit = 0 * eV;
|
||||
lowEnergyLimitOfModel = 7.4 * eV; // The model lower energy is 7.4 eV
|
||||
highEnergyLimit = 10 * MeV;
|
||||
highEnergyLimit = 1. * MeV;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
@@ -63,6 +62,7 @@ G4DNAChampionElasticModel::G4DNAChampionElasticModel(const G4ParticleDefinition*
|
||||
<< highEnergyLimit / MeV << " MeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -131,14 +131,14 @@ void G4DNAChampionElasticModel::Initialise(const G4ParticleDefinition* /*particl
|
||||
tableData[electron] = tableE;
|
||||
|
||||
// For final state
|
||||
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
G4Exception("G4FinalStateElasticChampion::Initialise: G4LEDATA environment variable not set");
|
||||
|
||||
std::ostringstream eFullFileName;
|
||||
eFullFileName << path << "/dna/sigmadiff_elastic_e_champion.dat";
|
||||
eFullFileName << path << "/dna/sigmadiff_cumulatedshort_elastic_e_champion.dat";
|
||||
std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
|
||||
|
||||
if (!eDiffCrossSection) G4Exception("G4DNAChampionElasticModel::Initialise: error opening electron DATA FILE");
|
||||
@@ -150,8 +150,9 @@ void G4DNAChampionElasticModel::Initialise(const G4ParticleDefinition* /*particl
|
||||
double tDummy;
|
||||
double eDummy;
|
||||
eDiffCrossSection>>tDummy>>eDummy;
|
||||
|
||||
|
||||
// SI : mandatory eVecm initialization
|
||||
|
||||
if (tDummy != eTdummyVec.back())
|
||||
{
|
||||
eTdummyVec.push_back(tDummy);
|
||||
@@ -160,11 +161,8 @@ void G4DNAChampionElasticModel::Initialise(const G4ParticleDefinition* /*particl
|
||||
|
||||
eDiffCrossSection>>eDiffCrossSectionData[tDummy][eDummy];
|
||||
|
||||
// SI : only if not end of file reached !
|
||||
if (!eDiffCrossSection.eof()) eDiffCrossSectionData[tDummy][eDummy]*=scaleFactor;
|
||||
|
||||
if (eDummy != eVecm[tDummy].back()) eVecm[tDummy].push_back(eDummy);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// End final state
|
||||
@@ -196,45 +194,11 @@ void G4DNAChampionElasticModel::Initialise(const G4ParticleDefinition* /*particl
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAChampionElasticModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNAChampionElasticModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
@@ -247,14 +211,14 @@ G4double G4DNAChampionElasticModel::CrossSectionPerVolume(const G4Material*,
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = p->GetParticleName();
|
||||
|
||||
if (ekin < highEnergyLimit)
|
||||
{
|
||||
//SI : XS must not be zero otherwise sampling of secondaries method ignored
|
||||
if (ekin < lowEnergyLimitOfModel) ekin = lowEnergyLimitOfModel;
|
||||
if (ekin < killBelowEnergy) return DBL_MAX;
|
||||
//
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
@@ -278,12 +242,12 @@ G4double G4DNAChampionElasticModel::CrossSectionPerVolume(const G4Material*,
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (flagMaterialIsWater)
|
||||
}
|
||||
|
||||
return sigma*densityWater;
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -309,6 +273,7 @@ void G4DNAChampionElasticModel::SampleSecondaries(std::vector<G4DynamicParticle*
|
||||
|
||||
if (electronEnergy0>= killBelowEnergy && electronEnergy0 < highEnergyLimit)
|
||||
{
|
||||
|
||||
G4double cosTheta = RandomizeCosTheta(electronEnergy0);
|
||||
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
@@ -333,11 +298,10 @@ void G4DNAChampionElasticModel::SampleSecondaries(std::vector<G4DynamicParticle*
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAChampionElasticModel::DifferentialCrossSection
|
||||
(G4ParticleDefinition * particleDefinition, G4double k, G4double theta)
|
||||
G4double G4DNAChampionElasticModel::Theta
|
||||
(G4ParticleDefinition * particleDefinition, G4double k, G4double integrDiff)
|
||||
{
|
||||
|
||||
G4double sigma = 0.;
|
||||
G4double theta = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
@@ -349,18 +313,15 @@ G4double G4DNAChampionElasticModel::DifferentialCrossSection
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
|
||||
//SI : ensure the correct computation of cross section at the 180*deg limit
|
||||
if (theta==180.) theta=theta-1e-9;
|
||||
|
||||
if (particleDefinition == G4Electron::ElectronDefinition())
|
||||
{
|
||||
std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(), integrDiff);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(), integrDiff);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
@@ -374,24 +335,18 @@ G4double G4DNAChampionElasticModel::DifferentialCrossSection
|
||||
xs12 = eDiffCrossSectionData[valueT1][valueE12];
|
||||
xs21 = eDiffCrossSectionData[valueT2][valueE21];
|
||||
xs22 = eDiffCrossSectionData[valueT2][valueE22];
|
||||
|
||||
}
|
||||
|
||||
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
|
||||
}
|
||||
|
||||
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
|
||||
|
||||
if (xsProduct != 0.)
|
||||
{
|
||||
sigma = QuadInterpolator( valueE11, valueE12,
|
||||
if (xs11==0 && xs12==0 && xs21==0 && xs22==0) return (0.);
|
||||
|
||||
theta = QuadInterpolator ( valueE11, valueE12,
|
||||
valueE21, valueE22,
|
||||
xs11, xs12,
|
||||
xs21, xs22,
|
||||
valueT1, valueT2,
|
||||
k, theta );
|
||||
}
|
||||
|
||||
return sigma;
|
||||
k, integrDiff );
|
||||
|
||||
return theta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -410,6 +365,20 @@ G4double G4DNAChampionElasticModel::LinLogInterpolate(G4double e1,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAChampionElasticModel::LinLinInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double d1 = xs1;
|
||||
G4double d2 = xs2;
|
||||
G4double value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAChampionElasticModel::LogLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
@@ -425,6 +394,7 @@ G4double G4DNAChampionElasticModel::LogLogInterpolate(G4double e1,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4DNAChampionElasticModel::QuadInterpolator(G4double e11, G4double e12,
|
||||
G4double e21, G4double e22,
|
||||
G4double xs11, G4double xs12,
|
||||
@@ -432,17 +402,24 @@ G4double G4DNAChampionElasticModel::QuadInterpolator(G4double e11, G4double e12,
|
||||
G4double t1, G4double t2,
|
||||
G4double t, G4double e)
|
||||
{
|
||||
// Log-Log
|
||||
// Log-Log
|
||||
/*
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
|
||||
// Lin-Log
|
||||
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
|
||||
// Lin-Lin
|
||||
G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -450,36 +427,16 @@ G4double G4DNAChampionElasticModel::QuadInterpolator(G4double e11, G4double e12,
|
||||
|
||||
G4double G4DNAChampionElasticModel::RandomizeCosTheta(G4double k)
|
||||
{
|
||||
// ***** Similar method as for screened Rutherford scattering
|
||||
|
||||
G4int iMax=180;
|
||||
G4double max=0;
|
||||
G4double tmp=0;
|
||||
|
||||
// Look for maximum :
|
||||
for (G4int i=0; i<iMax; i++)
|
||||
{
|
||||
tmp = DifferentialCrossSection(G4Electron::ElectronDefinition(),k/eV,G4double(i)*180./(iMax-1));
|
||||
if (tmp>max) max = tmp;
|
||||
}
|
||||
G4double integrdiff=0;
|
||||
G4double uniformRand=G4UniformRand();
|
||||
integrdiff = uniformRand;
|
||||
|
||||
G4double theta=0.;
|
||||
G4double cosTheta=0.;
|
||||
theta = Theta(G4Electron::ElectronDefinition(),k/eV,integrdiff);
|
||||
|
||||
G4double oneOverMax=0;
|
||||
if (max!=0) oneOverMax = 1./max;
|
||||
|
||||
G4double cosTheta = 0.;
|
||||
G4double fCosTheta = 0.;
|
||||
|
||||
do
|
||||
{
|
||||
cosTheta = 2. * G4UniformRand() - 1.;
|
||||
fCosTheta = oneOverMax * DifferentialCrossSection(G4Electron::ElectronDefinition(),k/eV,std::acos(cosTheta)*180./pi);
|
||||
}
|
||||
while (fCosTheta < G4UniformRand());
|
||||
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Cos(theta)=" << cosTheta << G4endl;
|
||||
}
|
||||
cosTheta= std::cos(theta*pi/180);
|
||||
|
||||
return cosTheta;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAChargeDecrease.cc,v 1.3 2009/03/04 13:28:49 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAChargeDecrease.cc,v 1.4 2010/03/18 16:36:48 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
|
||||
#include "G4DNAChargeDecrease.hh"
|
||||
|
||||
@@ -71,7 +71,16 @@ void G4DNAChargeDecrease::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
|
||||
if( name == "proton" || name == "alpha" || name == "alpha+" )
|
||||
if( name == "proton" )
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNADingfelderChargeDecreaseModel);
|
||||
Model()->SetLowEnergyLimit(100*eV);
|
||||
Model()->SetHighEnergyLimit(10*MeV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
|
||||
if( name == "alpha" || name == "alpha+" )
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNADingfelderChargeDecreaseModel);
|
||||
Model()->SetLowEnergyLimit(1*keV);
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAChargeIncrease.cc,v 1.3 2009/03/04 13:28:49 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAChargeIncrease.cc,v 1.4 2010/03/18 16:36:48 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
|
||||
#include "G4DNAChargeIncrease.hh"
|
||||
|
||||
@@ -71,7 +71,16 @@ void G4DNAChargeIncrease::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
|
||||
if( name == "hydrogen" || name =="alpha+" || name =="helium" )
|
||||
if( name == "hydrogen" )
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNADingfelderChargeIncreaseModel);
|
||||
Model()->SetLowEnergyLimit(100*eV);
|
||||
Model()->SetHighEnergyLimit(10*MeV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
|
||||
if( name =="alpha+" || name =="helium" )
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNADingfelderChargeIncreaseModel);
|
||||
Model()->SetLowEnergyLimit(1*keV);
|
||||
@@ -79,6 +88,7 @@ void G4DNAChargeIncrease::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+11
-43
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNADingfelderChargeDecreaseModel.cc,v 1.6 2009/08/13 11:32:47 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNADingfelderChargeDecreaseModel.cc,v 1.9 2010/04/06 11:00:35 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
//
|
||||
|
||||
#include "G4DNADingfelderChargeDecreaseModel.hh"
|
||||
@@ -83,7 +83,7 @@ void G4DNADingfelderChargeDecreaseModel::Initialise(const G4ParticleDefinition*
|
||||
if (protonDef != 0)
|
||||
{
|
||||
proton = protonDef->GetParticleName();
|
||||
lowEnergyLimit[proton] = 1. * keV;
|
||||
lowEnergyLimit[proton] = 100. * eV;
|
||||
highEnergyLimit[proton] = 10. * MeV;
|
||||
}
|
||||
else
|
||||
@@ -208,45 +208,11 @@ void G4DNADingfelderChargeDecreaseModel::Initialise(const G4ParticleDefinition*
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNADingfelderChargeDecreaseModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNADingfelderChargeDecreaseModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double k,
|
||||
G4double,
|
||||
@@ -274,7 +240,7 @@ G4double G4DNADingfelderChargeDecreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
G4double highLim = 0;
|
||||
G4double crossSection = 0.;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
@@ -303,12 +269,12 @@ G4double G4DNADingfelderChargeDecreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << k/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << crossSection/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << crossSection*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << crossSection*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (flagMaterialIsWater)
|
||||
}
|
||||
|
||||
return crossSection*densityWater;
|
||||
return crossSection*material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
}
|
||||
|
||||
@@ -326,6 +292,8 @@ void G4DNADingfelderChargeDecreaseModel::SampleSecondaries(std::vector<G4Dynamic
|
||||
G4double inK = aDynamicParticle->GetKineticEnergy();
|
||||
|
||||
G4ParticleDefinition* definition = aDynamicParticle->GetDefinition();
|
||||
|
||||
G4double particleMass = definition->GetPDGMass();
|
||||
|
||||
G4int finalStateIndex = RandomSelect(inK,definition);
|
||||
|
||||
@@ -337,7 +305,7 @@ void G4DNADingfelderChargeDecreaseModel::SampleSecondaries(std::vector<G4Dynamic
|
||||
if (definition==G4Proton::Proton())
|
||||
outK = inK - n*(inK*electron_mass_c2/proton_mass_c2) - waterBindingEnergy + outgoingParticleBindingEnergy;
|
||||
else
|
||||
outK = inK - n*(inK*electron_mass_c2/(3728*MeV)) - waterBindingEnergy + outgoingParticleBindingEnergy;
|
||||
outK = inK - n*(inK*electron_mass_c2/particleMass) - waterBindingEnergy + outgoingParticleBindingEnergy;
|
||||
|
||||
if (outK<0)
|
||||
{
|
||||
|
||||
+12
-44
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNADingfelderChargeIncreaseModel.cc,v 1.6 2009/08/13 11:32:47 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNADingfelderChargeIncreaseModel.cc,v 1.9 2010/04/06 11:00:35 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
//
|
||||
|
||||
#include "G4DNADingfelderChargeIncreaseModel.hh"
|
||||
@@ -84,7 +84,7 @@ void G4DNADingfelderChargeIncreaseModel::Initialise(const G4ParticleDefinition*
|
||||
if (hydrogenDef != 0)
|
||||
{
|
||||
hydrogen = hydrogenDef->GetParticleName();
|
||||
lowEnergyLimit[hydrogen] = 1. * keV;
|
||||
lowEnergyLimit[hydrogen] = 100. * eV;
|
||||
highEnergyLimit[hydrogen] = 10. * MeV;
|
||||
}
|
||||
else
|
||||
@@ -199,45 +199,11 @@ void G4DNADingfelderChargeIncreaseModel::Initialise(const G4ParticleDefinition*
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double k,
|
||||
G4double,
|
||||
@@ -265,7 +231,7 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
G4double highLim = 0;
|
||||
G4double totalCrossSection = 0.;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
@@ -314,12 +280,12 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << k/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << totalCrossSection/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << totalCrossSection*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << totalCrossSection*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (flagMaterialIsWater)
|
||||
}
|
||||
|
||||
return totalCrossSection*densityWater;
|
||||
return totalCrossSection*material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
}
|
||||
|
||||
@@ -338,7 +304,9 @@ void G4DNADingfelderChargeIncreaseModel::SampleSecondaries(std::vector<G4Dynamic
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(0.);
|
||||
|
||||
G4ParticleDefinition* definition = aDynamicParticle->GetDefinition();
|
||||
|
||||
|
||||
G4double particleMass = definition->GetPDGMass();
|
||||
|
||||
G4double inK = aDynamicParticle->GetKineticEnergy();
|
||||
|
||||
G4int finalStateIndex = RandomSelect(inK,definition);
|
||||
@@ -352,7 +320,7 @@ void G4DNADingfelderChargeIncreaseModel::SampleSecondaries(std::vector<G4Dynamic
|
||||
|
||||
G4double electronK;
|
||||
if (definition == instance->GetIon("hydrogen")) electronK = inK*electron_mass_c2/proton_mass_c2;
|
||||
else electronK = inK*electron_mass_c2/(3728*MeV);
|
||||
else electronK = inK*electron_mass_c2/(particleMass);
|
||||
|
||||
if (outK<0)
|
||||
{
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAElastic.cc,v 1.3 2009/03/04 13:28:49 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAElastic.cc,v 1.4 2010/09/08 14:07:16 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "G4DNAElastic.hh"
|
||||
|
||||
@@ -61,7 +61,7 @@ void G4DNAElastic::InitialiseProcess(const G4ParticleDefinition*)
|
||||
SetBuildTableFlag(false);
|
||||
if(!Model()) SetModel(new G4DNAScreenedRutherfordElasticModel);
|
||||
Model()->SetLowEnergyLimit(0*eV);
|
||||
Model()->SetHighEnergyLimit(10*MeV);
|
||||
Model()->SetHighEnergyLimit(1.*MeV);
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
}
|
||||
|
||||
+11
-46
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAEmfietzoglouExcitationModel.cc,v 1.8 2009/08/13 11:32:47 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAEmfietzoglouExcitationModel.cc,v 1.10 2010/06/08 21:50:00 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
//
|
||||
|
||||
#include "G4DNAEmfietzoglouExcitationModel.hh"
|
||||
@@ -45,6 +45,8 @@ G4DNAEmfietzoglouExcitationModel::G4DNAEmfietzoglouExcitationModel(const G4Parti
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
nLevels = waterExcitation.NumberOfLevels();
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
@@ -95,10 +97,6 @@ void G4DNAEmfietzoglouExcitationModel::Initialise(const G4ParticleDefinition* /*
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
nLevels = waterExcitation.NumberOfLevels();
|
||||
|
||||
//
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
@@ -121,45 +119,11 @@ void G4DNAEmfietzoglouExcitationModel::Initialise(const G4ParticleDefinition* /*
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAEmfietzoglouExcitationModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNAEmfietzoglouExcitationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
@@ -172,7 +136,7 @@ G4double G4DNAEmfietzoglouExcitationModel::CrossSectionPerVolume(const G4Materia
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
|
||||
if (particleDefinition == G4Electron::ElectronDefinition())
|
||||
@@ -187,12 +151,12 @@ G4double G4DNAEmfietzoglouExcitationModel::CrossSectionPerVolume(const G4Materia
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (flagMaterialIsWater)
|
||||
|
||||
return sigma*densityWater;
|
||||
}
|
||||
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -270,6 +234,7 @@ G4double G4DNAEmfietzoglouExcitationModel::PartialCrossSection(G4double t, G4int
|
||||
* std::pow((1.- (exc/t)), pj[level]);
|
||||
sigma = excitationSigma / density;
|
||||
}
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAExcitation.cc,v 1.3 2009/03/04 13:28:49 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAExcitation.cc,v 1.7 2010/10/08 08:53:17 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "G4DNAExcitation.hh"
|
||||
|
||||
@@ -56,6 +56,7 @@ G4bool G4DNAExcitation::IsApplicable(const G4ParticleDefinition& p)
|
||||
(
|
||||
&p == G4Electron::Electron()
|
||||
|| &p == G4Proton::ProtonDefinition()
|
||||
|| &p == instance->GetIon("hydrogen")
|
||||
|| &p == instance->GetIon("alpha++")
|
||||
|| &p == instance->GetIon("alpha+")
|
||||
|| &p == instance->GetIon("helium")
|
||||
@@ -75,9 +76,18 @@ void G4DNAExcitation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
|
||||
if(name == "e-")
|
||||
{
|
||||
|
||||
// Emfietzoglou model
|
||||
/*
|
||||
if(!Model()) SetModel(new G4DNAEmfietzoglouExcitationModel);
|
||||
Model()->SetLowEnergyLimit(8.23*eV);
|
||||
Model()->SetHighEnergyLimit(10*MeV);
|
||||
*/
|
||||
// Born model
|
||||
|
||||
if(!Model()) SetModel(new G4DNABornExcitationModel);
|
||||
Model()->SetLowEnergyLimit(9*eV);
|
||||
Model()->SetHighEnergyLimit(1*MeV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
@@ -90,17 +100,27 @@ void G4DNAExcitation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
|
||||
if(!Model(2)) SetModel(new G4DNABornExcitationModel,2);
|
||||
Model(2)->SetLowEnergyLimit(500*keV);
|
||||
Model(2)->SetHighEnergyLimit(10*MeV);
|
||||
Model(2)->SetHighEnergyLimit(100*MeV);
|
||||
|
||||
AddEmModel(1, Model(1));
|
||||
AddEmModel(2, Model(2));
|
||||
}
|
||||
|
||||
if(name == "hydrogen")
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNAMillerGreenExcitationModel);
|
||||
Model()->SetLowEnergyLimit(10*eV);
|
||||
Model()->SetHighEnergyLimit(500*keV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
|
||||
|
||||
if( name == "alpha" || name == "alpha+" || name == "helium" )
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNAMillerGreenExcitationModel);
|
||||
Model()->SetLowEnergyLimit(1*keV);
|
||||
Model()->SetHighEnergyLimit(10*MeV);
|
||||
Model()->SetHighEnergyLimit(400*MeV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAGenericIonsManager.cc,v 1.6 2009/06/10 13:32:36 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAGenericIonsManager.cc,v 1.7 2010/11/03 10:44:26 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
#include "G4Alpha.hh"
|
||||
@@ -70,8 +70,49 @@ G4DNAGenericIonsManager :: G4DNAGenericIonsManager()
|
||||
G4Ions *positronium1s;
|
||||
G4Ions *positronium2s;
|
||||
|
||||
G4Ions *carbon;
|
||||
G4Ions *nitrogen;
|
||||
G4Ions *oxygen;
|
||||
G4Ions *iron;
|
||||
|
||||
iron= new G4Ions(
|
||||
"iron", 52.5672*GeV, 0.0*MeV, +26.0*eplus,
|
||||
0, +1, 0,
|
||||
0, 0, 0,
|
||||
"nucleus", +26, +56, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
oxygen= new G4Ions(
|
||||
"oxygen", 15.0074*GeV, 0.0*MeV, +8.0*eplus,
|
||||
0, +1, 0,
|
||||
0, 0, 0,
|
||||
"nucleus", +8, +16, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
|
||||
nitrogen= new G4Ions(
|
||||
"nitrogen", 13.132*GeV, 0.0*MeV, +7.0*eplus,
|
||||
0, +1, 0,
|
||||
0, 0, 0,
|
||||
"nucleus", +7, +14, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
carbon= new G4Ions(
|
||||
"carbon", 11.267025440*GeV, 0.0*MeV, +6.0*eplus,
|
||||
0, +1, 0,
|
||||
0, 0, 0,
|
||||
"nucleus", +6, +12, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
helium= new G4Ions(
|
||||
helium= new G4Ions(
|
||||
"helium", 3.727417*GeV, 0.0*MeV, +0.0*eplus,
|
||||
0, +1, 0,
|
||||
0, 0, 0,
|
||||
@@ -80,7 +121,7 @@ G4DNAGenericIonsManager :: G4DNAGenericIonsManager()
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
alphaPlus= new G4Ions("alpha+", 3.727417*GeV, 0.0*MeV, +1.0*eplus,
|
||||
alphaPlus= new G4Ions("alpha+", 3.727417*GeV, 0.0*MeV, +1.0*eplus,
|
||||
1, +1, 0,
|
||||
0, 0, 0,
|
||||
"nucleus", +1, +4, 0,
|
||||
@@ -109,81 +150,17 @@ G4DNAGenericIonsManager :: G4DNAGenericIonsManager()
|
||||
"", 0, 0.0);
|
||||
|
||||
|
||||
/*
|
||||
// molechules construction
|
||||
|
||||
G4Ions* oxonium; // H3O -- it will become H3O+
|
||||
G4Ions* hydroxyl; // OH -- it will produce OH- too
|
||||
G4Ions* molHydrogen; // H2
|
||||
//G4Ions* hydroxide; // OH-
|
||||
G4Ions* hydroPeroxide; // H2O2
|
||||
G4Ions* water; // H2O -- it will become also H2O+
|
||||
|
||||
|
||||
G4double mass = 19.02*g/Avogadro - 11*electron_mass_c2;
|
||||
|
||||
oxonium = new G4Ions("H3O", mass, 0, +11.0*eplus,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
"molecule", 0, 0, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
mass = 17.00734*g/Avogadro - 9*electron_mass_c2;
|
||||
|
||||
hydroxyl = new G4Ions("OH", mass, 0, +9.0*eplus,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
"molecule", 0, 0, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
mass = 2.01588*g/Avogadro - 2*electron_mass_c2;
|
||||
|
||||
molHydrogen = new G4Ions("H2", mass, 0, +2.0*eplus,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
"molecule", 0, 0, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
mass = 34.01468*g/Avogadro - 18*electron_mass_c2;
|
||||
|
||||
hydroPeroxide = new G4Ions("H2O2", mass, 0, +18.0*eplus,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
"molecule", 0, 0, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
mass = 18.015*g/Avogadro - 10*electron_mass_c2;
|
||||
|
||||
water = new G4Ions("H2O", mass, 0, +10.0*eplus,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
"molecule", 0, 0, 0,
|
||||
true, -1.0, 0,
|
||||
false, "", 0,
|
||||
0.0);
|
||||
|
||||
map["H3O" ] =oxonium;
|
||||
map["OH" ] =hydroxyl;
|
||||
map["H2" ] =molHydrogen;
|
||||
map["H2O2"] =hydroPeroxide;
|
||||
map["H2O" ] =water;
|
||||
*/
|
||||
|
||||
|
||||
map["helium" ]=helium;
|
||||
map["hydrogen"]=hydrogen;
|
||||
map["alpha+" ]=alphaPlus;
|
||||
map["alpha++" ]=G4Alpha::Alpha();
|
||||
map["Ps-1s" ]=positronium1s;
|
||||
map["Ps-2s" ]=positronium2s;
|
||||
map["carbon" ]=carbon;
|
||||
map["nitrogen"]=nitrogen;
|
||||
map["oxygen" ]=oxygen;
|
||||
map["iron" ]=iron;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAIonisation.cc,v 1.4 2009/11/02 17:00:11 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAIonisation.cc,v 1.5 2010/09/08 14:30:45 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "G4DNAIonisation.hh"
|
||||
|
||||
@@ -90,7 +90,7 @@ void G4DNAIonisation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
|
||||
if(!Model(2)) SetModel(new G4DNABornIonisationModel,2);
|
||||
Model(2)->SetLowEnergyLimit(500*keV);
|
||||
Model(2)->SetHighEnergyLimit(10*MeV);
|
||||
Model(2)->SetHighEnergyLimit(100*MeV);
|
||||
|
||||
AddEmModel(1, Model(1));
|
||||
AddEmModel(2, Model(2));
|
||||
@@ -109,7 +109,7 @@ void G4DNAIonisation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNARuddIonisationModel);
|
||||
Model()->SetLowEnergyLimit(0*keV);
|
||||
Model()->SetHighEnergyLimit(10*MeV);
|
||||
Model()->SetHighEnergyLimit(400*MeV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4DNAMeltonAttachmentModel.cc,v 1.2 2010/09/15 05:47:33 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
// Created by Z. Francis
|
||||
|
||||
#include "G4DNAMeltonAttachmentModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAMeltonAttachmentModel::G4DNAMeltonAttachmentModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
{
|
||||
|
||||
lowEnergyLimit = 4 * eV;
|
||||
lowEnergyLimitOfModel = 4 * eV;
|
||||
highEnergyLimit = 13 * eV;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "Melton Attachment model is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / eV << " eV - "
|
||||
<< highEnergyLimit / eV << " eV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAMeltonAttachmentModel::~G4DNAMeltonAttachmentModel()
|
||||
{
|
||||
// For total cross section
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
|
||||
for (pos = tableData.begin(); pos != tableData.end(); ++pos)
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
delete table;
|
||||
}
|
||||
|
||||
// For final state
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAMeltonAttachmentModel::Initialise(const G4ParticleDefinition* /*particle*/,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNAMeltonAttachmentModel::Initialise()" << G4endl;
|
||||
|
||||
// Energy limits
|
||||
|
||||
if (LowEnergyLimit() < lowEnergyLimit)
|
||||
{
|
||||
G4cout << "G4DNAMeltonAttachmentModel: low energy limit increased from " <<
|
||||
LowEnergyLimit()/eV << " eV to " << lowEnergyLimit/eV << " eV" << G4endl;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
}
|
||||
|
||||
if (HighEnergyLimit() > highEnergyLimit)
|
||||
{
|
||||
G4cout << "G4DNAMeltonAttachmentModel: high energy limit decreased from " <<
|
||||
HighEnergyLimit()/eV << " eV to " << highEnergyLimit/eV << " eV" << G4endl;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
}
|
||||
|
||||
// Reading of data files
|
||||
|
||||
G4double scaleFactor = 1e-18*cm*cm;
|
||||
|
||||
G4String fileElectron("dna/sigma_attachment_e_melton");
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
G4String electron;
|
||||
|
||||
if (electronDef != 0)
|
||||
{
|
||||
// For total cross section
|
||||
|
||||
electron = electronDef->GetParticleName();
|
||||
|
||||
tableFile[electron] = fileElectron;
|
||||
|
||||
G4DNACrossSectionDataSet* tableE = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
|
||||
tableE->LoadData(fileElectron);
|
||||
tableData[electron] = tableE;
|
||||
|
||||
}
|
||||
else G4Exception("G4DNAMeltonAttachmentModel::Initialise: electron is not defined");
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section data for Melton Attachment model" << G4endl;
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "Melton Attachment model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / eV << " eV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(!isInitialised)
|
||||
{
|
||||
isInitialised = true;
|
||||
|
||||
if(pParticleChange)
|
||||
fParticleChangeForGamma = reinterpret_cast<G4ParticleChangeForGamma*>(pParticleChange);
|
||||
else
|
||||
fParticleChangeForGamma = new G4ParticleChangeForGamma();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAMeltonAttachmentModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNAMeltonAttachmentModel" << G4endl;
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = p->GetParticleName();
|
||||
|
||||
if (ekin >= lowEnergyLimit && ekin < highEnergyLimit)
|
||||
{
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = tableData.find(particleName);
|
||||
|
||||
if (pos != tableData.end())
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != 0)
|
||||
{
|
||||
sigma = table->FindValue(ekin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNAMeltonAttachmentModel::ComputeCrossSectionPerVolume: attempting to calculate cross section for wrong particle");
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if water
|
||||
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAMeltonAttachmentModel::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4DynamicParticle* aDynamicElectron,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAMeltonAttachmentModel" << G4endl;
|
||||
|
||||
// Electron is killed
|
||||
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+112
-57
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAMillerGreenExcitationModel.cc,v 1.6 2009/08/13 11:32:47 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAMillerGreenExcitationModel.cc,v 1.11 2010/10/08 08:53:17 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
#include "G4DNAMillerGreenExcitationModel.hh"
|
||||
@@ -73,11 +73,13 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
|
||||
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
|
||||
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
|
||||
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
|
||||
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
|
||||
|
||||
G4String proton;
|
||||
G4String hydrogen;
|
||||
G4String alphaPlusPlus;
|
||||
G4String alphaPlus;
|
||||
G4String helium;
|
||||
@@ -101,11 +103,30 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
G4Exception("G4DNAMillerGreenExcitationModel::Initialise: proton is not defined");
|
||||
}
|
||||
|
||||
if (hydrogenDef != 0)
|
||||
{
|
||||
hydrogen = hydrogenDef->GetParticleName();
|
||||
lowEnergyLimit[hydrogen] = 10. * eV;
|
||||
highEnergyLimit[hydrogen] = 500. * keV;
|
||||
|
||||
kineticEnergyCorrection[0] = 1.;
|
||||
slaterEffectiveCharge[0][0] = 0.;
|
||||
slaterEffectiveCharge[1][0] = 0.;
|
||||
slaterEffectiveCharge[2][0] = 0.;
|
||||
sCoefficient[0][0] = 0.;
|
||||
sCoefficient[1][0] = 0.;
|
||||
sCoefficient[2][0] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNAMillerGreenExcitationModel::Initialise: hydrogen is not defined");
|
||||
|
||||
}
|
||||
if (alphaPlusPlusDef != 0)
|
||||
{
|
||||
alphaPlusPlus = alphaPlusPlusDef->GetParticleName();
|
||||
lowEnergyLimit[alphaPlusPlus] = 1. * keV;
|
||||
highEnergyLimit[alphaPlusPlus] = 10. * MeV;
|
||||
highEnergyLimit[alphaPlusPlus] = 400. * MeV;
|
||||
|
||||
kineticEnergyCorrection[1] = 0.9382723/3.727417;
|
||||
slaterEffectiveCharge[0][1]=0.;
|
||||
@@ -124,12 +145,15 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
{
|
||||
alphaPlus = alphaPlusDef->GetParticleName();
|
||||
lowEnergyLimit[alphaPlus] = 1. * keV;
|
||||
highEnergyLimit[alphaPlus] = 10. * MeV;
|
||||
highEnergyLimit[alphaPlus] = 400. * MeV;
|
||||
|
||||
kineticEnergyCorrection[2] = 0.9382723/3.727417;
|
||||
slaterEffectiveCharge[0][2]=2.0;
|
||||
slaterEffectiveCharge[1][2]=1.15;
|
||||
slaterEffectiveCharge[2][2]=1.15;
|
||||
|
||||
// Following values provided by M. Dingfelder
|
||||
slaterEffectiveCharge[1][2]=2.00;
|
||||
slaterEffectiveCharge[2][2]=2.00;
|
||||
//
|
||||
sCoefficient[0][2]=0.7;
|
||||
sCoefficient[1][2]=0.15;
|
||||
sCoefficient[2][2]=0.15;
|
||||
@@ -143,7 +167,7 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
{
|
||||
helium = heliumDef->GetParticleName();
|
||||
lowEnergyLimit[helium] = 1. * keV;
|
||||
highEnergyLimit[helium] = 10. * MeV;
|
||||
highEnergyLimit[helium] = 400. * MeV;
|
||||
|
||||
kineticEnergyCorrection[3] = 0.9382723/3.727417;
|
||||
slaterEffectiveCharge[0][3]=1.7;
|
||||
@@ -152,6 +176,7 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
sCoefficient[0][3]=0.5;
|
||||
sCoefficient[1][3]=0.25;
|
||||
sCoefficient[2][3]=0.25;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -164,6 +189,12 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
SetHighEnergyLimit(highEnergyLimit[proton]);
|
||||
}
|
||||
|
||||
if (particle==hydrogenDef)
|
||||
{
|
||||
SetLowEnergyLimit(lowEnergyLimit[hydrogen]);
|
||||
SetHighEnergyLimit(highEnergyLimit[hydrogen]);
|
||||
}
|
||||
|
||||
if (particle==alphaPlusPlusDef)
|
||||
{
|
||||
SetLowEnergyLimit(lowEnergyLimit[alphaPlusPlus]);
|
||||
@@ -209,40 +240,6 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -264,6 +261,8 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
if (
|
||||
particleDefinition != G4Proton::ProtonDefinition()
|
||||
&&
|
||||
particleDefinition != instance->GetIon("hydrogen")
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha++")
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha+")
|
||||
@@ -277,7 +276,7 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
G4double highLim = 0;
|
||||
G4double crossSection = 0.;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
@@ -305,19 +304,22 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
// add ONE or TWO electron-water excitation for alpha+ and helium
|
||||
|
||||
/*
|
||||
if ( particleDefinition == instance->GetIon("alpha+")
|
||||
||
|
||||
particleDefinition == instance->GetIon("helium")
|
||||
)
|
||||
{
|
||||
|
||||
G4DNAEmfietzoglouExcitationModel * excitationXS = new G4DNAEmfietzoglouExcitationModel();
|
||||
excitationXS->Initialise(G4Electron::ElectronDefinition());
|
||||
|
||||
G4double sigmaExcitation=0;
|
||||
G4double tmp =0.;
|
||||
|
||||
if (k*0.511/3728 > 7.4*eV && k*0.511/3728 < 10*keV) sigmaExcitation =
|
||||
excitationXS->CrossSectionPerVolume(material,particleDefinition,k*0.511/3728,tmp,tmp)/densityWater;
|
||||
if (k*0.511/3728 > 8.23*eV && k*0.511/3728 < 10*MeV ) sigmaExcitation =
|
||||
excitationXS->CrossSectionPerVolume(material,G4Electron::ElectronDefinition(),k*0.511/3728,tmp,tmp)
|
||||
/material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha+") )
|
||||
crossSection = crossSection + sigmaExcitation ;
|
||||
@@ -326,7 +328,29 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
crossSection = crossSection + 2*sigmaExcitation ;
|
||||
|
||||
delete excitationXS;
|
||||
|
||||
// Alternative excitation model
|
||||
|
||||
G4DNABornExcitationModel * excitationXS = new G4DNABornExcitationModel();
|
||||
excitationXS->Initialise(G4Electron::ElectronDefinition());
|
||||
|
||||
G4double sigmaExcitation=0;
|
||||
G4double tmp=0;
|
||||
|
||||
if (k*0.511/3728 > 9*eV && k*0.511/3728 < 1*MeV ) sigmaExcitation =
|
||||
excitationXS->CrossSectionPerVolume(material,G4Electron::ElectronDefinition(),k*0.511/3728,tmp,tmp)
|
||||
/material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha+") )
|
||||
crossSection = crossSection + sigmaExcitation ;
|
||||
|
||||
if ( particleDefinition == instance->GetIon("helium") )
|
||||
crossSection = crossSection + 2*sigmaExcitation ;
|
||||
|
||||
delete excitationXS;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -334,12 +358,12 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << k/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << crossSection/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << crossSection*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << crossSection*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (flagMaterialIsWater)
|
||||
}
|
||||
|
||||
return crossSection*densityWater;
|
||||
return crossSection*material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
}
|
||||
|
||||
@@ -359,7 +383,12 @@ void G4DNAMillerGreenExcitationModel::SampleSecondaries(std::vector<G4DynamicPar
|
||||
|
||||
G4int level = RandomSelect(particleEnergy0,aDynamicParticle->GetDefinition());
|
||||
|
||||
G4double excitationEnergy = waterExcitation.ExcitationEnergy(level);
|
||||
// G4double excitationEnergy = waterExcitation.ExcitationEnergy(level);
|
||||
|
||||
// Dingfelder's excitation levels
|
||||
const G4double excitation[]={ 8.17*eV, 10.13*eV, 11.31*eV, 12.91*eV, 14.50*eV};
|
||||
G4double excitationEnergy = excitation[level];
|
||||
|
||||
G4double newEnergy = particleEnergy0 - excitationEnergy;
|
||||
|
||||
if (newEnergy>0)
|
||||
@@ -396,11 +425,15 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
|
||||
const G4double jj[]={19820.*eV, 23490.*eV, 27770.*eV, 30830.*eV, 33080.*eV};
|
||||
const G4double omegaj[]={0.85, 0.88, 0.88, 0.78, 0.78};
|
||||
|
||||
// Dingfelder's excitation levels
|
||||
const G4double Eliq[5]={ 8.17*eV, 10.13*eV, 11.31*eV, 12.91*eV, 14.50*eV};
|
||||
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition()) particleTypeIndex=0;
|
||||
if (particleDefinition == instance->GetIon("hydrogen")) particleTypeIndex=0;
|
||||
if (particleDefinition == instance->GetIon("alpha++")) particleTypeIndex=1;
|
||||
if (particleDefinition == instance->GetIon("alpha+")) particleTypeIndex=2;
|
||||
if (particleDefinition == instance->GetIon("helium")) particleTypeIndex=3;
|
||||
@@ -409,14 +442,21 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
|
||||
tCorrected = k * kineticEnergyCorrection[particleTypeIndex];
|
||||
|
||||
// SI - added protection
|
||||
if (tCorrected < waterExcitation.ExcitationEnergy(excitationLevel)) return 0;
|
||||
if (tCorrected < Eliq[excitationLevel]) return 0;
|
||||
//
|
||||
|
||||
G4int z = 10;
|
||||
|
||||
G4double numerator;
|
||||
numerator = std::pow(z * aj[excitationLevel], omegaj[excitationLevel]) *
|
||||
std::pow(tCorrected - waterExcitation.ExcitationEnergy(excitationLevel), nu);
|
||||
std::pow(tCorrected - Eliq[excitationLevel], nu);
|
||||
|
||||
// H case : see S. Uehara et al. IJRB 77, 2, 139-154 (2001) - section 3.3
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
numerator = std::pow(z * 0.75*aj[excitationLevel], omegaj[excitationLevel]) *
|
||||
std::pow(tCorrected - Eliq[excitationLevel], nu);
|
||||
|
||||
|
||||
G4double power;
|
||||
power = omegaj[excitationLevel] + nu;
|
||||
@@ -426,12 +466,15 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
|
||||
|
||||
G4double zEff = particleDefinition->GetPDGCharge() / eplus + particleDefinition->GetLeptonNumber();
|
||||
|
||||
zEff -= ( sCoefficient[0][particleTypeIndex] * S_1s(k, waterExcitation.ExcitationEnergy(excitationLevel), slaterEffectiveCharge[0][particleTypeIndex], 1.) +
|
||||
sCoefficient[1][particleTypeIndex] * S_2s(k, waterExcitation.ExcitationEnergy(excitationLevel), slaterEffectiveCharge[1][particleTypeIndex], 2.) +
|
||||
sCoefficient[2][particleTypeIndex] * S_2p(k, waterExcitation.ExcitationEnergy(excitationLevel), slaterEffectiveCharge[2][particleTypeIndex], 2.) );
|
||||
zEff -= ( sCoefficient[0][particleTypeIndex] * S_1s(k, Eliq[excitationLevel], slaterEffectiveCharge[0][particleTypeIndex], 1.) +
|
||||
sCoefficient[1][particleTypeIndex] * S_2s(k, Eliq[excitationLevel], slaterEffectiveCharge[1][particleTypeIndex], 2.) +
|
||||
sCoefficient[2][particleTypeIndex] * S_2p(k, Eliq[excitationLevel], slaterEffectiveCharge[2][particleTypeIndex], 2.) );
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen")) zEff = 1.;
|
||||
|
||||
G4double cross = sigma0 * zEff * zEff * numerator / denominator;
|
||||
|
||||
|
||||
return cross;
|
||||
}
|
||||
|
||||
@@ -447,7 +490,11 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if ( particle == instance->GetIon("alpha++") ||
|
||||
particle == G4Proton::ProtonDefinition() )
|
||||
particle == G4Proton::ProtonDefinition()||
|
||||
particle == instance->GetIon("hydrogen") ||
|
||||
particle == instance->GetIon("alpha+") ||
|
||||
particle == instance->GetIon("helium")
|
||||
)
|
||||
{
|
||||
while (i > 0)
|
||||
{
|
||||
@@ -469,6 +516,7 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// add ONE or TWO electron-water excitation for alpha+ and helium
|
||||
|
||||
if ( particle == instance->GetIon("alpha+")
|
||||
@@ -481,14 +529,17 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
i--;
|
||||
|
||||
G4DNAEmfietzoglouExcitationModel * excitationXS = new G4DNAEmfietzoglouExcitationModel();
|
||||
excitationXS->Initialise(G4Electron::ElectronDefinition());
|
||||
|
||||
G4double sigmaExcitation=0;
|
||||
|
||||
if (k*0.511/3728 > 7.4*eV && k*0.511/3728 < 10*keV) sigmaExcitation = excitationXS->PartialCrossSection(k*0.511/3728,i);
|
||||
if (k*0.511/3728 > 8.23*eV && k*0.511/3728 < 10*MeV ) sigmaExcitation = excitationXS->PartialCrossSection(k*0.511/3728,i);
|
||||
|
||||
G4double partial = PartialCrossSection(k,i,particle);
|
||||
|
||||
if (particle == instance->GetIon("alpha+")) partial = PartialCrossSection(k,i,particle) + sigmaExcitation;
|
||||
if (particle == instance->GetIon("helium")) partial = PartialCrossSection(k,i,particle) + 2*sigmaExcitation;
|
||||
|
||||
values.push_front(partial);
|
||||
value += partial;
|
||||
delete excitationXS;
|
||||
@@ -506,6 +557,7 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
value-=values[i];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -584,8 +636,11 @@ G4double G4DNAMillerGreenExcitationModel::R(G4double t,
|
||||
// Dingfelder, in Chattanooga 2005 proceedings, p 4
|
||||
|
||||
G4double tElectron = 0.511/3728. * t;
|
||||
G4double value = 2. * tElectron * slaterEffectiveCharge / (energyTransferred * shellNumber);
|
||||
|
||||
// The following is provided by M. Dingfelder
|
||||
G4double H = 2.*13.60569172 * eV;
|
||||
G4double value = std::sqrt ( 2. * tElectron / H ) / ( energyTransferred / H ) * (slaterEffectiveCharge/shellNumber);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNARuddIonisationModel.cc,v 1.10 2009/08/13 11:32:47 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNARuddIonisationModel.cc,v 1.21 2010/11/04 14:52:17 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
#include "G4DNARuddIonisationModel.hh"
|
||||
@@ -158,7 +158,7 @@ void G4DNARuddIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
tableFile[alphaPlusPlus] = fileAlphaPlusPlus;
|
||||
|
||||
lowEnergyLimit[alphaPlusPlus] = lowEnergyLimitForZ2;
|
||||
highEnergyLimit[alphaPlusPlus] = 10. * MeV;
|
||||
highEnergyLimit[alphaPlusPlus] = 400. * MeV;
|
||||
|
||||
// Cross section
|
||||
|
||||
@@ -180,7 +180,7 @@ void G4DNARuddIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
tableFile[alphaPlus] = fileAlphaPlus;
|
||||
|
||||
lowEnergyLimit[alphaPlus] = lowEnergyLimitForZ2;
|
||||
highEnergyLimit[alphaPlus] = 10. * MeV;
|
||||
highEnergyLimit[alphaPlus] = 400. * MeV;
|
||||
|
||||
// Cross section
|
||||
|
||||
@@ -201,7 +201,7 @@ void G4DNARuddIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
tableFile[helium] = fileHelium;
|
||||
|
||||
lowEnergyLimit[helium] = lowEnergyLimitForZ2;
|
||||
highEnergyLimit[helium] = 10. * MeV;
|
||||
highEnergyLimit[helium] = 400. * MeV;
|
||||
|
||||
// Cross section
|
||||
|
||||
@@ -270,45 +270,11 @@ void G4DNARuddIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double k,
|
||||
G4double,
|
||||
@@ -354,7 +320,7 @@ G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double highLim = 0;
|
||||
G4double sigma=0;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
@@ -396,50 +362,6 @@ G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
{
|
||||
sigma = table->FindValue(k);
|
||||
|
||||
// BEGIN ELECTRON CORRECTION
|
||||
// add ONE or TWO electron-water excitation for alpha+ and helium
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha+")
|
||||
||
|
||||
particleDefinition == instance->GetIon("helium")
|
||||
)
|
||||
{
|
||||
|
||||
G4DNACrossSectionDataSet* electronDataset = new G4DNACrossSectionDataSet
|
||||
(new G4LogLogInterpolation, eV, (1./3.343e22)*m*m);
|
||||
|
||||
electronDataset->LoadData("dna/sigma_ionisation_e_born");
|
||||
|
||||
G4double kElectron = k * 0.511/3728;
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha+") )
|
||||
{
|
||||
G4double tmp1 = table->FindValue(k) + electronDataset->FindValue(kElectron);
|
||||
delete electronDataset;
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << k/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << tmp1/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << tmp1*densityWater/(1./cm) << G4endl;
|
||||
}
|
||||
return tmp1*densityWater;
|
||||
}
|
||||
|
||||
if ( particleDefinition == instance->GetIon("helium") )
|
||||
{
|
||||
G4double tmp2 = table->FindValue(k) + 2. * electronDataset->FindValue(kElectron);
|
||||
delete electronDataset;
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << k/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << tmp2/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << tmp2*densityWater/(1./cm) << G4endl;
|
||||
}
|
||||
return tmp2*densityWater;
|
||||
}
|
||||
}
|
||||
|
||||
// END ELECTRON CORRECTION
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -453,12 +375,13 @@ G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material*,
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << k/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*
|
||||
material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (waterMaterial)
|
||||
|
||||
return sigma*densityWater;
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
}
|
||||
|
||||
@@ -519,10 +442,12 @@ void G4DNARuddIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
{
|
||||
G4ParticleDefinition* definition = particle->GetDefinition();
|
||||
G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
|
||||
/*
|
||||
G4double particleMass = definition->GetPDGMass();
|
||||
G4double totalEnergy = k + particleMass;
|
||||
G4double pSquare = k*(totalEnergy+particleMass);
|
||||
G4double totalMomentum = std::sqrt(pSquare);
|
||||
*/
|
||||
|
||||
G4int ionizationShell = RandomSelect(k,particleName);
|
||||
|
||||
@@ -541,6 +466,8 @@ void G4DNARuddIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
G4ThreeVector deltaDirection(dirX,dirY,dirZ);
|
||||
deltaDirection.rotateUz(primaryDirection);
|
||||
|
||||
// Ignored for ions on electrons
|
||||
/*
|
||||
G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
|
||||
|
||||
G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
|
||||
@@ -555,35 +482,15 @@ void G4DNARuddIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
direction.set(finalPx,finalPy,finalPz);
|
||||
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
|
||||
*/
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
|
||||
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(k-bindingEnergy-secondaryKinetic);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy);
|
||||
|
||||
G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic) ;
|
||||
fvect->push_back(dp);
|
||||
|
||||
/*
|
||||
// creating neutral water molechule...
|
||||
|
||||
G4DNAGenericMoleculeManager *instance;
|
||||
instance = G4DNAGenericMoleculeManager::Instance();
|
||||
G4ParticleDefinition* waterDef = NULL;
|
||||
G4Molecule* water = instance->GetMolecule("H2O");
|
||||
waterDef = (G4ParticleDefinition*)water;
|
||||
|
||||
direction.set(0.,0.,0.);
|
||||
|
||||
//G4DynamicParticle* dynamicWater = new G4DynamicParticle(waterDef, direction, bindingEnergy);
|
||||
G4DynamicMolecule* dynamicWater = new G4DynamicMolecule(water, direction, bindingEnergy);
|
||||
//dynamicWater->RemoveElectron(ionizationShell, 1);
|
||||
|
||||
G4DynamicMolecule* dynamicWater2 = new G4DynamicMolecule(water, direction, bindingEnergy);
|
||||
G4DynamicMolecule* dynamicWater3 = new G4DynamicMolecule(water, direction, bindingEnergy);
|
||||
// insertion inside secondaries
|
||||
|
||||
fvect->push_back(dynamicWater);
|
||||
fvect->push_back(dynamicWater2);
|
||||
fvect->push_back(dynamicWater3);
|
||||
*/
|
||||
}
|
||||
|
||||
// SI - not useful since low energy of model is 0 eV
|
||||
@@ -622,12 +529,13 @@ G4double G4DNARuddIonisationModel::RandomizeEjectedElectronEnergy(G4ParticleDefi
|
||||
|
||||
G4double crossSectionMaximum = 0.;
|
||||
|
||||
for(G4double value=waterStructure.IonisationEnergy(shell); value<=4.*waterStructure.IonisationEnergy(shell) ; value+=0.1*eV)
|
||||
for(G4double value=waterStructure.IonisationEnergy(shell); value<=5.*waterStructure.IonisationEnergy(shell) && k>=value ; value+=0.1*eV)
|
||||
{
|
||||
G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k, value, shell);
|
||||
if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
|
||||
}
|
||||
|
||||
|
||||
G4double secElecKinetic = 0.;
|
||||
|
||||
do
|
||||
@@ -669,7 +577,14 @@ void G4DNARuddIonisationModel::RandomizeEjectedElectronDirection(G4ParticleDefin
|
||||
}
|
||||
|
||||
phi = twopi * G4UniformRand();
|
||||
cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
|
||||
//cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
|
||||
// Restriction below 100 eV from Emfietzoglou (2000)
|
||||
|
||||
if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
else cosTheta = (2.*G4UniformRand())-1.;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -709,6 +624,10 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
G4double D2 ;
|
||||
G4double alphaConst ;
|
||||
|
||||
// const G4double Bj[5] = {12.61*eV, 14.73*eV, 18.55*eV, 32.20*eV, 539.7*eV};
|
||||
// The following values are provided by M. dingfelder (priv. comm)
|
||||
const G4double Bj[5] = {12.60*eV, 14.70*eV, 18.40*eV, 32.20*eV, 540*eV};
|
||||
|
||||
if (j == 4)
|
||||
{
|
||||
//Data For Liquid Water K SHELL from Dingfelder (Protons in Water)
|
||||
@@ -732,7 +651,9 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
D1 = -0.80;
|
||||
E1 = 0.38;
|
||||
A2 = 1.07;
|
||||
B2 = 14.6;
|
||||
// Value provided by M. Dingfelder (priv. comm)
|
||||
B2 = 11.6;
|
||||
//
|
||||
C2 = 0.60;
|
||||
D2 = 0.04;
|
||||
alphaConst = 0.64;
|
||||
@@ -745,7 +666,12 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
G4double wBig = (energyTransfer - waterStructure.IonisationEnergy(ionizationLevelIndex));
|
||||
G4double w = wBig / waterStructure.IonisationEnergy(ionizationLevelIndex);
|
||||
if (wBig<0) return 0.;
|
||||
|
||||
G4double w = wBig / Bj[ionizationLevelIndex];
|
||||
// Note that the following (j==4) cases are provided by M. Dingfelder (priv. comm)
|
||||
if (j==4) w = wBig / waterStructure.IonisationEnergy(ionizationLevelIndex);
|
||||
|
||||
G4double Ry = 13.6*eV;
|
||||
|
||||
G4double tau = 0.;
|
||||
@@ -762,11 +688,16 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
{
|
||||
tau = (0.511/3728.) * k ;
|
||||
}
|
||||
|
||||
G4double S = 4.*pi * Bohr_radius*Bohr_radius * n * std::pow((Ry/waterStructure.IonisationEnergy(ionizationLevelIndex)),2);
|
||||
G4double v2 = tau / waterStructure.IonisationEnergy(ionizationLevelIndex);
|
||||
|
||||
G4double S = 4.*pi * Bohr_radius*Bohr_radius * n * std::pow((Ry/Bj[ionizationLevelIndex]),2);
|
||||
if (j==4) S = 4.*pi * Bohr_radius*Bohr_radius * n * std::pow((Ry/waterStructure.IonisationEnergy(ionizationLevelIndex)),2);
|
||||
|
||||
G4double v2 = tau / Bj[ionizationLevelIndex];
|
||||
if (j==4) v2 = tau / waterStructure.IonisationEnergy(ionizationLevelIndex);
|
||||
|
||||
G4double v = std::sqrt(v2);
|
||||
G4double wc = 4.*v2 - 2.*v - (Ry/(4.*waterStructure.IonisationEnergy(ionizationLevelIndex)));
|
||||
G4double wc = 4.*v2 - 2.*v - (Ry/(4.*Bj[ionizationLevelIndex]));
|
||||
if (j==4) wc = 4.*v2 - 2.*v - (Ry/(4.*waterStructure.IonisationEnergy(ionizationLevelIndex)));
|
||||
|
||||
G4double L1 = (C1* std::pow(v,(D1))) / (1.+ E1*std::pow(v, (D1+4.)));
|
||||
G4double L2 = C2*std::pow(v,(D2));
|
||||
@@ -776,10 +707,20 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
G4double F1 = L1+H1;
|
||||
G4double F2 = (L2*H2)/(L2+H2);
|
||||
|
||||
G4double sigma = CorrectionFactor(particleDefinition, k/eV)
|
||||
G4double sigma = CorrectionFactor(particleDefinition, k)
|
||||
* Gj[j] * (S/Bj[ionizationLevelIndex])
|
||||
* ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
|
||||
|
||||
if (j==4) sigma = CorrectionFactor(particleDefinition, k)
|
||||
* Gj[j] * (S/waterStructure.IonisationEnergy(ionizationLevelIndex))
|
||||
* ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
|
||||
|
||||
if ( (particleDefinition == instance->GetIon("hydrogen")) && (ionizationLevelIndex==4))
|
||||
|
||||
// sigma = Gj[j] * (S/Bj[ionizationLevelIndex])
|
||||
sigma = Gj[j] * (S/waterStructure.IonisationEnergy(ionizationLevelIndex))
|
||||
* ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
|
||||
|
||||
if ( particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen")
|
||||
)
|
||||
@@ -800,8 +741,10 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
if (particleDefinition == instance->GetIon("alpha+") )
|
||||
{
|
||||
slaterEffectiveCharge[0]=2.0;
|
||||
slaterEffectiveCharge[1]=1.15;
|
||||
slaterEffectiveCharge[2]=1.15;
|
||||
// The following values are provided by M. Dingfelder (priv. comm)
|
||||
slaterEffectiveCharge[1]=2.0;
|
||||
slaterEffectiveCharge[2]=2.0;
|
||||
//
|
||||
sCoefficient[0]=0.7;
|
||||
sCoefficient[1]=0.15;
|
||||
sCoefficient[2]=0.15;
|
||||
@@ -822,8 +765,11 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
|| particleDefinition == instance->GetIon("alpha++")
|
||||
)
|
||||
{
|
||||
sigma = Gj[j] * (S/waterStructure.IonisationEnergy(ionizationLevelIndex)) * ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
|
||||
sigma = Gj[j] * (S/Bj[ionizationLevelIndex]) * ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
|
||||
|
||||
if (j==4) sigma = Gj[j] * (S/waterStructure.IonisationEnergy(ionizationLevelIndex))
|
||||
* ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
|
||||
|
||||
G4double zEff = particleDefinition->GetPDGCharge() / eplus + particleDefinition->GetLeptonNumber();
|
||||
|
||||
zEff -= ( sCoefficient[0] * S_1s(k, energyTransfer, slaterEffectiveCharge[0], 1.) +
|
||||
@@ -896,7 +842,9 @@ G4double G4DNARuddIonisationModel::R(G4double t,
|
||||
// Dingfelder, in Chattanooga 2005 proceedings, p 4
|
||||
|
||||
G4double tElectron = 0.511/3728. * t;
|
||||
G4double value = 2. * tElectron * slaterEffectiveChg / (energyTransferred * shellNumber);
|
||||
// The following values are provided by M. Dingfelder (priv. comm)
|
||||
G4double H = 2.*13.60569172 * eV;
|
||||
G4double value = std::sqrt ( 2. * tElectron / H ) / ( energyTransferred / H ) * (slaterEffectiveChg/shellNumber);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -915,8 +863,9 @@ G4double G4DNARuddIonisationModel::CorrectionFactor(G4ParticleDefinition* partic
|
||||
else
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
{
|
||||
G4double value = (std::log(k/eV)-4.2)/0.5;
|
||||
return((0.8/(1+std::exp(value))) + 0.9);
|
||||
G4double value = (std::log10(k/eV)-4.2)/0.5;
|
||||
// The following values are provided by M. Dingfelder (priv. comm)
|
||||
return((0.6/(1+std::exp(value))) + 0.9);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -931,31 +880,11 @@ G4int G4DNARuddIonisationModel::RandomSelect(G4double k, const G4String& particl
|
||||
|
||||
// BEGIN PART 1/2 OF ELECTRON CORRECTION
|
||||
|
||||
// add ONE or TWO electron-water excitation for alpha+ and helium
|
||||
// add ONE or TWO electron-water ionisation for alpha+ and helium
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4double kElectron(0);
|
||||
G4double electronComponent(0);
|
||||
G4DNACrossSectionDataSet * electronDataset = new G4DNACrossSectionDataSet (new G4LogLogInterpolation, eV, (1./3.343e22)*m*m);
|
||||
|
||||
if ( particle == instance->GetIon("alpha+")->GetParticleName()
|
||||
||
|
||||
particle == instance->GetIon("helium")->GetParticleName()
|
||||
)
|
||||
{
|
||||
electronDataset->LoadData("dna/sigma_ionisation_e_born");
|
||||
|
||||
kElectron = k * 0.511/3728;
|
||||
|
||||
electronComponent = electronDataset->FindValue(kElectron);
|
||||
|
||||
}
|
||||
|
||||
delete electronDataset;
|
||||
|
||||
// END PART 1/2 OF ELECTRON CORRECTION
|
||||
|
||||
G4int level = 0;
|
||||
|
||||
// Retrieve data table corresponding to the current particle type
|
||||
@@ -979,17 +908,6 @@ G4int G4DNARuddIonisationModel::RandomSelect(G4double k, const G4String& particl
|
||||
{
|
||||
i--;
|
||||
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
|
||||
|
||||
// BEGIN PART 2/2 OF ELECTRON CORRECTION
|
||||
|
||||
if (particle == instance->GetIon("alpha+")->GetParticleName())
|
||||
{valuesBuffer[i]=table->GetComponent(i)->FindValue(k) + electronComponent; }
|
||||
|
||||
if (particle == instance->GetIon("helium")->GetParticleName())
|
||||
{valuesBuffer[i]=table->GetComponent(i)->FindValue(k) + 2*electronComponent; }
|
||||
|
||||
// BEGIN PART 2/2 OF ELECTRON CORRECTION
|
||||
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
@@ -1000,6 +918,7 @@ G4int G4DNARuddIonisationModel::RandomSelect(G4double k, const G4String& particl
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
|
||||
if (valuesBuffer[i] > value)
|
||||
{
|
||||
@@ -1017,7 +936,7 @@ G4int G4DNARuddIonisationModel::RandomSelect(G4double k, const G4String& particl
|
||||
{
|
||||
G4Exception("G4DNARuddIonisationModel::RandomSelect: attempting to calculate cross section for wrong particle");
|
||||
}
|
||||
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4DNASancheExcitationModel.cc,v 1.4 2010/11/11 22:32:22 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
// Created by Z. Francis
|
||||
|
||||
#include "G4DNASancheExcitationModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNASancheExcitationModel::G4DNASancheExcitationModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
{
|
||||
|
||||
lowEnergyLimit = 2 * eV;
|
||||
highEnergyLimit = 100 * eV;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
nLevels = 9;
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << "Sanche Excitation model is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / eV << " eV - "
|
||||
<< highEnergyLimit / eV << " eV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNASancheExcitationModel::~G4DNASancheExcitationModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNASancheExcitationModel::Initialise(const G4ParticleDefinition* /*particle*/,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNASancheExcitationModel::Initialise()" << G4endl;
|
||||
|
||||
// Energy limits
|
||||
|
||||
if (LowEnergyLimit() < lowEnergyLimit)
|
||||
{
|
||||
G4cout << "G4DNASancheExcitationModel: low energy limit increased from " <<
|
||||
LowEnergyLimit()/eV << " eV to " << lowEnergyLimit/eV << " eV" << G4endl;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
}
|
||||
|
||||
if (HighEnergyLimit() > highEnergyLimit)
|
||||
{
|
||||
G4cout << "G4DNASancheExcitationModel: high energy limit decreased from " <<
|
||||
HighEnergyLimit()/eV << " eV to " << highEnergyLimit/eV << " eV" << G4endl;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if (verboseLevel > 0)
|
||||
|
||||
G4cout << "Sanche Excitation model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / eV << " eV"
|
||||
<< G4endl;
|
||||
|
||||
if(!isInitialised)
|
||||
{
|
||||
isInitialised = true;
|
||||
|
||||
if(pParticleChange)
|
||||
fParticleChangeForGamma = reinterpret_cast<G4ParticleChangeForGamma*>(pParticleChange);
|
||||
else
|
||||
fParticleChangeForGamma = new G4ParticleChangeForGamma();
|
||||
}
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
std::ostringstream eFullFileName;
|
||||
eFullFileName << path << "/dna/sigma_excitationvib_e_sanche.dat";
|
||||
std::ifstream input(eFullFileName.str().c_str());
|
||||
|
||||
if (!input)
|
||||
{
|
||||
G4Exception("G4DNASancheExcitationModel:::ERROR OPENING XS DATA FILE");
|
||||
}
|
||||
|
||||
while(!input.eof())
|
||||
{
|
||||
double t;
|
||||
input>>t;
|
||||
tdummyVec.push_back(t);
|
||||
input>>map1[t][0]>>map1[t][1]>>map1[t][2]>>map1[t][3]>>map1[t][4]>>map1[t][5]>>map1[t][6]>>map1[t][7]>>map1[t][8];
|
||||
//G4cout<<t<<" "<<map1[t][0]<<map1[t][1]<<map1[t][2]<<map1[t][3]<<map1[t][4]<<map1[t][5]<<map1[t][6]<<map1[t][7]<<map1[t][8]<<G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNASancheExcitationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNASancheExcitationModel" << G4endl;
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
|
||||
if (particleDefinition == G4Electron::ElectronDefinition())
|
||||
{
|
||||
if (ekin >= lowEnergyLimit && ekin < highEnergyLimit)
|
||||
{
|
||||
sigma = Sum(ekin);
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if water
|
||||
|
||||
|
||||
return sigma*2*material->GetAtomicNumDensityVector()[1];
|
||||
// see papers for factor 2 description
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNASancheExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* aDynamicElectron,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNASancheExcitationModel" << G4endl;
|
||||
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
G4int level = RandomSelect(electronEnergy0);
|
||||
G4double excitationEnergy = VibrationEnergy(level); // levels go from 0 to 8
|
||||
G4double newEnergy = electronEnergy0 - excitationEnergy;
|
||||
|
||||
/*
|
||||
if (electronEnergy0 < highEnergyLimit)
|
||||
{
|
||||
if (newEnergy >= lowEnergyLimit)
|
||||
{
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(aDynamicElectron->GetMomentumDirection());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (electronEnergy0 < highEnergyLimit && newEnergy>0.)
|
||||
{
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(aDynamicElectron->GetMomentumDirection());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
}
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNASancheExcitationModel::PartialCrossSection(G4double t, G4int level)
|
||||
{
|
||||
std::vector<double>::iterator t2 = std::upper_bound(tdummyVec.begin(),tdummyVec.end(), t/eV);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
double sigma = LinInterpolate((*t1), (*t2), t/eV, map1[*t1][level], map1[*t2][level]);
|
||||
sigma*=1e-16*cm*cm;
|
||||
if(sigma==0.)sigma=1e-30;
|
||||
return (sigma);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNASancheExcitationModel::VibrationEnergy(G4int level)
|
||||
{
|
||||
G4double energies[9] = {0.01, 0.024, 0.061, 0.092, 0.204, 0.417, 0.460, 0.500, 0.835};
|
||||
return(energies[level]*eV);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int G4DNASancheExcitationModel::RandomSelect(G4double k)
|
||||
{
|
||||
|
||||
// Level Selection Counting can be done here !
|
||||
|
||||
G4int i = nLevels;
|
||||
G4double value = 0.;
|
||||
std::deque<double> values;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
G4double partial = PartialCrossSection(k,i);
|
||||
values.push_front(partial);
|
||||
value += partial;
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
i = nLevels;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
if (values[i] > value)
|
||||
{
|
||||
//outcount<<i<<" "<<VibrationEnergy(i)<<G4endl;
|
||||
return i;
|
||||
}
|
||||
value -= values[i];
|
||||
}
|
||||
|
||||
//outcount<<0<<" "<<VibrationEnergy(0)<<G4endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNASancheExcitationModel::Sum(G4double k)
|
||||
{
|
||||
G4double totalCrossSection = 0.;
|
||||
|
||||
for (G4int i=0; i<nLevels; i++)
|
||||
{
|
||||
totalCrossSection += PartialCrossSection(k,i);
|
||||
}
|
||||
return totalCrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNASancheExcitationModel::LinInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double a = (xs2 - xs1) / (e2 - e1);
|
||||
G4double b = xs2 - a*e2;
|
||||
G4double value = a*e + b;
|
||||
// G4cout<<"interP >> "<<e1<<" "<<e2<<" "<<e<<" "<<xs1<<" "<<xs2<<" "<<a<<" "<<b<<" "<<value<<G4endl;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
+11
-48
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DNAScreenedRutherfordElasticModel.cc,v 1.9 2009/08/13 11:32:47 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4DNAScreenedRutherfordElasticModel.cc,v 1.15 2010/11/11 22:32:22 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
|
||||
#include "G4DNAScreenedRutherfordElasticModel.hh"
|
||||
@@ -40,11 +40,10 @@ G4DNAScreenedRutherfordElasticModel::G4DNAScreenedRutherfordElasticModel
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
{
|
||||
|
||||
killBelowEnergy = 8.23*eV; // Minimum e- energy for energy loss by excitation
|
||||
killBelowEnergy = 9*eV;
|
||||
lowEnergyLimit = 0 * eV;
|
||||
lowEnergyLimitOfModel = 7 * eV; // The model lower energy is 7 eV
|
||||
intermediateEnergyLimit = 200 * eV; // Switch between two final state models
|
||||
highEnergyLimit = 10 * MeV;
|
||||
highEnergyLimit = 1. * MeV;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
@@ -151,45 +150,11 @@ void G4DNAScreenedRutherfordElasticModel::Initialise(const G4ParticleDefinition*
|
||||
|
||||
// InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
// Test if water material
|
||||
|
||||
flagMaterialIsWater= false;
|
||||
densityWater = 0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
if(theCoupleTable)
|
||||
{
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(numOfCouples>0)
|
||||
{
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
G4double density = material->GetAtomicNumDensityVector()[1];
|
||||
flagMaterialIsWater = true;
|
||||
densityWater = density;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "****** Water material is found with density(cm^-3)=" << density/(cm*cm*cm) << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if(numOfCouples>0)
|
||||
|
||||
} // if (theCoupleTable)
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAScreenedRutherfordElasticModel::CrossSectionPerVolume(const G4Material*,
|
||||
G4double G4DNAScreenedRutherfordElasticModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition*,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
@@ -202,15 +167,13 @@ G4double G4DNAScreenedRutherfordElasticModel::CrossSectionPerVolume(const G4Mate
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
if (flagMaterialIsWater)
|
||||
if (material->GetName() == "G4_WATER")
|
||||
{
|
||||
|
||||
if (ekin < highEnergyLimit)
|
||||
{
|
||||
|
||||
//SI : XS must not be zero otherwise sampling of secondaries method ignored
|
||||
if (ekin < lowEnergyLimitOfModel) ekin = lowEnergyLimitOfModel;
|
||||
//
|
||||
|
||||
if (ekin < killBelowEnergy) return DBL_MAX;
|
||||
|
||||
G4double z = 10.;
|
||||
G4double n = ScreeningFactor(ekin,z);
|
||||
@@ -222,12 +185,12 @@ G4double G4DNAScreenedRutherfordElasticModel::CrossSectionPerVolume(const G4Mate
|
||||
{
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*densityWater/(1./cm) << G4endl;
|
||||
G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
}
|
||||
|
||||
} // if (flagMaterialIsWater)
|
||||
}
|
||||
|
||||
return sigma*densityWater;
|
||||
return sigma*material->GetAtomicNumDensityVector()[1];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4DNAVibExcitation.cc,v 1.2 2010/11/11 22:32:22 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
|
||||
#include "G4DNAVibExcitation.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4DNAVibExcitation::G4DNAVibExcitation(const G4String& processName,
|
||||
G4ProcessType type):G4VEmProcess (processName, type),
|
||||
isInitialised(false)
|
||||
{
|
||||
SetProcessSubType(51);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4DNAVibExcitation::~G4DNAVibExcitation()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4DNAVibExcitation::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
return (&p == G4Electron::Electron());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAVibExcitation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!isInitialised)
|
||||
{
|
||||
isInitialised = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
|
||||
if(name == "e-")
|
||||
{
|
||||
if(!Model()) SetModel(new G4DNASancheExcitationModel);
|
||||
Model()->SetLowEnergyLimit(2*eV);
|
||||
Model()->SetHighEnergyLimit(100*eV);
|
||||
|
||||
AddEmModel(1, Model());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4DNAVibExcitation::PrintInfo()
|
||||
{
|
||||
G4cout
|
||||
<< " Total cross sections computed from "
|
||||
<< Model()->GetName()
|
||||
<< G4endl;
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EMDataSet.cc,v 1.20 2009/09/25 07:41:34 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4EMDataSet.cc,v 1.21 2010/12/02 17:37:26 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
@@ -107,7 +107,7 @@ G4EMDataSet::G4EMDataSet(G4int argZ,
|
||||
if ((energies == 0) ^ (data == 0))
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - different size for energies and data (zero case)");
|
||||
|
||||
if (energies == 0) return;
|
||||
//if (energies == 0) return;
|
||||
|
||||
if (energies->size() != data->size())
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - different size for energies and data");
|
||||
@@ -140,7 +140,7 @@ G4EMDataSet::G4EMDataSet(G4int argZ,
|
||||
if ((energies == 0) ^ (data == 0))
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - different size for energies and data (zero case)");
|
||||
|
||||
if (energies == 0) return;
|
||||
//if (energies == 0) return;
|
||||
|
||||
if (energies->size() != data->size())
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - different size for energies and data");
|
||||
@@ -148,7 +148,7 @@ G4EMDataSet::G4EMDataSet(G4int argZ,
|
||||
if ((log_energies == 0) ^ (log_data == 0))
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - different size for log energies and log data (zero case)");
|
||||
|
||||
if (log_energies == 0) return;
|
||||
//if (log_energies == 0) return;
|
||||
|
||||
if (log_energies->size() != log_data->size())
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - different size for log energies and log data");
|
||||
@@ -160,11 +160,11 @@ G4EMDataSet::G4EMDataSet(G4int argZ,
|
||||
G4EMDataSet::~G4EMDataSet()
|
||||
{
|
||||
delete algorithm;
|
||||
if (energies) delete energies;
|
||||
if (data) delete data;
|
||||
if (pdf) delete pdf;
|
||||
if (log_energies) delete log_energies;
|
||||
if (log_data) delete log_data;
|
||||
if (energies) { energies->clear(); delete energies; }
|
||||
if (data) { data->clear(); delete data; }
|
||||
if (pdf) { pdf->clear(); delete pdf; }
|
||||
if (log_energies) { log_energies->clear(); delete log_energies; }
|
||||
if (log_data) { log_data->clear(); delete log_data; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4Generator2BN.cc,v 1.9 2010/10/14 14:01:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -44,13 +46,13 @@
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Concrete base class for Bremsstrahlung Angular Distribution Generation - 2BN Distribution
|
||||
// Concrete base class for Bremsstrahlung Angular Distribution Generation
|
||||
// 2BN Distribution
|
||||
//
|
||||
// Class Description: End
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4Generator2BN.hh"
|
||||
#include "Randomize.hh"
|
||||
@@ -149,7 +151,8 @@ G4double G4Generator2BN::ctab[320] =
|
||||
};
|
||||
|
||||
|
||||
G4Generator2BN::G4Generator2BN(const G4String& name):G4VBremAngularDistribution(name)
|
||||
G4Generator2BN::G4Generator2BN(const G4String&)
|
||||
: G4VBremAngularDistribution("AngularGen2BN")
|
||||
{
|
||||
b = 1.2;
|
||||
index_min = -300;
|
||||
@@ -171,7 +174,7 @@ G4Generator2BN::G4Generator2BN(const G4String& name):G4VBremAngularDistribution(
|
||||
//
|
||||
|
||||
G4Generator2BN::~G4Generator2BN()
|
||||
{;}
|
||||
{}
|
||||
|
||||
//
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4Generator2BS.cc,v 1.10 2010/10/14 14:01:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -38,31 +40,37 @@
|
||||
// Creation date: 2 June 2003
|
||||
//
|
||||
// Modifications:
|
||||
// 02 Jun 2003 First implementation acording with new design
|
||||
// 05 Nov 2003 MGP Fixed std namespace
|
||||
// 17 Nov 2003 MGP Fixed compilation problem on Windows
|
||||
// 02 Jun 2003 First implementation acording with new design
|
||||
// 05 Nov 2003 MGP Fixed std namespace
|
||||
// 17 Nov 2003 MGP Fixed compilation problem on Windows
|
||||
// 12 Oct 2010 V.Ivanchenko Moved RejectionFunction inline, use G4Pow to speadup
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Concrete base class for Bremsstrahlung Angular Distribution Generation - 2BS Distribution
|
||||
// Concrete base class for Bremsstrahlung Angular Distribution Generation
|
||||
// 2BS Distribution
|
||||
//
|
||||
// Class Description: End
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4Generator2BS.hh"
|
||||
#include "Randomize.hh"
|
||||
//
|
||||
#include "Randomize.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
G4Generator2BS::G4Generator2BS(const G4String& name):G4VBremAngularDistribution(name)
|
||||
{;}
|
||||
//
|
||||
|
||||
G4Generator2BS::G4Generator2BS(const G4String&)
|
||||
: G4VBremAngularDistribution("AngularGen2BS")
|
||||
{
|
||||
g4pow = G4Pow::GetInstance();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
G4Generator2BS::~G4Generator2BS()
|
||||
{;}
|
||||
{}
|
||||
|
||||
//
|
||||
|
||||
@@ -78,7 +86,6 @@ G4double G4Generator2BS::PolarAngle(const G4double initial_energy,
|
||||
// National Research Council of Canada
|
||||
// Departement of Medical Physics, Memorial Sloan-Kettering Cancer Center, New York
|
||||
|
||||
|
||||
G4double theta = 0;
|
||||
|
||||
G4double initialTotalEnergy = (initial_energy+electron_mass_c2)/electron_mass_c2;
|
||||
@@ -86,8 +93,11 @@ G4double G4Generator2BS::PolarAngle(const G4double initial_energy,
|
||||
EnergyRatio = finalTotalEnergy/initialTotalEnergy;
|
||||
G4double gMaxEnergy = (pi*initialTotalEnergy)*(pi*initialTotalEnergy);
|
||||
|
||||
G4double Zeff = std::sqrt(static_cast<G4double>(Z) * (static_cast<G4double>(Z) + 1.0));
|
||||
z = (0.00008116224*(std::pow(Zeff,0.3333333)));
|
||||
//G4double Zeff = std::sqrt(static_cast<G4double>(Z) * (static_cast<G4double>(Z) + 1.0));
|
||||
//z = (0.00008116224*(std::pow(Zeff,0.3333333)));
|
||||
|
||||
// VI speadup
|
||||
z = 0.00008116224*(g4pow->Z13(Z) + g4pow->Z13(Z+1));
|
||||
|
||||
// Rejection arguments
|
||||
rejection_argument1 = (1.0+EnergyRatio*EnergyRatio);
|
||||
@@ -96,11 +106,10 @@ G4double G4Generator2BS::PolarAngle(const G4double initial_energy,
|
||||
((1-EnergyRatio)/(2.0*initialTotalEnergy*EnergyRatio));
|
||||
|
||||
// Calculate rejection function at 0, 1 and Emax
|
||||
G4double gfunction0 = RejectionFunction(0);
|
||||
G4double gfunction1 = RejectionFunction(1);
|
||||
G4double gfunction0 = RejectionFunction(0.0);
|
||||
G4double gfunction1 = RejectionFunction(1.0);
|
||||
G4double gfunctionEmax = RejectionFunction(gMaxEnergy);
|
||||
|
||||
|
||||
// Calculate Maximum value
|
||||
G4double gMaximum = std::max(gfunction0,gfunction1);
|
||||
gMaximum = std::max(gMaximum,gfunctionEmax);
|
||||
@@ -109,35 +118,24 @@ G4double G4Generator2BS::PolarAngle(const G4double initial_energy,
|
||||
|
||||
do{
|
||||
rand = G4UniformRand();
|
||||
rand = rand/(1-rand+1.0/gMaxEnergy);
|
||||
rand /= (1 - rand + 1.0/gMaxEnergy);
|
||||
gfunctionTest = RejectionFunction(rand);
|
||||
randTest = G4UniformRand();
|
||||
|
||||
}while(randTest > (gfunctionTest/gMaximum));
|
||||
} while(randTest*gMaximum > gfunctionTest);
|
||||
|
||||
theta = std::sqrt(rand)/initialTotalEnergy;
|
||||
|
||||
|
||||
return theta;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
G4double G4Generator2BS::RejectionFunction(G4double value) const
|
||||
{
|
||||
|
||||
G4double argument = (1+value)*(1+value);
|
||||
|
||||
G4double gfunction = (4+std::log(rejection_argument3+(z/argument)))*
|
||||
((4*EnergyRatio*value/argument)-rejection_argument1)+rejection_argument2;
|
||||
|
||||
return gfunction;
|
||||
|
||||
}
|
||||
|
||||
void G4Generator2BS::PrintGeneratorInformation() const
|
||||
{
|
||||
G4cout << "\n" << G4endl;
|
||||
G4cout << "Bremsstrahlung Angular Generator is 2BS Generator from 2BS Koch & Motz distribution (Rev Mod Phys 31(4), 920 (1959))" << G4endl;
|
||||
G4cout << "Bremsstrahlung Angular Generator is 2BS Generator "
|
||||
<< "from 2BS Koch & Motz distribution (Rev Mod Phys 31(4), 920 (1959))" << G4endl;
|
||||
G4cout << "Sampling algorithm adapted from PIRS-0203" << G4endl;
|
||||
G4cout << "\n" << G4endl;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4IonParametrisedLossModel.cc,v 1.10 2010/11/04 12:21:48 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// ===========================================================================
|
||||
// GEANT4 class source file
|
||||
@@ -63,6 +64,7 @@
|
||||
// modified BuildRangeVector, ComputeLossForStep
|
||||
// functions accordingly, added new cache param.)
|
||||
// - Removed GetRange function (AL)
|
||||
// 04. 11. 2010 - Moved virtual methods to the source (VI)
|
||||
//
|
||||
//
|
||||
// Class description:
|
||||
@@ -106,14 +108,13 @@ G4IonParametrisedLossModel::G4IonParametrisedLossModel(
|
||||
nmbBins(90),
|
||||
nmbSubBins(100),
|
||||
particleChangeLoss(0),
|
||||
modelIsInitialised(false),
|
||||
corrections(0),
|
||||
corrFactor(1.0),
|
||||
energyLossLimit(0.01),
|
||||
cutEnergies(0) {
|
||||
|
||||
cutEnergies(0)
|
||||
{
|
||||
genericIon = G4GenericIon::Definition();
|
||||
genericIonPDGMass = genericIon -> GetPDGMass();
|
||||
corrections = G4LossTableManager::Instance() -> EmCorrections();
|
||||
|
||||
// The upper limit of the current model is set to 100 TeV
|
||||
SetHighEnergyLimit(100.0 * TeV);
|
||||
@@ -195,6 +196,62 @@ G4double G4IonParametrisedLossModel::MinEnergyCut(
|
||||
|
||||
// #########################################################################
|
||||
|
||||
G4double G4IonParametrisedLossModel::MaxSecondaryEnergy(
|
||||
const G4ParticleDefinition* particle,
|
||||
G4double kineticEnergy) {
|
||||
|
||||
// ############## Maximum energy of secondaries ##########################
|
||||
// Function computes maximum energy of secondary electrons which are
|
||||
// released by an ion
|
||||
//
|
||||
// See Geant4 physics reference manual (version 9.1), section 9.1.1
|
||||
//
|
||||
// Ref.: W.M. Yao et al, Jour. of Phys. G 33 (2006) 1.
|
||||
// C.Caso et al. (Part. Data Group), Europ. Phys. Jour. C 3 1 (1998).
|
||||
// B. Rossi, High energy particles, New York, NY: Prentice-Hall (1952).
|
||||
//
|
||||
// (Implementation adapted from G4BraggIonModel)
|
||||
|
||||
if(particle != cacheParticle) UpdateCache(particle);
|
||||
|
||||
G4double tau = kineticEnergy/cacheMass;
|
||||
G4double tmax = 2.0 * electron_mass_c2 * tau * (tau + 2.) /
|
||||
(1. + 2.0 * (tau + 1.) * cacheElecMassRatio +
|
||||
cacheElecMassRatio * cacheElecMassRatio);
|
||||
|
||||
return tmax;
|
||||
}
|
||||
|
||||
// #########################################################################
|
||||
|
||||
G4double G4IonParametrisedLossModel::GetChargeSquareRatio(
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4Material* material,
|
||||
G4double kineticEnergy) { // Kinetic energy
|
||||
|
||||
G4double chargeSquareRatio = corrections ->
|
||||
EffectiveChargeSquareRatio(particle,
|
||||
material,
|
||||
kineticEnergy);
|
||||
corrFactor = chargeSquareRatio *
|
||||
corrections -> EffectiveChargeCorrection(particle,
|
||||
material,
|
||||
kineticEnergy);
|
||||
return corrFactor;
|
||||
}
|
||||
|
||||
// #########################################################################
|
||||
|
||||
G4double G4IonParametrisedLossModel::GetParticleCharge(
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4Material* material,
|
||||
G4double kineticEnergy) { // Kinetic energy
|
||||
|
||||
return corrections -> GetParticleCharge(particle, material, kineticEnergy);
|
||||
}
|
||||
|
||||
// #########################################################################
|
||||
|
||||
void G4IonParametrisedLossModel::Initialise(
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4DataVector& cuts) {
|
||||
@@ -294,22 +351,9 @@ void G4IonParametrisedLossModel::Initialise(
|
||||
}
|
||||
}
|
||||
|
||||
// The particle change object is cast to G4ParticleChangeForLoss
|
||||
if(! modelIsInitialised) {
|
||||
|
||||
modelIsInitialised = true;
|
||||
corrections = G4LossTableManager::Instance() -> EmCorrections();
|
||||
|
||||
if(!particleChangeLoss) {
|
||||
if(pParticleChange) {
|
||||
|
||||
particleChangeLoss = reinterpret_cast<G4ParticleChangeForLoss*>
|
||||
(pParticleChange);
|
||||
}
|
||||
else {
|
||||
particleChangeLoss = new G4ParticleChangeForLoss();
|
||||
}
|
||||
}
|
||||
// The particle change object
|
||||
if(! particleChangeLoss) {
|
||||
particleChangeLoss = GetParticleChangeForLoss();
|
||||
}
|
||||
|
||||
// The G4BraggIonModel and G4BetheBlochModel instances are initialised with
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LivermoreBremsstrahlungModel.cc,v 1.6 2009/06/11 15:47:08 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4LivermoreBremsstrahlungModel.cc,v 1.8 2010/12/02 16:07:05 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -141,7 +141,7 @@ void G4LivermoreBremsstrahlungModel::Initialise(const G4ParticleDefinition* part
|
||||
delete crossSectionHandler;
|
||||
crossSectionHandler = 0;
|
||||
}
|
||||
G4VDataSetAlgorithm* interpolation = new G4SemiLogInterpolation();
|
||||
G4VDataSetAlgorithm* interpolation = 0;//new G4SemiLogInterpolation();
|
||||
crossSectionHandler = new G4BremsstrahlungCrossSectionHandler(energySpectrum,interpolation);
|
||||
crossSectionHandler->Initialise(0,LowEnergyLimit(),HighEnergyLimit(),
|
||||
fNBinEnergyLoss);
|
||||
@@ -195,6 +195,7 @@ G4LivermoreBremsstrahlungModel::ComputeCrossSectionPerAtom(const G4ParticleDefin
|
||||
G4cout << "G4LivermoreBremsstrahlungModel::ComputeCrossSectionPerAtom" << G4endl;
|
||||
G4cout << "The cross section handler is not correctly initialized" << G4endl;
|
||||
G4Exception();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//The cut is already included in the crossSectionHandler
|
||||
|
||||
@@ -0,0 +1,381 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4LivermoreGammaConversionModelRC.cc,v 1.1 2010/11/10 17:12:22 flongo Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
//
|
||||
// Author: Sebastien Inserti
|
||||
// 30 October 2008
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 12 Apr 2009 V Ivanchenko Cleanup initialisation and generation of secondaries:
|
||||
// - apply internal high-energy limit only in constructor
|
||||
// - do not apply low-energy limit (default is 0)
|
||||
// - use CLHEP electron mass for low-enegry limit
|
||||
// - remove MeanFreePath method and table
|
||||
|
||||
|
||||
#include "G4LivermoreGammaConversionModelRC.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LivermoreGammaConversionModelRC::G4LivermoreGammaConversionModelRC(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),smallEnergy(2.*MeV),isInitialised(false),
|
||||
crossSectionHandler(0),meanFreePathTable(0)
|
||||
{
|
||||
lowEnergyLimit = 2.0*electron_mass_c2;
|
||||
highEnergyLimit = 100 * GeV;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Livermore Gamma conversion is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / MeV << " MeV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LivermoreGammaConversionModelRC::~G4LivermoreGammaConversionModelRC()
|
||||
{
|
||||
if (crossSectionHandler) delete crossSectionHandler;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void
|
||||
G4LivermoreGammaConversionModelRC::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4LivermoreGammaConversionModelRC::Initialise()" << G4endl;
|
||||
|
||||
if (crossSectionHandler)
|
||||
{
|
||||
crossSectionHandler->Clear();
|
||||
delete crossSectionHandler;
|
||||
}
|
||||
|
||||
// Read data tables for all materials
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
crossSectionHandler->Initialise(0,lowEnergyLimit,100.*GeV,400);
|
||||
G4String crossSectionFile = "pair/pp-cs-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
//
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for PenelopeGammaConversion" << G4endl;
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Livermore Gamma Conversion model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / MeV << " MeV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(isInitialised) return;
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4LivermoreGammaConversionModelRC::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
|
||||
G4double GammaEnergy,
|
||||
G4double Z, G4double,
|
||||
G4double, G4double)
|
||||
{
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling ComputeCrossSectionPerAtom() of G4LivermoreGammaConversionModelRC"
|
||||
<< G4endl;
|
||||
}
|
||||
if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit) return 0;
|
||||
|
||||
G4double cs = crossSectionHandler->FindValue(G4int(Z), GammaEnergy);
|
||||
return cs;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermoreGammaConversionModelRC::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
// The energies of the e+ e- secondaries are sampled using the Bethe - Heitler
|
||||
// cross sections with Coulomb correction. A modified version of the random
|
||||
// number techniques of Butcher & Messel is used (Nuc Phys 20(1960),15).
|
||||
|
||||
// Note 1 : Effects due to the breakdown of the Born approximation at low
|
||||
// energy are ignored.
|
||||
// Note 2 : The differential cross section implicitly takes account of
|
||||
// pair creation in both nuclear and atomic electron fields. However triplet
|
||||
// prodution is not generated.
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4LivermoreGammaConversionModelRC" << G4endl;
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
G4double epsilon ;
|
||||
G4double epsilon0 = electron_mass_c2 / photonEnergy ;
|
||||
G4double electronTotEnergy;
|
||||
G4double positronTotEnergy;
|
||||
|
||||
|
||||
// Do it fast if photon energy < 2. MeV
|
||||
if (photonEnergy < smallEnergy )
|
||||
{
|
||||
epsilon = epsilon0 + (0.5 - epsilon0) * G4UniformRand();
|
||||
|
||||
if (CLHEP::RandBit::shootBit())
|
||||
{
|
||||
electronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
positronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
positronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
electronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select randomly one element in the current material
|
||||
//const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* element = SelectRandomAtom(couple,particle,photonEnergy);
|
||||
G4cout << "G4LivermoreGammaConversionModelRC::SampleSecondaries" << G4endl;
|
||||
|
||||
if (element == 0)
|
||||
{
|
||||
G4cout << "G4LivermoreGammaConversionModelRC::SampleSecondaries - element = 0"
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
G4IonisParamElm* ionisation = element->GetIonisation();
|
||||
if (ionisation == 0)
|
||||
{
|
||||
G4cout << "G4LivermoreGammaConversionModelRC::SampleSecondaries - ionisation = 0"
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract Coulomb factor for this Element
|
||||
G4double fZ = 8. * (ionisation->GetlogZ3());
|
||||
if (photonEnergy > 50. * MeV) fZ += 8. * (element->GetfCoulomb());
|
||||
|
||||
// Limits of the screening variable
|
||||
G4double screenFactor = 136. * epsilon0 / (element->GetIonisation()->GetZ3()) ;
|
||||
G4double screenMax = std::exp ((42.24 - fZ)/8.368) - 0.952 ;
|
||||
G4double screenMin = std::min(4.*screenFactor,screenMax) ;
|
||||
|
||||
// Limits of the energy sampling
|
||||
G4double epsilon1 = 0.5 - 0.5 * std::sqrt(1. - screenMin / screenMax) ;
|
||||
G4double epsilonMin = std::max(epsilon0,epsilon1);
|
||||
G4double epsilonRange = 0.5 - epsilonMin ;
|
||||
|
||||
// Sample the energy rate of the created electron (or positron)
|
||||
G4double screen;
|
||||
G4double gReject ;
|
||||
|
||||
G4double f10 = ScreenFunction1(screenMin) - fZ;
|
||||
G4double f20 = ScreenFunction2(screenMin) - fZ;
|
||||
G4double normF1 = std::max(f10 * epsilonRange * epsilonRange,0.);
|
||||
G4double normF2 = std::max(1.5 * f20,0.);
|
||||
G4double a=393.3750918, b=115.3070201, c=810.6428451, d=19.96497475, e=1016.874592, f=1.936685510,
|
||||
g=751.2140962, h=0.099751048, i=299.9466339, j=0.002057250, k=49.81034926;
|
||||
G4double aa=-18.6371131, bb=-1729.95248, cc=9450.971186, dd=106336.0145, ee=55143.09287, ff=-117602.840,
|
||||
gg=-721455.467, hh=693957.8635, ii=156266.1085, jj=533209.9347;
|
||||
G4double Rechazo = 0.;
|
||||
G4double logepsMin = log(epsilonMin);
|
||||
G4double NormaRC = a + b*logepsMin + c/logepsMin + d*pow(logepsMin,2.) + e/pow(logepsMin,2.) + f*pow(logepsMin,3.) +
|
||||
g/pow(logepsMin,3.) + h*pow(logepsMin,4.) + i/pow(logepsMin,4.) + j*pow(logepsMin,5.) +
|
||||
k/pow(logepsMin,5.);
|
||||
|
||||
do {
|
||||
do {
|
||||
if (normF1 / (normF1 + normF2) > G4UniformRand() )
|
||||
{
|
||||
epsilon = 0.5 - epsilonRange * std::pow(G4UniformRand(), 0.3333) ;
|
||||
screen = screenFactor / (epsilon * (1. - epsilon));
|
||||
gReject = (ScreenFunction1(screen) - fZ) / f10 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilon = epsilonMin + epsilonRange * G4UniformRand();
|
||||
screen = screenFactor / (epsilon * (1 - epsilon));
|
||||
gReject = (ScreenFunction2(screen) - fZ) / f20 ;
|
||||
}
|
||||
} while ( gReject < G4UniformRand() );
|
||||
|
||||
if (CLHEP::RandBit::shootBit()) epsilon = (1. - epsilon); // Extención de Epsilon hasta 1.
|
||||
|
||||
G4double logepsilon = log(epsilon);
|
||||
G4double deltaP_R1 = 1. + (a + b*logepsilon + c/logepsilon + d*pow(logepsilon,2.) + e/pow(logepsilon,2.) +
|
||||
f*pow(logepsilon,3.) + g/pow(logepsilon,3.) + h*pow(logepsilon,4.) + i/pow(logepsilon,4.) +
|
||||
j*pow(logepsilon,5.) + k/pow(logepsilon,5.))/100.;
|
||||
G4double deltaP_R2 = 1.+((aa + cc*logepsilon + ee*pow(logepsilon,2.) + gg*pow(logepsilon,3.) + ii*pow(logepsilon,4.))
|
||||
/ (1. + bb*logepsilon + dd*pow(logepsilon,2.) + ff*pow(logepsilon,3.) + hh*pow(logepsilon,4.)
|
||||
+ jj*pow(logepsilon,5.) ))/100.;
|
||||
|
||||
if (epsilon <= 0.5)
|
||||
{
|
||||
Rechazo = deltaP_R1/NormaRC;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rechazo = deltaP_R2/NormaRC;
|
||||
}
|
||||
G4cout << Rechazo << " " << NormaRC << " " << epsilon << G4endl;
|
||||
} while (Rechazo < G4UniformRand() );
|
||||
|
||||
electronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
positronTotEnergy = epsilon * photonEnergy;
|
||||
|
||||
} // End of epsilon sampling
|
||||
|
||||
// Fix charges randomly
|
||||
|
||||
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev. Mod. Phys. 49, 421 (1977)
|
||||
|
||||
G4double u;
|
||||
const G4double a1 = 0.625;
|
||||
G4double a2 = 3. * a1;
|
||||
// G4double d = 27. ;
|
||||
|
||||
// if (9. / (9. + d) > G4UniformRand())
|
||||
if (0.25 > G4UniformRand())
|
||||
{
|
||||
u = - std::log(G4UniformRand() * G4UniformRand()) / a1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
u = - std::log(G4UniformRand() * G4UniformRand()) / a2 ;
|
||||
}
|
||||
|
||||
G4double thetaEle = u*electron_mass_c2/electronTotEnergy;
|
||||
G4double thetaPos = u*electron_mass_c2/positronTotEnergy;
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
|
||||
G4double dxEle= std::sin(thetaEle)*std::cos(phi),dyEle= std::sin(thetaEle)*std::sin(phi),dzEle=std::cos(thetaEle);
|
||||
G4double dxPos=-std::sin(thetaPos)*std::cos(phi),dyPos=-std::sin(thetaPos)*std::sin(phi),dzPos=std::cos(thetaPos);
|
||||
|
||||
|
||||
// Kinematics of the created pair:
|
||||
// the electron and positron are assumed to have a symetric angular
|
||||
// distribution with respect to the Z axis along the parent photon
|
||||
|
||||
G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
|
||||
|
||||
G4ThreeVector electronDirection (dxEle, dyEle, dzEle);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
|
||||
// The e+ is always created (even with kinetic energy = 0) for further annihilation
|
||||
G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
|
||||
|
||||
G4ThreeVector positronDirection (dxPos, dyPos, dzPos);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
// Fill output vector
|
||||
// G4cout << "Cree el e+ " << epsilon << G4endl;
|
||||
fvect->push_back(particle1);
|
||||
fvect->push_back(particle2);
|
||||
|
||||
// kill incident photon
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermoreGammaConversionModelRC::ScreenFunction1(G4double screenVariable)
|
||||
{
|
||||
// Compute the value of the screening function 3*phi1 - phi2
|
||||
|
||||
G4double value;
|
||||
|
||||
if (screenVariable > 1.)
|
||||
value = 42.24 - 8.368 * std::log(screenVariable + 0.952);
|
||||
else
|
||||
value = 42.392 - screenVariable * (7.796 - 1.961 * screenVariable);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermoreGammaConversionModelRC::ScreenFunction2(G4double screenVariable)
|
||||
{
|
||||
// Compute the value of the screening function 1.5*phi1 - 0.5*phi2
|
||||
|
||||
G4double value;
|
||||
|
||||
if (screenVariable > 1.)
|
||||
value = 42.24 - 8.368 * std::log(screenVariable + 0.952);
|
||||
else
|
||||
value = 41.405 - screenVariable * (5.828 - 0.8945 * screenVariable);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LivermoreIonisationModel.cc,v 1.7 2009/10/23 09:30:08 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4LivermoreIonisationModel.cc,v 1.13 2010/12/02 16:06:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -43,6 +43,12 @@
|
||||
// 23 Oct 2009 L Pandola
|
||||
// - atomic deexcitation managed via G4VEmModel::DeexcitationFlag() is
|
||||
// set as "true" (default would be false)
|
||||
// 12 Oct 2010 L Pandola
|
||||
// - add debugging information about energy in
|
||||
// SampleDeexcitationAlongStep()
|
||||
// - generate fluorescence SampleDeexcitationAlongStep() only above
|
||||
// the cuts.
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4LivermoreIonisationModel.hh"
|
||||
@@ -84,11 +90,10 @@ G4LivermoreIonisationModel::G4LivermoreIonisationModel(const G4ParticleDefinitio
|
||||
SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
|
||||
//
|
||||
verboseLevel = 0;
|
||||
//
|
||||
//By default: use deexcitation, not auger
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
//
|
||||
//
|
||||
// Notice: the fluorescence along step is generated only if it is
|
||||
// set by the PROCESS (e.g. G4eIonisation) via the command
|
||||
@@ -125,7 +130,7 @@ void G4LivermoreIonisationModel::Initialise(const G4ParticleDefinition* particle
|
||||
energySpectrum = 0;
|
||||
}
|
||||
energySpectrum = new G4eIonisationSpectrum();
|
||||
if (verboseLevel > 0)
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "G4VEnergySpectrum is initialized" << G4endl;
|
||||
|
||||
//Initialize cross section handler
|
||||
@@ -142,8 +147,12 @@ void G4LivermoreIonisationModel::Initialise(const G4ParticleDefinition* particle
|
||||
crossSectionHandler->Clear();
|
||||
crossSectionHandler->LoadShellData("ioni/ion-ss-cs-");
|
||||
//This is used to retrieve cross section values later on
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials(&cuts);
|
||||
|
||||
G4VEMDataSet* emdata =
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials(&cuts);
|
||||
//The method BuildMeanFreePathForMaterials() is required here only to force
|
||||
//the building of an internal table: the output pointer can be deleted
|
||||
delete emdata;
|
||||
|
||||
//Fluorescence data
|
||||
transitionManager = G4AtomicTransitionManager::Instance();
|
||||
if (shellVacancy) delete shellVacancy;
|
||||
@@ -159,7 +168,7 @@ void G4LivermoreIonisationModel::Initialise(const G4ParticleDefinition* particle
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if (verboseLevel > 1)
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Cross section data: " << G4endl;
|
||||
crossSectionHandler->PrintData();
|
||||
@@ -194,6 +203,7 @@ G4double G4LivermoreIonisationModel::ComputeCrossSectionPerAtom(const G4Particle
|
||||
G4cout << "G4LivermoreIonisationModel::ComputeCrossSectionPerAtom" << G4endl;
|
||||
G4cout << "The cross section handler is not correctly initialized" << G4endl;
|
||||
G4Exception();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//The cut is already included in the crossSectionHandler
|
||||
@@ -387,6 +397,8 @@ void G4LivermoreIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle
|
||||
{
|
||||
theEnergyDeposit -= e;
|
||||
fvect->push_back(aSecondary);
|
||||
aSecondary = 0;
|
||||
(*secondaryVector)[i]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -395,6 +407,8 @@ void G4LivermoreIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle
|
||||
}
|
||||
}
|
||||
}
|
||||
//secondaryVector = 0;
|
||||
delete secondaryVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,10 +454,14 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
//(including fluctuations) and produces explicit fluorescence/Auger
|
||||
//secondaries. The eloss value is updated.
|
||||
G4double energyLossBefore = eloss;
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Energy loss along step before deexcitation : " << energyLossBefore/keV <<
|
||||
" keV" << G4endl;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
G4cout << " SampleDeexcitationAlongStep() from G4LivermoreIonisation" << G4endl;
|
||||
G4cout << "Energy loss along step before deexcitation : " << energyLossBefore/keV <<
|
||||
" keV" << G4endl;
|
||||
}
|
||||
G4double incidentEnergy = theTrack.GetDynamicParticle()->GetKineticEnergy();
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable =
|
||||
@@ -453,9 +471,6 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
|
||||
G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
|
||||
|
||||
//Notice: in LowEnergyIonisation, fluorescence is always generated above 250 eV
|
||||
//not above the tracking cut.
|
||||
//G4double cutForLowEnergySecondaryParticles = 250.0*eV;
|
||||
|
||||
std::vector<G4DynamicParticle*>* deexcitationProducts =
|
||||
new std::vector<G4DynamicParticle*>;
|
||||
@@ -505,7 +520,10 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
if (aSecondary)
|
||||
{
|
||||
e = aSecondary->GetKineticEnergy();
|
||||
if ( eTot + e <= eloss )
|
||||
G4double itsCut = cutg;
|
||||
if (aSecondary->GetParticleDefinition() == G4Electron::Electron())
|
||||
itsCut = cute;
|
||||
if ( eTot + e <= eloss && e > itsCut )
|
||||
{
|
||||
eTot += e;
|
||||
deexcitationProducts->push_back(aSecondary);
|
||||
@@ -524,10 +542,14 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
}
|
||||
}
|
||||
|
||||
G4double energyLossInFluorescence = 0.0;
|
||||
size_t nSecondaries = deexcitationProducts->size();
|
||||
if (nSecondaries > 0)
|
||||
{
|
||||
fParticleChange->SetNumberOfSecondaries(nSecondaries);
|
||||
//You may have already secondaries produced by SampleSubCutSecondaries()
|
||||
//at the process G4VEnergyLossProcess
|
||||
G4int secondariesBefore = fParticleChange->GetNumberOfSecondaries();
|
||||
fParticleChange->SetNumberOfSecondaries(nSecondaries+secondariesBefore);
|
||||
const G4StepPoint* preStep = theTrack.GetStep()->GetPreStepPoint();
|
||||
const G4StepPoint* postStep = theTrack.GetStep()->GetPostStepPoint();
|
||||
G4ThreeVector r = preStep->GetPosition();
|
||||
@@ -538,7 +560,7 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
deltaT -= t;
|
||||
G4double time, q;
|
||||
G4ThreeVector position;
|
||||
|
||||
|
||||
for (size_t i=0; i<nSecondaries; i++)
|
||||
{
|
||||
G4DynamicParticle* part = (*deexcitationProducts)[i];
|
||||
@@ -553,6 +575,7 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
position = deltaR*q;
|
||||
position += r;
|
||||
G4Track* newTrack = new G4Track(part, time, position);
|
||||
energyLossInFluorescence += eSecondary;
|
||||
pParticleChange->AddSecondary(newTrack);
|
||||
}
|
||||
else
|
||||
@@ -566,9 +589,32 @@ void G4LivermoreIonisationModel::SampleDeexcitationAlongStep(const G4Material* t
|
||||
}
|
||||
delete deexcitationProducts;
|
||||
|
||||
//Check and verbosities. Ensure energy conservation
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Energy loss along step after deexcitation : " << eloss/keV <<
|
||||
" keV" << G4endl;
|
||||
{
|
||||
G4cout << "Energy loss along step after deexcitation : " << eloss/keV <<
|
||||
" keV" << G4endl;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "------------------------------------------------------------------" << G4endl;
|
||||
G4cout << "Energy in fluorescence: " << energyLossInFluorescence/keV << " keV" << G4endl;
|
||||
G4cout << "Residual energy loss: " << eloss/keV << " keV " << G4endl;
|
||||
G4cout << "Total final: " << (energyLossInFluorescence+eloss)/keV << " keV" << G4endl;
|
||||
G4cout << "Total initial: " << energyLossBefore/keV << " keV" << G4endl;
|
||||
G4cout << "------------------------------------------------------------------" << G4endl;
|
||||
}
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
if (std::fabs(energyLossBefore-energyLossInFluorescence-eloss)>10*eV)
|
||||
{
|
||||
G4cout << "Found energy non-conservation at SampleDeexcitationAlongStep() " << G4endl;
|
||||
G4cout << "Energy in fluorescence: " << energyLossInFluorescence/keV << " keV" << G4endl;
|
||||
G4cout << "Residual energy loss: " << eloss/keV << " keV " << G4endl;
|
||||
G4cout << "Total final: " << (energyLossInFluorescence+eloss)/keV << " keV" << G4endl;
|
||||
G4cout << "Total initial: " << energyLossBefore/keV << " keV" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -579,6 +625,7 @@ void G4LivermoreIonisationModel::InitialiseFluorescence()
|
||||
G4DataVector* energyVector = 0;
|
||||
size_t binForFluo = fNBinEnergyLoss/10;
|
||||
|
||||
//Used to produce a log-spaced energy grid. To be deleted at the end.
|
||||
G4PhysicsLogVector* eVector = new G4PhysicsLogVector(LowEnergyLimit(),HighEnergyLimit(),
|
||||
binForFluo);
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
@@ -655,9 +702,11 @@ void G4LivermoreIonisationModel::InitialiseFluorescence()
|
||||
G4VEMDataSet* p = new G4EMDataSet(iZ,energyVector,ksi,interp,1.,1.);
|
||||
xsis->AddComponent(p);
|
||||
}
|
||||
if(verboseLevel>0) xsis->PrintData();
|
||||
if(verboseLevel>3) xsis->PrintData();
|
||||
shellVacancy->AddXsiTable(xsis);
|
||||
}
|
||||
if (eVector)
|
||||
delete eVector;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
+349
@@ -0,0 +1,349 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4LivermoreNuclearGammaConversionModel.cc,v 1.1 2010/11/10 17:09:16 flongo Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
//
|
||||
// Author: Sebastien Inserti
|
||||
// 30 October 2008
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 12 Apr 2009 V Ivanchenko Cleanup initialisation and generation of secondaries:
|
||||
// - apply internal high-energy limit only in constructor
|
||||
// - do not apply low-energy limit (default is 0)
|
||||
// - use CLHEP electron mass for low-enegry limit
|
||||
// - remove MeanFreePath method and table
|
||||
|
||||
|
||||
#include "G4LivermoreNuclearGammaConversionModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LivermoreNuclearGammaConversionModel::G4LivermoreNuclearGammaConversionModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),smallEnergy(2.*MeV),isInitialised(false),
|
||||
crossSectionHandler(0),meanFreePathTable(0)
|
||||
{
|
||||
lowEnergyLimit = 2.0*electron_mass_c2;
|
||||
highEnergyLimit = 100 * GeV;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Livermore Nuclear Gamma conversion is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / MeV << " MeV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LivermoreNuclearGammaConversionModel::~G4LivermoreNuclearGammaConversionModel()
|
||||
{
|
||||
if (crossSectionHandler) delete crossSectionHandler;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void
|
||||
G4LivermoreNuclearGammaConversionModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4LivermoreNuclearGammaConversionModel::Initialise()" << G4endl;
|
||||
|
||||
if (crossSectionHandler)
|
||||
{
|
||||
crossSectionHandler->Clear();
|
||||
delete crossSectionHandler;
|
||||
}
|
||||
|
||||
// Read data tables for all materials
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
crossSectionHandler->Initialise(0,lowEnergyLimit,100.*GeV,400);
|
||||
G4String crossSectionFile = "pairdata/pp-pair-cs-"; // here only pair in nuclear field cs should be used
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
//
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Loaded cross section files for Livermore GammaConversion" << G4endl;
|
||||
G4cout << "To obtain the total cross section this should be used only " << G4endl
|
||||
<< "in connection with G4ElectronGammaConversion " << G4endl;
|
||||
}
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Livermore Nuclear Gamma Conversion model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / MeV << " MeV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(isInitialised) return;
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4LivermoreNuclearGammaConversionModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
|
||||
G4double GammaEnergy,
|
||||
G4double Z, G4double,
|
||||
G4double, G4double)
|
||||
{
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling ComputeCrossSectionPerAtom() of G4LivermoreNuclearGammaConversionModel"
|
||||
<< G4endl;
|
||||
}
|
||||
if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit) return 0;
|
||||
|
||||
G4double cs = crossSectionHandler->FindValue(G4int(Z), GammaEnergy);
|
||||
return cs;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermoreNuclearGammaConversionModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
// The energies of the e+ e- secondaries are sampled using the Bethe - Heitler
|
||||
// cross sections with Coulomb correction. A modified version of the random
|
||||
// number techniques of Butcher & Messel is used (Nuc Phys 20(1960),15).
|
||||
|
||||
// Note 1 : Effects due to the breakdown of the Born approximation at low
|
||||
// energy are ignored.
|
||||
// Note 2 : The differential cross section implicitly takes account of
|
||||
// pair creation in both nuclear and atomic electron fields. However triplet
|
||||
// prodution is not generated.
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4LivermoreNuclearGammaConversionModel" << G4endl;
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
G4double epsilon ;
|
||||
G4double epsilon0 = electron_mass_c2 / photonEnergy ;
|
||||
|
||||
// Do it fast if photon energy < 2. MeV
|
||||
if (photonEnergy < smallEnergy )
|
||||
{
|
||||
epsilon = epsilon0 + (0.5 - epsilon0) * G4UniformRand();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select randomly one element in the current material
|
||||
//const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* element = SelectRandomAtom(couple,particle,photonEnergy);
|
||||
|
||||
if (element == 0)
|
||||
{
|
||||
G4cout << "G4LivermoreNuclearGammaConversionModel::SampleSecondaries - element = 0"
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
G4IonisParamElm* ionisation = element->GetIonisation();
|
||||
if (ionisation == 0)
|
||||
{
|
||||
G4cout << "G4LivermoreNuclearGammaConversionModel::SampleSecondaries - ionisation = 0"
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract Coulomb factor for this Element
|
||||
G4double fZ = 8. * (ionisation->GetlogZ3());
|
||||
if (photonEnergy > 50. * MeV) fZ += 8. * (element->GetfCoulomb());
|
||||
|
||||
// Limits of the screening variable
|
||||
G4double screenFactor = 136. * epsilon0 / (element->GetIonisation()->GetZ3()) ;
|
||||
G4double screenMax = std::exp ((42.24 - fZ)/8.368) - 0.952 ;
|
||||
G4double screenMin = std::min(4.*screenFactor,screenMax) ;
|
||||
|
||||
// Limits of the energy sampling
|
||||
G4double epsilon1 = 0.5 - 0.5 * std::sqrt(1. - screenMin / screenMax) ;
|
||||
G4double epsilonMin = std::max(epsilon0,epsilon1);
|
||||
G4double epsilonRange = 0.5 - epsilonMin ;
|
||||
|
||||
// Sample the energy rate of the created electron (or positron)
|
||||
G4double screen;
|
||||
G4double gReject ;
|
||||
|
||||
G4double f10 = ScreenFunction1(screenMin) - fZ;
|
||||
G4double f20 = ScreenFunction2(screenMin) - fZ;
|
||||
G4double normF1 = std::max(f10 * epsilonRange * epsilonRange,0.);
|
||||
G4double normF2 = std::max(1.5 * f20,0.);
|
||||
|
||||
do {
|
||||
if (normF1 / (normF1 + normF2) > G4UniformRand() )
|
||||
{
|
||||
epsilon = 0.5 - epsilonRange * std::pow(G4UniformRand(), 0.3333) ;
|
||||
screen = screenFactor / (epsilon * (1. - epsilon));
|
||||
gReject = (ScreenFunction1(screen) - fZ) / f10 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilon = epsilonMin + epsilonRange * G4UniformRand();
|
||||
screen = screenFactor / (epsilon * (1 - epsilon));
|
||||
gReject = (ScreenFunction2(screen) - fZ) / f20 ;
|
||||
}
|
||||
} while ( gReject < G4UniformRand() );
|
||||
|
||||
} // End of epsilon sampling
|
||||
|
||||
// Fix charges randomly
|
||||
|
||||
G4double electronTotEnergy;
|
||||
G4double positronTotEnergy;
|
||||
|
||||
if (CLHEP::RandBit::shootBit())
|
||||
{
|
||||
electronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
positronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
positronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
electronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
|
||||
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev. Mod. Phys. 49, 421 (1977)
|
||||
|
||||
G4double u;
|
||||
const G4double a1 = 0.625;
|
||||
G4double a2 = 3. * a1;
|
||||
// G4double d = 27. ;
|
||||
|
||||
// if (9. / (9. + d) > G4UniformRand())
|
||||
if (0.25 > G4UniformRand())
|
||||
{
|
||||
u = - std::log(G4UniformRand() * G4UniformRand()) / a1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
u = - std::log(G4UniformRand() * G4UniformRand()) / a2 ;
|
||||
}
|
||||
|
||||
G4double thetaEle = u*electron_mass_c2/electronTotEnergy;
|
||||
G4double thetaPos = u*electron_mass_c2/positronTotEnergy;
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
|
||||
G4double dxEle= std::sin(thetaEle)*std::cos(phi),dyEle= std::sin(thetaEle)*std::sin(phi),dzEle=std::cos(thetaEle);
|
||||
G4double dxPos=-std::sin(thetaPos)*std::cos(phi),dyPos=-std::sin(thetaPos)*std::sin(phi),dzPos=std::cos(thetaPos);
|
||||
|
||||
|
||||
// Kinematics of the created pair:
|
||||
// the electron and positron are assumed to have a symetric angular
|
||||
// distribution with respect to the Z axis along the parent photon
|
||||
|
||||
G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
|
||||
|
||||
G4ThreeVector electronDirection (dxEle, dyEle, dzEle);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
|
||||
// The e+ is always created (even with kinetic energy = 0) for further annihilation
|
||||
G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
|
||||
|
||||
G4ThreeVector positronDirection (dxPos, dyPos, dzPos);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
// Fill output vector
|
||||
|
||||
fvect->push_back(particle1);
|
||||
fvect->push_back(particle2);
|
||||
|
||||
// kill incident photon
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermoreNuclearGammaConversionModel::ScreenFunction1(G4double screenVariable)
|
||||
{
|
||||
// Compute the value of the screening function 3*phi1 - phi2
|
||||
|
||||
G4double value;
|
||||
|
||||
if (screenVariable > 1.)
|
||||
value = 42.24 - 8.368 * std::log(screenVariable + 0.952);
|
||||
else
|
||||
value = 42.392 - screenVariable * (7.796 - 1.961 * screenVariable);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermoreNuclearGammaConversionModel::ScreenFunction2(G4double screenVariable)
|
||||
{
|
||||
// Compute the value of the screening function 1.5*phi1 - 0.5*phi2
|
||||
|
||||
G4double value;
|
||||
|
||||
if (screenVariable > 1.)
|
||||
value = 42.24 - 8.368 * std::log(screenVariable + 0.952);
|
||||
else
|
||||
value = 41.405 - screenVariable * (5.828 - 0.8945 * screenVariable);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LivermorePhotoElectricModel.cc,v 1.9 2009/10/23 09:31:03 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4LivermorePhotoElectricModel.cc,v 1.12 2010/10/13 07:15:42 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
//
|
||||
// Author: Sebastien Inserti
|
||||
@@ -42,7 +42,10 @@
|
||||
// 23 Oct 2009 L Pandola
|
||||
// - atomic deexcitation managed via G4VEmModel::DeexcitationFlag() is
|
||||
// set as "true" (default would be false)
|
||||
//
|
||||
// 15 Mar 2010 L Pandola
|
||||
// - removed methods to set explicitely fluorescence cuts.
|
||||
// Main cuts from G4ProductionCutsTable are always used
|
||||
//
|
||||
|
||||
#include "G4LivermorePhotoElectricModel.hh"
|
||||
|
||||
@@ -61,11 +64,7 @@ G4LivermorePhotoElectricModel::G4LivermorePhotoElectricModel(const G4ParticleDef
|
||||
highEnergyLimit = 100 * GeV;
|
||||
// SetLowEnergyLimit(lowEnergyLimit);
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
|
||||
//Set atomic deexcitation by default
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
@@ -73,6 +72,11 @@ G4LivermorePhotoElectricModel::G4LivermorePhotoElectricModel(const G4ParticleDef
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
//Set atomic deexcitation by default
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
if(verboseLevel>0) {
|
||||
G4cout << "Livermore PhotoElectric is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
@@ -124,9 +128,7 @@ G4LivermorePhotoElectricModel::Initialise(const G4ParticleDefinition*,
|
||||
G4String shellCrossSectionFile = "phot/pe-ss-cs-";
|
||||
shellCrossSectionHandler->LoadShellData(shellCrossSectionFile);
|
||||
|
||||
// SI - Simple generator is buggy
|
||||
//generatorName = "geant4.6.2";
|
||||
//ElectronAngularGenerator = new G4PhotoElectricAngularGeneratorSimple("GEANTSimpleGenerator"); // default generator
|
||||
// default generator
|
||||
ElectronAngularGenerator =
|
||||
new G4PhotoElectricAngularGeneratorSauterGavrila("GEANTSauterGavrilaGenerator");
|
||||
|
||||
@@ -297,25 +299,17 @@ G4LivermorePhotoElectricModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermorePhotoElectricModel::SetCutForLowEnSecPhotons(G4double cut)
|
||||
void G4LivermorePhotoElectricModel::ActivateAuger(G4bool augerbool)
|
||||
{
|
||||
cutForLowEnergySecondaryPhotons = cut;
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cut);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermorePhotoElectricModel::SetCutForLowEnSecElectrons(G4double cut)
|
||||
{
|
||||
cutForLowEnergySecondaryElectrons = cut;
|
||||
deexcitationManager.SetCutForAugerElectrons(cut);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermorePhotoElectricModel::ActivateAuger(G4bool val)
|
||||
{
|
||||
deexcitationManager.ActivateAugerElectronProduction(val);
|
||||
if (!DeexcitationFlag() && augerbool)
|
||||
{
|
||||
G4cout << "WARNING - G4LivermorePhotoElectricModel" << G4endl;
|
||||
G4cout << "The use of the Atomic Deexcitation Manager is set to false " << G4endl;
|
||||
G4cout << "Therefore, Auger electrons will be not generated anyway" << G4endl;
|
||||
}
|
||||
deexcitationManager.ActivateAugerElectronProduction(augerbool);
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "Auger production set to " << augerbool << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
+5
-5
@@ -131,10 +131,7 @@ void G4LivermorePolarizedGammaConversionModel::Initialise(const G4ParticleDefini
|
||||
|
||||
if(isInitialised) return;
|
||||
|
||||
if(pParticleChange)
|
||||
fParticleChange = reinterpret_cast<G4ParticleChangeForGamma*>(pParticleChange);
|
||||
else
|
||||
fParticleChange = new G4ParticleChangeForGamma();
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
|
||||
isInitialised = true;
|
||||
}
|
||||
@@ -218,7 +215,10 @@ void G4LivermorePolarizedGammaConversionModel::SampleSecondaries(std::vector<G4D
|
||||
// Select randomly one element in the current material
|
||||
|
||||
// G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
|
||||
const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
|
||||
//const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
|
||||
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* element = SelectRandomAtom(couple,particle,photonEnergy);
|
||||
|
||||
if (element == 0)
|
||||
{
|
||||
|
||||
+153
-147
@@ -49,6 +49,9 @@ G4LivermorePolarizedPhotoElectricModel::G4LivermorePolarizedPhotoElectricModel(c
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
G4cout << "Livermore Polarized PhotoElectric is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
@@ -61,7 +64,7 @@ G4LivermorePolarizedPhotoElectricModel::G4LivermorePolarizedPhotoElectricModel(c
|
||||
|
||||
G4LivermorePolarizedPhotoElectricModel::~G4LivermorePolarizedPhotoElectricModel()
|
||||
{
|
||||
if (meanFreePathTable) delete meanFreePathTable;
|
||||
// if (meanFreePathTable) delete meanFreePathTable;
|
||||
if (crossSectionHandler) delete crossSectionHandler;
|
||||
if (shellCrossSectionHandler) delete shellCrossSectionHandler;
|
||||
}
|
||||
@@ -89,22 +92,24 @@ void G4LivermorePolarizedPhotoElectricModel::Initialise(const G4ParticleDefiniti
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Energy limits
|
||||
|
||||
if (LowEnergyLimit() < lowEnergyLimit)
|
||||
{
|
||||
G4cout << "G4LivermorePolarizedPhotoElectricModel: low energy limit increased from " <<
|
||||
LowEnergyLimit()/eV << " eV to " << lowEnergyLimit << " eV" << G4endl;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
}
|
||||
|
||||
{
|
||||
G4cout << "G4LivermorePolarizedPhotoElectricModel: low energy limit increased from " <<
|
||||
LowEnergyLimit()/eV << " eV to " << lowEnergyLimit << " eV" << G4endl;
|
||||
SetLowEnergyLimit(lowEnergyLimit);
|
||||
}
|
||||
|
||||
if (HighEnergyLimit() > highEnergyLimit)
|
||||
{
|
||||
G4cout << "G4LivermorePolarizedPhotoElectricModel: high energy limit decreased from " <<
|
||||
HighEnergyLimit()/GeV << " GeV to " << highEnergyLimit << " GeV" << G4endl;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
}
|
||||
|
||||
{
|
||||
G4cout << "G4LivermorePolarizedPhotoElectricModel: high energy limit decreased from " <<
|
||||
HighEnergyLimit()/GeV << " GeV to " << highEnergyLimit << " GeV" << G4endl;
|
||||
SetHighEnergyLimit(highEnergyLimit);
|
||||
}
|
||||
*/
|
||||
|
||||
// Reading of data files - all materials are read
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler;
|
||||
@@ -113,7 +118,7 @@ void G4LivermorePolarizedPhotoElectricModel::Initialise(const G4ParticleDefiniti
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
meanFreePathTable = 0;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
// meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
|
||||
shellCrossSectionHandler = new G4CrossSectionHandler();
|
||||
shellCrossSectionHandler->Clear();
|
||||
@@ -124,7 +129,7 @@ void G4LivermorePolarizedPhotoElectricModel::Initialise(const G4ParticleDefiniti
|
||||
//
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for Livermore Polarized PhotoElectric model" << G4endl;
|
||||
|
||||
|
||||
InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
G4cout << "Livermore Polarized PhotoElectric model is initialized " << G4endl
|
||||
@@ -137,11 +142,14 @@ void G4LivermorePolarizedPhotoElectricModel::Initialise(const G4ParticleDefiniti
|
||||
|
||||
if(isInitialised) return;
|
||||
|
||||
if(pParticleChange)
|
||||
/* if(pParticleChange)
|
||||
fParticleChange = reinterpret_cast<G4ParticleChangeForGamma*>(pParticleChange);
|
||||
else
|
||||
fParticleChange = new G4ParticleChangeForGamma();
|
||||
*/
|
||||
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
@@ -178,28 +186,29 @@ void G4LivermorePolarizedPhotoElectricModel::SampleSecondaries(std::vector<G4Dyn
|
||||
G4cout << "Calling SampleSecondaries() of G4LivermorePolarizedPhotoElectricModel" << G4endl;
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
// Within energy limit?
|
||||
G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
G4ThreeVector photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
// kill incident photon
|
||||
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
// low-energy gamma is absorpted by this process
|
||||
|
||||
if(photonEnergy <= lowEnergyLimit)
|
||||
if (photonEnergy <= lowEnergyLimit)
|
||||
{
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeLocalEnergyDeposit(photonEnergy);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
|
||||
|
||||
// Protection: a polarisation parallel to the
|
||||
// direction causes problems;
|
||||
// in that case find a random polarization
|
||||
|
||||
G4ThreeVector photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
// Make sure that the polarization vector is perpendicular to the
|
||||
// gamma direction. If not
|
||||
|
||||
|
||||
if(!(gammaPolarization0.isOrthogonal(photonDirection, 1e-6))||(gammaPolarization0.mag()==0))
|
||||
{ // only for testing now
|
||||
gammaPolarization0 = GetRandomPolarization(photonDirection);
|
||||
@@ -211,14 +220,18 @@ void G4LivermorePolarizedPhotoElectricModel::SampleSecondaries(std::vector<G4Dyn
|
||||
gammaPolarization0 = GetPerpendicularPolarization(photonDirection, gammaPolarization0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// End of Protection
|
||||
|
||||
|
||||
// G4double E0_m = photonEnergy / electron_mass_c2 ;
|
||||
|
||||
// Select randomly one element in the current material
|
||||
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
|
||||
// G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
|
||||
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* elm = SelectRandomAtom(couple->GetMaterial(),particle,photonEnergy);
|
||||
G4int Z = (G4int)elm->GetZ();
|
||||
|
||||
// Select the ionised shell in the current atom according to shell cross sections
|
||||
|
||||
@@ -228,16 +241,9 @@ void G4LivermorePolarizedPhotoElectricModel::SampleSecondaries(std::vector<G4Dyn
|
||||
const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
|
||||
G4double bindingEnergy = shell->BindingEnergy();
|
||||
G4int shellId = shell->ShellId();
|
||||
|
||||
// Create lists of pointers to DynamicParticles (photons and electrons)
|
||||
// (Is the electron vector necessary? To be checked)
|
||||
std::vector<G4DynamicParticle*>* photonVector = 0;
|
||||
std::vector<G4DynamicParticle*> electronVector;
|
||||
|
||||
G4double energyDeposit = 0.0;
|
||||
|
||||
|
||||
// Primary outgoing electron
|
||||
|
||||
|
||||
G4double eKineticEnergy = photonEnergy - bindingEnergy;
|
||||
|
||||
|
||||
@@ -255,7 +261,7 @@ void G4LivermorePolarizedPhotoElectricModel::SampleSecondaries(std::vector<G4Dyn
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
eKineticEnergy);
|
||||
electronVector.push_back(electron);
|
||||
fvect->push_back(electron);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -263,113 +269,111 @@ void G4LivermorePolarizedPhotoElectricModel::SampleSecondaries(std::vector<G4Dyn
|
||||
}
|
||||
|
||||
|
||||
G4int nElectrons = electronVector.size();
|
||||
size_t nTotPhotons = 0;
|
||||
G4int nPhotons=0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t index = couple->GetIndex();
|
||||
G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
|
||||
cutg = std::min(cutForLowEnergySecondaryPhotons,cutg);
|
||||
|
||||
G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
|
||||
cute = std::min(cutForLowEnergySecondaryPhotons,cute);
|
||||
|
||||
G4DynamicParticle* aPhoton;
|
||||
|
||||
// Generation of fluorescence
|
||||
// Data in EADL are available only for Z > 5
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// shell binding energy > photon energy
|
||||
if (Z > 5 && (bindingEnergy > cutg || bindingEnergy > cute))
|
||||
{
|
||||
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
|
||||
nTotPhotons = photonVector->size();
|
||||
for (size_t k=0; k<nTotPhotons; k++)
|
||||
{
|
||||
aPhoton = (*photonVector)[k];
|
||||
if (aPhoton)
|
||||
{
|
||||
G4double itsCut = cutg;
|
||||
if(aPhoton->GetDefinition() == G4Electron::Electron()) itsCut = cute;
|
||||
|
||||
G4double itsEnergy = aPhoton->GetKineticEnergy();
|
||||
|
||||
if (itsEnergy > itsCut && itsEnergy <= bindingEnergy)
|
||||
// deexcitation
|
||||
if(DeexcitationFlag() && Z > 5) {
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t index = couple->GetIndex();
|
||||
G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
|
||||
//cutg = std::min(cutForLowEnergySecondaryPhotons,cutg);
|
||||
G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
|
||||
//cute = std::min(cutForLowEnergySecondaryPhotons,cute);
|
||||
|
||||
// G4DynamicParticle* aPhoton;
|
||||
|
||||
// Generation of fluorescence
|
||||
// Data in EADL are available only for Z > 5
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// shell binding energy > photon energy
|
||||
if (bindingEnergy > cutg || bindingEnergy > cute)
|
||||
{
|
||||
G4DynamicParticle* aPhoton;
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cutg);
|
||||
deexcitationManager.SetCutForAugerElectrons(cute);
|
||||
std::vector<G4DynamicParticle*>* photonVector =
|
||||
deexcitationManager.GenerateParticles(Z,shellId);
|
||||
size_t nTotPhotons = photonVector->size();
|
||||
for (size_t k=0; k<nTotPhotons; k++)
|
||||
{
|
||||
aPhoton = (*photonVector)[k];
|
||||
if (aPhoton)
|
||||
{
|
||||
G4double itsEnergy = aPhoton->GetKineticEnergy();
|
||||
if (itsEnergy <= bindingEnergy)
|
||||
{
|
||||
nPhotons++;
|
||||
// Local energy deposit is given as the sum of the
|
||||
// energies of incident photons minus the energies
|
||||
// of the outcoming fluorescence photons
|
||||
bindingEnergy -= itsEnergy;
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aPhoton;
|
||||
(*photonVector)[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete photonVector;
|
||||
}
|
||||
}
|
||||
// excitation energy left
|
||||
fParticleChange->ProposeLocalEnergyDeposit(bindingEnergy);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aPhoton;
|
||||
(*photonVector)[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
energyDeposit += bindingEnergy;
|
||||
// Final state
|
||||
|
||||
|
||||
for (G4int l = 0; l<nElectrons; l++ )
|
||||
{
|
||||
aPhoton = electronVector[l];
|
||||
if(aPhoton) {
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
}
|
||||
{
|
||||
aPhoton = electronVector[l];
|
||||
if(aPhoton) {
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
}
|
||||
for ( size_t ll = 0; ll < nTotPhotons; ll++)
|
||||
{
|
||||
aPhoton = (*photonVector)[ll];
|
||||
if(aPhoton) {
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
{
|
||||
aPhoton = (*photonVector)[ll];
|
||||
if(aPhoton) {
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
}
|
||||
|
||||
delete photonVector;
|
||||
|
||||
if (energyDeposit < 0)
|
||||
|
||||
delete photonVector;
|
||||
|
||||
if (energyDeposit < 0)
|
||||
{
|
||||
G4cout << "WARNING - "
|
||||
<< "G4LowEnergyPhotoElectric::PostStepDoIt - Negative energy deposit"
|
||||
<< G4endl;
|
||||
energyDeposit = 0;
|
||||
G4cout << "WARNING - "
|
||||
<< "G4LowEnergyPhotoElectric::PostStepDoIt - Negative energy deposit"
|
||||
<< G4endl;
|
||||
energyDeposit = 0;
|
||||
}
|
||||
|
||||
// kill incident photon
|
||||
|
||||
// kill incident photon
|
||||
fParticleChange->ProposeMomentumDirection( 0., 0., 0. );
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->ProposeLocalEnergyDeposit(energyDeposit);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermorePolarizedPhotoElectricModel::SetCutForLowEnSecPhotons(G4double cut)
|
||||
void G4LivermorePolarizedPhotoElectricModel::ActivateAuger(G4bool augerbool)
|
||||
{
|
||||
cutForLowEnergySecondaryPhotons = cut;
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cut);
|
||||
}
|
||||
if (!DeexcitationFlag() && augerbool)
|
||||
{
|
||||
G4cout << "WARNING - G4LivermorePolarizedPhotoElectricModel" << G4endl;
|
||||
G4cout << "The use of the Atomic Deexcitation Manager is set to false " << G4endl;
|
||||
G4cout << "Therefore, Auger electrons will be not generated anyway" << G4endl;
|
||||
}
|
||||
deexcitationManager.ActivateAugerElectronProduction(augerbool);
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "Auger production set to " << augerbool << G4endl;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermorePolarizedPhotoElectricModel::SetCutForLowEnSecElectrons(G4double cut)
|
||||
{
|
||||
cutForLowEnergySecondaryElectrons = cut;
|
||||
deexcitationManager.SetCutForAugerElectrons(cut);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermorePolarizedPhotoElectricModel::ActivateAuger(G4bool val)
|
||||
{
|
||||
deexcitationManager.ActivateAugerElectronProduction(val);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -525,29 +529,31 @@ void G4LivermorePolarizedPhotoElectricModel::SystemOfRefChange
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermorePolarizedPhotoElectricModel::GetMeanFreePath(const G4Track& track,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
// size_t materialIndex = material->GetIndex();
|
||||
|
||||
G4double meanFreePath = DBL_MAX;
|
||||
|
||||
// if (energy > highEnergyLimit)
|
||||
// meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
// else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
// else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
|
||||
G4double cross = shellCrossSectionHandler->ValueForMaterial(material,energy);
|
||||
if(cross > 0.0) meanFreePath = 1.0/cross;
|
||||
|
||||
return meanFreePath;
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
G4double G4LivermorePolarizedPhotoElectricModel::GetMeanFreePath(const G4Track& track,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
// size_t materialIndex = material->GetIndex();
|
||||
|
||||
G4double meanFreePath = DBL_MAX;
|
||||
|
||||
// if (energy > highEnergyLimit)
|
||||
// meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
// else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
// else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
|
||||
G4double cross = shellCrossSectionHandler->ValueForMaterial(material,energy);
|
||||
if(cross > 0.0) meanFreePath = 1.0/cross;
|
||||
|
||||
return meanFreePath;
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -1,102 +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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4ModifiedTsai
|
||||
//
|
||||
// Author: Andreia Trindade (andreia@lip.pt)
|
||||
// Pedro Rodrigues (psilva@lip.pt)
|
||||
// Luis Peralta (luis@lip.pt)
|
||||
//
|
||||
// Creation date: 21 March 2003
|
||||
//
|
||||
// Modifications:
|
||||
// 21 Mar 2003 A. Trindade First implementation acording with new design
|
||||
// 24 Mar 2003 & Fix in Tsai generator in order to prevent theta generation above pi
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Concrete base class for Bremsstrahlung Angular Distribution Generation - Tsai Model
|
||||
//
|
||||
// Class Description: End
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4ModifiedTsai.hh"
|
||||
#include "Randomize.hh"
|
||||
//
|
||||
|
||||
G4ModifiedTsai::G4ModifiedTsai(const G4String& name):G4VBremAngularDistribution(name)
|
||||
{;}
|
||||
|
||||
//
|
||||
|
||||
G4ModifiedTsai::~G4ModifiedTsai()
|
||||
{;}
|
||||
|
||||
//
|
||||
|
||||
G4double G4ModifiedTsai::PolarAngle(const G4double initial_energy,
|
||||
const G4double, // final_energy
|
||||
const G4int ) // Z
|
||||
{
|
||||
|
||||
// Sample gamma angle (Z - axis along the parent particle).
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993)
|
||||
// Phys211) derived from Tsai distribution (Rev Mod Phys 49,421(1977))
|
||||
|
||||
G4double totalEnergy = initial_energy + electron_mass_c2;
|
||||
|
||||
const G4double a1 = 0.625, a2 = 3.*a1, d = 27.;
|
||||
G4double u, theta = 0;
|
||||
|
||||
do{
|
||||
u = - std::log(G4UniformRand()*G4UniformRand());
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()) u /= a1;
|
||||
else u /= a2;
|
||||
|
||||
theta = u*electron_mass_c2/totalEnergy;
|
||||
}while(u > (totalEnergy*pi/electron_mass_c2));
|
||||
|
||||
return theta;
|
||||
}
|
||||
//
|
||||
|
||||
void G4ModifiedTsai::PrintGeneratorInformation() const
|
||||
{
|
||||
|
||||
G4cout << "\n" << G4endl;
|
||||
G4cout << "Bremsstrahlung Angular Generator is Modified Tsai" << G4endl;
|
||||
G4cout << "Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211)" << G4endl;
|
||||
G4cout << "Derived from Tsai distribution (Rev Mod Phys 49,421(1977)) \n" << G4endl;
|
||||
}
|
||||
+57
-23
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//$Id: G4OrlicLCrossSection.cc,v 1.6.2.2 2009/12/11 18:44:44 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
//$Id: G4OrlicLiCrossSection.cc,v 1.6 2010/11/22 18:32:00 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Haifa Ben Abdelouahed
|
||||
//
|
||||
@@ -33,6 +33,8 @@
|
||||
// -----------
|
||||
// 23 Apr 2008 H. Ben Abdelouahed 1st implementation
|
||||
// 28 Apr 2008 MGP Major revision according to a design iteration
|
||||
// 21 Apr 2009 ALF Some correction for compatibility to G4VShellCrossSection
|
||||
// and changed name to G4OrlicLiCrossSection
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// Class description:
|
||||
@@ -42,16 +44,21 @@
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4OrlicLCrossSection.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4OrlicLiCrossSection.hh"
|
||||
#include "G4Proton.hh"
|
||||
|
||||
|
||||
G4OrlicLCrossSection::G4OrlicLCrossSection()
|
||||
{ }
|
||||
G4OrlicLiCrossSection::G4OrlicLiCrossSection()
|
||||
{
|
||||
|
||||
G4OrlicLCrossSection::~G4OrlicLCrossSection()
|
||||
{ }
|
||||
transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
}
|
||||
|
||||
G4OrlicLiCrossSection::~G4OrlicLiCrossSection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//this L-CrossSection calculation method is done according to
|
||||
//I.ORLIC, C.H.SOW and S.M.TANG,International Journal of PIXE.Vol.4(1997) 217-230
|
||||
@@ -59,11 +66,15 @@ G4OrlicLCrossSection::~G4OrlicLCrossSection()
|
||||
|
||||
//*****************************************************************************************************************************************
|
||||
|
||||
G4double G4OrlicLCrossSection::CalculateL1CrossSection(G4int zTarget, G4double energyIncident)
|
||||
G4double G4OrlicLiCrossSection::CalculateL1CrossSection(G4int zTarget, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
if ( (energyIncident < 0.1*MeV) || energyIncident > 10*MeV )
|
||||
|
||||
{return 0;}
|
||||
|
||||
|
||||
|
||||
G4double massIncident;
|
||||
|
||||
@@ -93,6 +104,10 @@ G4double G4OrlicLCrossSection::CalculateL1CrossSection(G4int zTarget, G4double e
|
||||
|
||||
if ( zTarget>=14 && zTarget<=40)
|
||||
{
|
||||
|
||||
return 0;
|
||||
/*
|
||||
// parameters used for calculating total L cross section
|
||||
a0=12.5081;
|
||||
a1=0.2177;
|
||||
a2=-0.3758;
|
||||
@@ -102,7 +117,7 @@ G4double G4OrlicLCrossSection::CalculateL1CrossSection(G4int zTarget, G4double e
|
||||
a6=0.;
|
||||
a7=0.;
|
||||
a8=0.;
|
||||
a9=0.;
|
||||
a9=0.; */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -183,7 +198,7 @@ G4double G4OrlicLCrossSection::CalculateL1CrossSection(G4int zTarget, G4double e
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "ERREUR: L1 Cross-Section exist only for ZTarget between 14 and 92!!! " << G4endl;
|
||||
G4cout << "ERROR: L1 Cross-Section exist only for ZTarget between 14 and 92!!! " << G4endl;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -200,21 +215,29 @@ G4double analyticalFunction = a0 + (a1*x)+(a2*x*x)+(a3*std::pow(x,3))+(a4*std::p
|
||||
|
||||
G4double L1crossSection = std::exp(analyticalFunction)/(l1BindingEnergy*l1BindingEnergy);
|
||||
|
||||
return L1crossSection;
|
||||
|
||||
if (L1crossSection >= 0) {
|
||||
return L1crossSection * barn;
|
||||
}
|
||||
else {return 0;}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************************************************************************
|
||||
|
||||
|
||||
G4double G4OrlicLCrossSection::CalculateL2CrossSection(G4int zTarget, G4double energyIncident)
|
||||
G4double G4OrlicLiCrossSection::CalculateL2CrossSection(G4int zTarget, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
if ( (energyIncident < 0.1*MeV) || energyIncident > 10*MeV )
|
||||
|
||||
{return 0;}
|
||||
|
||||
|
||||
G4double massIncident;
|
||||
|
||||
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
|
||||
massIncident = aProtone->GetPDGMass();
|
||||
@@ -301,7 +324,7 @@ G4double G4OrlicLCrossSection::CalculateL2CrossSection(G4int zTarget, G4double e
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "ERREUR: L2 Cross-Section exist only for ZTarget between 14 and 92!!! " << G4endl;
|
||||
G4cout << "ERROR: L2 Cross-Section exist only for ZTarget between 14 and 92!!! " << G4endl;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -317,21 +340,28 @@ G4double G4OrlicLCrossSection::CalculateL2CrossSection(G4int zTarget, G4double e
|
||||
|
||||
}
|
||||
|
||||
return L2crossSection;
|
||||
if (L2crossSection >= 0) {
|
||||
return L2crossSection * barn;
|
||||
}
|
||||
else {return 0;}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************************************************************************
|
||||
|
||||
|
||||
G4double G4OrlicLCrossSection::CalculateL3CrossSection(G4int zTarget, G4double energyIncident)
|
||||
G4double G4OrlicLiCrossSection::CalculateL3CrossSection(G4int zTarget, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
if ( (energyIncident < 0.1*MeV) || energyIncident > 10*MeV )
|
||||
|
||||
{return 0;}
|
||||
|
||||
|
||||
|
||||
G4double massIncident;
|
||||
|
||||
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
|
||||
massIncident = aProtone->GetPDGMass();
|
||||
@@ -414,7 +444,7 @@ G4double G4OrlicLCrossSection::CalculateL3CrossSection(G4int zTarget, G4double e
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "ERREUR: L3 Cross-Section exist only for ZTarget between 14 and 92!!! " << G4endl;
|
||||
G4cout << "ERROR: L3 Cross-Section exist only for ZTarget between 14 and 92!!! " << G4endl;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -429,6 +459,10 @@ G4double G4OrlicLCrossSection::CalculateL3CrossSection(G4int zTarget, G4double e
|
||||
L3crossSection = std::exp(analyticalFunction)/(l3BindingEnergy*l3BindingEnergy);
|
||||
|
||||
}
|
||||
if (L3crossSection >= 0) {
|
||||
return L3crossSection * barn;
|
||||
}
|
||||
else {return 0;}
|
||||
|
||||
|
||||
return L3crossSection;
|
||||
}
|
||||
@@ -24,52 +24,103 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 21 Apr 2008 H. Abdelohauwed - 1st implementation
|
||||
// 29 Apr 2009 ALF Major Design Revision
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Class description:
|
||||
// Low Energy Electromagnetic Physics, Cross section, p ionisation, K shell
|
||||
// Further documentation available from http://www.ge.infn.it/geant4/lowE
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
//#include "G4CompositeEMDataSet.hh"
|
||||
//#include "G4ShellEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
//#include "G4VEMDataSet.hh"
|
||||
//#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4PaulKCrossSection.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
|
||||
G4PaulKCrossSection::G4PaulKCrossSection()
|
||||
{ }
|
||||
{
|
||||
|
||||
G4PaulKCrossSection::~G4PaulKCrossSection()
|
||||
{ }
|
||||
|
||||
G4double G4PaulKCrossSection::CalculateKCrossSection(G4int zTarget,G4int zIncident, G4double energyIncident)
|
||||
{
|
||||
|
||||
G4String fileName;
|
||||
interpolation = new G4LogLogInterpolation();
|
||||
|
||||
if (zIncident == 1)
|
||||
{ fileName = "kcsPaul/kcs-";}
|
||||
else
|
||||
{
|
||||
if (zIncident == 2)
|
||||
{ fileName = "kacsPaul/kacs-";}
|
||||
|
||||
/*
|
||||
G4String path = getenv("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
G4Exception("G4paulKCrossSection::G4paulKCrossSection: G4LEDATA environment variable not set");
|
||||
G4cout << path + "/kcsPaul/kcs-" << G4endl;
|
||||
*/
|
||||
|
||||
|
||||
for (G4int i=4; i<93; i++) {
|
||||
protonDataSetMap[i] = new G4EMDataSet(i,interpolation);
|
||||
protonDataSetMap[i]->LoadData("pixe/kpcsPaul/kcs-");
|
||||
}
|
||||
for (G4int i=6; i<93; i++) {
|
||||
alphaDataSetMap[i] = new G4EMDataSet(i,interpolation);
|
||||
alphaDataSetMap[i]->LoadData("pixe/kacsPaul/kacs-");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
G4PaulKCrossSection::~G4PaulKCrossSection()
|
||||
{
|
||||
|
||||
protonDataSetMap.clear();
|
||||
alphaDataSetMap.clear();
|
||||
|
||||
}
|
||||
|
||||
G4double G4PaulKCrossSection::CalculateKCrossSection(G4int zTarget,G4double massIncident, G4double energyIncident)
|
||||
{
|
||||
|
||||
G4VDataSetAlgorithm* interpolation = new G4LogLogInterpolation();
|
||||
|
||||
G4VEMDataSet* dataSet;
|
||||
|
||||
dataSet = new G4EMDataSet(zTarget,interpolation);
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
dataSet->LoadData(fileName);
|
||||
|
||||
G4double sigma = 0;
|
||||
|
||||
G4double sigma = dataSet->FindValue(energyIncident/MeV) / barn;
|
||||
|
||||
return sigma;
|
||||
if (massIncident == aProtone->GetPDGMass() )
|
||||
{
|
||||
|
||||
sigma = protonDataSetMap[zTarget]->FindValue(energyIncident/MeV);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (massIncident == aAlpha->GetPDGMass())
|
||||
{
|
||||
|
||||
sigma = alphaDataSetMap[zTarget]->FindValue(energyIncident/MeV);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "we can treat only Proton or Alpha incident particles " << G4endl;
|
||||
sigma = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sigma is in internal units (mm^2)
|
||||
return sigma;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,838 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4Penelope08ComptonModel.cc,v 1.7 2010/07/28 07:09:16 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 15 Feb 2010 L Pandola Implementation
|
||||
// 18 Mar 2010 L. Pandola Removed GetAtomsPerMolecule(), now demanded
|
||||
// to G4PenelopeOscillatorManager
|
||||
//
|
||||
#include "G4Penelope08ComptonModel.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4PenelopeOscillatorManager.hh"
|
||||
#include "G4PenelopeOscillator.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4Penelope08ComptonModel::G4Penelope08ComptonModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false),oscManager(0)
|
||||
{
|
||||
fIntrinsicLowEnergyLimit = 100.0*eV;
|
||||
fIntrinsicHighEnergyLimit = 100.0*GeV;
|
||||
// SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
|
||||
SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
|
||||
//
|
||||
oscManager = G4PenelopeOscillatorManager::GetOscillatorManager();
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
//by default, the model will use atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4Penelope08ComptonModel::~G4Penelope08ComptonModel()
|
||||
{;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08ComptonModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4Penelope08ComptonModel::Initialise()" << G4endl;
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Penelope Compton model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / keV << " keV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(isInitialised) return;
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08ComptonModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double energy,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
// Penelope model to calculate the Compton scattering cross section:
|
||||
// D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
|
||||
//
|
||||
// The cross section for Compton scattering is calculated according to the Klein-Nishina
|
||||
// formula for energy > 5 MeV.
|
||||
// For E < 5 MeV it is used a parametrization for the differential cross-section dSigma/dOmega,
|
||||
// which is integrated numerically in cos(theta), G4Penelope08ComptonModel::DifferentialCrossSection().
|
||||
// The parametrization includes the J(p)
|
||||
// distribution profiles for the atomic shells, that are tabulated from Hartree-Fock calculations
|
||||
// from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201
|
||||
//
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4Penelope08ComptonModel" << G4endl;
|
||||
SetupForMaterial(p, material, energy);
|
||||
|
||||
//Retrieve the oscillator table for this material
|
||||
G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
|
||||
|
||||
G4double cs = 0;
|
||||
|
||||
if (energy < 5*MeV) //explicit calculation for E < 5 MeV
|
||||
{
|
||||
size_t numberOfOscillators = theTable->size();
|
||||
for (size_t i=0;i<numberOfOscillators;i++)
|
||||
{
|
||||
G4PenelopeOscillator* theOsc = (*theTable)[i];
|
||||
//sum contributions coming from each oscillator
|
||||
cs += OscillatorTotalCrossSection(energy,theOsc);
|
||||
}
|
||||
}
|
||||
else //use Klein-Nishina for E>5 MeV
|
||||
cs = KleinNishinaCrossSection(energy,material);
|
||||
|
||||
//cross sections are in units of pi*classic_electr_radius^2
|
||||
cs *= pi*classic_electr_radius*classic_electr_radius;
|
||||
|
||||
//Now, cs is the cross section *per molecule*, let's calculate the
|
||||
//cross section per volume
|
||||
|
||||
G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
|
||||
G4double atPerMol = oscManager->GetAtomsPerMolecule(material);
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Material " << material->GetName() << " has " << atPerMol <<
|
||||
"atoms per molecule" << G4endl;
|
||||
|
||||
G4double moleculeDensity = 0.;
|
||||
|
||||
if (atPerMol)
|
||||
moleculeDensity = atomDensity/atPerMol;
|
||||
|
||||
G4double csvolume = cs*moleculeDensity;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Compton mean free path at " << energy/keV << " keV for material " <<
|
||||
material->GetName() << " = " << (1./csvolume)/mm << " mm" << G4endl;
|
||||
return csvolume;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
//This is a dummy method. Never inkoved by the tracking, it just issues
|
||||
//a warning if one tries to get Cross Sections per Atom via the
|
||||
//G4EmCalculator.
|
||||
G4double G4Penelope08ComptonModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
G4cout << "*** G4Penelope08ComptonModel -- WARNING ***" << G4endl;
|
||||
G4cout << "Penelope Compton model does not calculate cross section _per atom_ " << G4endl;
|
||||
G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
|
||||
G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08ComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
// Penelope model to sample the Compton scattering final state.
|
||||
// D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
|
||||
// The model determines also the original shell from which the electron is expelled,
|
||||
// in order to produce fluorescence de-excitation (from G4DeexcitationManager)
|
||||
//
|
||||
// The final state for Compton scattering is calculated according to the Klein-Nishina
|
||||
// formula for energy > 5 MeV. In this case, the Doppler broadening is negligible and
|
||||
// one can assume that the target electron is at rest.
|
||||
// For E < 5 MeV it is used the parametrization for the differential cross-section dSigma/dOmega,
|
||||
// to sample the scattering angle and the energy of the emerging electron, which is
|
||||
// G4Penelope08ComptonModel::DifferentialCrossSection(). The rejection method is
|
||||
// used to sample cos(theta). The efficiency increases monotonically with photon energy and is
|
||||
// nearly independent on the Z; typical values are 35%, 80% and 95% for 1 keV, 1 MeV and 10 MeV,
|
||||
// respectively.
|
||||
// The parametrization includes the J(p) distribution profiles for the atomic shells, that are
|
||||
// tabulated
|
||||
// from Hartree-Fock calculations from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201.
|
||||
// Doppler broadening is included.
|
||||
//
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4Penelope08ComptonModel" << G4endl;
|
||||
|
||||
G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
|
||||
if (photonEnergy0 <= fIntrinsicLowEnergyLimit)
|
||||
{
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeLocalEnergyDeposit(photonEnergy0);
|
||||
return ;
|
||||
}
|
||||
|
||||
G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
|
||||
|
||||
const G4int nmax = 64;
|
||||
G4double rn[nmax],pac[nmax];
|
||||
|
||||
G4double S=0.0;
|
||||
G4double epsilon = 0.0;
|
||||
G4double cosTheta = 1.0;
|
||||
G4double hartreeFunc = 0.0;
|
||||
G4double oscStren = 0.0;
|
||||
size_t numberOfOscillators = theTable->size();
|
||||
size_t targetOscillator = 0;
|
||||
G4double ionEnergy = 0.0*eV;
|
||||
|
||||
G4double ek = photonEnergy0/electron_mass_c2;
|
||||
G4double ek2 = 2.*ek+1.0;
|
||||
G4double eks = ek*ek;
|
||||
G4double ek1 = eks-ek2-1.0;
|
||||
|
||||
G4double taumin = 1.0/ek2;
|
||||
G4double a1 = std::log(ek2);
|
||||
G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
|
||||
|
||||
G4double TST = 0;
|
||||
G4double tau = 0.;
|
||||
|
||||
//If the incoming photon is above 5 MeV, the quicker approach based on the
|
||||
//pure Klein-Nishina formula is used
|
||||
if (photonEnergy0 > 5*MeV)
|
||||
{
|
||||
do{
|
||||
do{
|
||||
if ((a2*G4UniformRand()) < a1)
|
||||
tau = std::pow(taumin,G4UniformRand());
|
||||
else
|
||||
tau = std::sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));
|
||||
//rejection function
|
||||
TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
|
||||
}while (G4UniformRand()> TST);
|
||||
epsilon=tau;
|
||||
cosTheta = 1.0 - (1.0-tau)/(ek*tau);
|
||||
|
||||
//Target shell electrons
|
||||
TST = oscManager->GetTotalZ(material)*G4UniformRand();
|
||||
targetOscillator = numberOfOscillators-1; //last level
|
||||
S=0.0;
|
||||
G4bool levelFound = false;
|
||||
for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
|
||||
{
|
||||
S += (*theTable)[j]->GetOscillatorStrength();
|
||||
if (S > TST)
|
||||
{
|
||||
targetOscillator = j;
|
||||
levelFound = true;
|
||||
}
|
||||
}
|
||||
//check whether the level is valid
|
||||
ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
|
||||
}while((epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
|
||||
}
|
||||
else //photonEnergy0 < 5 MeV
|
||||
{
|
||||
//Incoherent scattering function for theta=PI
|
||||
G4double s0=0.0;
|
||||
G4double pzomc=0.0;
|
||||
G4double rni=0.0;
|
||||
G4double aux=0.0;
|
||||
for (size_t i=0;i<numberOfOscillators;i++)
|
||||
{
|
||||
ionEnergy = (*theTable)[i]->GetIonisationEnergy();
|
||||
if (photonEnergy0 > ionEnergy)
|
||||
{
|
||||
G4double aux = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
|
||||
hartreeFunc = (*theTable)[i]->GetHartreeFactor();
|
||||
oscStren = (*theTable)[i]->GetOscillatorStrength();
|
||||
pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
|
||||
(electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
|
||||
if (pzomc > 0)
|
||||
rni = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
|
||||
(std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
|
||||
else
|
||||
rni = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
|
||||
(std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
|
||||
s0 += oscStren*rni;
|
||||
}
|
||||
}
|
||||
//Sampling tau
|
||||
G4double cdt1 = 0.;
|
||||
do
|
||||
{
|
||||
if ((G4UniformRand()*a2) < a1)
|
||||
tau = std::pow(taumin,G4UniformRand());
|
||||
else
|
||||
tau = std::sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));
|
||||
cdt1 = (1.0-tau)/(ek*tau);
|
||||
//Incoherent scattering function
|
||||
S = 0.;
|
||||
for (size_t i=0;i<numberOfOscillators;i++)
|
||||
{
|
||||
ionEnergy = (*theTable)[i]->GetIonisationEnergy();
|
||||
if (photonEnergy0 > ionEnergy) //sum only on excitable levels
|
||||
{
|
||||
aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
|
||||
hartreeFunc = (*theTable)[i]->GetHartreeFactor();
|
||||
oscStren = (*theTable)[i]->GetOscillatorStrength();
|
||||
pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
|
||||
(electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
|
||||
if (pzomc > 0)
|
||||
rn[i] = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
|
||||
(std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
|
||||
else
|
||||
rn[i] = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
|
||||
(std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
|
||||
S += oscStren*rn[i];
|
||||
pac[i] = S;
|
||||
}
|
||||
else
|
||||
pac[i] = S-1e-6;
|
||||
}
|
||||
//Rejection function
|
||||
TST = S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
|
||||
}while ((G4UniformRand()*s0) > TST);
|
||||
|
||||
cosTheta = 1.0 - cdt1;
|
||||
G4double fpzmax=0.0,fpz=0.0;
|
||||
G4double A=0.0;
|
||||
//Target electron shell
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
TST = S*G4UniformRand();
|
||||
targetOscillator = numberOfOscillators-1; //last level
|
||||
G4bool levelFound = false;
|
||||
for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
|
||||
{
|
||||
if (pac[i]>TST)
|
||||
{
|
||||
targetOscillator = i;
|
||||
levelFound = true;
|
||||
}
|
||||
}
|
||||
A = G4UniformRand()*rn[targetOscillator];
|
||||
hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
|
||||
oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
|
||||
if (A < 0.5)
|
||||
pzomc = (std::sqrt(0.5)-std::sqrt(0.5-std::log(2.0*A)))/
|
||||
(std::sqrt(2.0)*hartreeFunc);
|
||||
else
|
||||
pzomc = (std::sqrt(0.5-std::log(2.0-2.0*A))-std::sqrt(0.5))/
|
||||
(std::sqrt(2.0)*hartreeFunc);
|
||||
} while (pzomc < -1);
|
||||
|
||||
// F(EP) rejection
|
||||
G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
|
||||
G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
|
||||
if (AF > 0)
|
||||
fpzmax = 1.0+AF*0.2;
|
||||
else
|
||||
fpzmax = 1.0-AF*0.2;
|
||||
fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
|
||||
}while ((fpzmax*G4UniformRand())>fpz);
|
||||
|
||||
//Energy of the scattered photon
|
||||
G4double T = pzomc*pzomc;
|
||||
G4double b1 = 1.0-T*tau*tau;
|
||||
G4double b2 = 1.0-T*tau*cosTheta;
|
||||
if (pzomc > 0.0)
|
||||
epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
|
||||
else
|
||||
epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
|
||||
} //energy < 5 MeV
|
||||
|
||||
//Ok, the kinematics has been calculated.
|
||||
G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sinTheta * std::cos(phi);
|
||||
G4double diry = sinTheta * std::sin(phi);
|
||||
G4double dirz = cosTheta ;
|
||||
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
G4ThreeVector photonDirection1(dirx,diry,dirz);
|
||||
photonDirection1.rotateUz(photonDirection0);
|
||||
fParticleChange->ProposeMomentumDirection(photonDirection1) ;
|
||||
|
||||
G4double photonEnergy1 = epsilon * photonEnergy0;
|
||||
|
||||
if (photonEnergy1 > 0.)
|
||||
fParticleChange->SetProposedKineticEnergy(photonEnergy1) ;
|
||||
else
|
||||
{
|
||||
fParticleChange->SetProposedKineticEnergy(0.) ;
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
}
|
||||
|
||||
//Create scattered electron
|
||||
G4double diffEnergy = photonEnergy0*(1-epsilon);
|
||||
ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
|
||||
|
||||
G4double Q2 =
|
||||
photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
|
||||
G4double cosThetaE = 0.; //scattering angle for the electron
|
||||
|
||||
if (Q2 > 1.0e-12)
|
||||
cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
|
||||
else
|
||||
cosThetaE = 1.0;
|
||||
G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
|
||||
|
||||
//Now, try to handle fluorescence
|
||||
//Notice: merged levels are indicated with Z=0 and flag=30
|
||||
G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
|
||||
G4int Z = (G4int) (*theTable)[targetOscillator]->GetParentZ();
|
||||
|
||||
//initialize here, then check photons created by Atomic-Deexcitation, and the final state e-
|
||||
std::vector<G4DynamicParticle*>* photonVector=0;
|
||||
const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
G4double bindingEnergy = 0.*eV;
|
||||
G4int shellId = 0;
|
||||
|
||||
//Real level
|
||||
if (Z > 0 && shFlag<30)
|
||||
{
|
||||
const G4AtomicShell* shell = transitionManager->Shell(Z,shFlag-1);
|
||||
bindingEnergy = shell->BindingEnergy();
|
||||
shellId = shell->ShellId();
|
||||
}
|
||||
|
||||
G4double ionEnergyInPenelopeDatabase = ionEnergy;
|
||||
//protection against energy non-conservation
|
||||
ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
|
||||
|
||||
//subtract the excitation energy. If not emitted by fluorescence
|
||||
//the ionization energy is deposited as local energy deposition
|
||||
G4double eKineticEnergy = diffEnergy - ionEnergy;
|
||||
G4double localEnergyDeposit = ionEnergy;
|
||||
G4double energyInFluorescence = 0.; //testing purposes only
|
||||
|
||||
if (eKineticEnergy < 0)
|
||||
{
|
||||
//It means that there was some problem/mismatch between the two databases.
|
||||
//Try to make it work
|
||||
//In this case available Energy (diffEnergy) < ionEnergy
|
||||
//Full residual energy is deposited locally
|
||||
localEnergyDeposit = diffEnergy;
|
||||
eKineticEnergy = 0.0;
|
||||
}
|
||||
|
||||
//the local energy deposit is what remains: part of this may be spent for fluorescence.
|
||||
if(DeexcitationFlag() && Z > 5) {
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
size_t index = couple->GetIndex();
|
||||
G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
|
||||
G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
|
||||
|
||||
// Generation of fluorescence
|
||||
// Data in EADL are available only for Z > 5
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// shell binding energy > photon energy
|
||||
if (localEnergyDeposit > cutg || localEnergyDeposit > cute)
|
||||
{
|
||||
G4DynamicParticle* aPhoton;
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cutg);
|
||||
deexcitationManager.SetCutForAugerElectrons(cute);
|
||||
|
||||
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
|
||||
if(photonVector)
|
||||
{
|
||||
size_t nPhotons = photonVector->size();
|
||||
for (size_t k=0; k<nPhotons; k++)
|
||||
{
|
||||
aPhoton = (*photonVector)[k];
|
||||
if (aPhoton)
|
||||
{
|
||||
G4double itsEnergy = aPhoton->GetKineticEnergy();
|
||||
if (itsEnergy <= localEnergyDeposit)
|
||||
{
|
||||
localEnergyDeposit -= itsEnergy;
|
||||
if (aPhoton->GetDefinition() == G4Gamma::Gamma())
|
||||
energyInFluorescence += itsEnergy;;
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aPhoton;
|
||||
(*photonVector)[k]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete photonVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Always produce explicitely the electron
|
||||
G4DynamicParticle* electron = 0;
|
||||
|
||||
G4double xEl = sinThetaE * std::cos(phi+pi);
|
||||
G4double yEl = sinThetaE * std::sin(phi+pi);
|
||||
G4double zEl = cosThetaE;
|
||||
G4ThreeVector eDirection(xEl,yEl,zEl); //electron direction
|
||||
eDirection.rotateUz(photonDirection0);
|
||||
electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
eDirection,eKineticEnergy) ;
|
||||
fvect->push_back(electron);
|
||||
|
||||
|
||||
if (localEnergyDeposit < 0)
|
||||
{
|
||||
G4cout << "WARNING-"
|
||||
<< "G4Penelope08ComptonModel::SampleSecondaries - Negative energy deposit"
|
||||
<< G4endl;
|
||||
localEnergyDeposit=0.;
|
||||
}
|
||||
fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
|
||||
|
||||
G4double electronEnergy = 0.;
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
G4cout << "Energy balance from G4Penelope08Compton" << G4endl;
|
||||
G4cout << "Incoming photon energy: " << photonEnergy0/keV << " keV" << G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
G4cout << "Scattered photon: " << photonEnergy1/keV << " keV" << G4endl;
|
||||
if (electron)
|
||||
electronEnergy = eKineticEnergy;
|
||||
G4cout << "Scattered electron " << electronEnergy/keV << " keV" << G4endl;
|
||||
G4cout << "Fluorescence: " << energyInFluorescence/keV << " keV" << G4endl;
|
||||
G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
|
||||
G4cout << "Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
|
||||
localEnergyDeposit)/keV <<
|
||||
" keV" << G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
}
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4double energyDiff = std::fabs(photonEnergy1+
|
||||
electronEnergy+energyInFluorescence+
|
||||
localEnergyDeposit-photonEnergy0);
|
||||
if (energyDiff > 0.05*keV)
|
||||
G4cout << "Warning from G4Penelope08Compton: problem with energy conservation: " <<
|
||||
(photonEnergy1+electronEnergy+energyInFluorescence+localEnergyDeposit)/keV <<
|
||||
" keV (final) vs. " <<
|
||||
photonEnergy0/keV << " keV (initial)" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08ComptonModel::DifferentialCrossSection(G4double cosTheta,G4double energy,
|
||||
G4PenelopeOscillator* osc)
|
||||
{
|
||||
//
|
||||
// Penelope model. Single differential cross section *per electron*
|
||||
// for photon Compton scattering by
|
||||
// electrons in the given atomic oscillator, differential in the direction of the
|
||||
// scattering photon. This is in units of pi*classic_electr_radius**2
|
||||
//
|
||||
// D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
|
||||
// The parametrization includes the J(p) distribution profiles for the atomic shells,
|
||||
// that are tabulated from Hartree-Fock calculations
|
||||
// from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201
|
||||
//
|
||||
G4double ionEnergy = osc->GetIonisationEnergy();
|
||||
G4double harFunc = osc->GetHartreeFactor();
|
||||
|
||||
const G4double k2 = std::sqrt(2.);
|
||||
const G4double k1 = 1./k2;
|
||||
|
||||
if (energy < ionEnergy)
|
||||
return 0;
|
||||
|
||||
//energy of the Compton line
|
||||
G4double cdt1 = 1.0-cosTheta;
|
||||
G4double EOEC = 1.0+(energy/electron_mass_c2)*cdt1;
|
||||
G4double ECOE = 1.0/EOEC;
|
||||
|
||||
//Incoherent scattering function (analytical profile)
|
||||
G4double aux = energy*(energy-ionEnergy)*cdt1;
|
||||
G4double Pzimax =
|
||||
(aux - electron_mass_c2*ionEnergy)/(electron_mass_c2*std::sqrt(2*aux+ionEnergy*ionEnergy));
|
||||
G4double sia = 0.0;
|
||||
G4double x = harFunc*Pzimax;
|
||||
if (x > 0)
|
||||
sia = 1.0-0.5*std::exp(0.5-(k1+k2*x)*(k1+k2*x));
|
||||
else
|
||||
sia = 0.5*std::exp(0.5-(k1-k2*x)*(k1-k2*x));
|
||||
|
||||
//1st order correction, integral of Pz times the Compton profile.
|
||||
//Calculated approximately using a free-electron gas profile
|
||||
G4double pf = 3.0/(4.0*harFunc);
|
||||
if (std::fabs(Pzimax) < pf)
|
||||
{
|
||||
G4double QCOE2 = 1.0+ECOE*ECOE-2.0*ECOE*cosTheta;
|
||||
G4double p2 = Pzimax*Pzimax;
|
||||
G4double dspz = std::sqrt(QCOE2)*
|
||||
(1.0+ECOE*(ECOE-cosTheta)/QCOE2)*harFunc
|
||||
*0.25*(2*p2-(p2*p2)/(pf*pf)-(pf*pf));
|
||||
sia += std::max(dspz,-1.0*sia);
|
||||
}
|
||||
|
||||
G4double XKN = EOEC+ECOE-1.0+cosTheta*cosTheta;
|
||||
|
||||
//Differential cross section (per electron, in units of pi*classic_electr_radius**2)
|
||||
G4double diffCS = ECOE*ECOE*XKN*sia;
|
||||
|
||||
return diffCS;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08ComptonModel::ActivateAuger(G4bool augerbool)
|
||||
{
|
||||
if (!DeexcitationFlag() && augerbool)
|
||||
{
|
||||
G4cout << "WARNING - G4Penelope08ComptonModel" << G4endl;
|
||||
G4cout << "The use of the Atomic Deexcitation Manager is set to false " << G4endl;
|
||||
G4cout << "Therefore, Auger electrons will be not generated anyway" << G4endl;
|
||||
}
|
||||
deexcitationManager.ActivateAugerElectronProduction(augerbool);
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "Auger production set to " << augerbool << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08ComptonModel::OscillatorTotalCrossSection(G4double energy,G4PenelopeOscillator* osc)
|
||||
{
|
||||
//Total cross section (integrated) for the given oscillator in units of
|
||||
//pi*classic_electr_radius^2
|
||||
|
||||
//Integrate differential cross section for each oscillator
|
||||
G4double stre = osc->GetOscillatorStrength();
|
||||
|
||||
// here one uses the using the 20-point
|
||||
// Gauss quadrature method with an adaptive bipartition scheme
|
||||
const G4int npoints=10;
|
||||
const G4int ncallsmax=20000;
|
||||
const G4int nst=256;
|
||||
static G4double Abscissas[10] = {7.652651133497334e-02,2.2778585114164508e-01,3.7370608871541956e-01,
|
||||
5.1086700195082710e-01,6.3605368072651503e-01,7.4633190646015079e-01,
|
||||
8.3911697182221882e-01,9.1223442825132591e-01,9.6397192727791379e-01,
|
||||
9.9312859918509492e-01};
|
||||
static G4double Weights[10] = {1.5275338713072585e-01,1.4917298647260375e-01,1.4209610931838205e-01,
|
||||
1.3168863844917663e-01,1.1819453196151842e-01,1.0193011981724044e-01,
|
||||
8.3276741576704749e-02,6.2672048334109064e-02,4.0601429800386941e-02,
|
||||
1.7614007139152118e-02};
|
||||
|
||||
G4double MaxError = 1e-5;
|
||||
//Error control
|
||||
G4double Ctol = std::min(std::max(MaxError,1e-13),1e-02);
|
||||
G4double Ptol = 0.01*Ctol;
|
||||
G4double Err=1e35;
|
||||
|
||||
//Gauss integration from -1 to 1
|
||||
G4double LowPoint = -1.0;
|
||||
G4double HighPoint = 1.0;
|
||||
|
||||
G4double h=HighPoint-LowPoint;
|
||||
G4double sumga=0.0;
|
||||
G4double a=0.5*(HighPoint-LowPoint);
|
||||
G4double b=0.5*(HighPoint+LowPoint);
|
||||
G4double c=a*Abscissas[0];
|
||||
G4double d= Weights[0]*
|
||||
(DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
|
||||
for (G4int i=2;i<=npoints;i++)
|
||||
{
|
||||
c=a*Abscissas[i-1];
|
||||
d += Weights[i-1]*
|
||||
(DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
|
||||
}
|
||||
G4int icall = 2*npoints;
|
||||
G4int LH=1;
|
||||
G4double S[nst],x[nst],sn[nst],xrn[nst];
|
||||
S[0]=d*a;
|
||||
x[0]=LowPoint;
|
||||
|
||||
G4bool loopAgain = true;
|
||||
|
||||
//Adaptive bipartition scheme
|
||||
do{
|
||||
G4double h0=h;
|
||||
h=0.5*h; //bipartition
|
||||
G4double sumr=0;
|
||||
G4int LHN=0;
|
||||
G4double si,xa,xb,xc;
|
||||
for (G4int i=1;i<=LH;i++){
|
||||
si=S[i-1];
|
||||
xa=x[i-1];
|
||||
xb=xa+h;
|
||||
xc=xa+h0;
|
||||
a=0.5*(xb-xa);
|
||||
b=0.5*(xb+xa);
|
||||
c=a*Abscissas[0];
|
||||
G4double d = Weights[0]*
|
||||
(DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
|
||||
|
||||
for (G4int j=1;j<npoints;j++)
|
||||
{
|
||||
c=a*Abscissas[j];
|
||||
d += Weights[j]*
|
||||
(DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
|
||||
}
|
||||
G4double s1=d*a;
|
||||
a=0.5*(xc-xb);
|
||||
b=0.5*(xc+xb);
|
||||
c=a*Abscissas[0];
|
||||
d=Weights[0]*
|
||||
(DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
|
||||
|
||||
for (G4int j=1;j<npoints;j++)
|
||||
{
|
||||
c=a*Abscissas[j];
|
||||
d += Weights[j]*
|
||||
(DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
|
||||
}
|
||||
G4double s2=d*a;
|
||||
icall=icall+4*npoints;
|
||||
G4double s12=s1+s2;
|
||||
if (std::abs(s12-si)<std::max(Ptol*std::abs(s12),1e-35))
|
||||
sumga += s12;
|
||||
else
|
||||
{
|
||||
sumr += s12;
|
||||
LHN += 2;
|
||||
sn[LHN-1]=s2;
|
||||
xrn[LHN-1]=xb;
|
||||
sn[LHN-2]=s1;
|
||||
xrn[LHN-2]=xa;
|
||||
}
|
||||
|
||||
if (icall>ncallsmax || LHN>nst)
|
||||
{
|
||||
G4cout << "G4Penelope08ComptonModel: " << G4endl;
|
||||
G4cout << "LowPoint: " << LowPoint << ", High Point: " << HighPoint << G4endl;
|
||||
G4cout << "Tolerance: " << MaxError << G4endl;
|
||||
G4cout << "Calls: " << icall << ", Integral: " << sumga << ", Error: " << Err << G4endl;
|
||||
G4cout << "Number of open subintervals: " << LHN << G4endl;
|
||||
G4cout << "WARNING: the required accuracy has not been attained" << G4endl;
|
||||
loopAgain = false;
|
||||
}
|
||||
}
|
||||
Err=std::abs(sumr)/std::max(std::abs(sumr+sumga),1e-35);
|
||||
if (Err < Ctol || LHN == 0)
|
||||
loopAgain = false; //end of cycle
|
||||
LH=LHN;
|
||||
for (G4int i=0;i<LH;i++)
|
||||
{
|
||||
S[i]=sn[i];
|
||||
x[i]=xrn[i];
|
||||
}
|
||||
}while(Ctol < 1.0 && loopAgain);
|
||||
|
||||
|
||||
G4double xs = stre*sumga;
|
||||
|
||||
return xs;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08ComptonModel::KleinNishinaCrossSection(G4double energy,
|
||||
const G4Material* material)
|
||||
{
|
||||
// use Klein-Nishina formula
|
||||
// total cross section in units of pi*classic_electr_radius^2
|
||||
|
||||
G4double cs = 0;
|
||||
|
||||
G4double ek =energy/electron_mass_c2;
|
||||
G4double eks = ek*ek;
|
||||
G4double ek2 = 1.0+ek+ek;
|
||||
G4double ek1 = eks-ek2-1.0;
|
||||
|
||||
G4double t0 = 1.0/ek2;
|
||||
G4double csl = 0.5*eks*t0*t0+ek2*t0+ek1*std::log(t0)-(1.0/t0);
|
||||
|
||||
G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
|
||||
|
||||
for (size_t i=0;i<theTable->size();i++)
|
||||
{
|
||||
G4PenelopeOscillator* theOsc = (*theTable)[i];
|
||||
G4double ionEnergy = theOsc->GetIonisationEnergy();
|
||||
G4double tau=(energy-ionEnergy)/energy;
|
||||
if (tau > t0)
|
||||
{
|
||||
G4double csu = 0.5*eks*tau*tau+ek2*tau+ek1*std::log(tau)-(1.0/tau);
|
||||
G4double stre = theOsc->GetOscillatorStrength();
|
||||
|
||||
cs += stre*(csu-csl);
|
||||
}
|
||||
}
|
||||
|
||||
cs /= (ek*eks);
|
||||
|
||||
return cs;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,614 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4Penelope08GammaConversionModel.cc,v 1.4 2010/07/28 07:09:16 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 13 Jan 2010 L Pandola First implementation (updated to Penelope08)
|
||||
//
|
||||
|
||||
#include "G4Penelope08GammaConversionModel.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4PhysicsFreeVector.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4Penelope08GammaConversionModel::G4Penelope08GammaConversionModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),logAtomicCrossSection(0),fEffectiveCharge(0),fMaterialInvScreeningRadius(0),
|
||||
fScreeningFunction(0),isInitialised(false)
|
||||
{
|
||||
fIntrinsicLowEnergyLimit = 2.0*electron_mass_c2;
|
||||
fIntrinsicHighEnergyLimit = 100.0*GeV;
|
||||
fSmallEnergy = 1.1*MeV;
|
||||
InitializeScreeningRadii();
|
||||
|
||||
// SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
|
||||
SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
|
||||
//
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4Penelope08GammaConversionModel::~G4Penelope08GammaConversionModel()
|
||||
{
|
||||
std::map <const G4int,G4PhysicsFreeVector*>::iterator i;
|
||||
if (logAtomicCrossSection)
|
||||
{
|
||||
for (i=logAtomicCrossSection->begin();i != logAtomicCrossSection->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete logAtomicCrossSection;
|
||||
}
|
||||
if (fEffectiveCharge)
|
||||
delete fEffectiveCharge;
|
||||
if (fMaterialInvScreeningRadius)
|
||||
delete fMaterialInvScreeningRadius;
|
||||
if (fScreeningFunction)
|
||||
delete fScreeningFunction;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08GammaConversionModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4Penelope08GammaConversionModel::Initialise()" << G4endl;
|
||||
|
||||
// logAtomicCrossSection is created only once, since it is never cleared
|
||||
if (!logAtomicCrossSection)
|
||||
logAtomicCrossSection = new std::map<const G4int,G4PhysicsFreeVector*>;
|
||||
|
||||
//delete old material data...
|
||||
if (fEffectiveCharge)
|
||||
{
|
||||
delete fEffectiveCharge;
|
||||
fEffectiveCharge = 0;
|
||||
}
|
||||
if (fMaterialInvScreeningRadius)
|
||||
{
|
||||
delete fMaterialInvScreeningRadius;
|
||||
fMaterialInvScreeningRadius = 0;
|
||||
}
|
||||
if (fScreeningFunction)
|
||||
{
|
||||
delete fScreeningFunction;
|
||||
fScreeningFunction = 0;
|
||||
}
|
||||
//and create new ones
|
||||
fEffectiveCharge = new std::map<const G4Material*,G4double>;
|
||||
fMaterialInvScreeningRadius = new std::map<const G4Material*,G4double>;
|
||||
fScreeningFunction = new std::map<const G4Material*,std::pair<G4double,G4double> >;
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Penelope Gamma Conversion model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / MeV << " MeV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(isInitialised) return;
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08GammaConversionModel::ComputeCrossSectionPerAtom(
|
||||
const G4ParticleDefinition*,
|
||||
G4double energy,
|
||||
G4double Z, G4double,
|
||||
G4double, G4double)
|
||||
{
|
||||
//
|
||||
// Penelope model.
|
||||
// Cross section (including triplet production) read from database and managed
|
||||
// through the G4CrossSectionHandler utility. Cross section data are from
|
||||
// M.J. Berger and J.H. Hubbel (XCOM), Report NBSIR 887-3598
|
||||
//
|
||||
|
||||
if (energy < fIntrinsicLowEnergyLimit)
|
||||
return 0;
|
||||
|
||||
G4int iZ = (G4int) Z;
|
||||
|
||||
//read data files
|
||||
if (!logAtomicCrossSection->count(iZ))
|
||||
ReadDataFile(iZ);
|
||||
//now it should be ok
|
||||
if (!logAtomicCrossSection->count(iZ))
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08GammaConversion::ComputeCrossSectionPerAtom"
|
||||
<< G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
|
||||
G4double cs = 0;
|
||||
G4double logene = std::log(energy);
|
||||
G4PhysicsFreeVector* theVec = logAtomicCrossSection->find(iZ)->second;
|
||||
|
||||
G4double logXS = theVec->Value(logene);
|
||||
cs = std::exp(logXS);
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Gamma conversion cross section at " << energy/MeV << " MeV for Z=" << Z <<
|
||||
" = " << cs/barn << " barn" << G4endl;
|
||||
return cs;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void
|
||||
G4Penelope08GammaConversionModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
//
|
||||
// Penelope model.
|
||||
// Final state is sampled according to the Bethe-Heitler model with Coulomb
|
||||
// corrections, according to the semi-empirical model of
|
||||
// J. Baro' et al., Radiat. Phys. Chem. 44 (1994) 531.
|
||||
//
|
||||
// The model uses the high energy Coulomb correction from
|
||||
// H. Davies et al., Phys. Rev. 93 (1954) 788
|
||||
// and atomic screening radii tabulated from
|
||||
// J.H. Hubbel et al., J. Phys. Chem. Ref. Data 9 (1980) 1023
|
||||
// for Z= 1 to 92.
|
||||
//
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SamplingSecondaries() of G4Penelope08GammaConversionModel" << G4endl;
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
|
||||
// Always kill primary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
|
||||
if (photonEnergy <= fIntrinsicLowEnergyLimit)
|
||||
{
|
||||
fParticleChange->ProposeLocalEnergyDeposit(photonEnergy);
|
||||
return ;
|
||||
}
|
||||
|
||||
G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
const G4Material* mat = couple->GetMaterial();
|
||||
|
||||
//check if material data are available
|
||||
if (!fEffectiveCharge->count(mat))
|
||||
InitializeScreeningFunctions(mat);
|
||||
if (!fEffectiveCharge->count(mat))
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08GammaConversion::SampleSecondaries()" << G4endl;
|
||||
G4cout << "Unable to allocate the EffectiveCharge data" << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
|
||||
// eps is the fraction of the photon energy assigned to e- (including rest mass)
|
||||
G4double eps = 0;
|
||||
G4double eki = electron_mass_c2/photonEnergy;
|
||||
|
||||
//Do it fast for photon energy < 1.1 MeV (close to threshold)
|
||||
if (photonEnergy < fSmallEnergy)
|
||||
eps = eki + (1.0-2.0*eki)*G4UniformRand();
|
||||
else
|
||||
{
|
||||
//Complete calculation
|
||||
G4double effC = fEffectiveCharge->find(mat)->second;
|
||||
G4double alz = effC*fine_structure_const;
|
||||
G4double T = std::sqrt(2.0*eki);
|
||||
G4double F00=(-1.774-1.210e1*alz+1.118e1*alz*alz)*T
|
||||
+(8.523+7.326e1*alz-4.441e1*alz*alz)*T*T
|
||||
-(1.352e1+1.211e2*alz-9.641e1*alz*alz)*T*T*T
|
||||
+(8.946+6.205e1*alz-6.341e1*alz*alz)*T*T*T*T;
|
||||
|
||||
G4double F0b = fScreeningFunction->find(mat)->second.second;
|
||||
G4double g0 = F0b + F00;
|
||||
G4double invRad = fMaterialInvScreeningRadius->find(mat)->second;
|
||||
G4double bmin = 4.0*eki/invRad;
|
||||
std::pair<G4double,G4double> scree = GetScreeningFunctions(bmin);
|
||||
G4double g1 = scree.first;
|
||||
G4double g2 = scree.second;
|
||||
G4double g1min = g1+g0;
|
||||
G4double g2min = g2+g0;
|
||||
G4double xr = 0.5-eki;
|
||||
G4double a1 = 2.*g1min*xr*xr/3.;
|
||||
G4double p1 = a1/(a1+g2min);
|
||||
|
||||
G4bool loopAgain = false;
|
||||
//Random sampling of eps
|
||||
do{
|
||||
loopAgain = false;
|
||||
if (G4UniformRand() <= p1)
|
||||
{
|
||||
G4double ru2m1 = 2.0*G4UniformRand()-1.0;
|
||||
if (ru2m1 < 0)
|
||||
eps = 0.5-xr*std::pow(std::abs(ru2m1),1./3.);
|
||||
else
|
||||
eps = 0.5+xr*std::pow(ru2m1,1./3.);
|
||||
G4double B = eki/(invRad*eps*(1.0-eps));
|
||||
scree = GetScreeningFunctions(B);
|
||||
g1 = scree.first;
|
||||
g1 = std::max(g1+g0,0.);
|
||||
if (G4UniformRand()*g1min > g1)
|
||||
loopAgain = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
eps = eki+2.0*xr*G4UniformRand();
|
||||
G4double B = eki/(invRad*eps*(1.0-eps));
|
||||
scree = GetScreeningFunctions(B);
|
||||
g2 = scree.second;
|
||||
g2 = std::max(g2+g0,0.);
|
||||
if (G4UniformRand()*g2min > g2)
|
||||
loopAgain = true;
|
||||
}
|
||||
}while(loopAgain);
|
||||
|
||||
}
|
||||
if (verboseLevel > 4)
|
||||
G4cout << "Sampled eps = " << eps << G4endl;
|
||||
|
||||
G4double electronTotEnergy = eps*photonEnergy;
|
||||
G4double positronTotEnergy = (1.0-eps)*photonEnergy;
|
||||
|
||||
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
|
||||
//electron kinematics
|
||||
G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
G4double costheta_el = G4UniformRand()*2.0-1.0;
|
||||
G4double kk = std::sqrt(electronKineEnergy*(electronKineEnergy+2.*electron_mass_c2));
|
||||
costheta_el = (costheta_el*electronTotEnergy+kk)/(electronTotEnergy+costheta_el*kk);
|
||||
G4double phi_el = twopi * G4UniformRand() ;
|
||||
G4double dirX_el = std::sqrt(1.-costheta_el*costheta_el) * std::cos(phi_el);
|
||||
G4double dirY_el = std::sqrt(1.-costheta_el*costheta_el) * std::sin(phi_el);
|
||||
G4double dirZ_el = costheta_el;
|
||||
|
||||
//positron kinematics
|
||||
G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
G4double costheta_po = G4UniformRand()*2.0-1.0;
|
||||
kk = std::sqrt(positronKineEnergy*(positronKineEnergy+2.*electron_mass_c2));
|
||||
costheta_po = (costheta_po*positronTotEnergy+kk)/(positronTotEnergy+costheta_po*kk);
|
||||
G4double phi_po = twopi * G4UniformRand() ;
|
||||
G4double dirX_po = std::sqrt(1.-costheta_po*costheta_po) * std::cos(phi_po);
|
||||
G4double dirY_po = std::sqrt(1.-costheta_po*costheta_po) * std::sin(phi_po);
|
||||
G4double dirZ_po = costheta_po;
|
||||
|
||||
// Kinematics of the created pair:
|
||||
// the electron and positron are assumed to have a symetric angular
|
||||
// distribution with respect to the Z axis along the parent photon
|
||||
G4double localEnergyDeposit = 0. ;
|
||||
|
||||
if (electronKineEnergy > 0.0)
|
||||
{
|
||||
G4ThreeVector electronDirection ( dirX_el, dirY_el, dirZ_el);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
fvect->push_back(electron);
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += electronKineEnergy;
|
||||
electronKineEnergy = 0;
|
||||
}
|
||||
|
||||
//Generate the positron. Real particle in any case, because it will annihilate. If below
|
||||
//threshold, produce it at rest
|
||||
if (positronKineEnergy < 0.0)
|
||||
{
|
||||
localEnergyDeposit += positronKineEnergy;
|
||||
positronKineEnergy = 0; //produce it at rest
|
||||
}
|
||||
G4ThreeVector positronDirection(dirX_po,dirY_po,dirZ_po);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
G4DynamicParticle* positron = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
fvect->push_back(positron);
|
||||
|
||||
//Add rest of energy to the local energy deposit
|
||||
fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
|
||||
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
G4cout << "Energy balance from G4Penelope08GammaConversion" << G4endl;
|
||||
G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
if (electronKineEnergy)
|
||||
G4cout << "Electron (explicitely produced) " << electronKineEnergy/keV << " keV"
|
||||
<< G4endl;
|
||||
if (positronKineEnergy)
|
||||
G4cout << "Positron (not at rest) " << positronKineEnergy/keV << " keV" << G4endl;
|
||||
G4cout << "Rest masses of e+/- " << 2.0*electron_mass_c2/keV << " keV" << G4endl;
|
||||
if (localEnergyDeposit)
|
||||
G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
|
||||
G4cout << "Total final state: " << (electronKineEnergy+positronKineEnergy+
|
||||
localEnergyDeposit+2.0*electron_mass_c2)/keV <<
|
||||
" keV" << G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
}
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4double energyDiff = std::fabs(electronKineEnergy+positronKineEnergy+
|
||||
localEnergyDeposit+2.0*electron_mass_c2-photonEnergy);
|
||||
if (energyDiff > 0.05*keV)
|
||||
G4cout << "Warning from G4Penelope08GammaConversion: problem with energy conservation: "
|
||||
<< (electronKineEnergy+positronKineEnergy+
|
||||
localEnergyDeposit+2.0*electron_mass_c2)/keV
|
||||
<< " keV (final) vs. " << photonEnergy/keV << " keV (initial)" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08GammaConversionModel::ReadDataFile(const G4int Z)
|
||||
{
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "G4Penelope08GammaConversionModel::ReadDataFile()" << G4endl;
|
||||
G4cout << "Going to read Gamma Conversion data files for Z=" << Z << G4endl;
|
||||
}
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep =
|
||||
"G4Penelope08GammaConversionModel - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
/*
|
||||
Read the cross section file
|
||||
*/
|
||||
std::ostringstream ost;
|
||||
if (Z>9)
|
||||
ost << path << "/penelope/pairproduction/pdgpp" << Z << ".p08";
|
||||
else
|
||||
ost << path << "/penelope/pairproduction/pdgpp0" << Z << ".p08";
|
||||
std::ifstream file(ost.str().c_str());
|
||||
if (!file.is_open())
|
||||
{
|
||||
G4String excep = "G4Penelope08GammaConversionModel - data file " +
|
||||
G4String(ost.str()) + " not found!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
//I have to know in advance how many points are in the data list
|
||||
//to initialize the G4PhysicsFreeVector()
|
||||
size_t ndata=0;
|
||||
G4String line;
|
||||
while( getline(file, line) )
|
||||
ndata++;
|
||||
ndata -= 1; //remove one header line
|
||||
//G4cout << "Found: " << ndata << " lines" << G4endl;
|
||||
|
||||
file.clear();
|
||||
file.close();
|
||||
file.open(ost.str().c_str());
|
||||
G4int readZ =0;
|
||||
file >> readZ;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Element Z=" << Z << G4endl;
|
||||
|
||||
//check the right file is opened.
|
||||
if (readZ != Z)
|
||||
{
|
||||
G4cout << "G4Penelope08GammaConversionModel::ReadDataFile()" << G4endl;
|
||||
G4cout << "Corrupted data file for Z=" << Z << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
|
||||
G4PhysicsFreeVector* theVec = new G4PhysicsFreeVector(ndata);
|
||||
G4double ene=0,xs=0;
|
||||
for (size_t i=0;i<ndata;i++)
|
||||
{
|
||||
file >> ene >> xs;
|
||||
//dimensional quantities
|
||||
ene *= eV;
|
||||
xs *= barn;
|
||||
if (xs < 1e-40*cm2) //protection against log(0)
|
||||
xs = 1e-40*cm2;
|
||||
theVec->PutValue(i,std::log(ene),std::log(xs));
|
||||
}
|
||||
file.close();
|
||||
|
||||
if (!logAtomicCrossSection)
|
||||
{
|
||||
G4cout << "G4Penelope08RayleighModel::ReadDataFile()" << G4endl;
|
||||
G4cout << "Problem with allocation of logAtomicCrossSection data table " << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
logAtomicCrossSection->insert(std::make_pair(Z,theVec));
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08GammaConversionModel::InitializeScreeningRadii()
|
||||
{
|
||||
G4double temp[99] = {1.2281e+02,7.3167e+01,6.9228e+01,6.7301e+01,6.4696e+01,
|
||||
6.1228e+01,5.7524e+01,5.4033e+01,5.0787e+01,4.7851e+01,4.6373e+01,
|
||||
4.5401e+01,4.4503e+01,4.3815e+01,4.3074e+01,4.2321e+01,4.1586e+01,
|
||||
4.0953e+01,4.0524e+01,4.0256e+01,3.9756e+01,3.9144e+01,3.8462e+01,
|
||||
3.7778e+01,3.7174e+01,3.6663e+01,3.5986e+01,3.5317e+01,3.4688e+01,
|
||||
3.4197e+01,3.3786e+01,3.3422e+01,3.3068e+01,3.2740e+01,3.2438e+01,
|
||||
3.2143e+01,3.1884e+01,3.1622e+01,3.1438e+01,3.1142e+01,3.0950e+01,
|
||||
3.0758e+01,3.0561e+01,3.0285e+01,3.0097e+01,2.9832e+01,2.9581e+01,
|
||||
2.9411e+01,2.9247e+01,2.9085e+01,2.8930e+01,2.8721e+01,2.8580e+01,
|
||||
2.8442e+01,2.8312e+01,2.8139e+01,2.7973e+01,2.7819e+01,2.7675e+01,
|
||||
2.7496e+01,2.7285e+01,2.7093e+01,2.6911e+01,2.6705e+01,2.6516e+01,
|
||||
2.6304e+01,2.6108e+01,2.5929e+01,2.5730e+01,2.5577e+01,2.5403e+01,
|
||||
2.5245e+01,2.5100e+01,2.4941e+01,2.4790e+01,2.4655e+01,2.4506e+01,
|
||||
2.4391e+01,2.4262e+01,2.4145e+01,2.4039e+01,2.3922e+01,2.3813e+01,
|
||||
2.3712e+01,2.3621e+01,2.3523e+01,2.3430e+01,2.3331e+01,2.3238e+01,
|
||||
2.3139e+01,2.3048e+01,2.2967e+01,2.2833e+01,2.2694e+01,2.2624e+01,
|
||||
2.2545e+01,2.2446e+01,2.2358e+01,2.2264e+01};
|
||||
|
||||
//copy temporary vector in class data member
|
||||
for (G4int i=0;i<99;i++)
|
||||
fAtomicScreeningRadius[i] = temp[i];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08GammaConversionModel::InitializeScreeningFunctions(const G4Material* material)
|
||||
{
|
||||
// This is subroutine GPPa0 of Penelope
|
||||
//
|
||||
// 1) calculate the effective Z for the purpose
|
||||
//
|
||||
G4double zeff = 0;
|
||||
G4int intZ = 0;
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
|
||||
//avoid calculations if only one building element!
|
||||
if (nElements == 1)
|
||||
{
|
||||
zeff = (*elementVector)[0]->GetZ();
|
||||
intZ = (G4int) zeff;
|
||||
}
|
||||
else // many elements...let's do the calculation
|
||||
{
|
||||
const G4double* fractionVector = material->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double atot = 0;
|
||||
for (G4int i=0;i<nElements;i++)
|
||||
{
|
||||
G4double Zelement = (*elementVector)[i]->GetZ();
|
||||
G4double Aelement = (*elementVector)[i]->GetA();
|
||||
atot += Aelement*fractionVector[i];
|
||||
zeff += Zelement*Aelement*fractionVector[i]; //average with the number of nuclei
|
||||
}
|
||||
atot /= material->GetTotNbOfAtomsPerVolume();
|
||||
zeff /= (material->GetTotNbOfAtomsPerVolume()*atot);
|
||||
|
||||
intZ = (G4int) (zeff+0.25);
|
||||
if (intZ <= 0)
|
||||
intZ = 1;
|
||||
if (intZ > 99)
|
||||
intZ = 99;
|
||||
}
|
||||
|
||||
if (fEffectiveCharge)
|
||||
fEffectiveCharge->insert(std::make_pair(material,zeff));
|
||||
|
||||
//
|
||||
// 2) Calculate Coulomb Correction
|
||||
//
|
||||
G4double alz = fine_structure_const*zeff;
|
||||
G4double alzSquared = alz*alz;
|
||||
G4double fc = alzSquared*(0.202059-alzSquared*
|
||||
(0.03693-alzSquared*
|
||||
(0.00835-alzSquared*(0.00201-alzSquared*
|
||||
(0.00049-alzSquared*
|
||||
(0.00012-alzSquared*0.00003)))))
|
||||
+1.0/(alzSquared+1.0));
|
||||
//
|
||||
// 3) Screening functions and low-energy corrections
|
||||
//
|
||||
G4double matRadius = 2.0/ fAtomicScreeningRadius[intZ-1];
|
||||
if (fMaterialInvScreeningRadius)
|
||||
fMaterialInvScreeningRadius->insert(std::make_pair(material,matRadius));
|
||||
|
||||
std::pair<G4double,G4double> myPair(0,0);
|
||||
G4double f0a = 4.0*std::log(fAtomicScreeningRadius[intZ-1]);
|
||||
G4double f0b = f0a - 4.0*fc;
|
||||
myPair.first = f0a;
|
||||
myPair.second = f0b;
|
||||
|
||||
if (fScreeningFunction)
|
||||
fScreeningFunction->insert(std::make_pair(material,myPair));
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "Average Z for material " << material->GetName() << " = " <<
|
||||
zeff << G4endl;
|
||||
G4cout << "Effective radius for material " << material->GetName() << " = " <<
|
||||
fAtomicScreeningRadius[intZ-1] << " m_e*c/hbar --> BCB = " <<
|
||||
matRadius << G4endl;
|
||||
G4cout << "Screening parameters F0 for material " << material->GetName() << " = " <<
|
||||
f0a << "," << f0b << G4endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
std::pair<G4double,G4double>
|
||||
G4Penelope08GammaConversionModel::GetScreeningFunctions(G4double B)
|
||||
{
|
||||
// This is subroutine SCHIFF of Penelope
|
||||
//
|
||||
// Screening Functions F1(B) and F2(B) in the Bethe-Heitler differential cross
|
||||
// section for pair production
|
||||
//
|
||||
std::pair<G4double,G4double> result(0.,0.);
|
||||
G4double BSquared = B*B;
|
||||
G4double f1 = 2.0-2.0*std::log(1.0+BSquared);
|
||||
G4double f2 = f1 - 6.66666666e-1; // (-2/3)
|
||||
if (B < 1.0e-10)
|
||||
f1 = f1-twopi*B;
|
||||
else
|
||||
{
|
||||
G4double a0 = 4.0*B*std::atan(1./B);
|
||||
f1 = f1 - a0;
|
||||
f2 += 2.0*BSquared*(4.0-a0-3.0*std::log((1.0+BSquared)/BSquared));
|
||||
}
|
||||
G4double g1 = 0.5*(3.0*f1-f2);
|
||||
G4double g2 = 0.25*(3.0*f1+f2);
|
||||
|
||||
result.first = g1;
|
||||
result.second = g2;
|
||||
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,674 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4Penelope08PhotoElectricModel.cc,v 1.5 2010/07/28 07:09:16 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 08 Jan 2010 L Pandola First implementation
|
||||
|
||||
#include "G4Penelope08PhotoElectricModel.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4PhysicsFreeVector.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4Penelope08PhotoElectricModel::G4Penelope08PhotoElectricModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false),logAtomicShellXS(0)
|
||||
{
|
||||
fIntrinsicLowEnergyLimit = 100.0*eV;
|
||||
fIntrinsicHighEnergyLimit = 100.0*GeV;
|
||||
// SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
|
||||
SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
|
||||
//
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
//by default the model will inkove the atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4Penelope08PhotoElectricModel::~G4Penelope08PhotoElectricModel()
|
||||
{
|
||||
std::map <const G4int,G4PhysicsTable*>::iterator i;
|
||||
if (logAtomicShellXS)
|
||||
{
|
||||
for (i=logAtomicShellXS->begin();i != logAtomicShellXS->end();i++)
|
||||
{
|
||||
G4PhysicsTable* tab = i->second;
|
||||
tab->clearAndDestroy();
|
||||
delete tab;
|
||||
}
|
||||
}
|
||||
delete logAtomicShellXS;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08PhotoElectricModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4Penelope08PhotoElectricModel::Initialise()" << G4endl;
|
||||
|
||||
// logAtomicShellXS is created only once, since it is never cleared
|
||||
if (!logAtomicShellXS)
|
||||
logAtomicShellXS = new std::map<const G4int,G4PhysicsTable*>;
|
||||
|
||||
InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "Penelope Photo-Electric model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / MeV << " MeV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(isInitialised) return;
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08PhotoElectricModel::ComputeCrossSectionPerAtom(
|
||||
const G4ParticleDefinition*,
|
||||
G4double energy,
|
||||
G4double Z, G4double,
|
||||
G4double, G4double)
|
||||
{
|
||||
//
|
||||
// Penelope model.
|
||||
//
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling ComputeCrossSectionPerAtom() of G4Penelope08PhotoElectricModel" << G4endl;
|
||||
|
||||
G4int iZ = (G4int) Z;
|
||||
|
||||
//read data files
|
||||
if (!logAtomicShellXS->count(iZ))
|
||||
ReadDataFile(iZ);
|
||||
//now it should be ok
|
||||
if (!logAtomicShellXS->count(iZ))
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08PhotoElectricModel::ComputeCrossSectionPerAtom"
|
||||
<< G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
|
||||
G4double cross = 0;
|
||||
|
||||
G4PhysicsTable* theTable = logAtomicShellXS->find(iZ)->second;
|
||||
G4PhysicsFreeVector* totalXSLog = (G4PhysicsFreeVector*) (*theTable)[0];
|
||||
|
||||
if (!totalXSLog)
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08PhotoElectricModel::ComputeCrossSectionPerAtom"
|
||||
<< G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
G4double logene = std::log(energy);
|
||||
G4double logXS = totalXSLog->Value(logene);
|
||||
cross = std::exp(logXS);
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Photoelectric cross section at " << energy/MeV << " MeV for Z=" << Z <<
|
||||
" = " << cross/barn << " barn" << G4endl;
|
||||
return cross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08PhotoElectricModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
//
|
||||
// Photoelectric effect, Penelope model
|
||||
//
|
||||
// The target atom and the target shell are sampled according to the Livermore
|
||||
// database
|
||||
// D.E. Cullen et al., Report UCRL-50400 (1989)
|
||||
// The angular distribution of the electron in the final state is sampled
|
||||
// according to the Sauter distribution from
|
||||
// F. Sauter, Ann. Phys. 11 (1931) 454
|
||||
// The energy of the final electron is given by the initial photon energy minus
|
||||
// the binding energy. Fluorescence de-excitation is subsequently produced
|
||||
// (to fill the vacancy) according to the general Geant4 G4DeexcitationManager:
|
||||
// J. Stepanek, Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SamplingSecondaries() of G4Penelope08PhotoElectricModel" << G4endl;
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
|
||||
// always kill primary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
|
||||
if (photonEnergy <= fIntrinsicLowEnergyLimit)
|
||||
{
|
||||
fParticleChange->ProposeLocalEnergyDeposit(photonEnergy);
|
||||
return ;
|
||||
}
|
||||
|
||||
G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element in the current material
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Going to select element in " << couple->GetMaterial()->GetName() << G4endl;
|
||||
|
||||
// atom can be selected efficiently if element selectors are initialised
|
||||
const G4Element* anElement =
|
||||
SelectRandomAtom(couple,G4Gamma::GammaDefinition(),photonEnergy);
|
||||
G4int Z = (G4int) anElement->GetZ();
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Selected " << anElement->GetName() << G4endl;
|
||||
|
||||
// Select the ionised shell in the current atom according to shell cross sections
|
||||
//shellIndex = 0 --> K shell
|
||||
// 1-3 --> L shells
|
||||
// 4-8 --> M shells
|
||||
// 9 --> outer shells cumulatively
|
||||
//
|
||||
size_t shellIndex = SelectRandomShell(Z,photonEnergy);
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Selected shell " << shellIndex << " of element " << anElement->GetName() << G4endl;
|
||||
|
||||
// Retrieve the corresponding identifier and binding energy of the selected shell
|
||||
const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
//The number of shell cross section possibly reported in the Penelope database
|
||||
//might be different from the number of shells in the G4AtomicTransitionManager
|
||||
//(namely, Penelope may contain more shell, especially for very light elements).
|
||||
//In order to avoid a warning message from the G4AtomicTransitionManager, I
|
||||
//add this protection. Results are anyway changed, because when G4AtomicTransitionManager
|
||||
//has a shellID>maxID, it sets the shellID to the last valid shell.
|
||||
size_t numberOfShells = (size_t) transitionManager->NumberOfShells(Z);
|
||||
if (shellIndex >= numberOfShells)
|
||||
shellIndex = numberOfShells-1;
|
||||
|
||||
const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
|
||||
G4double bindingEnergy = shell->BindingEnergy();
|
||||
G4int shellId = shell->ShellId();
|
||||
|
||||
//Penelope considers only K, L and M shells. Cross sections of outer shells are
|
||||
//not included in the Penelope database. If SelectRandomShell() returns
|
||||
//shellIndex = 9, it means that an outer shell was ionized. In this case the
|
||||
//Penelope recipe is to set bindingEnergy = 0 (the energy is entirely assigned
|
||||
//to the electron) and to disregard fluorescence.
|
||||
if (shellIndex == 9)
|
||||
bindingEnergy = 0.*eV;
|
||||
|
||||
|
||||
G4double localEnergyDeposit = 0.0;
|
||||
G4double cosTheta = 1.0;
|
||||
|
||||
// Primary outcoming electron
|
||||
G4double eKineticEnergy = photonEnergy - bindingEnergy;
|
||||
|
||||
// There may be cases where the binding energy of the selected shell is > photon energy
|
||||
// In such cases do not generate secondaries
|
||||
if (eKineticEnergy > 0.)
|
||||
{
|
||||
// The electron is created
|
||||
// Direction sampled from the Sauter distribution
|
||||
cosTheta = SampleElectronDirection(eKineticEnergy);
|
||||
G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sinTheta * std::cos(phi);
|
||||
G4double diry = sinTheta * std::sin(phi);
|
||||
G4double dirz = cosTheta ;
|
||||
G4ThreeVector electronDirection(dirx,diry,dirz); //electron direction
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
eKineticEnergy);
|
||||
fvect->push_back(electron);
|
||||
}
|
||||
else
|
||||
{
|
||||
bindingEnergy = photonEnergy;
|
||||
}
|
||||
|
||||
G4double energyInFluorescence = 0; //testing purposes
|
||||
|
||||
//Now, take care of fluorescence, if required
|
||||
if(DeexcitationFlag() && Z > 5)
|
||||
{
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t indx = couple->GetIndex();
|
||||
G4double cutG = (*(theCoupleTable->GetEnergyCutsVector(0)))[indx];
|
||||
G4double cutE = (*(theCoupleTable->GetEnergyCutsVector(1)))[indx];
|
||||
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// shell binding energy > photon energy
|
||||
if (bindingEnergy > cutG || bindingEnergy > cutE)
|
||||
{
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cutG);
|
||||
deexcitationManager.SetCutForAugerElectrons(cutE);
|
||||
std::vector<G4DynamicParticle*>* photonVector =
|
||||
deexcitationManager.GenerateParticles(Z,shellId);
|
||||
//Check for secondaries
|
||||
if(photonVector)
|
||||
{
|
||||
for (size_t k=0; k< photonVector->size(); k++)
|
||||
{
|
||||
G4DynamicParticle* aPhoton = (*photonVector)[k];
|
||||
if (aPhoton)
|
||||
{
|
||||
G4double itsEnergy = aPhoton->GetKineticEnergy();
|
||||
if (itsEnergy <= bindingEnergy)
|
||||
{
|
||||
if(aPhoton->GetDefinition() == G4Gamma::Gamma())
|
||||
energyInFluorescence += itsEnergy;
|
||||
bindingEnergy -= itsEnergy;
|
||||
fvect->push_back(aPhoton);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aPhoton;
|
||||
(*photonVector)[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete photonVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Residual energy is deposited locally
|
||||
localEnergyDeposit += bindingEnergy;
|
||||
|
||||
if (localEnergyDeposit < 0)
|
||||
{
|
||||
G4cout << "WARNING - "
|
||||
<< "G4Penelope08PhotoElectric::PostStepDoIt - Negative energy deposit"
|
||||
<< G4endl;
|
||||
localEnergyDeposit = 0;
|
||||
}
|
||||
|
||||
fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
|
||||
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
G4cout << "Energy balance from G4Penelope08PhotoElectric" << G4endl;
|
||||
G4cout << "Selected shell: " << WriteTargetShell(shellIndex) << " of element " <<
|
||||
anElement->GetName() << G4endl;
|
||||
G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
if (eKineticEnergy)
|
||||
G4cout << "Outgoing electron " << eKineticEnergy/keV << " keV" << G4endl;
|
||||
G4cout << "Fluorescence: " << energyInFluorescence/keV << " keV" << G4endl;
|
||||
G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
|
||||
G4cout << "Total final state: " << (eKineticEnergy+energyInFluorescence+localEnergyDeposit)/keV <<
|
||||
" keV" << G4endl;
|
||||
G4cout << "-----------------------------------------------------------" << G4endl;
|
||||
}
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4double energyDiff =
|
||||
std::fabs(eKineticEnergy+energyInFluorescence+localEnergyDeposit-photonEnergy);
|
||||
if (energyDiff > 0.05*keV)
|
||||
G4cout << "Warning from G4Penelope08PhotoElectric: problem with energy conservation: " <<
|
||||
(eKineticEnergy+energyInFluorescence+localEnergyDeposit)/keV
|
||||
<< " keV (final) vs. " <<
|
||||
photonEnergy/keV << " keV (initial)" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08PhotoElectricModel::ActivateAuger(G4bool augerbool)
|
||||
{
|
||||
if (!DeexcitationFlag() && augerbool)
|
||||
{
|
||||
G4cout << "WARNING - G4Penelope08PhotoElectricModel" << G4endl;
|
||||
G4cout << "The use of the Atomic Deexcitation Manager is set to false " << G4endl;
|
||||
G4cout << "Therefore, Auger electrons will be not generated anyway" << G4endl;
|
||||
}
|
||||
deexcitationManager.ActivateAugerElectronProduction(augerbool);
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "Auger production set to " << augerbool << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08PhotoElectricModel::SampleElectronDirection(G4double energy)
|
||||
{
|
||||
G4double costheta = 1.0;
|
||||
if (energy>1*GeV) return costheta;
|
||||
|
||||
//1) initialize energy-dependent variables
|
||||
// Variable naming according to Eq. (2.24) of Penelope Manual
|
||||
// (pag. 44)
|
||||
G4double gamma = 1.0 + energy/electron_mass_c2;
|
||||
G4double gamma2 = gamma*gamma;
|
||||
G4double beta = std::sqrt((gamma2-1.0)/gamma2);
|
||||
|
||||
// ac corresponds to "A" of Eq. (2.31)
|
||||
//
|
||||
G4double ac = (1.0/beta) - 1.0;
|
||||
G4double a1 = 0.5*beta*gamma*(gamma-1.0)*(gamma-2.0);
|
||||
G4double a2 = ac + 2.0;
|
||||
G4double gtmax = 2.0*(a1 + 1.0/ac);
|
||||
|
||||
G4double tsam = 0;
|
||||
G4double gtr = 0;
|
||||
|
||||
//2) sampling. Eq. (2.31) of Penelope Manual
|
||||
// tsam = 1-std::cos(theta)
|
||||
// gtr = rejection function according to Eq. (2.28)
|
||||
do{
|
||||
G4double rand = G4UniformRand();
|
||||
tsam = 2.0*ac * (2.0*rand + a2*std::sqrt(rand)) / (a2*a2 - 4.0*rand);
|
||||
gtr = (2.0 - tsam) * (a1 + 1.0/(ac+tsam));
|
||||
}while(G4UniformRand()*gtmax > gtr);
|
||||
costheta = 1.0-tsam;
|
||||
|
||||
|
||||
return costheta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4Penelope08PhotoElectricModel::ReadDataFile(G4int Z)
|
||||
{
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "G4Penelope08PhotoElectricModel::ReadDataFile()" << G4endl;
|
||||
G4cout << "Going to read PhotoElectric data files for Z=" << Z << G4endl;
|
||||
}
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4Penelope08PhotoElectricModel - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
/*
|
||||
Read the cross section file
|
||||
*/
|
||||
std::ostringstream ost;
|
||||
if (Z>9)
|
||||
ost << path << "/penelope/photoelectric/pdgph" << Z << ".p08";
|
||||
else
|
||||
ost << path << "/penelope/photoelectric/pdgph0" << Z << ".p08";
|
||||
std::ifstream file(ost.str().c_str());
|
||||
if (!file.is_open())
|
||||
{
|
||||
G4String excep = "G4Penelope08PhotoElectricModel - data file " + G4String(ost.str()) + " not found!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
//I have to know in advance how many points are in the data list
|
||||
//to initialize the G4PhysicsFreeVector()
|
||||
size_t ndata=0;
|
||||
G4String line;
|
||||
while( getline(file, line) )
|
||||
ndata++;
|
||||
ndata -= 1;
|
||||
//G4cout << "Found: " << ndata << " lines" << G4endl;
|
||||
|
||||
file.clear();
|
||||
file.close();
|
||||
file.open(ost.str().c_str());
|
||||
|
||||
G4int readZ =0;
|
||||
size_t nShells= 0;
|
||||
file >> readZ >> nShells;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Element Z=" << Z << " , nShells = " << nShells << G4endl;
|
||||
|
||||
//check the right file is opened.
|
||||
if (readZ != Z || nShells <= 0)
|
||||
{
|
||||
G4cout << "G4Penelope08PhotoElectricModel::ReadDataFile()" << G4endl;
|
||||
G4cout << "Corrupted data file for Z=" << Z << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
G4PhysicsTable* thePhysicsTable = new G4PhysicsTable();
|
||||
|
||||
//the table has to contain nShell+1 G4PhysicsFreeVectors,
|
||||
//(theTable)[0] --> total cross section
|
||||
//(theTable)[ishell] --> cross section for shell (ishell-1)
|
||||
|
||||
//reserve space for the vectors
|
||||
//everything is log-log
|
||||
for (size_t i=0;i<nShells+1;i++)
|
||||
thePhysicsTable->push_back(new G4PhysicsFreeVector(ndata));
|
||||
|
||||
size_t k =0;
|
||||
for (k=0;k<ndata && !file.eof();k++)
|
||||
{
|
||||
G4double energy = 0;
|
||||
G4double aValue = 0;
|
||||
file >> energy ;
|
||||
energy *= eV;
|
||||
G4double logene = std::log(energy);
|
||||
//loop on the columns
|
||||
for (size_t i=0;i<nShells+1;i++)
|
||||
{
|
||||
file >> aValue;
|
||||
aValue *= barn;
|
||||
G4PhysicsFreeVector* theVec = (G4PhysicsFreeVector*) ((*thePhysicsTable)[i]);
|
||||
if (aValue < 1e-40*cm2) //protection against log(0)
|
||||
aValue = 1e-40*cm2;
|
||||
theVec->PutValue(k,logene,std::log(aValue));
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "G4Penelope08PhotoElectricModel: read " << k << " points for element Z = "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
|
||||
logAtomicShellXS->insert(std::make_pair(Z,thePhysicsTable));
|
||||
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
size_t G4Penelope08PhotoElectricModel::SelectRandomShell(G4int Z,G4double energy)
|
||||
{
|
||||
G4double logEnergy = std::log(energy);
|
||||
|
||||
//Check if data have been read (it should be!)
|
||||
if (!logAtomicShellXS->count(Z))
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08PhotoElectricModel::SelectRandomShell" << G4endl;
|
||||
G4cout << "Cannot find data for Z=" << Z << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
|
||||
size_t shellIndex = 0;
|
||||
|
||||
G4PhysicsTable* theTable = logAtomicShellXS->find(Z)->second;
|
||||
|
||||
G4DataVector* tempVector = new G4DataVector();
|
||||
|
||||
G4double sum = 0;
|
||||
//loop on shell partial XS, retrieve the value for the given energy and store on
|
||||
//a temporary vector
|
||||
tempVector->push_back(sum); //first element is zero
|
||||
|
||||
G4PhysicsFreeVector* totalXSLog = (G4PhysicsFreeVector*) (*theTable)[0];
|
||||
G4double logXS = totalXSLog->Value(logEnergy);
|
||||
G4double totalXS = std::exp(logXS);
|
||||
|
||||
//Notice: totalXS is the total cross section and it does *not* correspond to
|
||||
//the sum of partialXS's, since these include only K, L and M shells.
|
||||
//
|
||||
// Therefore, here one have to consider the possibility of ionisation of
|
||||
// an outer shell. Conventionally, it is indicated with id=10 in Penelope
|
||||
//
|
||||
|
||||
for (size_t k=1;k<theTable->entries();k++)
|
||||
{
|
||||
G4PhysicsFreeVector* partialXSLog = (G4PhysicsFreeVector*) (*theTable)[k];
|
||||
G4double logXS = partialXSLog->Value(logEnergy);
|
||||
G4double partialXS = std::exp(logXS);
|
||||
sum += partialXS;
|
||||
tempVector->push_back(sum);
|
||||
}
|
||||
|
||||
tempVector->push_back(totalXS); //last element
|
||||
|
||||
G4double random = G4UniformRand()*totalXS;
|
||||
|
||||
/*
|
||||
for (size_t i=0;i<tempVector->size(); i++)
|
||||
G4cout << i << " " << (*tempVector)[i]/totalXS << G4endl;
|
||||
*/
|
||||
|
||||
//locate bin of tempVector
|
||||
//Now one has to sample according to the elements in tempVector
|
||||
//This gives the left edge of the interval...
|
||||
size_t lowerBound = 0;
|
||||
size_t upperBound = tempVector->size()-1;
|
||||
while (lowerBound <= upperBound)
|
||||
{
|
||||
size_t midBin = (lowerBound + upperBound)/2;
|
||||
if( random < (*tempVector)[midBin])
|
||||
upperBound = midBin-1;
|
||||
else
|
||||
lowerBound = midBin+1;
|
||||
}
|
||||
|
||||
shellIndex = upperBound;
|
||||
|
||||
delete tempVector;
|
||||
return shellIndex;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
size_t G4Penelope08PhotoElectricModel::GetNumberOfShellXS(G4int Z)
|
||||
{
|
||||
//read data files
|
||||
if (!logAtomicShellXS->count(Z))
|
||||
ReadDataFile(Z);
|
||||
//now it should be ok
|
||||
if (!logAtomicShellXS->count(Z))
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08PhotoElectricModel::GetNumberOfShellXS()"
|
||||
<< G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
//one vector is allocated for the _total_ cross section
|
||||
size_t nEntries = logAtomicShellXS->find(Z)->second->entries();
|
||||
return (nEntries-1);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4Penelope08PhotoElectricModel::GetShellCrossSection(G4int Z,size_t shellID,G4double energy)
|
||||
{
|
||||
//this forces also the loading of the data
|
||||
size_t entries = GetNumberOfShellXS(Z);
|
||||
|
||||
if (shellID >= entries)
|
||||
{
|
||||
G4cout << "Element Z=" << Z << " has data for " << entries << " shells only" << G4endl;
|
||||
G4cout << "so shellID should be from 0 to " << entries-1 << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
G4PhysicsTable* theTable = logAtomicShellXS->find(Z)->second;
|
||||
//[0] is the total XS, shellID is in the element [shellID+1]
|
||||
G4PhysicsFreeVector* totalXSLog = (G4PhysicsFreeVector*) (*theTable)[shellID+1];
|
||||
|
||||
if (!totalXSLog)
|
||||
{
|
||||
G4cout << "Problem in G4Penelope08PhotoElectricModel::GetShellCrossSection()"
|
||||
<< G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
G4double logene = std::log(energy);
|
||||
G4double logXS = totalXSLog->Value(logene);
|
||||
G4double cross = std::exp(logXS);
|
||||
if (cross < 2e-40*cm2) cross = 0;
|
||||
return cross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4String G4Penelope08PhotoElectricModel::WriteTargetShell(size_t shellID)
|
||||
{
|
||||
G4String theShell = "outer shell";
|
||||
if (shellID == 0)
|
||||
theShell = "K";
|
||||
else if (shellID == 1)
|
||||
theShell = "L1";
|
||||
else if (shellID == 2)
|
||||
theShell = "L2";
|
||||
else if (shellID == 3)
|
||||
theShell = "L3";
|
||||
else if (shellID == 4)
|
||||
theShell = "M1";
|
||||
else if (shellID == 5)
|
||||
theShell = "M2";
|
||||
else if (shellID == 6)
|
||||
theShell = "M3";
|
||||
else if (shellID == 7)
|
||||
theShell = "M4";
|
||||
else if (shellID == 8)
|
||||
theShell = "M5";
|
||||
|
||||
return theShell;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeBremsstrahlungAngular.cc,v 1.8 2009/06/10 13:32:36 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeBremsstrahlungAngular.cc,v 1.10 2010/12/01 15:20:20 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
@@ -77,6 +77,7 @@ void G4PenelopeBremsstrahlungAngular::InterpolationTableForZ()
|
||||
{
|
||||
G4String excep = "G4PenelopeBremsstrahlungAngular - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/br-ang-pen.dat";
|
||||
@@ -92,10 +93,11 @@ void G4PenelopeBremsstrahlungAngular::InterpolationTableForZ()
|
||||
G4double a1,a2;
|
||||
while(i != -1) {
|
||||
file >> i >> j >> k >> a1 >> a2;
|
||||
if (i > -1){
|
||||
QQ1[i][j][k]=a1;
|
||||
QQ2[i][j][k]=a2;
|
||||
}
|
||||
if (i > -1 && j > -1 && k >- 1)
|
||||
{
|
||||
QQ1[i][j][k]=a1;
|
||||
QQ2[i][j][k]=a2;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
|
||||
+3
-2
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeBremsstrahlungContinuous.cc,v 1.12 2009/06/10 13:32:36 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeBremsstrahlungContinuous.cc,v 1.13 2010/11/25 09:43:47 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
@@ -88,6 +88,7 @@ void G4PenelopeBremsstrahlungContinuous::LoadFromFile()
|
||||
{
|
||||
G4String excep = "G4PenelopeBremsstrahlungContinuous - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String filename = "br-pen-cont-";
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeBremsstrahlungModel.cc,v 1.7 2009/06/11 15:47:08 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeBremsstrahlungModel.cc,v 1.8 2010/11/25 09:44:05 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
// --------
|
||||
@@ -182,8 +182,12 @@ void G4PenelopeBremsstrahlungModel::Initialise(const G4ParticleDefinition* parti
|
||||
crossSectionHandler->LoadData("penelope/br-cs-pos-"); //cross section for positrons
|
||||
|
||||
//This is used to retrieve cross section values later on
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
|
||||
G4VEMDataSet* emdata =
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
//The method BuildMeanFreePathForMaterials() is required here only to force
|
||||
//the building of an internal table: the output pointer can be deleted
|
||||
delete emdata;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for PenelopeBremsstrahlungModel" << G4endl;
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeComptonModel.cc,v 1.8 2009/10/23 09:29:24 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeComptonModel.cc,v 1.11 2010/12/01 15:20:26 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -80,10 +80,6 @@ G4PenelopeComptonModel::G4PenelopeComptonModel(const G4ParticleDefinition*,
|
||||
energyForIntegration = 0.0;
|
||||
ZForIntegration = 1;
|
||||
|
||||
//by default, the model will use atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
@@ -92,6 +88,10 @@ G4PenelopeComptonModel::G4PenelopeComptonModel(const G4ParticleDefinition*,
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
//by default, the model will use atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
//These vectors do not change when materials or cut change.
|
||||
//Therefore I can read it at the constructor
|
||||
ionizationEnergy = new std::map<G4int,G4DataVector*>;
|
||||
@@ -107,20 +107,24 @@ G4PenelopeComptonModel::G4PenelopeComptonModel(const G4ParticleDefinition*,
|
||||
G4PenelopeComptonModel::~G4PenelopeComptonModel()
|
||||
{
|
||||
std::map <G4int,G4DataVector*>::iterator i;
|
||||
for (i=ionizationEnergy->begin();i != ionizationEnergy->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
for (i=hartreeFunction->begin();i != hartreeFunction->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
for (i=occupationNumber->begin();i != occupationNumber->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
|
||||
|
||||
if (ionizationEnergy)
|
||||
delete ionizationEnergy;
|
||||
{
|
||||
for (i=ionizationEnergy->begin();i != ionizationEnergy->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete ionizationEnergy;
|
||||
}
|
||||
if (hartreeFunction)
|
||||
delete hartreeFunction;
|
||||
{
|
||||
for (i=hartreeFunction->begin();i != hartreeFunction->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete hartreeFunction;
|
||||
}
|
||||
if (occupationNumber)
|
||||
delete occupationNumber;
|
||||
{
|
||||
for (i=occupationNumber->begin();i != occupationNumber->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete occupationNumber;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -264,7 +268,8 @@ void G4PenelopeComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>*
|
||||
G4cout << "Selected " << anElement->GetName() << G4endl;
|
||||
|
||||
const G4int nmax = 64;
|
||||
G4double rn[nmax],pac[nmax];
|
||||
G4double rn[nmax]={0.0};
|
||||
G4double pac[nmax]={0.0};
|
||||
|
||||
G4double ki,ki1,ki2,ki3,taumin,a1,a2;
|
||||
G4double tau,TST;
|
||||
@@ -628,6 +633,7 @@ void G4PenelopeComptonModel::ReadData()
|
||||
{
|
||||
G4String excep = "G4PenelopeComptonModel - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/compton-pen.dat";
|
||||
@@ -647,15 +653,23 @@ void G4PenelopeComptonModel::ReadData()
|
||||
{
|
||||
G4String excep = "G4PenelopeComptonModel: problem with reading data from file";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
|
||||
do{
|
||||
G4double harOfElectronsBelowThreshold = 0;
|
||||
G4int nbOfElectronsBelowThreshold = 0;
|
||||
G4int nbOfElectronsBelowThreshold = 0;
|
||||
file >> Z >> nLevels;
|
||||
//Check for nLevels validity, before using it in a loop
|
||||
if (nLevels<0 || nLevels>64)
|
||||
{
|
||||
G4String excep = "G4PenelopeComptonModel: corrupted data file?";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
G4DataVector* occVector = new G4DataVector;
|
||||
G4DataVector* harVector = new G4DataVector;
|
||||
G4DataVector* bindingEVector = new G4DataVector;
|
||||
file >> Z >> nLevels;
|
||||
for (G4int h=0;h<nLevels;h++)
|
||||
{
|
||||
file >> k1 >> a1 >> a2;
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeCrossSection.cc,v 1.2 2010/12/15 07:39:14 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 18 Mar 2010 L Pandola First implementation
|
||||
//
|
||||
#include "G4PenelopeCrossSection.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4PhysicsFreeVector.hh"
|
||||
#include "G4DataVector.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
G4PenelopeCrossSection::G4PenelopeCrossSection(size_t nPointsE,size_t nShells) :
|
||||
numberOfEnergyPoints(nPointsE),numberOfShells(nShells),softCrossSections(0),
|
||||
hardCrossSections(0),shellCrossSections(0)
|
||||
{
|
||||
//check the number of points is not zero
|
||||
if (!numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "G4PenelopeCrossSection: invalid number of energy points " << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
|
||||
isNormalized = false;
|
||||
|
||||
// 1) soft XS table
|
||||
softCrossSections = new G4PhysicsTable();
|
||||
//the table contains 3 G4PhysicsFreeVectors,
|
||||
//(softCrossSections)[0] --> log XS0 vs. log E
|
||||
//(softCrossSections)[1] --> log XS1 vs. log E
|
||||
//(softCrossSections)[2] --> log XS2 vs. log E
|
||||
|
||||
//everything is log-log
|
||||
for (size_t i=0;i<3;i++)
|
||||
softCrossSections->push_back(new G4PhysicsFreeVector(numberOfEnergyPoints));
|
||||
|
||||
//2) hard XS table
|
||||
hardCrossSections = new G4PhysicsTable();
|
||||
//the table contains 3 G4PhysicsFreeVectors,
|
||||
//(hardCrossSections)[0] --> log XH0 vs. log E
|
||||
//(hardCrossSections)[1] --> log XH1 vs. log E
|
||||
//(hardCrossSections)[2] --> log XH2 vs. log E
|
||||
|
||||
//everything is log-log
|
||||
for (size_t i=0;i<3;i++)
|
||||
hardCrossSections->push_back(new G4PhysicsFreeVector(numberOfEnergyPoints));
|
||||
|
||||
//3) shell XS table, if it is the case
|
||||
if (numberOfShells)
|
||||
{
|
||||
shellCrossSections = new G4PhysicsTable();
|
||||
//the table has to contain numberofShells G4PhysicsFreeVectors,
|
||||
//(theTable)[ishell] --> cross section for shell #ishell
|
||||
for (size_t i=0;i<numberOfShells;i++)
|
||||
shellCrossSections->push_back(new G4PhysicsFreeVector(numberOfEnergyPoints));
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
G4PenelopeCrossSection::~G4PenelopeCrossSection()
|
||||
{
|
||||
//clean up tables
|
||||
if (shellCrossSections)
|
||||
{
|
||||
shellCrossSections->clearAndDestroy();
|
||||
delete shellCrossSections;
|
||||
}
|
||||
if (softCrossSections)
|
||||
{
|
||||
softCrossSections->clearAndDestroy();
|
||||
delete softCrossSections;
|
||||
}
|
||||
if (hardCrossSections)
|
||||
{
|
||||
hardCrossSections->clearAndDestroy();
|
||||
delete hardCrossSections;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
void G4PenelopeCrossSection::AddCrossSectionPoint(size_t binNumber,G4double energy,
|
||||
G4double XH0,
|
||||
G4double XH1, G4double XH2,
|
||||
G4double XS0, G4double XS1,
|
||||
G4double XS2)
|
||||
{
|
||||
if (!softCrossSections || !hardCrossSections)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::AddCrossSectionPoint" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to fill un-initialized tables" << G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//fill vectors
|
||||
G4PhysicsFreeVector* theVector = (G4PhysicsFreeVector*) (*softCrossSections)[0];
|
||||
|
||||
if (binNumber >= numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::AddCrossSectionPoint" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to register more points than originally declared" << G4endl;
|
||||
return;
|
||||
}
|
||||
G4double logEne = std::log(energy);
|
||||
|
||||
//XS0
|
||||
G4double val = std::log(std::max(XS0,1e-42*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
//XS1
|
||||
theVector = (G4PhysicsFreeVector*) (*softCrossSections)[1];
|
||||
val = std::log(std::max(XS1,1e-42*eV*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
//XS2
|
||||
theVector = (G4PhysicsFreeVector*) (*softCrossSections)[2];
|
||||
val = std::log(std::max(XS2,1e-42*eV*eV*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
//XH0
|
||||
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[0];
|
||||
val = std::log(std::max(XH0,1e-42*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
//XH1
|
||||
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[1];
|
||||
val = std::log(std::max(XH1,1e-42*eV*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
//XH2
|
||||
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[2];
|
||||
val = std::log(std::max(XH2,1e-42*eV*eV*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
|
||||
void G4PenelopeCrossSection::AddShellCrossSectionPoint(size_t binNumber,
|
||||
size_t shellID,
|
||||
G4double energy,
|
||||
G4double xs)
|
||||
{
|
||||
if (!shellCrossSections)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::AddShellCrossSectionPoint" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to fill un-initialized table" << G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (shellID >= numberOfShells)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::AddShellCrossSectionPoint" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to fill shell #" << shellID << " while the maximum is "
|
||||
<< numberOfShells-1 << G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//fill vector
|
||||
G4PhysicsFreeVector* theVector = (G4PhysicsFreeVector*) (*shellCrossSections)[shellID];
|
||||
|
||||
if (binNumber >= numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::AddShellCrossSectionPoint" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to register more points than originally declared" << G4endl;
|
||||
return;
|
||||
}
|
||||
G4double logEne = std::log(energy);
|
||||
G4double val = std::log(std::max(xs,1e-42*cm2)); //avoid log(0)
|
||||
theVector->PutValue(binNumber,logEne,val);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
|
||||
G4double G4PenelopeCrossSection::GetTotalCrossSection(G4double energy)
|
||||
{
|
||||
G4double result = 0;
|
||||
//take here XS0 + XH0
|
||||
if (!softCrossSections || !hardCrossSections)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetTotalCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to retrieve from un-initialized tables" << G4endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 1) soft part
|
||||
G4PhysicsFreeVector* theVector = (G4PhysicsFreeVector*) (*softCrossSections)[0];
|
||||
if (theVector->GetVectorLength() < numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetTotalCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Soft cross section table looks not filled" << G4endl;
|
||||
return result;
|
||||
}
|
||||
G4double logene = std::log(energy);
|
||||
G4double logXS = theVector->Value(logene);
|
||||
G4double softXS = std::exp(logXS);
|
||||
|
||||
// 2) hard part
|
||||
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[0];
|
||||
if (theVector->GetVectorLength() < numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetTotalCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Hard cross section table looks not filled" << G4endl;
|
||||
return result;
|
||||
}
|
||||
logXS = theVector->Value(logene);
|
||||
G4double hardXS = std::exp(logXS);
|
||||
|
||||
result = hardXS + softXS;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
|
||||
G4double G4PenelopeCrossSection::GetHardCrossSection(G4double energy)
|
||||
{
|
||||
G4double result = 0;
|
||||
//take here XH0
|
||||
if (!hardCrossSections)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetHardCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to retrieve from un-initialized tables" << G4endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
G4PhysicsFreeVector* theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[0];
|
||||
if (theVector->GetVectorLength() < numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetHardCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Hard cross section table looks not filled" << G4endl;
|
||||
return result;
|
||||
}
|
||||
G4double logene = std::log(energy);
|
||||
G4double logXS = theVector->Value(logene);
|
||||
result = std::exp(logXS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
|
||||
G4double G4PenelopeCrossSection::GetSoftStoppingPower(G4double energy)
|
||||
{
|
||||
G4double result = 0;
|
||||
//take here XH0
|
||||
if (!softCrossSections)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetSoftStoppingPower" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to retrieve from un-initialized tables" << G4endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
G4PhysicsFreeVector* theVector = (G4PhysicsFreeVector*) (*softCrossSections)[1];
|
||||
if (theVector->GetVectorLength() < numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetSoftStoppingPower" <<
|
||||
G4endl;
|
||||
G4cout << "Soft cross section table looks not filled" << G4endl;
|
||||
return result;
|
||||
}
|
||||
G4double logene = std::log(energy);
|
||||
G4double logXS = theVector->Value(logene);
|
||||
result = std::exp(logXS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
|
||||
G4double G4PenelopeCrossSection::GetShellCrossSection(size_t shellID,G4double energy)
|
||||
{
|
||||
G4double result = 0;
|
||||
if (!shellCrossSections)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetShellCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to retrieve from un-initialized tables" << G4endl;
|
||||
return result;
|
||||
}
|
||||
if (shellID >= numberOfShells)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetShellCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Trying to retrieve shell #" << shellID << " while the maximum is "
|
||||
<< numberOfShells-1 << G4endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
G4PhysicsFreeVector* theVector = (G4PhysicsFreeVector*) (*shellCrossSections)[shellID];
|
||||
|
||||
if (theVector->GetVectorLength() < numberOfEnergyPoints)
|
||||
{
|
||||
G4cout << "Something wrong in G4PenelopeCrossSection::GetShellCrossSection" <<
|
||||
G4endl;
|
||||
G4cout << "Soft cross section table looks not filled" << G4endl;
|
||||
return result;
|
||||
}
|
||||
G4double logene = std::log(energy);
|
||||
G4double logXS = theVector->Value(logene);
|
||||
result = std::exp(logXS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
|
||||
void G4PenelopeCrossSection::NormalizeShellCrossSections()
|
||||
{
|
||||
if (isNormalized) //already done!
|
||||
{
|
||||
G4cout << "G4PenelopeCrossSection::NormalizeShellCrossSections()" << G4endl;
|
||||
G4cout << "already invoked. Ignore it" << G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i=0;i<numberOfEnergyPoints;i++) //loop on energy
|
||||
{
|
||||
//energy grid is the same for all shells
|
||||
|
||||
//Recalculate manually the XS factor, to avoid problems with
|
||||
//underflows
|
||||
G4double normFactor = 0.;
|
||||
for (size_t shellID=0;shellID<numberOfShells;shellID++)
|
||||
{
|
||||
G4PhysicsFreeVector* theVec =
|
||||
(G4PhysicsFreeVector*) (*shellCrossSections)[shellID];
|
||||
|
||||
normFactor += std::exp((*theVec)[i]);
|
||||
}
|
||||
G4double logNormFactor = std::log(normFactor);
|
||||
//Normalize
|
||||
for (size_t shellID=0;shellID<numberOfShells;shellID++)
|
||||
{
|
||||
G4PhysicsFreeVector* theVec =
|
||||
(G4PhysicsFreeVector*) (*shellCrossSections)[shellID];
|
||||
G4double previousValue = (*theVec)[i]; //log(XS)
|
||||
G4double logEnergy = theVec->GetLowEdgeEnergy(i);
|
||||
//log(XS/normFactor) = log(XS) - log(normFactor)
|
||||
theVec->PutValue(i,logEnergy,previousValue-logNormFactor);
|
||||
}
|
||||
}
|
||||
|
||||
isNormalized = true;
|
||||
|
||||
|
||||
/*
|
||||
//TESTING
|
||||
for (size_t shellID=0;shellID<numberOfShells;shellID++)
|
||||
{
|
||||
G4cout << "SHELL " << shellID << G4endl;
|
||||
G4PhysicsFreeVector* theVec =
|
||||
(G4PhysicsFreeVector*) (*shellCrossSections)[shellID];
|
||||
for (size_t i=0;i<numberOfEnergyPoints;i++) //loop on energy
|
||||
{
|
||||
G4double logene = theVec->GetLowEdgeEnergy(i);
|
||||
G4cout << std::exp(logene)/MeV << " " << std::exp((*theVec)[i]) << G4endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ std::vector<G4VEMDataSet*>* G4PenelopeCrossSectionHandler::BuildCrossSectionsFor
|
||||
const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
G4int verbose = 0;
|
||||
//G4int verbose = 0;
|
||||
std::vector<G4VEMDataSet*>* set = new std::vector<G4VEMDataSet*>;
|
||||
|
||||
G4DataVector* energies;
|
||||
@@ -93,11 +93,13 @@ std::vector<G4VEMDataSet*>* G4PenelopeCrossSectionHandler::BuildCrossSectionsFor
|
||||
material->GetTotNbOfElectPerVolume(); //electron density
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
/*
|
||||
if(verbose > 0) {
|
||||
G4cout << "Penelope CS for " << m << "th material "
|
||||
<< material->GetName()
|
||||
<< " eEl= " << nElements << G4endl;
|
||||
}
|
||||
*/
|
||||
|
||||
G4double tcut = (*energyCuts)[m];
|
||||
|
||||
@@ -123,6 +125,7 @@ std::vector<G4VEMDataSet*>* G4PenelopeCrossSectionHandler::BuildCrossSectionsFor
|
||||
particle);
|
||||
value += cross * p * density;
|
||||
|
||||
/*
|
||||
if(verbose>0 && m == 0 && e>=1. && e<=0.) {
|
||||
G4cout << "G4PenIonCrossSH: e(MeV)= " << e/MeV
|
||||
<< " cross= " << cross
|
||||
@@ -133,6 +136,7 @@ std::vector<G4VEMDataSet*>* G4PenelopeCrossSectionHandler::BuildCrossSectionsFor
|
||||
<< " Z= " << Z
|
||||
<< G4endl;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
cs->push_back(value);
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeGammaConversionModel.cc,v 1.6 2009/06/11 15:47:08 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeGammaConversionModel.cc,v 1.7 2010/11/25 09:45:13 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -104,7 +105,11 @@ void G4PenelopeGammaConversionModel::Initialise(const G4ParticleDefinition*,
|
||||
G4String crossSectionFile = "penelope/pp-cs-pen-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
//This is used to retrieve cross section values later on
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
G4VEMDataSet* emdata =
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
//The method BuildMeanFreePathForMaterials() is required here only to force
|
||||
//the building of an internal table: the output pointer can be deleted
|
||||
delete emdata;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for PenelopeGammaConversion" << G4endl;
|
||||
@@ -416,6 +421,7 @@ G4double G4PenelopeGammaConversionModel::GetScreeningRadius(G4double Z)
|
||||
{
|
||||
G4String excep = "G4PenelopeGammaConversionModel - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
return result;
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/pp-pen.dat";
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeIonisationModel.cc,v 1.10 2009/10/23 09:29:24 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeIonisationModel.cc,v 1.18 2010/12/01 15:20:35 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -41,6 +41,13 @@
|
||||
// 21 Oct 2009 L Pandola Remove un-necessary fUseAtomicDeexcitation flag - now managed by
|
||||
// G4VEmModel::DeexcitationFlag()
|
||||
// Add ActivateAuger() method
|
||||
// 15 Mar 2010 L Pandola Explicitely initialize Auger to false
|
||||
// 29 Mar 2010 L Pandola Added a dummy ComputeCrossSectionPerAtom() method issueing a
|
||||
// warning if users try to access atomic cross sections via
|
||||
// G4EmCalculator
|
||||
// 15 Apr 2010 L. Pandola Implemented model's own version of MinEnergyCut()
|
||||
// 23 Apr 2010 L. Pandola Removed InitialiseElementSelectors() call. Useless here and
|
||||
// triggers fake warning messages
|
||||
//
|
||||
|
||||
#include "G4PenelopeIonisationModel.hh"
|
||||
@@ -79,8 +86,7 @@ G4PenelopeIonisationModel::G4PenelopeIonisationModel(const G4ParticleDefinition*
|
||||
// SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
|
||||
SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
|
||||
//
|
||||
// Atomic deexcitation model activated by default
|
||||
SetDeexcitationFlag(true);
|
||||
//
|
||||
verboseLevel= 0;
|
||||
|
||||
// Verbosity scale:
|
||||
@@ -89,6 +95,10 @@ G4PenelopeIonisationModel::G4PenelopeIonisationModel(const G4ParticleDefinition*
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
// Atomic deexcitation model activated by default
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
|
||||
//These vectors do not change when materials or cut change.
|
||||
//Therefore I can read it at the constructor
|
||||
@@ -117,29 +127,36 @@ G4PenelopeIonisationModel::~G4PenelopeIonisationModel()
|
||||
|
||||
|
||||
std::map <G4int,G4DataVector*>::iterator i;
|
||||
for (i=ionizationEnergy->begin();i != ionizationEnergy->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
for (i=resonanceEnergy->begin();i != resonanceEnergy->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
for (i=occupationNumber->begin();i != occupationNumber->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
for (i=shellFlag->begin();i != shellFlag->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
|
||||
if (ionizationEnergy)
|
||||
delete ionizationEnergy;
|
||||
{
|
||||
for (i=ionizationEnergy->begin();i != ionizationEnergy->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete ionizationEnergy;
|
||||
}
|
||||
if (resonanceEnergy)
|
||||
delete resonanceEnergy;
|
||||
{
|
||||
for (i=resonanceEnergy->begin();i != resonanceEnergy->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete resonanceEnergy;
|
||||
}
|
||||
if (occupationNumber)
|
||||
delete occupationNumber;
|
||||
{
|
||||
for (i=occupationNumber->begin();i != occupationNumber->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete occupationNumber;
|
||||
}
|
||||
if (shellFlag)
|
||||
delete shellFlag;
|
||||
{
|
||||
for (i=shellFlag->begin();i != shellFlag->end();i++)
|
||||
if (i->second) delete i->second;
|
||||
delete shellFlag;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4PenelopeIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& cuts)
|
||||
const G4DataVector& )
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4PenelopeIonisationModel::Initialise()" << G4endl;
|
||||
@@ -173,10 +190,12 @@ void G4PenelopeIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
crossSectionFile = "penelope/ion-cs-po-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
//This is used to retrieve cross section values later on
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
G4VEMDataSet* emdata =
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
//The method BuildMeanFreePathForMaterials() is required here only to force
|
||||
//the building of an internal table: the output pointer can be deleted
|
||||
delete emdata;
|
||||
|
||||
InitialiseElementSelectors(particle,cuts);
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for PenelopeIonisationModel" << G4endl;
|
||||
|
||||
@@ -279,6 +298,25 @@ G4double G4PenelopeIonisationModel::CrossSectionPerVolume(const G4Material* mate
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
//This is a dummy method. Never inkoved by the tracking, it just issues
|
||||
//a warning if one tries to get Cross Sections per Atom via the
|
||||
//G4EmCalculator.
|
||||
G4double G4PenelopeIonisationModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
G4cout << "*** G4PenelopeIonisationModel -- WARNING ***" << G4endl;
|
||||
G4cout << "Penelope Ionisation model does not calculate cross section _per atom_ " << G4endl;
|
||||
G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
|
||||
G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4PenelopeIonisationModel::ComputeDEDXPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* theParticle,
|
||||
G4double kineticEnergy,
|
||||
@@ -351,6 +389,14 @@ G4double G4PenelopeIonisationModel::ComputeDEDXPerVolume(const G4Material* mater
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4PenelopeIonisationModel::MinEnergyCut(const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple*)
|
||||
{
|
||||
return fIntrinsicLowEnergyLimit;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4PenelopeIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicParticle,
|
||||
@@ -598,6 +644,7 @@ void G4PenelopeIonisationModel::ReadData()
|
||||
{
|
||||
G4String excep = "G4PenelopeIonisationModel - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/ion-pen.dat";
|
||||
@@ -613,17 +660,27 @@ void G4PenelopeIonisationModel::ReadData()
|
||||
{
|
||||
G4String excep = "G4PenelopeIonisationModel: problem with reading data from file";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
|
||||
G4int Z=1,nLevels=0;
|
||||
G4int test,test1;
|
||||
|
||||
do{
|
||||
file >> Z >> nLevels;
|
||||
//Check for nLevels validity, before using it in a loop
|
||||
if (nLevels<0 || nLevels>64)
|
||||
{
|
||||
G4String excep = "G4PenelopeIonisationModel: corrupted data file ?";
|
||||
G4Exception(excep);
|
||||
return;
|
||||
}
|
||||
//Allocate space for storage
|
||||
G4DataVector* occVector = new G4DataVector;
|
||||
G4DataVector* ionEVector = new G4DataVector;
|
||||
G4DataVector* resEVector = new G4DataVector;
|
||||
G4DataVector* shellIndVector = new G4DataVector;
|
||||
file >> Z >> nLevels;
|
||||
//
|
||||
G4double a1,a2,a3,a4;
|
||||
G4int k1,k2,k3;
|
||||
for (G4int h=0;h<nLevels;h++)
|
||||
@@ -1623,6 +1680,7 @@ G4PenelopeIonisationModel::BuildCrossSectionTable(const G4ParticleDefinition* th
|
||||
std::vector<G4VEMDataSet*>* set = new std::vector<G4VEMDataSet*>;
|
||||
|
||||
size_t nOfBins = 200;
|
||||
//Temporary vector, a quick way to produce a log-spaced energy grid
|
||||
G4PhysicsLogVector* theLogVector = new G4PhysicsLogVector(LowEnergyLimit(),
|
||||
HighEnergyLimit(),
|
||||
nOfBins);
|
||||
@@ -1676,6 +1734,7 @@ G4PenelopeIonisationModel::BuildCrossSectionTable(const G4ParticleDefinition* th
|
||||
}
|
||||
set->push_back(setForMat);
|
||||
}
|
||||
delete theLogVector;
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 18 Dec 2008 L Pandola First implementation
|
||||
|
||||
#include "G4PenelopeOscillator.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PenelopeOscillator::G4PenelopeOscillator() :
|
||||
hartreeFactor(0), ionisationEnergy(0*eV), resonanceEnergy(0*eV),
|
||||
oscillatorStrength(0), shellFlag(-1), parentZ(0),
|
||||
parentShellID(-1),cutoffRecoilResonantEnergy(0*eV)
|
||||
{;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PenelopeOscillator::G4PenelopeOscillator(const G4PenelopeOscillator& right)
|
||||
{
|
||||
hartreeFactor = right.hartreeFactor;
|
||||
ionisationEnergy = right.ionisationEnergy;
|
||||
resonanceEnergy = right.resonanceEnergy;
|
||||
oscillatorStrength = right.oscillatorStrength;
|
||||
shellFlag = right.shellFlag;
|
||||
parentZ = right.parentZ;
|
||||
parentShellID = right.parentShellID;
|
||||
cutoffRecoilResonantEnergy = right.cutoffRecoilResonantEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4PenelopeOscillator& G4PenelopeOscillator::operator=(const G4PenelopeOscillator& right)
|
||||
{
|
||||
hartreeFactor = right.hartreeFactor;
|
||||
ionisationEnergy = right.ionisationEnergy;
|
||||
resonanceEnergy = right.resonanceEnergy;
|
||||
oscillatorStrength = right.oscillatorStrength;
|
||||
shellFlag = right.shellFlag;
|
||||
parentZ = right.parentZ;
|
||||
parentShellID = right.parentShellID;
|
||||
cutoffRecoilResonantEnergy = right.cutoffRecoilResonantEnergy;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
int G4PenelopeOscillator::operator==(const G4PenelopeOscillator& right) const
|
||||
{
|
||||
//Oscillator are ordered according to the ionisation energy. They are considered to be
|
||||
//equal if the ionisation energy is the same
|
||||
return (ionisationEnergy == right.ionisationEnergy) ? 1 : 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
int G4PenelopeOscillator::operator>(const G4PenelopeOscillator& right) const
|
||||
{
|
||||
//Oscillator are ordered according to the ionisation energy.
|
||||
return (ionisationEnergy > right.ionisationEnergy) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
int G4PenelopeOscillator::operator<(const G4PenelopeOscillator& right) const
|
||||
{
|
||||
//Oscillator are ordered according to the ionisation energy.
|
||||
return (ionisationEnergy < right.ionisationEnergy) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopePhotoElectricModel.cc,v 1.10 2009/10/23 09:29:24 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopePhotoElectricModel.cc,v 1.13 2010/11/26 11:51:11 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -45,6 +45,7 @@
|
||||
// Initialise(), since they might be checked later on
|
||||
// 21 Oct 2009 L Pandola Remove un-necessary fUseAtomicDeexcitation flag - now managed by
|
||||
// G4VEmModel::DeexcitationFlag()
|
||||
// 15 Mar 2010 L Pandola Explicitely initialize Auger to false
|
||||
//
|
||||
|
||||
#include "G4PenelopePhotoElectricModel.hh"
|
||||
@@ -60,6 +61,7 @@
|
||||
#include "G4AtomicShell.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -74,9 +76,6 @@ G4PenelopePhotoElectricModel::G4PenelopePhotoElectricModel(const G4ParticleDefin
|
||||
// SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
|
||||
SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
|
||||
//
|
||||
//by default the model will inkove the atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
@@ -84,6 +83,10 @@ G4PenelopePhotoElectricModel::G4PenelopePhotoElectricModel(const G4ParticleDefin
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
//by default the model will inkove the atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
ActivateAuger(false);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -124,7 +127,11 @@ void G4PenelopePhotoElectricModel::Initialise(const G4ParticleDefinition*,
|
||||
crossSectionFile = "penelope/ph-ss-cs-pen-";
|
||||
shellCrossSectionHandler->LoadShellData(crossSectionFile);
|
||||
//This is used to retrieve cross section values later on
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
G4VEMDataSet* emdata =
|
||||
crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
//The method BuildMeanFreePathForMaterials() is required here only to force
|
||||
//the building of an internal table: the output pointer can be deleted
|
||||
delete emdata;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for PenelopePhotoElectric" << G4endl;
|
||||
@@ -251,10 +258,7 @@ void G4PenelopePhotoElectricModel::SampleSecondaries(std::vector<G4DynamicPartic
|
||||
// There may be cases where the binding energy of the selected shell is > photon energy
|
||||
// In such cases do not generate secondaries
|
||||
if (eKineticEnergy > 0.)
|
||||
{
|
||||
//Now check if the electron is above cuts: if so, it is created explicitely
|
||||
//VI: checking cut here provides inconsistency in testing
|
||||
// if (eKineticEnergy > cutE)
|
||||
{
|
||||
// The electron is created
|
||||
// Direction sampled from the Sauter distribution
|
||||
G4double cosTheta = SampleElectronDirection(eKineticEnergy);
|
||||
@@ -270,12 +274,6 @@ void G4PenelopePhotoElectricModel::SampleSecondaries(std::vector<G4DynamicPartic
|
||||
eKineticEnergy);
|
||||
fvect->push_back(electron);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// localEnergyDeposit += eKineticEnergy;
|
||||
// eKineticEnergy = 0;
|
||||
// }
|
||||
// }
|
||||
else
|
||||
{
|
||||
bindingEnergy = photonEnergy;
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4PenelopeRayleighModel.cc,v 1.6 2009/06/11 15:47:08 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4PenelopeRayleighModel.cc,v 1.8 2010/11/26 11:51:11 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
@@ -36,6 +36,9 @@
|
||||
// - do not apply low-energy limit (default is 0)
|
||||
// 19 May 2009 L Pandola Explicitely set to zero pointers deleted in
|
||||
// PrepareConstants(), since they might be checked later on
|
||||
// 18 Dec 2009 L Pandola Added a dummy ComputeCrossSectionPerAtom() method issueing a
|
||||
// warning if users try to access atomic cross sections via
|
||||
// G4EmCalculator
|
||||
//
|
||||
|
||||
#include "G4PenelopeRayleighModel.hh"
|
||||
@@ -189,7 +192,14 @@ G4PenelopeRayleighModel::CrossSectionPerVolume(const G4Material* material,
|
||||
//Calculate the total number of atoms per molecule
|
||||
G4int atomsPerMolecule = 0;
|
||||
for (G4int k=0;k<nElements;k++)
|
||||
{
|
||||
atomsPerMolecule += stechiometric[k];
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "Element: " << (G4int) (*elementVector)[k]->GetZ() << " has " <<
|
||||
stechiometric[k] << " atoms/molecule" << G4endl;
|
||||
}
|
||||
}
|
||||
if (atomsPerMolecule)
|
||||
{
|
||||
isAMolecule = true;
|
||||
@@ -202,7 +212,7 @@ G4PenelopeRayleighModel::CrossSectionPerVolume(const G4Material* material,
|
||||
cross = cs*moleculeDensity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
if (isAMolecule)
|
||||
@@ -221,6 +231,25 @@ G4PenelopeRayleighModel::CrossSectionPerVolume(const G4Material* material,
|
||||
return cross;
|
||||
}
|
||||
|
||||
|
||||
//This is a dummy method. Never inkoved by the tracking, it just issues
|
||||
//a warning if one tries to get Cross Sections per Atom via the
|
||||
//G4EmCalculator.
|
||||
G4double G4PenelopeRayleighModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
G4cout << "*** G4PenelopeRayleighModel -- WARNING ***" << G4endl;
|
||||
G4cout << "Penelope Rayleigh model does not calculate cross section _per atom_ " << G4endl;
|
||||
G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
|
||||
G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4PenelopeRayleighModel::SampleSecondaries(std::vector<G4DynamicParticle*>* ,
|
||||
@@ -478,8 +507,10 @@ void G4PenelopeRayleighModel::InitialiseSampling()
|
||||
if (!samplingFunction_x || !samplingFunction_xNoLog)
|
||||
{
|
||||
G4cout << "G4PenelopeRayleighModel::InitialiseSampling(), something wrong" << G4endl;
|
||||
G4cout << "It looks like G4PenelopeRayleighModel::PrepareConstants() has not been called" << G4endl;
|
||||
G4cout << "It looks like G4PenelopeRayleighModel::PrepareConstants() has not been called"
|
||||
<< G4endl;
|
||||
G4Exception();
|
||||
return;
|
||||
}
|
||||
if (!SamplingTable.count(theMaterial)) //material not defined yet
|
||||
{
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeSamplingData.cc,v 1.1 2010/03/17 14:18:50 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 09 Dec 2009 L Pandola First implementation
|
||||
//
|
||||
#include "G4PenelopeSamplingData.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
G4PenelopeSamplingData::G4PenelopeSamplingData(G4int nPoints) :
|
||||
np(nPoints)
|
||||
{
|
||||
//create vectors
|
||||
x = new G4DataVector();
|
||||
pac = new G4DataVector();
|
||||
a = new G4DataVector();
|
||||
b = new G4DataVector();
|
||||
ITTL = new std::vector<size_t>;
|
||||
ITTU = new std::vector<size_t>;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
G4PenelopeSamplingData::~G4PenelopeSamplingData()
|
||||
{
|
||||
if (x) delete x;
|
||||
if (pac) delete pac;
|
||||
if (a) delete a;
|
||||
if (b) delete b;
|
||||
if (ITTL) delete ITTL;
|
||||
if (ITTU) delete ITTU;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
size_t G4PenelopeSamplingData::GetNumberOfStoredPoints()
|
||||
{
|
||||
size_t points = x->size();
|
||||
|
||||
//check everything is all right
|
||||
if (pac->size() != points || a->size() != points ||
|
||||
b->size() != points || ITTL->size() != points ||
|
||||
ITTU->size() != points)
|
||||
{
|
||||
G4cout << "G4PenelopeSamplingData::GetNumberOfStoredPoints()" << G4endl;
|
||||
G4cout << "Data vectors look to have different dimensions !" << G4endl;
|
||||
G4Exception();
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
void G4PenelopeSamplingData::Clear()
|
||||
{
|
||||
if (x) delete x;
|
||||
if (pac) delete pac;
|
||||
if (a) delete a;
|
||||
if (b) delete b;
|
||||
if (ITTL) delete ITTL;
|
||||
if (ITTU) delete ITTU;
|
||||
//create vectors
|
||||
x = new G4DataVector();
|
||||
pac = new G4DataVector();
|
||||
a = new G4DataVector();
|
||||
b = new G4DataVector();
|
||||
ITTL = new std::vector<size_t>;
|
||||
ITTU = new std::vector<size_t>;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
|
||||
void G4PenelopeSamplingData::AddPoint(G4double x0,G4double pac0,G4double a0,G4double b0,
|
||||
size_t ITTL0,size_t ITTU0)
|
||||
{
|
||||
x->push_back(x0);
|
||||
pac->push_back(pac0);
|
||||
a->push_back(a0);
|
||||
b->push_back(b0);
|
||||
ITTL->push_back(ITTL0);
|
||||
ITTU->push_back(ITTU0);
|
||||
|
||||
//check how many points we do have now
|
||||
size_t nOfPoints = GetNumberOfStoredPoints();
|
||||
|
||||
if (nOfPoints > ((size_t)np))
|
||||
{
|
||||
G4cout << "G4PenelopeSamplingData::AddPoint() " << G4endl;
|
||||
G4cout << "WARNING: Up to now there are " << nOfPoints << " points in the table" << G4endl;
|
||||
G4cout << "while the anticipated (declared) number is " << np << G4endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
void G4PenelopeSamplingData::DumpTable()
|
||||
{
|
||||
|
||||
G4cout << "*************************************************************************" << G4endl;
|
||||
G4cout << GetNumberOfStoredPoints() << " points" << G4endl;
|
||||
G4cout << "*************************************************************************" << G4endl;
|
||||
for (size_t i=0;i<GetNumberOfStoredPoints();i++)
|
||||
{
|
||||
G4cout << i << " " << (*x)[i] << " " << (*pac)[i] << " " << (*a)[i] << " " <<
|
||||
(*b)[i] << " " << (*ITTL)[i] << " " << (*ITTU)[i] << G4endl;
|
||||
}
|
||||
G4cout << "*************************************************************************" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
G4double G4PenelopeSamplingData::GetX(size_t index)
|
||||
{
|
||||
if (index < x->size())
|
||||
return (*x)[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
G4double G4PenelopeSamplingData::GetPAC(size_t index)
|
||||
{
|
||||
if (index < pac->size())
|
||||
return (*pac)[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
G4double G4PenelopeSamplingData::GetA(size_t index)
|
||||
{
|
||||
if (index < a->size())
|
||||
return (*a)[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
G4double G4PenelopeSamplingData::GetB(size_t index)
|
||||
{
|
||||
if (index < b->size())
|
||||
return (*b)[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..
|
||||
G4double G4PenelopeSamplingData::SampleValue(G4double maxRand)
|
||||
{
|
||||
//One passes here a random number in (0,1).
|
||||
//Notice: it possible that is between (0,b) with b<1
|
||||
size_t points = GetNumberOfStoredPoints();
|
||||
|
||||
size_t itn = (size_t) (maxRand*(points-1));
|
||||
size_t i = (*ITTL)[itn];
|
||||
size_t j = (*ITTU)[itn];
|
||||
|
||||
while ((j-i) > 1)
|
||||
{
|
||||
size_t k = (i+j)/2;
|
||||
if (maxRand > (*pac)[k])
|
||||
i = k;
|
||||
else
|
||||
j = k;
|
||||
}
|
||||
|
||||
//Sampling from the rational inverse cumulative distribution
|
||||
G4double result = 0;
|
||||
|
||||
G4double rr = maxRand - (*pac)[i];
|
||||
if (rr > 1e-16)
|
||||
{
|
||||
G4double d = (*pac)[i+1]-(*pac)[i];
|
||||
result = (*x)[i]+
|
||||
((1.0+(*a)[i]+(*b)[i])*d*rr/
|
||||
(d*d+((*a)[i]*d+(*b)[i]*rr)*rr))*((*x)[i+1]-(*x)[i]);
|
||||
}
|
||||
else
|
||||
result = (*x)[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
+3
-1
@@ -79,7 +79,9 @@ G4ThreeVector G4PhotoElectricAngularGeneratorSauterGavrila::GetPhotoElectronDire
|
||||
|
||||
if (gamma > 5.) {
|
||||
G4ThreeVector direction (sinteta*cosphi, sinteta*sinphi, costeta);
|
||||
return costeta;
|
||||
return direction;
|
||||
// Bugzilla 1120
|
||||
// SI on 05/09/2010 as suggested by JG 04/09/10
|
||||
}
|
||||
|
||||
G4double beta = std::sqrt(gamma*gamma-1.)/gamma;
|
||||
|
||||
@@ -0,0 +1,545 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4UAtomicDeexcitation.cc,v 1.11
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// Geant4 Class file
|
||||
//
|
||||
// Authors: Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
//
|
||||
// Created 22 April 2010 from old G4UAtomicDeexcitation class
|
||||
//
|
||||
// Modified:
|
||||
// ---------
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// Class description:
|
||||
// Implementation of atomic deexcitation
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4UAtomicDeexcitation.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4FluoTransition.hh"
|
||||
#include "G4Proton.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4UAtomicDeexcitation::G4UAtomicDeexcitation():
|
||||
G4VAtomDeexcitation("UAtomDeexcitation"),
|
||||
minGammaEnergy(DBL_MAX),
|
||||
minElectronEnergy(DBL_MAX)
|
||||
{
|
||||
PIXEshellCS = 0;
|
||||
}
|
||||
|
||||
G4UAtomicDeexcitation::~G4UAtomicDeexcitation()
|
||||
{
|
||||
delete PIXEshellCS;
|
||||
}
|
||||
|
||||
void G4UAtomicDeexcitation::InitialiseForNewRun()
|
||||
{
|
||||
transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
// initializing PIXE
|
||||
if ("" == PIXECrossSectionModel()) {
|
||||
SetPIXECrossSectionModel("Empirical");
|
||||
}
|
||||
|
||||
if (PIXECrossSectionModel() == "ECPSSR_Analytical") {
|
||||
delete PIXEshellCS;
|
||||
PIXEshellCS = new G4teoCrossSection("analytical");
|
||||
}
|
||||
|
||||
else if (PIXECrossSectionModel() == "Empirical") {
|
||||
delete PIXEshellCS;
|
||||
PIXEshellCS = new G4empCrossSection;
|
||||
}
|
||||
else {
|
||||
G4cout << "### G4UAtomicDeexcitation::InitialiseForNewRun WARNING "
|
||||
<< G4endl;
|
||||
G4cout << " PIXE cross section name " << PIXECrossSectionModel()
|
||||
<< " is unknown, PIXE is disabled" << G4endl;
|
||||
SetPIXEActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
void G4UAtomicDeexcitation::InitialiseForExtraAtom(G4int /*Z*/)
|
||||
{}
|
||||
|
||||
const G4AtomicShell*
|
||||
G4UAtomicDeexcitation::GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)
|
||||
{
|
||||
return transitionManager->Shell(Z, G4int(shell));
|
||||
}
|
||||
|
||||
void G4UAtomicDeexcitation::GenerateParticles(
|
||||
std::vector<G4DynamicParticle*>* vectorOfParticles,
|
||||
const G4AtomicShell* atomicShell,
|
||||
G4int Z,
|
||||
G4double gammaCut,
|
||||
G4double eCut)
|
||||
{
|
||||
// Defined initial conditions
|
||||
G4int givenShellId = atomicShell->ShellId();
|
||||
minGammaEnergy = gammaCut;
|
||||
minElectronEnergy = eCut;
|
||||
|
||||
// generation secondaries
|
||||
G4DynamicParticle* aParticle;
|
||||
G4int provShellId = 0;
|
||||
G4int counter = 0;
|
||||
|
||||
// The aim of this loop is to generate more than one fluorecence photon
|
||||
// from the same ionizing event
|
||||
do
|
||||
{
|
||||
if (counter == 0)
|
||||
// First call to GenerateParticles(...):
|
||||
// givenShellId is given by the process
|
||||
{
|
||||
provShellId = SelectTypeOfTransition(Z, givenShellId);
|
||||
|
||||
if ( provShellId >0)
|
||||
{
|
||||
aParticle = GenerateFluorescence(Z,givenShellId,provShellId);
|
||||
}
|
||||
else if ( provShellId == -1)
|
||||
{
|
||||
aParticle = GenerateAuger(Z, givenShellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4UAtomicDeexcitation: starting shell uncorrect: check it");
|
||||
}
|
||||
}
|
||||
else
|
||||
// Following calls to GenerateParticles(...):
|
||||
// newShellId is given by GenerateFluorescence(...)
|
||||
{
|
||||
provShellId = SelectTypeOfTransition(Z,newShellId);
|
||||
if (provShellId >0)
|
||||
{
|
||||
aParticle = GenerateFluorescence(Z,newShellId,provShellId);
|
||||
}
|
||||
else if ( provShellId == -1)
|
||||
{
|
||||
aParticle = GenerateAuger(Z, newShellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4UAtomicDeexcitation: starting shell uncorrect: check it");
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
if (aParticle != 0)
|
||||
{
|
||||
vectorOfParticles->push_back(aParticle);
|
||||
// G4cout << "FLUO!" << G4endl; //debug
|
||||
}
|
||||
else {provShellId = -2;}
|
||||
}
|
||||
|
||||
// Look this in a particular way: only one auger emitted! // ????
|
||||
while (provShellId > -2);
|
||||
}
|
||||
|
||||
G4double
|
||||
G4UAtomicDeexcitation::GetShellIonisationCrossSectionPerAtom(
|
||||
const G4ParticleDefinition* pdef,
|
||||
G4int Z /*Z*/,
|
||||
G4AtomicShellEnumerator shellEnum/*shell*/,
|
||||
G4double kineticEnergy/*kinE*/)
|
||||
{
|
||||
// scaling to protons
|
||||
G4double mass = proton_mass_c2;
|
||||
G4double escaled = kineticEnergy*mass/(pdef->GetPDGMass());
|
||||
G4double q = pdef->GetPDGCharge()/eplus;
|
||||
|
||||
|
||||
std::vector<G4double> atomXSs = PIXEshellCS->GetCrossSection(Z,escaled,mass,0);
|
||||
G4double res = 0.0;
|
||||
G4int idx = G4int(shellEnum);
|
||||
G4int length = atomXSs.size();
|
||||
if(idx < length) { res = q*q*atomXSs[idx]; }
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void G4UAtomicDeexcitation::SetCutForSecondaryPhotons(G4double cut)
|
||||
{
|
||||
minGammaEnergy = cut;
|
||||
}
|
||||
|
||||
void G4UAtomicDeexcitation::SetCutForAugerElectrons(G4double cut)
|
||||
{
|
||||
minElectronEnergy = cut;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4UAtomicDeexcitation::ComputeShellIonisationCrossSectionPerAtom(
|
||||
const G4ParticleDefinition* p,
|
||||
G4int Z,
|
||||
G4AtomicShellEnumerator shell,
|
||||
G4double kinE)
|
||||
{
|
||||
return GetShellIonisationCrossSectionPerAtom(p,Z,shell,kinE);
|
||||
}
|
||||
|
||||
G4int G4UAtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
|
||||
{
|
||||
if (shellId <=0 ) {
|
||||
{G4Exception("G4UAtomicDeexcitation: zero or negative shellId");}
|
||||
}
|
||||
G4bool fluoTransitionFoundFlag = false;
|
||||
|
||||
G4int provShellId = -1;
|
||||
G4int shellNum = 0;
|
||||
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
|
||||
|
||||
const G4FluoTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
|
||||
|
||||
// This loop gives shellNum the value of the index of shellId
|
||||
// in the vector storing the list of the shells reachable through
|
||||
// a radiative transition
|
||||
if ( shellId <= refShell->FinalShellId())
|
||||
{
|
||||
while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId())
|
||||
{
|
||||
if(shellNum ==maxNumOfShells-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
shellNum++;
|
||||
}
|
||||
G4int transProb = 0; //AM change 29/6/07 was 1
|
||||
|
||||
G4double partialProb = G4UniformRand();
|
||||
G4double partSum = 0;
|
||||
const G4FluoTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
|
||||
G4int trSize = (aShell->TransitionProbabilities()).size();
|
||||
|
||||
// Loop over the shells wich can provide an electron for a
|
||||
// radiative transition towards shellId:
|
||||
// in every loop the partial sum of the first transProb shells
|
||||
// is calculated and compared with a random number [0,1].
|
||||
// If the partial sum is greater, the shell whose index is transProb
|
||||
// is chosen as the starting shell for a radiative transition
|
||||
// and its identity is returned
|
||||
// Else, terminateded the loop, -1 is returned
|
||||
while(transProb < trSize){
|
||||
|
||||
partSum += aShell->TransitionProbability(transProb);
|
||||
|
||||
if(partialProb <= partSum)
|
||||
{
|
||||
provShellId = aShell->OriginatingShellId(transProb);
|
||||
fluoTransitionFoundFlag = true;
|
||||
|
||||
break;
|
||||
}
|
||||
transProb++;
|
||||
}
|
||||
|
||||
// here provShellId is the right one or is -1.
|
||||
// if -1, the control is passed to the Auger generation part of the package
|
||||
}
|
||||
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
provShellId = -1;
|
||||
|
||||
}
|
||||
return provShellId;
|
||||
}
|
||||
|
||||
G4DynamicParticle*
|
||||
G4UAtomicDeexcitation::GenerateFluorescence(G4int Z, G4int shellId,
|
||||
G4int provShellId )
|
||||
{
|
||||
//isotropic angular distribution for the outcoming photon
|
||||
G4double newcosTh = 1.-2.*G4UniformRand();
|
||||
G4double newsinTh = std::sqrt((1.-newcosTh)*(1. + newcosTh));
|
||||
G4double newPhi = twopi*G4UniformRand();
|
||||
|
||||
G4double xDir = newsinTh*std::sin(newPhi);
|
||||
G4double yDir = newsinTh*std::cos(newPhi);
|
||||
G4double zDir = newcosTh;
|
||||
|
||||
G4ThreeVector newGammaDirection(xDir,yDir,zDir);
|
||||
|
||||
G4int shellNum = 0;
|
||||
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
|
||||
|
||||
// find the index of the shell named shellId
|
||||
while (shellId != transitionManager->
|
||||
ReachableShell(Z,shellNum)->FinalShellId())
|
||||
{
|
||||
if(shellNum == maxNumOfShells-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
shellNum++;
|
||||
}
|
||||
// number of shell from wich an electron can reach shellId
|
||||
size_t transitionSize = transitionManager->
|
||||
ReachableShell(Z,shellNum)->OriginatingShellIds().size();
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
// find the index of the shell named provShellId in the vector
|
||||
// storing the shells from which shellId can be reached
|
||||
while (provShellId != transitionManager->
|
||||
ReachableShell(Z,shellNum)->OriginatingShellId(index))
|
||||
{
|
||||
if(index == transitionSize-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
// energy of the gamma leaving provShellId for shellId
|
||||
G4double transitionEnergy = transitionManager->
|
||||
ReachableShell(Z,shellNum)->TransitionEnergy(index);
|
||||
|
||||
if (transitionEnergy < minGammaEnergy) return 0;
|
||||
|
||||
// This is the shell where the new vacancy is: it is the same
|
||||
// shell where the electron came from
|
||||
newShellId = transitionManager->
|
||||
ReachableShell(Z,shellNum)->OriginatingShellId(index);
|
||||
|
||||
|
||||
G4DynamicParticle* newPart = new G4DynamicParticle(G4Gamma::Gamma(),
|
||||
newGammaDirection,
|
||||
transitionEnergy);
|
||||
return newPart;
|
||||
}
|
||||
|
||||
G4DynamicParticle* G4UAtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
{
|
||||
if(!IsAugerActive()) { return 0; }
|
||||
|
||||
if (shellId <=0 ) {
|
||||
{G4Exception("G4UAtomicDeexcitation: zero or negative shellId");}
|
||||
}
|
||||
// G4int provShellId = -1;
|
||||
G4int maxNumOfShells = transitionManager->NumberOfReachableAugerShells(Z);
|
||||
|
||||
const G4AugerTransition* refAugerTransition =
|
||||
transitionManager->ReachableAugerShell(Z,maxNumOfShells-1);
|
||||
|
||||
// This loop gives to shellNum the value of the index of shellId
|
||||
// in the vector storing the list of the vacancies in the variuos shells
|
||||
// that can originate a NON-radiative transition
|
||||
|
||||
// ---- MGP ---- Next line commented out to remove compilation warning
|
||||
// G4int p = refAugerTransition->FinalShellId();
|
||||
|
||||
G4int shellNum = 0;
|
||||
|
||||
if ( shellId <= refAugerTransition->FinalShellId() )
|
||||
//"FinalShellId" is final from the point of view of the elctron who makes the transition,
|
||||
// being the Id of the shell in which there is a vacancy
|
||||
{
|
||||
G4int pippo = transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId();
|
||||
if (shellId != pippo ) {
|
||||
do {
|
||||
shellNum++;
|
||||
if(shellNum == maxNumOfShells)
|
||||
{
|
||||
//G4Exception("G4UAtomicDeexcitation: No Auger transition found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (shellId != (transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId()) ) ;
|
||||
}
|
||||
|
||||
|
||||
// Now we have that shellnum is the shellIndex of the shell named ShellId
|
||||
|
||||
// G4cout << " the index of the shell is: "<<shellNum<<G4endl;
|
||||
|
||||
// But we have now to select two shells: one for the transition,
|
||||
// and another for the auger emission.
|
||||
|
||||
G4int transitionLoopShellIndex = 0;
|
||||
G4double partSum = 0;
|
||||
const G4AugerTransition* anAugerTransition =
|
||||
transitionManager->ReachableAugerShell(Z,shellNum);
|
||||
|
||||
// G4cout << " corresponding to the ID: "<< anAugerTransition->FinalShellId() << G4endl;
|
||||
|
||||
|
||||
G4int transitionSize =
|
||||
(anAugerTransition->TransitionOriginatingShellIds())->size();
|
||||
while (transitionLoopShellIndex < transitionSize) {
|
||||
|
||||
std::vector<G4int>::const_iterator pos =
|
||||
anAugerTransition->TransitionOriginatingShellIds()->begin();
|
||||
|
||||
G4int transitionLoopShellId = *(pos+transitionLoopShellIndex);
|
||||
G4int numberOfPossibleAuger =
|
||||
(anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size();
|
||||
G4int augerIndex = 0;
|
||||
// G4int partSum2 = 0;
|
||||
|
||||
|
||||
if (augerIndex < numberOfPossibleAuger) {
|
||||
|
||||
do
|
||||
{
|
||||
G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex,
|
||||
transitionLoopShellId);
|
||||
partSum += thisProb;
|
||||
augerIndex++;
|
||||
|
||||
} while (augerIndex < numberOfPossibleAuger);
|
||||
}
|
||||
transitionLoopShellIndex++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now we have the entire probability of an auger transition for the vacancy
|
||||
// located in shellNum (index of shellId)
|
||||
|
||||
// AM *********************** F I X E D **************************** AM
|
||||
// Here we duplicate the previous loop, this time looking to the sum of the probabilities
|
||||
// to be under the random number shoot by G4 UniformRdandom. This could have been done in the
|
||||
// previuos loop, while integrating the probabilities. There is a bug that will be fixed
|
||||
// 5 minutes from now: a line:
|
||||
// G4int numberOfPossibleAuger = (anAugerTransition->
|
||||
// AugerTransitionProbabilities(transitionLoopShellId))->size();
|
||||
// to be inserted.
|
||||
// AM *********************** F I X E D **************************** AM
|
||||
|
||||
// Remains to get the same result with a single loop.
|
||||
|
||||
// AM *********************** F I X E D **************************** AM
|
||||
// Another Bug: in EADL Auger Transition are normalized to all the transitions deriving from
|
||||
// a vacancy in one shell, but not all of these are present in data tables. So if a transition
|
||||
// doesn't occur in the main one a local energy deposition must occur, instead of (like now)
|
||||
// generating the last transition present in EADL data.
|
||||
// AM *********************** F I X E D **************************** AM
|
||||
|
||||
|
||||
G4double totalVacancyAugerProbability = partSum;
|
||||
|
||||
|
||||
//And now we start to select the right auger transition and emission
|
||||
G4int transitionRandomShellIndex = 0;
|
||||
G4int transitionRandomShellId = 1;
|
||||
G4int augerIndex = 0;
|
||||
partSum = 0;
|
||||
G4double partialProb = G4UniformRand();
|
||||
// G4int augerOriginatingShellId = 0;
|
||||
|
||||
G4int numberOfPossibleAuger = 0;
|
||||
|
||||
G4bool foundFlag = false;
|
||||
|
||||
while (transitionRandomShellIndex < transitionSize) {
|
||||
|
||||
std::vector<G4int>::const_iterator pos =
|
||||
anAugerTransition->TransitionOriginatingShellIds()->begin();
|
||||
|
||||
transitionRandomShellId = *(pos+transitionRandomShellIndex);
|
||||
|
||||
augerIndex = 0;
|
||||
numberOfPossibleAuger = (anAugerTransition->
|
||||
AugerTransitionProbabilities(transitionRandomShellId))->size();
|
||||
|
||||
while (augerIndex < numberOfPossibleAuger) {
|
||||
G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex,
|
||||
transitionRandomShellId);
|
||||
|
||||
partSum += thisProb;
|
||||
|
||||
if (partSum >= (partialProb*totalVacancyAugerProbability) ) { // was /
|
||||
foundFlag = true;
|
||||
break;
|
||||
}
|
||||
augerIndex++;
|
||||
}
|
||||
if (partSum >= (partialProb*totalVacancyAugerProbability) ) {break;} // was /
|
||||
transitionRandomShellIndex++;
|
||||
}
|
||||
|
||||
// Now we have the index of the shell from wich comes the auger electron (augerIndex),
|
||||
// and the id of the shell, from which the transition e- come (transitionRandomShellid)
|
||||
// If no Transition has been found, 0 is returned.
|
||||
|
||||
if (!foundFlag) {return 0;}
|
||||
|
||||
// Isotropic angular distribution for the outcoming e-
|
||||
G4double newcosTh = 1.-2.*G4UniformRand();
|
||||
G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
|
||||
G4double newPhi = twopi*G4UniformRand();
|
||||
|
||||
G4double xDir = newsinTh*std::sin(newPhi);
|
||||
G4double yDir = newsinTh*std::cos(newPhi);
|
||||
G4double zDir = newcosTh;
|
||||
|
||||
G4ThreeVector newElectronDirection(xDir,yDir,zDir);
|
||||
|
||||
// energy of the auger electron emitted
|
||||
|
||||
|
||||
G4double transitionEnergy = anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId);
|
||||
/*
|
||||
G4cout << "AUger TransitionId " << anAugerTransition->FinalShellId() << G4endl;
|
||||
G4cout << "augerIndex: " << augerIndex << G4endl;
|
||||
G4cout << "transitionShellId: " << transitionRandomShellId << G4endl;
|
||||
*/
|
||||
|
||||
if (transitionEnergy < minElectronEnergy) return 0;
|
||||
|
||||
// This is the shell where the new vacancy is: it is the same
|
||||
// shell where the electron came from
|
||||
newShellId = transitionRandomShellId;
|
||||
|
||||
return new G4DynamicParticle(G4Electron::Electron(),
|
||||
newElectronDirection,
|
||||
transitionEnergy);
|
||||
}
|
||||
else
|
||||
{
|
||||
//G4Exception("G4UAtomicDeexcitation: no auger transition found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VCrossSectionHandler.cc,v 1.19 2009/09/25 07:41:34 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4VCrossSectionHandler.cc,v 1.20 2010/12/02 17:39:47 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
@@ -151,6 +151,7 @@ void G4VCrossSectionHandler::Initialise(G4VDataSetAlgorithm* algorithm,
|
||||
}
|
||||
else
|
||||
{
|
||||
delete interpolation;
|
||||
interpolation = CreateInterpolation();
|
||||
}
|
||||
|
||||
@@ -496,6 +497,7 @@ G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4Data
|
||||
|
||||
G4VDataSetAlgorithm* algo = CreateInterpolation();
|
||||
G4VEMDataSet* materialSet = new G4CompositeEMDataSet(algo);
|
||||
//G4cout << "G4VCrossSectionHandler new dataset " << materialSet << G4endl;
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* data;
|
||||
|
||||
+28
-33
@@ -23,46 +23,41 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//$Id: G4VecpssrKModel.cc,v 1.2 2010/06/06 23:52:28 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
//
|
||||
// Author: Haifa Ben Abdelouahed
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 01 Sep 2009 ALF created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4VBremAngularDistribution
|
||||
//
|
||||
// Author: Andreia Trindade (andreia@lip.pt)
|
||||
// Pedro Rodrigues (psilva@lip.pt)
|
||||
// Luis Peralta (luis@lip.pt)
|
||||
// Maria Grazia Pia (MariaGrazia.Pia@ge.infn.it)
|
||||
//
|
||||
// Creation date: 21 March 2003
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Abstract base class for Bremsstrahlung Angular Distribution Generation
|
||||
//
|
||||
// Class Description: End
|
||||
|
||||
// Class description:
|
||||
// Low Energy Electromagnetic Physics, Cross section, p and alpha ionisation, L shell
|
||||
// Further documentation available from http://www.ge.infn.it/geant4/lowE
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4VBremAngularDistribution.hh"
|
||||
|
||||
//
|
||||
|
||||
G4VBremAngularDistribution::G4VBremAngularDistribution(const G4String& ) // name
|
||||
{;}
|
||||
#include "G4VecpssrKModel.hh"
|
||||
|
||||
//
|
||||
|
||||
G4VBremAngularDistribution::~G4VBremAngularDistribution()
|
||||
{;}
|
||||
G4VecpssrKModel::G4VecpssrKModel()
|
||||
{
|
||||
|
||||
void G4VBremAngularDistribution::PrintGeneratorInformation() const
|
||||
{;}
|
||||
}
|
||||
|
||||
G4VecpssrKModel::~G4VecpssrKModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
G4double G4VecpssrKModel::CalculateCrossSection(G4int,G4double,G4double)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4VecpssrLiModel.cc,v 1.2 2010/06/06 23:52:28 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
//
|
||||
// Author: Haifa Ben Abdelouahed
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 01 Sep 2009 ALF created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// Class description:
|
||||
// Low Energy Electromagnetic Physics, Cross section, p and alpha ionisation, L shell
|
||||
// Further documentation available from http://www.ge.infn.it/geant4/lowE
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "G4VecpssrLiModel.hh"
|
||||
|
||||
|
||||
G4VecpssrLiModel::G4VecpssrLiModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
G4VecpssrLiModel::~G4VecpssrLiModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*G4double G4VecpssrLiModel::CalculateL1CrossSection(G4int ,G4double , G4double )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
G4double G4VecpssrLiModel::CalculateL2CrossSection(G4int ,G4double , G4double )
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
G4double G4VecpssrLiModel::CalculateL3CrossSection(G4int ,G4double , G4double )
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
@@ -60,9 +60,11 @@ G4int G4VhShellCrossSection::SelectRandomShell(G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double mass,
|
||||
G4double deltaEnergy) const
|
||||
// returns the shell ionized if the shell exists. If the shell is not counted, it returns -1
|
||||
|
||||
{
|
||||
std::vector<G4double> p = Probabilities(Z,incidentEnergy,mass,deltaEnergy);
|
||||
G4int shell = 0;
|
||||
G4int shell = -1;
|
||||
size_t nShells = p.size();
|
||||
G4double q = G4UniformRand();
|
||||
for (size_t i=0; i<nShells; i++) {
|
||||
|
||||
@@ -1,303 +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: G4ecpssrCrossSection.cc,v 1.6.2.2 2009/12/11 18:44:44 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
//
|
||||
// Author: Haifa Ben Abdelouahed
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 21 Apr 2008 H. Ben Abdelouahed 1st implementation
|
||||
// 21 Apr 2008 MGP Major revision according to a design iteration
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// Class description:
|
||||
// Low Energy Electromagnetic Physics, Cross section, p ionisation, K shell
|
||||
// Further documentation available from http://www.ge.infn.it/geant4/lowE
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ecpssrCrossSection.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include <math.h>
|
||||
|
||||
G4ecpssrCrossSection::G4ecpssrCrossSection()
|
||||
{ }
|
||||
|
||||
G4ecpssrCrossSection::~G4ecpssrCrossSection()
|
||||
{ }
|
||||
|
||||
//---------------------------------this "ExpIntFunction" function allows fast evaluation of the n order exponential integral function En(x)------
|
||||
|
||||
G4double G4ecpssrCrossSection::ExpIntFunction(G4int n,G4double x)
|
||||
|
||||
{
|
||||
G4int i;
|
||||
G4int ii;
|
||||
G4int nm1;
|
||||
G4double a;
|
||||
G4double b;
|
||||
G4double c;
|
||||
G4double d;
|
||||
G4double del;
|
||||
G4double fact;
|
||||
G4double h;
|
||||
G4double psi;
|
||||
G4double ans = 0;
|
||||
const G4double euler= 0.5772156649;
|
||||
const G4int maxit= 100;
|
||||
const G4double fpmin = 1.0e-30;
|
||||
const G4double eps = 1.0e-7;
|
||||
nm1=n-1;
|
||||
if (n<0 || x<0.0 || (x==0.0 && (n==0 || n==1)))
|
||||
G4cout << "bad arguments in ExpIntFunction" << G4endl;
|
||||
else {
|
||||
if (n==0) ans=std::exp(-x)/x;
|
||||
else {
|
||||
if (x==0.0) ans=1.0/nm1;
|
||||
else {
|
||||
if (x > 1.0) {
|
||||
b=x+n;
|
||||
c=1.0/fpmin;
|
||||
d=1.0/b;
|
||||
h=d;
|
||||
for (i=1;i<=maxit;i++) {
|
||||
a=-i*(nm1+i);
|
||||
b +=2.0;
|
||||
d=1.0/(a*d+b);
|
||||
c=b+a/c;
|
||||
del=c*d;
|
||||
h *=del;
|
||||
if (std::fabs(del-1.0) < eps) {
|
||||
ans=h*std::exp(-x);
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ans = (nm1!=0 ? 1.0/nm1 : -std::log(x)-euler);
|
||||
fact=1.0;
|
||||
for (i=1;i<=maxit;i++) {
|
||||
fact *=-x/i;
|
||||
if (i !=nm1) del = -fact/(i-nm1);
|
||||
else {
|
||||
psi = -euler;
|
||||
for (ii=1;ii<=nm1;ii++) psi +=1.0/ii;
|
||||
del=fact*(-std::log(x)+psi);
|
||||
}
|
||||
ans += del;
|
||||
if (std::fabs(del) < std::fabs(ans)*eps) return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
G4double G4ecpssrCrossSection::CalculateCrossSection(G4int zTarget,G4int zIncident, G4double energyIncident)
|
||||
|
||||
//this K-CrossSection calculation method is done according to W.Brandt and G.Lapicki, Phys.Rev.A23(1981)//
|
||||
|
||||
{
|
||||
|
||||
G4NistManager* massManager = G4NistManager::Instance();
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double massIncident;
|
||||
|
||||
if (zIncident == 1)
|
||||
{
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
|
||||
massIncident = aProtone->GetPDGMass();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zIncident == 2)
|
||||
{
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
massIncident = aAlpha->GetPDGMass();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "we can treat only Proton or Alpha incident particles " << G4endl;
|
||||
massIncident =0.;
|
||||
}
|
||||
}
|
||||
|
||||
G4double kBindingEnergy = transitionManager->Shell(zTarget,0)->BindingEnergy();
|
||||
|
||||
G4double massTarget = (massManager->GetAtomicMassAmu(zTarget))*amu_c2;
|
||||
|
||||
G4double systemMass =((massIncident*massTarget)/(massIncident+massTarget))/electron_mass_c2;//the mass of the system (projectile, target)
|
||||
|
||||
const G4double zkshell= 0.3;
|
||||
|
||||
G4double screenedzTarget = zTarget-zkshell; // screenedzTarget is the screened nuclear charge of the target
|
||||
|
||||
const G4double rydbergMeV= 13.6e-6;
|
||||
|
||||
G4double tetaK = kBindingEnergy/((screenedzTarget*screenedzTarget)*rydbergMeV); //tetaK denotes the reduced binding energy of the electron
|
||||
|
||||
const G4double bohrPow2Barn=(Bohr_radius*Bohr_radius)/barn ;
|
||||
|
||||
G4double sigma0 = 8.*pi*(zIncident*zIncident)*bohrPow2Barn*std::pow(screenedzTarget,-4.); //sigma0 is the initial cross section of K shell at stable state
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double velocity = CalculateVelocity( zTarget, zIncident, energyIncident); //is the scaled velocity parameter of the system
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const G4double kAnalyticalApproximation= 1.5;
|
||||
|
||||
G4double x = kAnalyticalApproximation/velocity;
|
||||
|
||||
G4double electrIonizationEnergy;
|
||||
|
||||
if ( x<0.035)
|
||||
{
|
||||
electrIonizationEnergy= 0.75*pi*(std::log(1./(x*x))-1.);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( x<3.)
|
||||
{
|
||||
electrIonizationEnergy =std::exp(-2.*x)/(0.031+(0.213*std::pow(x,0.5))+(0.005*x)-(0.069*std::pow(x,3./2.))+(0.324*x*x));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
electrIonizationEnergy =2.*std::exp(-2.*x)/std::pow(x,1.6); }
|
||||
}
|
||||
|
||||
G4double hFunction =(electrIonizationEnergy*2.)/(tetaK*std::pow(velocity,3)); //hFunction represents the correction for polarization effet
|
||||
|
||||
G4double gFunction = (1.+(9.*velocity)+(31.*velocity*velocity)+(98.*std::pow(velocity,3.))+(12.*std::pow(velocity,4.))+(25.*std::pow(velocity,5.))
|
||||
+(4.2*std::pow(velocity,6.))+(0.515*std::pow(velocity,7.)))/std::pow(1.+velocity,9.); //gFunction represents the correction for binding effet
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double sigmaPSS = 1.+(((2.*zIncident)/(screenedzTarget*tetaK))*(gFunction-hFunction)); //describes the perturbed stationnairy state of the affected atomic electon
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const G4double cNaturalUnit= 1/fine_structure_const; // it's the speed of light according to Atomic-Unit-System
|
||||
|
||||
G4double ykFormula=0.4*(screenedzTarget/cNaturalUnit)*(screenedzTarget/cNaturalUnit)/(velocity/sigmaPSS);
|
||||
|
||||
G4double relativityCorrection = std::pow((1.+(1.1*ykFormula*ykFormula)),0.5)+ykFormula;// the relativistic correction parameter
|
||||
|
||||
G4double reducedVelocity = velocity*std::pow(relativityCorrection,0.5); // presents the reduced collision velocity parameter
|
||||
|
||||
G4double universalFunction = (std::pow(2.,9.)/45.)*std::pow(reducedVelocity/sigmaPSS,8.)*std::pow((1.+(1.72*(reducedVelocity/sigmaPSS)*(reducedVelocity/sigmaPSS))),-4.);// is the reduced universal cross section
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double sigmaPSSR = (sigma0/(sigmaPSS*tetaK))*universalFunction; //sigmaPSSR is the straight-line K-shell ionization cross section
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double pssDeltaK = (4./(systemMass*sigmaPSS*tetaK))*(sigmaPSS/velocity)*(sigmaPSS/velocity);
|
||||
|
||||
G4double energyLoss = std::pow(1-pssDeltaK,0.5); //energyLoss incorporates the straight-line energy-loss
|
||||
|
||||
G4double energyLossFunction = (std::pow(2.,-9)/8.)*((((9.*energyLoss)-1.)*std::pow(1.+energyLoss,9.))+(((9.*energyLoss)+1.)*std::pow(1.-energyLoss,9.)));//energy loss function
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
G4double coulombDeflection = (4.*pi*zIncident/systemMass)*std::pow(tetaK*sigmaPSS,-2.)*std::pow(velocity/sigmaPSS,-3.)*(zTarget/screenedzTarget); //incorporates Coulomb deflection parameter
|
||||
|
||||
G4double cParameter = 2.*coulombDeflection/(energyLoss*(energyLoss+1.));
|
||||
|
||||
|
||||
G4double coulombDeflectionFunction = 9.*ExpIntFunction(10,cParameter); //this function describes Coulomb-deflection effect
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
G4double crossSection = energyLossFunction* coulombDeflectionFunction*sigmaPSSR; //this ECPSSR cross section is estimated at perturbed-stationnairy-state(PSS)
|
||||
//and it's reduced by the energy-loss(E),the Coulomb deflection(C),
|
||||
//and the relativity(R) effects
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return crossSection;
|
||||
}
|
||||
|
||||
G4double G4ecpssrCrossSection::CalculateVelocity(G4int zTarget, G4int zIncident, G4double energyIncident)
|
||||
|
||||
{
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double kBindingEnergy = (transitionManager->Shell(zTarget,0)->BindingEnergy())/MeV;
|
||||
|
||||
G4double massIncident;
|
||||
|
||||
if (zIncident == 1)
|
||||
{
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
|
||||
massIncident = aProtone->GetPDGMass();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zIncident == 2)
|
||||
{
|
||||
G4Alpha* aAlpha = G4Alpha::Alpha();
|
||||
|
||||
massIncident = aAlpha->GetPDGMass();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "we can treat only Proton or Alpha incident particles " << G4endl;
|
||||
massIncident =0.;
|
||||
}
|
||||
}
|
||||
|
||||
const G4double zkshell= 0.3;
|
||||
|
||||
G4double screenedzTarget = zTarget- zkshell;
|
||||
|
||||
const G4double rydbergMeV= 13.6e-6;
|
||||
|
||||
G4double tetaK = kBindingEnergy/(screenedzTarget*screenedzTarget*rydbergMeV);
|
||||
|
||||
G4double velocity =(2./(tetaK*screenedzTarget))*std::pow(((energyIncident*electron_mass_c2)/(massIncident*rydbergMeV)),0.5);
|
||||
|
||||
return velocity;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4empCrossSection.cc,v 1.3 2010/11/12 18:09:44 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 29 Apr 2009 ALF 1st implementation
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// Class description:
|
||||
// empirical model for K and L Ionization CS for Protons and Alpha
|
||||
// Further documentation available from http://www.ge.infn.it/geant4/lowE
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4empCrossSection.hh"
|
||||
#include "G4Proton.hh"
|
||||
//#include "G4Alpha.hh"
|
||||
//#include <math.h>
|
||||
|
||||
G4empCrossSection::G4empCrossSection()
|
||||
:totalCS(0)
|
||||
{
|
||||
|
||||
paulShellK = new G4PaulKCrossSection();
|
||||
orlicShellLi = new G4OrlicLiCrossSection();
|
||||
|
||||
}
|
||||
|
||||
G4empCrossSection::~G4empCrossSection()
|
||||
{
|
||||
|
||||
delete paulShellK;
|
||||
delete orlicShellLi;
|
||||
|
||||
}
|
||||
|
||||
std::vector<G4double> G4empCrossSection::GetCrossSection(G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double mass,
|
||||
G4double deltaEnergy,
|
||||
G4bool testFlag) const
|
||||
{
|
||||
|
||||
deltaEnergy = 0;
|
||||
testFlag = 0;
|
||||
|
||||
std::vector<G4double> crossSections;
|
||||
|
||||
crossSections.push_back( paulShellK->CalculateKCrossSection(Z, mass, incidentEnergy) );
|
||||
|
||||
G4Proton* aProtone = G4Proton::Proton();
|
||||
|
||||
if (mass == aProtone->GetPDGMass() ) {
|
||||
|
||||
crossSections.push_back( orlicShellLi->CalculateL1CrossSection(Z, incidentEnergy) );
|
||||
crossSections.push_back( orlicShellLi->CalculateL2CrossSection(Z, incidentEnergy) );
|
||||
crossSections.push_back( orlicShellLi->CalculateL3CrossSection(Z, incidentEnergy) );
|
||||
}
|
||||
|
||||
return crossSections;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<G4double> G4empCrossSection::Probabilities(G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double mass,
|
||||
G4double deltaEnergy) const
|
||||
{
|
||||
|
||||
std::vector<G4double> crossSections = GetCrossSection(Z, incidentEnergy, mass, deltaEnergy);
|
||||
|
||||
for (size_t i=0; i<crossSections.size(); i++ ) {
|
||||
|
||||
if (totalCS) {
|
||||
crossSections[i] = crossSections[i]/totalCS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return crossSections;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4empCrossSection::SetTotalCS(G4double val){
|
||||
|
||||
totalCS = val;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
// 03 Oct 2005 V.Ivanchenko change logic of definition of high energy limit for
|
||||
// parametrised proton model: min(user value, model limit)
|
||||
// 26 Jan 2005 S. Chauvie added PrintInfoDefinition() for antiproton
|
||||
|
||||
|
||||
// 30 Sep 2009 A.Mantero Removed dependencies to old shell Ionisation XS models
|
||||
// 07 Jun 2010 Code Celaning for June beta Release
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -120,9 +120,6 @@
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4ShellVacancy.hh"
|
||||
#include "G4VhShellCrossSection.hh"
|
||||
#include "G4hShellCrossSection.hh"
|
||||
#include "G4hShellCrossSectionExp.hh"
|
||||
#include "G4hShellCrossSectionDoubleExp.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
@@ -131,7 +128,8 @@
|
||||
#include "G4SemiLogInterpolation.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
#include "G4teoCrossSection.hh"
|
||||
#include "G4empCrossSection.hh"
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4hLowEnergyIonisation::G4hLowEnergyIonisation(const G4String& processName)
|
||||
@@ -152,8 +150,7 @@ G4hLowEnergyIonisation::G4hLowEnergyIonisation(const G4String& processName)
|
||||
paramStepLimit (0.005),
|
||||
shellVacancy(0),
|
||||
shellCS(0),
|
||||
theFluo(false),
|
||||
expFlag(false)
|
||||
theFluo(false)
|
||||
{
|
||||
InitializeMe();
|
||||
}
|
||||
@@ -174,18 +171,12 @@ void G4hLowEnergyIonisation::InitializeMe()
|
||||
minElectronEnergy = 25.*keV;
|
||||
verboseLevel = 0;
|
||||
|
||||
//****************************************************************************
|
||||
// By default the method of cross section's calculation is swiched on an
|
||||
// 2nd implementation empirical model (G4hShellCrossSectionDoubleExp),
|
||||
// if you want to use Gryzinski's model (G4hShellCrossSection()) or the
|
||||
// 1st empiric one (G4hShellCrossSectionExp), you must change the
|
||||
// selection below and switching expFlag to FALSE
|
||||
//****************************************************************************
|
||||
shellCS = new G4teoCrossSection("analytical");
|
||||
|
||||
deexcitationManager.InitialiseForNewRun();
|
||||
deexcitationManager.SetAugerActive(false);
|
||||
deexcitationManager.SetPIXEActive(true);
|
||||
|
||||
//shellCS = new G4hShellCrossSection();
|
||||
//shellCS = new G4hShellCrossSectionExp();
|
||||
shellCS = new G4hShellCrossSectionDoubleExp();
|
||||
expFlag=true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -1002,6 +993,7 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
|
||||
|
||||
if(newpart != 0) {
|
||||
|
||||
// G4cout << "AlongStep DEEXCTATION!!!" << G4endl; //debug
|
||||
size_t nSecondaries = newpart->size();
|
||||
aParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
G4Track* newtrack = 0;
|
||||
@@ -1279,70 +1271,67 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
|
||||
// G4cout << "Fluorescence is switched :" << theFluo << G4endl;
|
||||
|
||||
// Fluorescence data start from element 6
|
||||
if(theFluo && Z > 5) {
|
||||
|
||||
|
||||
|
||||
// Atom total cross section for the Empiric Model
|
||||
if (expFlag) {
|
||||
// Atom total cross section
|
||||
shellCS->SetTotalCS(totalCrossSectionMap[Z]);
|
||||
}
|
||||
|
||||
G4int shell = shellCS->SelectRandomShell(Z, KineticEnergy,ParticleMass,DeltaKineticEnergy);
|
||||
|
||||
if (expFlag && shell==1) {
|
||||
aParticleChange.ProposeLocalEnergyDeposit (KineticEnergy);
|
||||
aParticleChange.ProposeEnergy(0);
|
||||
}
|
||||
|
||||
|
||||
const G4AtomicShell* atomicShell =
|
||||
(G4AtomicTransitionManager::Instance())->Shell(Z, shell);
|
||||
G4double bindingEnergy = atomicShell->BindingEnergy();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "PostStep Z= " << Z << " shell= " << shell
|
||||
<< " bindingE(keV)= " << bindingEnergy/keV
|
||||
<< " finalE(keV)= " << finalKineticEnergy/keV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Fluorescence data start from element 6
|
||||
|
||||
if (finalKineticEnergy >= bindingEnergy
|
||||
&& (bindingEnergy >= minGammaEnergy
|
||||
|| bindingEnergy >= minElectronEnergy) ) {
|
||||
|
||||
G4int shellId = atomicShell->ShellId();
|
||||
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
|
||||
|
||||
if (secondaryVector != 0) {
|
||||
|
||||
nSecondaries = secondaryVector->size();
|
||||
for (size_t i = 0; i<nSecondaries; i++) {
|
||||
|
||||
aSecondary = (*secondaryVector)[i];
|
||||
if (aSecondary) {
|
||||
|
||||
G4double e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if (e < finalKineticEnergy &&
|
||||
((type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
|
||||
(type == G4Electron::Electron() && e > minElectronEnergy ))) {
|
||||
|
||||
finalKineticEnergy -= e;
|
||||
totalNumber++;
|
||||
|
||||
} else {
|
||||
|
||||
delete aSecondary;
|
||||
(*secondaryVector)[i] = 0;
|
||||
if (shell!=-1) {
|
||||
|
||||
const G4AtomicShell* atomicShell =
|
||||
(G4AtomicTransitionManager::Instance())->Shell(Z, shell);
|
||||
G4double bindingEnergy = atomicShell->BindingEnergy();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "PostStep Z= " << Z << " shell= " << shell
|
||||
<< " bindingE(keV)= " << bindingEnergy/keV
|
||||
<< " finalE(keV)= " << finalKineticEnergy/keV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (finalKineticEnergy >= bindingEnergy
|
||||
&& (bindingEnergy >= minGammaEnergy
|
||||
|| bindingEnergy >= minElectronEnergy) ) {
|
||||
|
||||
// G4int shellId = atomicShell->ShellId();
|
||||
deexcitationManager.GenerateParticles(secondaryVector, atomicShell, Z, minGammaEnergy, minElectronEnergy);
|
||||
|
||||
if (secondaryVector != 0) {
|
||||
// debug G4cout << "DEEXCTATION!!!" << G4endl; //debug
|
||||
nSecondaries = secondaryVector->size();
|
||||
for (size_t i = 0; i<nSecondaries; i++) {
|
||||
|
||||
aSecondary = (*secondaryVector)[i];
|
||||
if (aSecondary) {
|
||||
|
||||
G4double e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if (e < finalKineticEnergy &&
|
||||
((type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
|
||||
(type == G4Electron::Electron() && e > minElectronEnergy ))) {
|
||||
|
||||
finalKineticEnergy -= e;
|
||||
totalNumber++;
|
||||
|
||||
} else {
|
||||
|
||||
delete aSecondary;
|
||||
(*secondaryVector)[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Save delta-electrons
|
||||
|
||||
G4double edep = 0.0;
|
||||
@@ -1400,8 +1389,26 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
std::vector<G4DynamicParticle*>*
|
||||
G4hLowEnergyIonisation::DeexciteAtom(const G4MaterialCutsCouple* couple,
|
||||
|
||||
|
||||
void G4hLowEnergyIonisation::SelectShellIonisationCS(G4String val) {
|
||||
|
||||
if (val == "analytical" ) {
|
||||
if (shellCS) delete shellCS;
|
||||
shellCS = new G4teoCrossSection(val);
|
||||
}
|
||||
else if (val == "empirical") {
|
||||
if (shellCS) delete shellCS;
|
||||
shellCS = new G4empCrossSection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
std::vector<G4DynamicParticle*>* G4hLowEnergyIonisation::DeexciteAtom(const G4MaterialCutsCouple* couple,
|
||||
G4double incidentEnergy,
|
||||
G4double hMass,
|
||||
G4double eLoss)
|
||||
@@ -1447,15 +1454,15 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4MaterialCutsCouple* couple,
|
||||
if(stop) return 0;
|
||||
|
||||
// create vector of tracks of secondary particles
|
||||
|
||||
|
||||
std::vector<G4DynamicParticle*>* partVector =
|
||||
new std::vector<G4DynamicParticle*>;
|
||||
std::vector<G4DynamicParticle*>* secVector = 0;
|
||||
std::vector<G4DynamicParticle*>* secVector = new std::vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* aSecondary = 0;
|
||||
G4ParticleDefinition* type = 0;
|
||||
G4double e, tkin, grej;
|
||||
G4ThreeVector position;
|
||||
G4int shell, shellId;
|
||||
G4int shell;
|
||||
|
||||
// sample secondaries
|
||||
|
||||
@@ -1479,44 +1486,54 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4MaterialCutsCouple* couple,
|
||||
|
||||
} while( G4UniformRand() > grej );
|
||||
|
||||
// Atom total cross section
|
||||
shellCS->SetTotalCS(totalCrossSectionMap[Z]);
|
||||
|
||||
shell = shellCS->SelectRandomShell(Z,incidentEnergy,hMass,tkin);
|
||||
|
||||
shellId = transitionManager->Shell(Z, shell)->ShellId();
|
||||
|
||||
// shellId = transitionManager->Shell(Z, shell)->ShellId();
|
||||
G4double maxE = transitionManager->Shell(Z, shell)->BindingEnergy();
|
||||
|
||||
if (maxE>minGammaEnergy || maxE>minElectronEnergy ) {
|
||||
secVector = deexcitationManager.GenerateParticles(Z, shellId);
|
||||
} else {
|
||||
secVector = 0;
|
||||
}
|
||||
|
||||
if (secVector) {
|
||||
|
||||
for (size_t l = 0; l<secVector->size(); l++) {
|
||||
|
||||
aSecondary = (*secVector)[l];
|
||||
if(aSecondary) {
|
||||
|
||||
e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if ( etot + e <= eLoss &&
|
||||
( (type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
|
||||
(type == G4Electron::Electron() && e > minElectronEnergy) ) ) {
|
||||
|
||||
etot += e;
|
||||
partVector->push_back(aSecondary);
|
||||
|
||||
} else {
|
||||
delete aSecondary;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxE>minGammaEnergy || maxE>minElectronEnergy )
|
||||
{
|
||||
deexcitationManager.GenerateParticles(secVector, transitionManager->Shell(Z, shell), Z, minGammaEnergy, minElectronEnergy);
|
||||
}
|
||||
|
||||
if (!(secVector->empty())) {
|
||||
size_t secN = secVector->size();
|
||||
for (size_t l = 0; l<secN; l++) {
|
||||
|
||||
aSecondary = (*secVector)[l];
|
||||
if(aSecondary) {
|
||||
|
||||
e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if ( etot + e <= eLoss &&
|
||||
( (type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
|
||||
(type == G4Electron::Electron() && e > minElectronEnergy) ) )
|
||||
{
|
||||
etot += e;
|
||||
partVector->push_back(aSecondary);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aSecondary;
|
||||
}
|
||||
aSecondary = 0;
|
||||
}
|
||||
(*secVector)[l] = 0;
|
||||
delete (*secVector)[l];
|
||||
}
|
||||
|
||||
// secVector = 0;
|
||||
|
||||
}
|
||||
delete secVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete secVector;
|
||||
|
||||
if(partVector->empty()) {
|
||||
delete partVector;
|
||||
return 0;
|
||||
@@ -2010,7 +2027,7 @@ void G4hLowEnergyIonisation::SetCutForAugerElectrons(G4double cut)
|
||||
|
||||
void G4hLowEnergyIonisation::ActivateAugerElectronProduction(G4bool val)
|
||||
{
|
||||
deexcitationManager.ActivateAugerElectronProduction(val);
|
||||
deexcitationManager.SetAugerActive(val);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
// Class Description:
|
||||
// Empiric Model for shell cross sections in proton ionisation
|
||||
// -------------------------------------------------------------------
|
||||
// $Id: G4hShellCrossSectionDoubleExp.cc,v 1.10 2009/06/10 13:32:36 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
// $Id: G4hShellCrossSectionDoubleExp.cc,v 1.11 2010/02/05 08:54:12 sincerti Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04-beta-01 $
|
||||
|
||||
#include "globals.hh"
|
||||
#include <vector>
|
||||
@@ -55,6 +55,8 @@
|
||||
G4hShellCrossSectionDoubleExp::G4hShellCrossSectionDoubleExp()
|
||||
{
|
||||
kShellData = new G4hShellCrossSectionDoubleExpData();
|
||||
|
||||
atomTotalCrossSection = 0.;
|
||||
}
|
||||
|
||||
G4hShellCrossSectionDoubleExp::~G4hShellCrossSectionDoubleExp()
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4teoCrossSection.cc,v 1.8 2010/11/22 22:48:30 mantero Exp $
|
||||
// GEANT4 tag $Name: geant4-09-04 $
|
||||
//
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 21 Apr 2009 ALF 1st implementation
|
||||
// 29 Apr 2009 ALF Updated Desing for Integration
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// Class description:
|
||||
// Low Energy Electromagnetic Physics, Cross section, p ionisation, K shell
|
||||
// Further documentation available from http://www.ge.infn.it/geant4/lowE
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4teoCrossSection.hh"
|
||||
//#include "G4AtomicTransitionManager.hh"
|
||||
//#include "G4NistManager.hh"
|
||||
#include "G4Proton.hh"
|
||||
//#include "G4Alpha.hh"
|
||||
//#include <math.h>
|
||||
|
||||
G4teoCrossSection::G4teoCrossSection(G4String shellModel)
|
||||
:totalCS(0)
|
||||
{
|
||||
|
||||
if (shellModel == "analytical") {
|
||||
|
||||
|
||||
ecpssrShellK = new G4AnalyticalEcpssrKCrossSection();
|
||||
ecpssrShellLi = new G4AnalyticalEcpssrLiCrossSection();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
G4teoCrossSection::~G4teoCrossSection()
|
||||
{
|
||||
|
||||
delete ecpssrShellK;
|
||||
delete ecpssrShellLi;
|
||||
|
||||
}
|
||||
|
||||
std::vector<G4double> G4teoCrossSection::GetCrossSection(G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double mass,
|
||||
G4double deltaEnergy,
|
||||
G4bool testFlag) const
|
||||
{
|
||||
|
||||
deltaEnergy = 0;
|
||||
testFlag = 0;
|
||||
|
||||
|
||||
std::vector<G4double> crossSections;
|
||||
|
||||
crossSections.push_back( ecpssrShellK->CalculateCrossSection(Z, mass, incidentEnergy) );
|
||||
|
||||
// G4Proton* aProtone = G4Proton::Proton();
|
||||
|
||||
// if (mass == aProtone->GetPDGMass() ) {
|
||||
|
||||
|
||||
// }
|
||||
|
||||
crossSections.push_back( ecpssrShellLi->CalculateL1CrossSection(Z, mass, incidentEnergy) );
|
||||
crossSections.push_back( ecpssrShellLi->CalculateL2CrossSection(Z, mass, incidentEnergy) );
|
||||
crossSections.push_back( ecpssrShellLi->CalculateL3CrossSection(Z, mass, incidentEnergy) );
|
||||
|
||||
|
||||
return crossSections;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<G4double> G4teoCrossSection::Probabilities(G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double mass,
|
||||
G4double deltaEnergy) const
|
||||
{
|
||||
|
||||
std::vector<G4double> crossSections = GetCrossSection(Z, incidentEnergy, mass, deltaEnergy);
|
||||
|
||||
for (size_t i=0; i<crossSections.size(); i++ ) {
|
||||
|
||||
if (totalCS) {
|
||||
crossSections[i] = crossSections[i]/totalCS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return crossSections;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4teoCrossSection::SetTotalCS(G4double val){
|
||||
|
||||
totalCS = val;
|
||||
// G4cout << "totalXS set to: " << val / barn << " barns" << G4endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user