Files
geant4/source/processes/electromagnetic/dna/models/src/G4DNADiracRMatrixExcitationModel.cc
T
2023-12-08 10:43:34 +01:00

319 lines
10 KiB
C++

//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Created on 2016/05/02
//
// Authors: D Sakata, S. Incerti
//
// This class perform electric excitation for electron transportation in gold,
// based on Dirac B-Spline R-Matrix method with scaled experimental data
// for low energy.
// See following reference paper
// Phys.Rev.A77,062711(2008) and Phys.Rev.A78,042713(2008)
#include "G4DNADiracRMatrixExcitationModel.hh"
#include "G4SystemOfUnits.hh"
#include "G4UAtomicDeexcitation.hh"
#include "G4LossTableManager.hh"
#include "G4Gamma.hh"
#include "G4RandomDirection.hh"
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNADiracRMatrixExcitationModel::G4DNADiracRMatrixExcitationModel
(const G4ParticleDefinition*,const G4String& nam) :
G4VEmModel(nam)
{
fpMaterialDensity = nullptr;
fHighEnergyLimit = 0;
fExperimentalEnergyLimit= 0;
fLowEnergyLimit = 0;
fParticleDefinition = nullptr;
verboseLevel = 0;
if (verboseLevel > 0)
{
G4cout << "Dirac R-matrix excitation model is constructed " << G4endl;
}
fParticleChangeForGamma = nullptr;
statCode = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DNADiracRMatrixExcitationModel::~G4DNADiracRMatrixExcitationModel()
{
delete fTableData;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DNADiracRMatrixExcitationModel::Initialise
(const G4ParticleDefinition* particle,const G4DataVector& /*cuts*/)
{
if (verboseLevel > 3)
{
G4cout <<
"Calling G4DNADiracRMatrixExcitationModel::Initialise()"
<< G4endl;
}
fParticleDefinition = particle;
if(particle->GetParticleName() == "e-")
{
fTableFile = "dna/sigma_excitation_e_diracrmatrix_Z79";
fLowEnergyLimit = 10 * eV;
fExperimentalEnergyLimit = 577.* eV;
fHighEnergyLimit = 1.0 * GeV;
}
else
{
G4Exception("G4DNADiracRMatrixExcitationModel::Initialise","em0001",
FatalException,"Not defined for other particles than electrons.");
return;
}
G4double scaleFactor = 1. * cm * cm;
fTableData = new G4DNACrossSectionDataSet
(new G4LogLogInterpolation,eV,scaleFactor );
fTableData->LoadData(fTableFile);
if( verboseLevel>0 )
{
G4cout << "Dirac R-matrix excitation model is initialized " << G4endl
<< "Energy range: "
<< LowEnergyLimit() / eV << " eV - "<< HighEnergyLimit() / keV << " keV "
<< " for "<< particle->GetParticleName()
<< G4endl;
}
if (isInitialised){return;}
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DNADiracRMatrixExcitationModel::CrossSectionPerVolume
(const G4Material* material,
const G4ParticleDefinition* particleDefinition,
G4double ekin,
G4double,
G4double)
{
if (verboseLevel > 3)
{
G4cout <<
"Calling CrossSectionPerVolume() of G4DNADiracRMatrixExcitationModel"
<< G4endl;
}
G4double atomicNDensity = material->GetAtomicNumDensityVector()[0];
// Protection: for single element
if(material->GetNumberOfElements()>1) return 0.;
G4double z = material->GetZ();
// Protection: for Gold
if(z!=79){return 0.;}
G4double sigma=0.;
if(atomicNDensity!= 0.0)
{
if (ekin >= fLowEnergyLimit && ekin < fExperimentalEnergyLimit)
{
sigma = fTableData->FindValue(ekin);
}
else if ((fExperimentalEnergyLimit <= ekin) && (ekin < fHighEnergyLimit))
{
sigma = GetExtendedTotalCrossSection(material,particleDefinition,ekin);
}
if (verboseLevel > 2)
{
G4cout<<"__________________________________" << G4endl;
G4cout<<"=== G4DNADiracRMatrixExcitationModel - XS INFO START"<<G4endl;
G4cout<<"=== Kinetic energy (eV)=" << ekin/eV << " particle : "
<<particleDefinition->GetParticleName() << G4endl;
G4cout<<"=== Cross section per atom for Z="<<z<<" is (cm^2)"
<<sigma/cm/cm << G4endl;
G4cout<<"=== Cross section per atom for Z="<<z<<" is (cm^-1)="
<<sigma*atomicNDensity/(1./cm) << G4endl;
G4cout<<"=== G4DNADiracRMatrixExcitationModel - XS INFO END"<<G4endl;
}
}
return sigma*atomicNDensity;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DNADiracRMatrixExcitationModel::SampleSecondaries
(std::vector<G4DynamicParticle*>* /*fvect*/,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* aDynamicParticle,
G4double,G4double)
{
if (verboseLevel > 3)
{
G4cout <<
"Calling SampleSecondaries() of G4DNADiracRMatrixExcitationModel"
<< G4endl;
}
G4ParticleDefinition* particle = aDynamicParticle->GetDefinition();
G4double k = aDynamicParticle->GetKineticEnergy();
G4int level = RandomSelect(couple->GetMaterial(),particle,
k);
G4double excitationEnergy = ExcitationEnergyAu[level]*eV;
G4double newEnergy = k - excitationEnergy;
if (newEnergy > 0)
{
//Energy Loss
fParticleChangeForGamma->ProposeMomentumDirection
(aDynamicParticle->GetMomentumDirection());
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
if(!statCode) fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
else fParticleChangeForGamma->SetProposedKineticEnergy(k);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNADiracRMatrixExcitationModel::GetExtendedTotalCrossSection
(const G4Material* material,
const G4ParticleDefinition* particle,
G4double kineticEnergy)
{
G4double value=0;
size_t N=fTableData->NumberOfComponents();
for(int i=0;i<(int)N;i++){
value = value+GetExtendedPartialCrossSection(material,i,particle,
kineticEnergy);
}
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DNADiracRMatrixExcitationModel::GetExtendedPartialCrossSection
(const G4Material*,
G4int level,
const G4ParticleDefinition* particle,
G4double kineticEnergy)
{
G4double value=0;
if(particle->GetParticleName()=="e-"){
if(level==0){
// y = [0]+[1]/pow(x-2,2)
value = paramFuncTCS_5dto6s1[0]+paramFuncTCS_5dto6s1[1]
/std::pow(kineticEnergy/eV-paramFuncTCS_5dto6s1[2],2);
}
else if(level==1){
// y = [0]+[1]/pow(x-2,2)
value = paramFuncTCS_5dto6s2[0]+paramFuncTCS_5dto6s2[1]
/std::pow(kineticEnergy/eV-paramFuncTCS_5dto6s2[2],2);
}
else if(level==2){
// y = [0]+[1]*log(x-2)/(x-[2])
value = paramFuncTCS_6sto6p1[0]+paramFuncTCS_6sto6p1[1]
*G4Log(kineticEnergy/eV-paramFuncTCS_6sto6p1[2])
/(kineticEnergy/eV-paramFuncTCS_6sto6p1[2]);
}
else if(level==3){
// y = [0]+[1]*log(x-2)/(x-[2])
value = paramFuncTCS_6sto6p2[0]+paramFuncTCS_6sto6p2[1]
*G4Log(kineticEnergy/eV-paramFuncTCS_6sto6p2[2])
/(kineticEnergy/eV-paramFuncTCS_6sto6p2[2]);
}
}
return value*cm*cm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int G4DNADiracRMatrixExcitationModel::RandomSelect
(const G4Material* material,
const G4ParticleDefinition* particle,
G4double kineticEnergy)
{
G4double value = 0.;
std::size_t NOfComp = fTableData->NumberOfComponents();
std::vector<G4double> valuesBuffer(NOfComp, 0.0);
const auto n = (G4int)fTableData->NumberOfComponents();
G4int i(n);
while (i > 0)
{
--i;
if
((fLowEnergyLimit<=kineticEnergy)&&(kineticEnergy<fExperimentalEnergyLimit))
{
valuesBuffer[i] = fTableData->GetComponent(i)->FindValue(kineticEnergy);
}
else if
((fExperimentalEnergyLimit<=kineticEnergy)&&(kineticEnergy<fHighEnergyLimit))
{
valuesBuffer[i]
= GetExtendedPartialCrossSection(material,i,particle,kineticEnergy);
}
value += valuesBuffer[i];
}
value *= G4UniformRand();
i = n;
while (i > 0)
{
--i;
if (valuesBuffer[i] > value)
{
return i;
}
value -= valuesBuffer[i];
}
return 9999;
}