Import Geant4 11.2.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2023-06-30 09:09:57 +02:00
parent aef78ca386
commit dd1f179cda
3780 changed files with 212808 additions and 142780 deletions
@@ -51,7 +51,6 @@
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -68,11 +67,10 @@
#include "G4ICRU90StoppingData.hh"
#include "G4Log.hh"
#include "G4DeltaAngle.hh"
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4BetheBlochModel::G4BetheBlochModel(const G4ParticleDefinition*,
const G4String& nam)
: G4VEmModel(nam),
@@ -97,20 +95,15 @@ void G4BetheBlochModel::Initialise(const G4ParticleDefinition* p,
{
if(p != particle) { SetupParameters(p); }
//G4cout << "G4BetheBlochModel::Initialise for " << p->GetParticleName()
// << " isIon= " << isIon
// << G4endl;
// always false before the run
SetDeexcitationFlag(false);
// initialisation once
if(nullptr == fParticleChange) {
const G4String& pname = particle->GetParticleName();
if(IsMaster() && G4EmParameters::Instance()->UseICRU90Data() &&
if(G4EmParameters::Instance()->UseICRU90Data() &&
(pname == "proton" || pname == "GenericIon" || pname == "alpha")) {
fICRU90 = nist->GetICRU90StoppingData();
fICRU90->Initialise();
}
if(particle->GetPDGCharge() > CLHEP::eplus ||
pname == "GenericIon") { isIon = true; }
@@ -121,17 +114,22 @@ void G4BetheBlochModel::Initialise(const G4ParticleDefinition* p,
SetAngularDistribution(new G4DeltaAngle());
}
}
// initialisation for each new run
if(IsMaster() && nullptr != fICRU90) {
fICRU90->Initialise();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BetheBlochModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
G4double kinEnergy)
{
// this method is called only for ions, so no check if it is an ion
return
(!isAlpha) ? corr->EffectiveChargeSquareRatio(p,mat,kineticEnergy) : 1.0;
if(isAlpha) { return 1.0; }
chargeSquare = corr->EffectiveChargeSquareRatio(p, mat, kinEnergy);
return chargeSquare;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -141,7 +139,7 @@ G4double G4BetheBlochModel::GetParticleCharge(const G4ParticleDefinition* p,
G4double kineticEnergy)
{
// this method is called only for ions, so no check if it is an ion
return corr->GetParticleCharge(p,mat,kineticEnergy);
return corr->GetParticleCharge(p, mat, kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -155,7 +153,7 @@ void G4BetheBlochModel::SetupParameters(const G4ParticleDefinition* p)
isIon = (!isAlpha && q > 1.1);
chargeSquare = q*q;
ratio = electron_mass_c2/mass;
static const G4double aMag = 1./(0.5*eplus*CLHEP::hbar_Planck*CLHEP::c_squared);
constexpr G4double aMag = 1./(0.5*eplus*CLHEP::hbar_Planck*CLHEP::c_squared);
G4double magmom = particle->GetPDGMagneticMoment()*mass*aMag;
magMoment2 = magmom*magmom - 1.0;
formfact = 0.0;
@@ -185,12 +183,13 @@ G4double G4BetheBlochModel::MinEnergyCut(const G4ParticleDefinition*,
G4double
G4BetheBlochModel::ComputeCrossSectionPerElectron(const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double cutEnergy,
G4double cut,
G4double maxKinEnergy)
{
G4double cross = 0.0;
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
G4double maxEnergy = std::min(tmax, maxKinEnergy);
const G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
const G4double cutEnergy = std::min(std::min(cut,tmax), tlimit);
const G4double maxEnergy = std::min(tmax, maxKinEnergy);
if(cutEnergy < maxEnergy) {
G4double totEnergy = kineticEnergy + mass;
@@ -373,23 +372,24 @@ void G4BetheBlochModel::CorrectionsAlongStep(const G4MaterialCutsCouple* couple,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
void G4BetheBlochModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double minKinEnergy,
G4double cut,
G4double maxEnergy)
{
G4double kineticEnergy = dp->GetKineticEnergy();
const G4double tmax = MaxSecondaryEnergy(dp->GetDefinition(),kineticEnergy);
const G4double maxKinEnergy = std::min(maxEnergy,tmax);
G4double kinEnergy = dp->GetKineticEnergy();
const G4double tmax = MaxSecondaryEnergy(dp->GetDefinition(), kinEnergy);
const G4double minKinEnergy = std::min(cut, tmax);
const G4double maxKinEnergy = std::min(maxEnergy, tmax);
if(minKinEnergy >= maxKinEnergy) { return; }
//G4cout << "G4BetheBlochModel::SampleSecondaries Emin= " << minKinEnergy
// << " Emax= " << maxKinEnergy << G4endl;
const G4double totEnergy = kineticEnergy + mass;
const G4double etot2 = totEnergy*totEnergy;
const G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/etot2;
const G4double totEnergy = kinEnergy + mass;
const G4double etot2 = totEnergy*totEnergy;
const G4double beta2 = kinEnergy*(kinEnergy + 2.0*mass)/etot2;
G4double deltaKinEnergy, f;
G4double f1 = 0.0;
@@ -429,7 +429,7 @@ void G4BetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
if(grej > 1.1) {
G4cout << "### G4BetheBlochModel WARNING: grej= " << grej
<< " " << dp->GetDefinition()->GetParticleName()
<< " Ekin(MeV)= " << kineticEnergy
<< " Ekin(MeV)= " << kinEnergy
<< " delEkin(MeV)= " << deltaKinEnergy
<< G4endl;
}
@@ -447,7 +447,7 @@ void G4BetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
} else {
G4double deltaMomentum =
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
std::sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
G4double cost = deltaKinEnergy * (totEnergy + electron_mass_c2) /
(deltaMomentum * dp->GetTotalMomentum());
cost = std::min(cost, 1.0);
@@ -460,7 +460,7 @@ void G4BetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
/*
G4cout << "### G4BetheBlochModel "
<< dp->GetDefinition()->GetParticleName()
<< " Ekin(MeV)= " << kineticEnergy
<< " Ekin(MeV)= " << kinEnergy
<< " delEkin(MeV)= " << deltaKinEnergy
<< " tmin(MeV)= " << minKinEnergy
<< " tmax(MeV)= " << maxKinEnergy
@@ -474,11 +474,11 @@ void G4BetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
vdp->push_back(delta);
// Change kinematics of primary particle
kineticEnergy -= deltaKinEnergy;
kinEnergy -= deltaKinEnergy;
G4ThreeVector finalP = dp->GetMomentum() - delta->GetMomentum();
finalP = finalP.unit();
finalP = finalP.unit();
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
fParticleChange->SetProposedKineticEnergy(kinEnergy);
fParticleChange->SetProposedMomentumDirection(finalP);
}
@@ -53,10 +53,16 @@
#include "G4Pow.hh"
#include "G4Exp.hh"
#include "G4ModifiedTsai.hh"
#include "G4AutoLock.hh"
const G4int G4BetheHeitlerModel::gMaxZet = 120;
std::vector<G4BetheHeitlerModel::ElementData*> G4BetheHeitlerModel::gElementData;
namespace
{
G4Mutex theBetheHMutex = G4MUTEX_INITIALIZER;
}
G4BetheHeitlerModel::G4BetheHeitlerModel(const G4ParticleDefinition*,
const G4String& nam)
: G4VEmModel(nam),
@@ -69,11 +75,8 @@ G4BetheHeitlerModel::G4BetheHeitlerModel(const G4ParticleDefinition*,
G4BetheHeitlerModel::~G4BetheHeitlerModel()
{
if (IsMaster()) {
// clear ElementData container
for (std::size_t iz = 0; iz < gElementData.size(); ++iz) {
if (gElementData[iz]) delete gElementData[iz];
}
if (isFirstInstance) {
for (auto const & ptr : gElementData) { delete ptr; }
gElementData.clear();
}
}
@@ -81,11 +84,23 @@ G4BetheHeitlerModel::~G4BetheHeitlerModel()
void G4BetheHeitlerModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if (IsMaster()) {
if (!fParticleChange) { fParticleChange = GetParticleChangeForGamma(); }
if (gElementData.empty()) {
G4AutoLock l(&theBetheHMutex);
if (gElementData.empty()) {
isFirstInstance = true;
gElementData.resize(gMaxZet+1, nullptr);
}
l.unlock();
}
// static data should be initialised only in the one instance
if(isFirstInstance) {
InitialiseElementData();
}
if (!fParticleChange) { fParticleChange = GetParticleChangeForGamma(); }
if (IsMaster()) {
// element selectors should be initialised in the master thread
if(IsMaster()) {
InitialiseElementSelectors(p, cuts);
}
}
@@ -295,17 +310,11 @@ void G4BetheHeitlerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
// should be called only by the master and at initialisation
void G4BetheHeitlerModel::InitialiseElementData()
{
G4int size = (G4int)gElementData.size();
if (size < gMaxZet+1) {
gElementData.resize(gMaxZet+1, nullptr);
}
// create for all elements that are in the detector
const G4ElementTable* elemTable = G4Element::GetElementTable();
std::size_t numElems = (*elemTable).size();
for (std::size_t ie = 0; ie < numElems; ++ie) {
const G4Element* elem = (*elemTable)[ie];
const G4int iz = std::min(gMaxZet, elem->GetZasInt());
if (!gElementData[iz]) { // create it if doesn't exist yet
auto elemTable = G4Element::GetElementTable();
for (auto const & elem : *elemTable) {
const G4int iz = std::min(gMaxZet, elem->GetZasInt());
if (nullptr == gElementData[iz]) { // create it if doesn't exist yet
G4double FZLow = 8.*elem->GetIonisation()->GetlogZ3();
G4double FZHigh = FZLow + 8.*elem->GetfCoulomb();
auto elD = new ElementData();
@@ -61,135 +61,74 @@
#include "Randomize.hh"
#include "G4Electron.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4LossTableManager.hh"
#include "G4EmCorrections.hh"
#include "G4EmParameters.hh"
#include "G4DeltaAngle.hh"
#include "G4ICRU90StoppingData.hh"
#include "G4ASTARStopping.hh"
#include "G4PSTARStopping.hh"
#include "G4NistManager.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4AutoLock.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4ASTARStopping* G4BraggIonModel::fASTAR = nullptr;
namespace
{
G4Mutex alphaMutex = G4MUTEX_INITIALIZER;
}
G4BraggIonModel::G4BraggIonModel(const G4ParticleDefinition* p,
const G4String& nam)
: G4VEmModel(nam),
theElectron(G4Electron::Electron()),
HeMass(3.727417*CLHEP::GeV),
theZieglerFactor(CLHEP::eV*CLHEP::cm2*1.0e-15),
lowestKinEnergy(0.25*CLHEP::keV)
: G4BraggModel(p, nam)
{
SetHighEnergyLimit(2.0*CLHEP::MeV);
rateMassHe2p = HeMass/CLHEP::proton_mass_c2;
HeMass = 3.727417*CLHEP::GeV;
massFactor = 1000.*CLHEP::amu_c2/HeMass;
if(nullptr != p) { SetParticle(p); }
else { SetParticle(theElectron); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4BraggIonModel::~G4BraggIonModel()
{
if(IsMaster()) { delete fASTAR; fASTAR = nullptr; }
if(isFirstAlpha) {
delete fASTAR;
fASTAR = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BraggIonModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector&)
const G4DataVector& ref)
{
if(p != particle) { SetParticle(p); }
// always false before the run
SetDeexcitationFlag(false);
// initialise once
if(nullptr == fParticleChange) {
const G4String& pname = particle->GetParticleName();
if(IsMaster()) {
if(pname == "proton" || pname == "GenericIon" || pname == "alpha") {
if(nullptr == fASTAR) { fASTAR = new G4ASTARStopping(); }
fASTAR->Initialise();
if(G4EmParameters::Instance()->UseICRU90Data()) {
fICRU90 = G4NistManager::Instance()->GetICRU90StoppingData();
fICRU90->Initialise();
}
}
G4BraggModel::Initialise(p, ref);
const G4String& pname = particle->GetParticleName();
if(pname == "alpha") { isAlpha = true; }
if(isAlpha && fASTAR == nullptr) {
G4AutoLock l(&alphaMutex);
if(fASTAR == nullptr) {
isFirstAlpha = true;
fASTAR = new G4ASTARStopping();
}
if(pname == "alpha") { isAlpha = true; }
if(UseAngularGeneratorFlag() && nullptr == GetAngularDistribution()) {
SetAngularDistribution(new G4DeltaAngle());
}
corr = G4LossTableManager::Instance()->EmCorrections();
fParticleChange = GetParticleChangeForLoss();
l.unlock();
}
if(isFirstAlpha) {
fASTAR->Initialise();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple* couple)
{
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
G4double kinEnergy)
{
return corr->EffectiveChargeSquareRatio(p,mat,kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::GetParticleCharge(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
{
return corr->GetParticleCharge(p,mat,kineticEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::ComputeCrossSectionPerElectron(
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double minKinEnergy,
G4double maxKinEnergy)
{
G4double cross = 0.0;
const G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
const G4double maxEnergy = std::min(tmax, maxKinEnergy);
const G4double cutEnergy = std::max(lowestKinEnergy*massRate, minKinEnergy);
if(cutEnergy < tmax) {
const G4double energy = kineticEnergy + mass;
const G4double energy2 = energy*energy;
const G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
cross = (maxEnergy - cutEnergy)/(cutEnergy*maxEnergy)
- beta2*G4Log(maxEnergy/cutEnergy)/tmax;
if( 0.0 < spin ) { cross += 0.5*(maxEnergy - cutEnergy)/energy2; }
cross *= CLHEP::twopi_mc2_rcl2*chargeSquare/beta2;
cross = std::max(cross, 0.0);
}
// G4cout << "BR: e= " << kineticEnergy << " tmin= " << cutEnergy
// << " tmax= " << tmax << " cross= " << cross << G4endl;
return cross;
// this method is called only for ions, so no check if it is an ion
if(isAlpha) { return 1.0; }
return G4BraggModel::GetChargeSquareRatio(p, mat, kinEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -233,40 +172,41 @@ G4double G4BraggIonModel::CrossSectionPerVolume(
G4double G4BraggIonModel::ComputeDEDXPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double minKinEnergy)
G4double cut)
{
const G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
const G4double tmin = std::max(lowestKinEnergy*massRate, minKinEnergy);
const G4double tlim = lowestKinEnergy*massRate;
const G4double tmin = std::max(std::min(cut, tmax), tlim);
G4double dedx = 0.0;
// T is alpha energy
G4double T = kineticEnergy;
const G4double zeff = material->GetTotNbOfElectPerVolume()/
material->GetTotNbOfAtomsPerVolume();
heChargeSquare = HeEffChargeSquare(zeff, T/CLHEP::MeV);
if(!isAlpha) { T *= rateMassHe2p; }
if(T < lowestKinEnergy) {
dedx = DEDX(material, lowestKinEnergy)*std::sqrt(T/lowestKinEnergy);
if(kineticEnergy < tlim) {
dedx = HeDEDX(material, tlim)*std::sqrt(kineticEnergy/tlim);
} else {
dedx = DEDX(material, T);
}
if(!isAlpha) { dedx /= heChargeSquare; }
if (tmin < tmax) {
const G4double tau = kineticEnergy/mass;
const G4double x = tmin/tmax;
dedx = HeDEDX(material, kineticEnergy);
G4double del =
(G4Log(x)*(tau + 1.)*(tau + 1.)/(tau * (tau + 2.0)) + 1.0 - x) *
CLHEP::twopi_mc2_rcl2*material->GetElectronDensity();
if(isAlpha) { del *= heChargeSquare; }
dedx += del;
if (tmin < tmax) {
const G4double tau = kineticEnergy/mass;
const G4double x = tmin/tmax;
G4double del =
(G4Log(x)*(tau + 1.)*(tau + 1.)/(tau * (tau + 2.0)) + 1.0 - x) *
CLHEP::twopi_mc2_rcl2*material->GetElectronDensity();
if(isAlpha) {
const G4double zeff = material->GetTotNbOfElectPerVolume()/
material->GetTotNbOfAtomsPerVolume();
heChargeSquare = HeEffChargeSquare(zeff, kineticEnergy/CLHEP::MeV);
del *= heChargeSquare;
}
dedx += del;
}
}
dedx = std::max(dedx, 0.0);
/*
G4cout << "BraggIon: tkin(MeV) = " << tkin/MeV << " dedx(MeV*cm^2/g) = "
<< dedx*gram/(MeV*cm2*material->GetDensity())
<< " q2 = " << chargeSquare << G4endl;
/*
G4cout << "BraggIon: " << material->GetName()
<< " E(MeV)=" << kineticEnergy/MeV
<< " Tmin(MeV)=" << tmin << " dedx(MeV*cm^2/g)="
<< dedx*gram/(MeV*cm2*material->GetDensity())
<< " q2=" << chargeSquare << G4endl;
*/
return dedx;
}
@@ -295,122 +235,19 @@ void G4BraggIonModel::CorrectionsAlongStep(const G4MaterialCutsCouple* couple,
const G4double q20 = corr->EffectiveChargeSquareRatio(p, mat, preKinEnergy);
const G4double q2 = corr->EffectiveChargeSquareRatio(p, mat, e);
const G4double qfactor = q2/q20;
/*
/*
G4cout << "G4BraggIonModel::CorrectionsAlongStep: Epre(MeV)="
<< preKinEnergy << " Eeff(MeV)=" << e
<< " eloss=" << eloss << " elossnew=" << eloss*qfactor
<< " qfactor=" << qfactor << " Qpre=" << q20
<< p->GetParticleName() <<G4endl;
*/
*/
eloss *= qfactor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BraggIonModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double minEnergy,
G4double maxEnergy)
{
const G4double tmax = MaxSecondaryKinEnergy(dp);
const G4double xmax = std::min(tmax, maxEnergy);
const G4double xmin = std::max(lowestKinEnergy*massRate, minEnergy);
if(xmin >= xmax) { return; }
G4double kineticEnergy = dp->GetKineticEnergy();
const G4double energy = kineticEnergy + mass;
const G4double energy2 = energy*energy;
const G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
const G4double grej = 1.0;
G4double deltaKinEnergy, f;
CLHEP::HepRandomEngine* rndmEngineMod = G4Random::getTheEngine();
G4double rndm[2];
// sampling follows ...
do {
rndmEngineMod->flatArray(2, rndm);
deltaKinEnergy = xmin*xmax/(xmin*(1.0 - rndm[0]) + xmax*rndm[0]);
f = 1.0 - beta2*deltaKinEnergy/tmax;
if(f > grej) {
G4cout << "G4BraggIonModel::SampleSecondary Warning! "
<< "Majorant " << grej << " < "
<< f << " for e= " << deltaKinEnergy
<< G4endl;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while( grej*rndm[1] >= f );
G4ThreeVector deltaDirection;
if(UseAngularGeneratorFlag()) {
const G4Material* mat = couple->GetMaterial();
G4int Z = SelectRandomAtomNumber(mat);
deltaDirection =
GetAngularDistribution()->SampleDirection(dp, deltaKinEnergy, Z, mat);
} else {
G4double deltaMomentum =
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
(deltaMomentum * dp->GetTotalMomentum());
if(cost > 1.0) { cost = 1.0; }
G4double sint = sqrt((1.0 - cost)*(1.0 + cost));
G4double phi = twopi*rndmEngineMod->flat();
deltaDirection.set(sint*cos(phi),sint*sin(phi), cost) ;
deltaDirection.rotateUz(dp->GetMomentumDirection());
}
// create G4DynamicParticle object for delta ray
auto delta = new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
vdp->push_back(delta);
// Change kinematics of primary particle
kineticEnergy -= deltaKinEnergy;
G4ThreeVector finalP = dp->GetMomentum() - delta->GetMomentum();
finalP = finalP.unit();
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
fParticleChange->SetProposedMomentumDirection(finalP);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::MaxSecondaryEnergy(const G4ParticleDefinition* pd,
G4double kinEnergy)
{
if(pd != particle) { SetParticle(pd); }
G4double tau = kinEnergy/mass;
G4double tmax = 2.0*electron_mass_c2*tau*(tau + 2.) /
(1. + 2.0*(tau + 1.)*ratio + ratio*ratio);
return tmax;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BraggIonModel::SetParticle(const G4ParticleDefinition* p)
{
particle = p;
mass = particle->GetPDGMass();
spin = particle->GetPDGSpin();
G4double q = particle->GetPDGCharge()/CLHEP::eplus;
chargeSquare = q*q;
massRate = mass/CLHEP::proton_mass_c2;
ratio = CLHEP::electron_mass_c2/mass;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int G4BraggIonModel::HasMaterial(const G4Material* mat) const
G4int G4BraggIonModel::HasMaterialForHe(const G4Material* mat) const
{
const G4String& chFormula = mat->GetChemicalFormula();
if(chFormula.empty()) { return -1; }
@@ -435,20 +272,16 @@ G4int G4BraggIonModel::HasMaterial(const G4Material* mat) const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::StoppingPower(const G4Material* material,
const G4double kineticEnergy) const
G4double G4BraggIonModel::HeStoppingPower(const G4double kineticEnergy) const
{
G4double ionloss = 0.0 ;
G4double ionloss = 0.0;
if (iMolecula >= 0) {
// The data and the fit from:
// ICRU Report N49, 1993. Ziegler's model for alpha
// He energy in internal units of parametrisation formula (MeV)
// Input scaled energy of a proton or GenericIon
// G4double T = kineticEnergy*rateMassHe2p/CLHEP::MeV;
G4double T = kineticEnergy/CLHEP::MeV;
G4double T = kineticEnergy/(massRate*CLHEP::MeV);
static const G4float a[11][5] = {
{9.43672f, 0.54398f, 84.341f, 1.3705f, 57.422f},
@@ -467,7 +300,7 @@ G4double G4BraggIonModel::StoppingPower(const G4Material* material,
101.96128f, 44.0098f, 16.0426f, 28.0536f, 42.0804f,
104.1512f, 44.665f, 60.0843f, 18.0152f, 18.0152f, 12.0f};
G4int i = iMolecula;
const G4int i = iMolecula;
G4double slow = (G4double)(a[i][0]);
@@ -480,7 +313,7 @@ G4double G4BraggIonModel::StoppingPower(const G4Material* material,
if ( T < 0.001 ) {
G4double shigh = G4Log( 1.0 + x3*1000.0 + x4*0.001 ) *x2*1000.0;
ionloss = slow*shigh / (slow + shigh) ;
ionloss *= sqrt(T*1000.0) ;
ionloss *= std::sqrt(T*1000.0) ;
// Main parametrisation
} else {
@@ -495,28 +328,18 @@ G4double G4BraggIonModel::StoppingPower(const G4Material* material,
<< G4endl;
*/
}
ionloss = std::max(ionloss, 0.0);
// He effective charge
ionloss /= (heChargeSquare*atomicWeight[iMolecula]);
// pure material (normally not the case for this function)
} else if(1 == (material->GetNumberOfElements())) {
const G4double z = material->GetZ() ;
ionloss = ElectronicStoppingPower( z, kineticEnergy ) ;
ionloss = std::max(ionloss, 0.0) * atomicWeight[iMolecula];
}
return ionloss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double
G4BraggIonModel::ElectronicStoppingPower(const G4double z,
const G4double kineticEnergy) const
G4double G4BraggIonModel::HeElectronicStoppingPower(const G4int z,
const G4double kineticEnergy) const
{
G4double ionloss ;
G4int i = std::min(std::max(G4lrint(z)-1,0),91); // index of atom
G4int i = std::min(z-1, 91); // index of atom
//G4cout << "ElectronicStoppingPower z=" << z << " i=" << i
// << " E=" << kineticEnergy << G4endl;
// The data and the fit from:
@@ -659,16 +482,12 @@ G4BraggIonModel::ElectronicStoppingPower(const G4double z,
*/
}
ionloss = std::max(ionloss, 0.0);
// He effective charge
// ionloss /= heChargeSquare;
// G4cout << ionloss << G4endl;
return ionloss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggIonModel::DEDX(const G4Material* material,
G4double G4BraggIonModel::HeDEDX(const G4Material* material,
const G4double aEnergy)
{
// aEnergy is energy of alpha
@@ -678,13 +497,18 @@ G4double G4BraggIonModel::DEDX(const G4Material* material,
currentMaterial = material;
baseMaterial = material->GetBaseMaterial()
? material->GetBaseMaterial() : material;
iPSTAR = -1;
iASTAR = -1;
iMolecula = -1;
iICRU90 = (nullptr != fICRU90) ? fICRU90->GetIndex(baseMaterial) : -1;
if(iICRU90 < 0) {
iASTAR = fASTAR->GetIndex(baseMaterial);
if(iASTAR < 0) { iMolecula = HasMaterial(baseMaterial); }
if(iICRU90 < 0) {
if(isAlpha) {
iASTAR = fASTAR->GetIndex(baseMaterial);
if(iASTAR < 0) { iMolecula = HasMaterialForHe(baseMaterial); }
} else {
iPSTAR = fPSTAR->GetIndex(baseMaterial);
}
}
/*
G4cout << "%%% " <<material->GetName() << " iMolecula= "
@@ -694,9 +518,16 @@ G4double G4BraggIonModel::DEDX(const G4Material* material,
}
// ICRU90
if(iICRU90 >= 0) {
eloss = fICRU90->GetElectronicDEDXforAlpha(iICRU90, aEnergy);
eloss = (isAlpha)
? fICRU90->GetElectronicDEDXforAlpha(iICRU90, aEnergy)
: fICRU90->GetElectronicDEDXforProton(iICRU90, aEnergy);
if(eloss > 0.0) { return eloss*material->GetDensity(); }
}
// PSTAR parameterisation
if( iPSTAR >= 0 ) {
return fPSTAR->GetElectronicDEDX(iPSTAR, aEnergy)
*material->GetDensity();
}
// ASTAR
if( iASTAR >= 0 ) {
eloss = fASTAR->GetElectronicDEDX(iASTAR, aEnergy);
@@ -709,28 +540,31 @@ G4double G4BraggIonModel::DEDX(const G4Material* material,
}
const std::size_t numberOfElements = material->GetNumberOfElements();
const G4ElementVector* theElmVector = material->GetElementVector();
const G4double* theAtomicNumDensityVector =
material->GetAtomicNumDensityVector();
// molecular data use proton stopping power table
// element data from ICRU49 include data for alpha
if(iMolecula >= 0) {
eloss = StoppingPower(baseMaterial, aEnergy)*material->GetDensity()/amu;
const G4double zeff = material->GetTotNbOfElectPerVolume()/
material->GetTotNbOfAtomsPerVolume();
heChargeSquare = HeEffChargeSquare(zeff, aEnergy/CLHEP::MeV);
eloss = HeStoppingPower(aEnergy)*heChargeSquare*material->GetDensity()/amu;
// pure material
} else if(1 == numberOfElements) {
const G4double z = material->GetZ();
eloss = ElectronicStoppingPower(z, aEnergy)
* (material->GetTotNbOfAtomsPerVolume());
const G4Element* element = (*theElmVector)[0];
eloss = HeElectronicStoppingPower(element->GetZasInt(), aEnergy)
* (material->GetTotNbOfAtomsPerVolume());
// Brugg's rule calculation
} else {
const G4ElementVector* theElmVector = material->GetElementVector();
// loop for the elements in the material
for (std::size_t i=0; i<numberOfElements; ++i) {
const G4Element* element = (*theElmVector)[i];
eloss += ElectronicStoppingPower(element->GetZ(), aEnergy)
eloss += HeElectronicStoppingPower(element->GetZasInt(), aEnergy)
* theAtomicNumDensityVector[i];
}
}
@@ -76,14 +76,20 @@
#include "G4NistManager.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4AutoLock.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ICRU90StoppingData* G4BraggModel::fICRU90 = nullptr;
G4PSTARStopping* G4BraggModel::fPSTAR = nullptr;
namespace
{
G4Mutex ionMutex = G4MUTEX_INITIALIZER;
}
G4BraggModel::G4BraggModel(const G4ParticleDefinition* p, const G4String& nam)
: G4VEmModel(nam),
protonMassAMU(1.007276)
: G4VEmModel(nam)
{
SetHighEnergyLimit(2.0*CLHEP::MeV);
@@ -94,14 +100,14 @@ G4BraggModel::G4BraggModel(const G4ParticleDefinition* p, const G4String& nam)
corr = G4LossTableManager::Instance()->EmCorrections();
if(nullptr != p) { SetParticle(p); }
else { SetParticle(theElectron); }
else { SetParticle(theElectron); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4BraggModel::~G4BraggModel()
{
if(IsMaster()) {
if(isFirst) {
delete fPSTAR;
fPSTAR = nullptr;
}
@@ -117,14 +123,21 @@ void G4BraggModel::Initialise(const G4ParticleDefinition* p,
// always false before the run
SetDeexcitationFlag(false);
if(IsMaster()) {
if(nullptr == fPSTAR) { fPSTAR = new G4PSTARStopping(); }
if(particle->GetPDGMass() < CLHEP::GeV) { fPSTAR->Initialise(); }
if(G4EmParameters::Instance()->UseICRU90Data()) {
if(!fICRU90) {
// initialise data only once
if(nullptr == fPSTAR) {
G4AutoLock l(&ionMutex);
if(nullptr == fPSTAR) {
isFirst = true;
fPSTAR = new G4PSTARStopping();
if(G4EmParameters::Instance()->UseICRU90Data()) {
fICRU90 = G4NistManager::Instance()->GetICRU90StoppingData();
} else if(particle->GetPDGMass() < CLHEP::GeV) { fICRU90->Initialise(); }
}
}
}
l.unlock();
}
if(isFirst) {
if(nullptr != fICRU90) { fICRU90->Initialise(); }
fPSTAR->Initialise();
}
if(nullptr == fParticleChange) {
@@ -144,14 +157,26 @@ void G4BraggModel::Initialise(const G4ParticleDefinition* p,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4BraggModel::SetParticle(const G4ParticleDefinition* p)
{
particle = p;
mass = particle->GetPDGMass();
spin = particle->GetPDGSpin();
G4double q = particle->GetPDGCharge()/CLHEP::eplus;
chargeSquare = q*q;
massRate = mass/CLHEP::proton_mass_c2;
ratio = CLHEP::electron_mass_c2/mass;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4BraggModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
G4double kinEnergy)
{
// this method is called only for ions
G4double q2 = corr->EffectiveChargeSquareRatio(p,mat,kineticEnergy);
GetModelOfFluctuations()->SetParticleAndCharge(p, q2);
return q2*corr->EffectiveChargeCorrection(p,mat,kineticEnergy);
chargeSquare = corr->EffectiveChargeSquareRatio(p, mat, kinEnergy);
return chargeSquare;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -230,22 +255,22 @@ G4double G4BraggModel::CrossSectionPerVolume(const G4Material* material,
G4double G4BraggModel::ComputeDEDXPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double kinEnergy,
G4double cut)
{
const G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
const G4double tkin = kineticEnergy/massRate;
const G4double cutEnergy = std::max(cut, lowestKinEnergy*massRate);
const G4double tmax = MaxSecondaryEnergy(p, kinEnergy);
const G4double tlim = lowestKinEnergy*massRate;
const G4double tmin = std::max(std::min(cut, tmax), tlim);
G4double dedx = 0.0;
if(tkin < lowestKinEnergy) {
dedx = DEDX(material, lowestKinEnergy)*std::sqrt(tkin/lowestKinEnergy);
if(kinEnergy < tlim) {
dedx = DEDX(material, lowestKinEnergy)*std::sqrt(kinEnergy/tlim);
} else {
dedx = DEDX(material, tkin);
dedx = DEDX(material, kinEnergy);
if (cutEnergy < tmax) {
const G4double tau = kineticEnergy/mass;
const G4double x = cutEnergy/tmax;
if (tmin < tmax) {
const G4double tau = kinEnergy/mass;
const G4double x = tmin/tmax;
dedx += (G4Log(x)*(tau + 1.)*(tau + 1.)/(tau * (tau + 2.0)) + 1.0 - x) *
CLHEP::twopi_mc2_rcl2 * material->GetElectronDensity();
@@ -268,7 +293,7 @@ void G4BraggModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
{
const G4double tmax = MaxSecondaryKinEnergy(dp);
const G4double xmax = std::min(tmax, maxEnergy);
const G4double xmin = std::max(lowestKinEnergy*massRate, minEnergy);
const G4double xmin = std::max(lowestKinEnergy*massRate, std::min(minEnergy, xmax));
if(xmin >= xmax) { return; }
G4double kineticEnergy = dp->GetKineticEnergy();
@@ -328,7 +353,7 @@ void G4BraggModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
// Change kinematics of primary particle
kineticEnergy -= deltaKinEnergy;
G4ThreeVector finalP = dp->GetMomentum() - delta->GetMomentum();
finalP = finalP.unit();
finalP = finalP.unit();
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
fParticleChange->SetProposedMomentumDirection(finalP);
@@ -55,12 +55,11 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
using namespace std;
G4CoulombScattering::G4CoulombScattering(const G4String& name)
: G4VEmProcess(name),q2Max(CLHEP::TeV*CLHEP::TeV),isInitialised(false)
G4CoulombScattering::G4CoulombScattering(const G4String& nam, G4bool comb)
: G4VEmProcess(nam),
q2Max(CLHEP::TeV*CLHEP::TeV),
isCombined(comb)
{
// G4cout << "G4CoulombScattering constructor "<< G4endl;
SetBuildTableFlag(true);
SetStartFromNullFlag(false);
SetSplineFlag(false);
@@ -71,6 +70,18 @@ G4CoulombScattering::G4CoulombScattering(const G4String& name)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4CoulombScattering::G4CoulombScattering(const G4String& nam)
: G4CoulombScattering(nam, true)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4CoulombScattering::G4CoulombScattering(G4bool comb)
: G4CoulombScattering("CoulombScat", comb)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4CoulombScattering::~G4CoulombScattering() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -95,13 +106,30 @@ void G4CoulombScattering::InitialiseProcess(const G4ParticleDefinition* p)
G4double theta = param->MscThetaLimit();
// restricted or non-restricted cross section table
G4bool yes = false;
if(theta == CLHEP::pi) {
yes = true;
// for restriced single scattering change cross section shape
SetCrossSectionType(fEmIncreasing);
if(isCombined) {
if(theta == CLHEP::pi) {
// for restriced single scattering change cross section shape
SetCrossSectionType(fEmIncreasing);
SetStartFromNullFlag(true);
}
} else {
SetSplineFlag(true);
SetCrossSectionType(fEmDecreasing);
}
isInitialised = true;
G4double mass = p->GetPDGMass();
G4String name = p->GetParticleName();
G4bool ion = false;
if (mass > CLHEP::GeV || p->GetParticleType() == "nucleus") {
SetBuildTableFlag(false);
ion = true;
if(name != "GenericIon") { SetVerboseLevel(0); }
} else {
if(name != "e-" && name != "e+" &&
name != "mu+" && name != "mu-" && name != "pi+" &&
name != "kaon+" && name != "proton" ) { SetVerboseLevel(0); }
}
SetStartFromNullFlag(yes);
/*
G4cout << "### G4CoulombScattering::InitialiseProcess: "
<< p->GetParticleName()
@@ -109,28 +137,14 @@ void G4CoulombScattering::InitialiseProcess(const G4ParticleDefinition* p)
<< " Emax(TeV)= " << MaxKinEnergy()/TeV
<< " nbins= " << LambdaBinning()
<< " theta= " << theta
<< " mass(MeV)= " << mass
<< " isCombined=" << isCombined
<< " ion=" << ion
<< G4endl;
*/
isInitialised = true;
G4double mass = p->GetPDGMass();
G4String name = p->GetParticleName();
//G4cout << name << " type: " << p->GetParticleType()
//<< " mass= " << mass << G4endl;
yes = true;
if (mass > CLHEP::GeV || p->GetParticleType() == "nucleus") {
SetBuildTableFlag(false);
yes = false;
if(name != "GenericIon") { SetVerboseLevel(0); }
} else {
if(name != "e-" && name != "e+" &&
name != "mu+" && name != "mu-" && name != "pi+" &&
name != "kaon+" && name != "proton" ) { SetVerboseLevel(0); }
}
if(nullptr == EmModel(0)) {
if(yes) { SetEmModel(new G4eCoulombScatteringModel()); }
else { SetEmModel(new G4IonCoulombScatteringModel()); }
if(ion) { SetEmModel(new G4IonCoulombScatteringModel()); }
else { SetEmModel(new G4eCoulombScatteringModel(isCombined)); }
}
G4VEmModel* model = EmModel(0);
G4double emin = std::max(param->MinKinEnergy(),model->LowEnergyLimit());
@@ -153,9 +167,9 @@ G4double G4CoulombScattering::MinPrimaryEnergy(const G4ParticleDefinition* part,
G4double theta = G4EmParameters::Instance()->MscThetaLimit();
if(0.0 < theta) {
G4double p2 = q2Max*mat->GetIonisation()->GetInvA23()/(1.0 - cos(theta));
G4double p2 = q2Max*mat->GetIonisation()->GetInvA23()/(1.0 - std::cos(theta));
G4double mass = part->GetPDGMass();
emin = sqrt(p2 + mass*mass) - mass;
emin = p2/(std::sqrt(p2 + mass*mass) + mass);
}
return emin;
@@ -171,7 +185,9 @@ void G4CoulombScattering::StreamProcessInfo(std::ostream& outFile) const
else { outFile << tetmin; }
outFile << " < Theta(degree) < 180";
if(q2Max < DBL_MAX) { outFile << "; pLimit(GeV^1)= " << sqrt(q2Max)/GeV; }
if(q2Max < DBL_MAX) {
outFile << ", pLimit(GeV^1)= " << std::sqrt(q2Max)/GeV;
}
outFile << G4endl;
}
@@ -46,6 +46,7 @@
#include "G4ESTARStopping.hh"
#include "G4SystemOfUnits.hh"
#include "G4Material.hh"
#include "G4EmParameters.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -101,14 +102,7 @@ G4double G4ESTARStopping::GetElectronicDEDX(G4int i, G4double energy)
}
void G4ESTARStopping::Initialise()
{
dirPath = G4FindDataDir("G4LEDATA");
if(!dirPath) {
G4Exception("G4ESTARStopping()","em0006",FatalException,
"Environment variable G4LEDATA not defined");
return;
}
{
static const G4double T0[25]={1.0E-03,3.0E-03,5.0E-03,9.0E-03,2.5E-02,4.5E-02,8.0E-02,.2,.4,.7,1.5,3.5,6.0,10.,30.,50.,90.,250.,450.,800.,2000.,4.0E+03,6.0E+03,8.0E+03,1.0E+04};
name[1]="G4_1,2-DICHLOROBENZENE";
@@ -960,6 +954,8 @@ void G4ESTARStopping::AddData(const G4double* ekin, const G4double* stop,
static const G4double fac = MeV*cm2/g;
if(nullptr != sdata[idx]) { delete sdata[idx]; }
const G4String& dirPath = G4EmParameters::Instance()->GetDirLEDATA();
// hardtyped data
if(0 == type) {
sdata[idx] = new G4PhysicsFreeVector(25, ekin[0]*MeV, ekin[24]*MeV, true);
@@ -53,6 +53,7 @@
#include "G4Material.hh"
#include "G4ElementVector.hh"
#include "G4Element.hh"
#include "G4EmParameters.hh"
#include <iostream>
#include <fstream>
@@ -262,14 +263,7 @@ void G4GSMottCorrection::LoadMCDataElement(const G4Element *elem) {
fMCDataPerElement[izet] = perElem;
//
// load data from file
const char* tmppath = G4FindDataDir("G4LEDATA");
if (!tmppath) {
G4Exception("G4GSMottCorrection::LoadMCDataElement()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
return;
}
std::string path(tmppath);
std::string path = G4EmParameters::Instance()->GetDirLEDATA();
if (fIsElectron) {
path += "/msc_GS/MottCor/el/";
} else {
@@ -51,6 +51,7 @@
#include "G4Material.hh"
#include "G4ElementVector.hh"
#include "G4Element.hh"
#include "G4EmParameters.hh"
const std::string G4GSPWACorrections::gElemSymbols[] = {"H","He","Li","Be","B" ,
@@ -180,14 +181,7 @@ void G4GSPWACorrections::LoadDataElement(const G4Element *elem) {
izet = gMaxZet;
}
// load data from file
const char* tmppath = G4FindDataDir("G4LEDATA");
if (!tmppath) {
G4Exception("G4GSPWACorrection::LoadDataElement()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
return;
}
std::string path(tmppath);
std::string path = G4EmParameters::Instance()->GetDirLEDATA();
if (fIsElectron) {
path += "/msc_GS/PWACor/el/";
} else {
@@ -87,6 +87,7 @@
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ProductionCutsTable.hh"
#include "G4EmParameters.hh"
#include "G4String.hh"
@@ -435,16 +436,8 @@ G4GoudsmitSaundersonTable::GSMSCAngularDtr* G4GoudsmitSaundersonTable::GetGSAngu
void G4GoudsmitSaundersonTable::LoadMSCData() {
const char* path = G4FindDataDir("G4LEDATA");
if (!path) {
G4Exception("G4GoudsmitSaundersonTable::LoadMSCData()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
return;
}
//
gGSMSCAngularDistributions1.resize(gLAMBNUM*gQNUM1,nullptr);
const G4String str1 = G4String(path) + "/msc_GS/GSGrid_1/gsDistr_";
const G4String str1 = G4EmParameters::Instance()->GetDirLEDATA() + "/msc_GS/GSGrid_1/gsDistr_";
for (G4int il=0; il<gLAMBNUM; ++il) {
G4String fname = str1 + std::to_string(il);
std::ifstream infile(fname,std::ios::in);
@@ -474,7 +467,7 @@ void G4GoudsmitSaundersonTable::LoadMSCData() {
//
// second grid
gGSMSCAngularDistributions2.resize(gLAMBNUM*gQNUM2,nullptr);
const G4String str2 = G4String(path) + "/msc_GS/GSGrid_2/gsDistr_";
const G4String str2 = G4EmParameters::Instance()->GetDirLEDATA() + "/msc_GS/GSGrid_2/gsDistr_";
for (G4int il=0; il<gLAMBNUM; ++il) {
G4String fname = str2 + std::to_string(il);
std::ifstream infile(fname,std::ios::in);
@@ -101,7 +101,7 @@ G4IonICRU73Data::G4IonICRU73Data()
fEmax = 2.5*CLHEP::MeV;
fNbins = fNbinsPerDecade*G4lrint(std::log10(fEmax/fEmin));
fVector = new G4PhysicsFreeVector(fSpline);
for(G4int i=0; i<81; ++i) {
for(G4int i=3; i<=ZPROJMAX; ++i) {
fMatData[i] = new std::vector<G4PhysicsLogVector*>;
}
}
@@ -111,13 +111,17 @@ G4IonICRU73Data::G4IonICRU73Data()
G4IonICRU73Data::~G4IonICRU73Data()
{
delete fVector;
for(G4int i=0; i<81; ++i) {
for(G4int i=3; i<=ZPROJMAX; ++i) {
auto v = fMatData[i];
for(G4int j=0; j<fNmat; ++j) {
delete (*v)[j];
if(nullptr != v) {
for(auto & dat : *v) {
delete dat;
}
delete v;
}
for(G4int j=1; j<=ZTARGMAX; ++j) {
delete fElmData[i][j];
}
delete v;
for(G4int j=0; j<93; ++j) { delete fElmData[i][j]; }
}
}
@@ -127,9 +131,9 @@ G4double G4IonICRU73Data::GetDEDX(const G4Material* mat, const G4int Z,
const G4double e, const G4double loge) const
{
G4PhysicsLogVector* v = nullptr;
G4int Z2 = std::min(Z, 80);
G4int Z2 = std::min(Z, ZPROJMAX);
if(1 == mat->GetNumberOfElements()) {
G4int Z1 = std::min((*(mat->GetElementVector()))[0]->GetZasInt(), 80);
G4int Z1 = std::min((*(mat->GetElementVector()))[0]->GetZasInt(), ZTARGMAX);
v = fElmData[Z2][Z1];
} else {
G4int idx = fMatIndex[mat->GetIndex()];
@@ -149,27 +153,20 @@ void G4IonICRU73Data::Initialise()
{
// fill directory path
if(fDataDirectory.empty()) {
const char* path = G4FindDataDir("G4LEDATA");
if (nullptr != path) {
std::ostringstream ost;
ost << path << "/ion_stopping_data/";
fDataDirectory = ost.str();
} else {
G4Exception("G4IonICRU73Data::Initialise(..)","em013",
FatalException,
"Environment variable G4LEDATA is not defined");
}
std::ostringstream ost;
ost << G4EmParameters::Instance()->GetDirLEDATA() << "/ion_stopping_data/";
fDataDirectory = ost.str();
}
std::size_t nmat = G4Material::GetNumberOfMaterials();
if(nmat == fMatIndex.size()) { return; }
if(0 < fVerbose) {
if(1 < fVerbose) {
G4cout << "### G4IonICRU73Data::Initialise() for " << nmat
<< " materials" << G4endl;
}
fMatIndex.resize(nmat, -1);
for(G4int j=0; j<81; ++j) {
for(G4int j=3; j<=ZPROJMAX; ++j) {
fMatData[j]->resize(nmat, nullptr);
}
G4bool useICRU90 = G4EmParameters::Instance()->UseICRU90Data();
@@ -181,7 +178,8 @@ void G4IonICRU73Data::Initialise()
G4int idx = (G4int)mat->GetIndex();
if(1 < fVerbose) {
G4cout << i << ". material:" << mat->GetName()
<< " idx=" << idx << G4endl;
<< " idx=" << idx << " matIdx=" << fMatIndex[idx]
<< " fNmat=" << fNmat << G4endl;
}
if(fMatIndex[idx] == -1) {
fMatIndex[idx] = i;
@@ -191,7 +189,7 @@ void G4IonICRU73Data::Initialise()
ReadElementData(mat, useICRU90);
isOK = true;
if(1 < fVerbose) {
G4cout << "Material from single element" << G4endl;
G4cout << "Material from single element fNmat=" << fNmat << G4endl;
}
}
if(!isOK && useICRU90) {
@@ -225,6 +223,9 @@ void G4IonICRU73Data::Initialise()
}
}
}
if(1 < fVerbose) {
G4cout << " matData: " << fMatData[i] << G4endl;
}
}
}
@@ -235,7 +236,7 @@ void G4IonICRU73Data::ReadMaterialData(const G4Material* mat,
const G4bool useICRU90)
{
G4String name = mat->GetName();
for(G4int Z=3; Z<81; ++Z) {
for(G4int Z=3; Z<=ZPROJMAX; ++Z) {
std::ostringstream ost;
ost << fDataDirectory << "icru";
G4int Z1 = Z;
@@ -294,7 +295,7 @@ void G4IonICRU73Data::ReadElementData(const G4Material* mat, G4bool useICRU90)
const G4ElementVector* elmv = mat->GetElementVector();
const G4double* dens = mat->GetFractionVector();
const G4int nelm = (G4int)mat->GetNumberOfElements();
for(G4int Z=3; Z<81; ++Z) {
for(G4int Z=3; Z<ZPROJMAX; ++Z) {
G4PhysicsLogVector* v = nullptr;
if(1 == nelm) {
v = FindOrBuildElementData(Z, (*elmv)[0]->GetZasInt(), useICRU90);
@@ -310,8 +311,8 @@ void G4IonICRU73Data::ReadElementData(const G4Material* mat, G4bool useICRU90)
v->PutValue(i, dedx);
}
if(fSpline) { v->FillSecondDerivatives(); }
(*(fMatData[Z]))[fNmat] = v;
}
(*(fMatData[Z]))[fNmat] = v;
// scale data for correct units
if(nullptr != v) {
const G4double fact =
@@ -333,7 +334,7 @@ G4IonICRU73Data::FindOrBuildElementData(const G4int Z, const G4int Z1,
G4bool useICRU90)
{
G4PhysicsLogVector* v = nullptr;
if(Z <= 80 && Z1 <= 92) {
if(Z <= ZPROJMAX && Z1 <= ZTARGMAX) {
v = fElmData[Z][Z1];
if(nullptr == v) {
G4int Z2 = Z1;
@@ -413,7 +414,7 @@ G4IonICRU73Data::RetrieveVector(std::ostringstream& ost, G4bool warn)
v->PutValue(i, dedx);
}
if(fSpline) { v->FillSecondDerivatives(); }
if(fVerbose > 1) { G4cout << *v << G4endl; }
if(fVerbose > 2) { G4cout << *v << G4endl; }
}
}
return v;
@@ -52,9 +52,10 @@
#include "G4Log.hh"
#include "G4DeltaAngle.hh"
#include "G4LindhardSorensenData.hh"
#include "G4BraggIonModel.hh"
#include "G4BraggModel.hh"
#include "G4BetheBlochModel.hh"
#include "G4IonICRU73Data.hh"
#include "G4AutoLock.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -62,26 +63,35 @@ using namespace std;
G4LindhardSorensenData* G4LindhardSorensenIonModel::lsdata = nullptr;
G4IonICRU73Data* G4LindhardSorensenIonModel::fIonData = nullptr;
std::vector<G4float>* G4LindhardSorensenIonModel::fact[] = {nullptr};
namespace
{
G4Mutex ionXSMutex = G4MUTEX_INITIALIZER;
}
G4LindhardSorensenIonModel::G4LindhardSorensenIonModel(const G4ParticleDefinition*,
const G4String& nam)
: G4VEmModel(nam),
particle(nullptr),
twoln10(2.0*G4Log(10.0))
{
fParticleChange = nullptr;
theElectron = G4Electron::Electron();
corr = G4LossTableManager::Instance()->EmCorrections();
nist = G4NistManager::Instance();
fBraggModel = new G4BraggIonModel();
fBraggModel = new G4BraggModel();
fBBModel = new G4BetheBlochModel();
fElimit = 2.0*CLHEP::MeV;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4LindhardSorensenIonModel::~G4LindhardSorensenIonModel() = default;
G4LindhardSorensenIonModel::~G4LindhardSorensenIonModel() {
if(isFirst) {
delete lsdata;
delete fIonData;
lsdata = nullptr;
fIonData = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -91,8 +101,6 @@ void G4LindhardSorensenIonModel::Initialise(const G4ParticleDefinition* p,
fBraggModel->Initialise(p, ptr);
fBBModel->Initialise(p, ptr);
SetParticle(p);
//G4cout << "G4LindhardSorensenIonModel::Initialise for "
// << p->GetParticleName() << G4endl;
// always false before the run
SetDeexcitationFlag(false);
@@ -103,13 +111,16 @@ void G4LindhardSorensenIonModel::Initialise(const G4ParticleDefinition* p,
SetAngularDistribution(new G4DeltaAngle());
}
}
if(IsMaster()) {
if(nullptr == lsdata) {
G4AutoLock l(&ionXSMutex);
if(nullptr == lsdata) {
isFirst = true;
lsdata = new G4LindhardSorensenData();
}
if(nullptr == fIonData) {
fIonData = new G4IonICRU73Data();
}
l.unlock();
}
if(isFirst) {
fIonData->Initialise();
}
}
@@ -121,7 +132,7 @@ G4LindhardSorensenIonModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kinEnergy)
{
chargeSquare = corr->EffectiveChargeSquareRatio(p,mat,kinEnergy);
chargeSquare = corr->EffectiveChargeSquareRatio(p, mat, kinEnergy);
return chargeSquare;
}
@@ -230,7 +241,7 @@ G4LindhardSorensenIonModel::ComputeDEDXPerVolume(const G4Material* mat,
: fBBModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cutEnergy);
//G4cout << "E(MeV)=" << kinEnergy/MeV << " dedx=" << dedx
// << " " << material->GetName() << " Ecut(MeV)=" << cutEnergy << G4endl;
// << " " << mat->GetName() << " Ecut(MeV)=" << cutEnergy << G4endl;
return dedx;
}
@@ -254,8 +265,6 @@ void G4LindhardSorensenIonModel::CorrectionsAlongStep(
const G4double tmax = MaxSecondaryEnergy(p, e);
const G4double escaled = e*pRatio;
const G4double tau = e/mass;
const G4double q20 = corr->EffectiveChargeSquareRatio(p, mat, preKinEnergy);
const G4double q2 = corr->EffectiveChargeSquareRatio(p, mat, e);
const G4int Z = p->GetAtomicNumber();
@@ -265,7 +274,7 @@ void G4LindhardSorensenIonModel::CorrectionsAlongStep(
if(Z > 2 && Z <= 80) {
res = fIonData->GetDEDX(mat, Z, escaled, G4Log(escaled));
/*
G4cout << "GetDEDX for Z=" << Z << " in " << mat->GetName()
G4cout << " GetDEDX for Z=" << Z << " in " << mat->GetName()
<< " Escaled=" << escaled << " E="
<< e << " dEdx=" << res << G4endl;
*/
@@ -281,7 +290,7 @@ void G4LindhardSorensenIonModel::CorrectionsAlongStep(
res *= length;
} else {
// simplified correction
res = eloss*q2/q20;
res = eloss*q2/chargeSquare;
}
} else {
// Lindhard-Sorensen model
@@ -292,18 +301,16 @@ void G4LindhardSorensenIonModel::CorrectionsAlongStep(
res = eloss +
CLHEP::twopi_mc2_rcl2*q2*eDensity*(deltaL+deltaL0)*length/beta2;
/*
G4cout << "G4LindhardSorensenIonModel::CorrectionsAlongStep: E(GeV)= "
<< preKinEnergy/GeV << " eloss(MeV)= " << eloss
<< " L= " << eloss*beta2/(twopi_mc2_rcl2*chargeSquare*eDensity*length)
<< " dL0= " << deltaL0
<< " dL= " << deltaL << G4endl;
*/
/*
G4cout << " E(GeV)=" << preKinEnergy/GeV << " eloss(MeV)=" << eloss
<< " L= " << eloss*beta2/(twopi_mc2_rcl2*q2*eDensity*length)
<< " dL0= " << deltaL0
<< " dL= " << deltaL << " dE(MeV)=" << res - eloss << G4endl;
*/
}
if(res > preKinEnergy) { res = preKinEnergy; }
else if(res < 0.0) { res = eloss; }
if(res > preKinEnergy || 2*res < eloss) { res = eloss; }
/*
G4cout << "G4LindhardSorensenIonModel::CorrectionsAlongStep: E(GeV)="
G4cout << " G4LindhardSorensenIonModel::CorrectionsAlongStep: E(GeV)="
<< preKinEnergy/GeV << " eloss(MeV)=" << eloss
<< " res(MeV)=" << res << G4endl;
*/
@@ -321,17 +328,17 @@ void G4LindhardSorensenIonModel::SampleSecondaries(
{
G4double kineticEnergy = dp->GetKineticEnergy();
// take into account formfactor
G4double tmax = MaxSecondaryEnergy(dp->GetDefinition(),kineticEnergy);
G4double minKinEnergy = std::min(cut, tmax);
G4double maxKinEnergy = std::min(maxEnergy,tmax);
const G4double tmax = MaxSecondaryEnergy(dp->GetDefinition(), kineticEnergy);
const G4double minKinEnergy = std::min(cut, tmax);
const G4double maxKinEnergy = std::min(maxEnergy, tmax);
if(minKinEnergy >= maxKinEnergy) { return; }
//G4cout << "G4LindhardSorensenIonModel::SampleSecondaries Emin= "
// << minKinEnergy << " Emax= " << maxKinEnergy << G4endl;
G4double totEnergy = kineticEnergy + mass;
G4double etot2 = totEnergy*totEnergy;
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/etot2;
G4double totEnergy = kineticEnergy + mass;
G4double etot2 = totEnergy*totEnergy;
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/etot2;
G4double deltaKinEnergy, f;
G4double f1 = 0.0;
@@ -421,7 +428,7 @@ void G4LindhardSorensenIonModel::SampleSecondaries(
// Change kinematics of primary particle
kineticEnergy -= deltaKinEnergy;
G4ThreeVector finalP = dp->GetMomentum() - delta->GetMomentum();
finalP = finalP.unit();
finalP = finalP.unit();
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
fParticleChange->SetProposedMomentumDirection(finalP);
@@ -148,13 +148,6 @@ void G4PAIModel::Initialise(const G4ParticleDefinition* p,
G4Material* mat = (*theMaterialTable)[jMat];
const G4MaterialCutsCouple* cutCouple = reg->FindCouple(mat);
std::size_t n = fMaterialCutsCoupleVector.size();
/*
G4cout << "Region: " << reg->GetName() << " " << reg
<< " Couple " << cutCouple
<< " PAI defined for " << n << " couples"
<< " jMat= " << jMat << " " << mat->GetName()
<< G4endl;
*/
if(nullptr != cutCouple) {
if(fVerbose > 1) {
G4cout << "Region <" << curReg->GetName() << "> mat <"
@@ -189,10 +182,9 @@ void G4PAIModel::Initialise(const G4ParticleDefinition* p,
/////////////////////////////////////////////////////////////////////////
void G4PAIModel::InitialiseLocal(const G4ParticleDefinition* p,
void G4PAIModel::InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel* masterModel)
{
SetParticle(p);
fModelData = static_cast<G4PAIModel*>(masterModel)->GetPAIModelData();
fMaterialCutsCoupleVector =
static_cast<G4PAIModel*>(masterModel)->GetVectorOfCouples();
@@ -214,20 +206,13 @@ G4double G4PAIModel::ComputeDEDXPerVolume(const G4Material*,
G4double kineticEnergy,
G4double cutEnergy)
{
//G4cout << "===1=== " << CurrentCouple()
// << " idx= " << CurrentCouple()->GetIndex()
// << " " << fMaterialCutsCoupleVector[0]
// << G4endl;
G4int coupleIndex = FindCoupleIndex(CurrentCouple());
//G4cout << "===2=== " << coupleIndex << G4endl;
if(0 > coupleIndex) { return 0.0; }
G4double cut = std::min(MaxSecondaryEnergy(p, kineticEnergy), cutEnergy);
G4double scaledTkin = kineticEnergy*fRatio;
return fChargeSquare*fModelData->DEDXPerVolume(coupleIndex, scaledTkin,
cut);
G4double dedx = fChargeSquare*fModelData->DEDXPerVolume(coupleIndex, scaledTkin, cut);
return dedx;
}
/////////////////////////////////////////////////////////////////////////
@@ -238,23 +223,16 @@ G4double G4PAIModel::CrossSectionPerVolume( const G4Material*,
G4double cutEnergy,
G4double maxEnergy )
{
//G4cout << "===3=== " << CurrentCouple()
// << " idx= " << CurrentCouple()->GetIndex()
// << " " << fMaterialCutsCoupleVector[0]
// << G4endl;
G4int coupleIndex = FindCoupleIndex(CurrentCouple());
//G4cout << "===4=== " << coupleIndex << G4endl;
if(0 > coupleIndex) { return 0.0; }
G4double tmax = std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
if(tmax <= cutEnergy) { return 0.0; }
G4double scaledTkin = kineticEnergy*fRatio;
return fChargeSquare*fModelData->CrossSectionPerVolume(coupleIndex,
scaledTkin,
cutEnergy,
tmax);
G4double xs = fChargeSquare*fModelData->CrossSectionPerVolume(coupleIndex,
scaledTkin, cutEnergy, tmax);
return xs;
}
///////////////////////////////////////////////////////////////////////////
@@ -303,7 +281,7 @@ void G4PAIModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4Element* anElement = SelectTargetAtom(matCC, fParticle, kineticEnergy,
dp->GetLogKineticEnergy());
G4int Z = G4lrint(anElement->GetZ());
G4int Z = anElement->GetZasInt();
auto deltaRay = new G4DynamicParticle(fElectron,
GetAngularDistribution()->SampleDirection(dp, deltaTkin,
@@ -171,10 +171,7 @@ void G4PAIModelData::Initialise(const G4MaterialCutsCouple* couple,
//G4cout << "DEDXVector:" << G4endl;
//G4cout << *dEdxVector << G4endl;
G4double ionloss = fPAIySection.GetMeanEnergyLoss();// total <dE/dx>
if(ionloss < 0.0) ionloss = 0.0;
G4double ionloss = std::max(fPAIySection.GetMeanEnergyLoss(), 0.0);// total <dE/dx>
dEdxMeanVector->PutValue(i,ionloss);
PAItransferTable->insertAt(i,transferVector);
@@ -141,11 +141,11 @@ void G4PAIPhotData::Initialise(const G4MaterialCutsCouple* couple,
const vector<G4double>* photonCutInKineticEnergy = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
G4double deltaCutInKineticEnergyNow = (*deltaCutInKineticEnergy)[jMatCC];
G4double photonCutInKineticEnergyNow = (*photonCutInKineticEnergy)[jMatCC];
/*
G4cout<<"G4PAIPhotData::Initialise: "<<"cut = "<<cut/keV<<" keV; cutEl = "
<<deltaCutInKineticEnergyNow/keV<<" keV; cutPh = "
<<photonCutInKineticEnergyNow/keV<<" keV"<<G4endl;
*/
// if( deltaCutInKineticEnergyNow != cut ) deltaCutInKineticEnergyNow = cut; // exception??
auto dEdxCutVector =
@@ -222,10 +222,7 @@ void G4PAIPhotData::Initialise(const G4MaterialCutsCouple* couple,
}
// G4cout << *transferVector << G4endl;
G4double ionloss = fPAIxSection.GetMeanEnergyLoss();// total <dE/dx>
if(ionloss < 0.0) ionloss = 0.0;
G4double ionloss = std::max(fPAIxSection.GetMeanEnergyLoss(), 0.0);// total <dE/dx>
dEdxMeanVector->PutValue(i,ionloss);
G4double dNdxCut = transferVector->Value(deltaCutInKineticEnergyNow)/deltaCutInKineticEnergyNow;
@@ -42,14 +42,9 @@
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4Region.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsFreeVector.hh"
#include "G4PhysicsTable.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4MaterialTable.hh"
#include "G4SandiaTable.hh"
#include "G4OrderedTable.hh"
#include "G4RegionStore.hh"
#include "Randomize.hh"
@@ -92,7 +87,6 @@ G4PAIPhotModel::G4PAIPhotModel(const G4ParticleDefinition* p, const G4String& na
G4PAIPhotModel::~G4PAIPhotModel()
{
//G4cout << "G4PAIPhotModel::~G4PAIPhotModel() " << this << G4endl;
if(IsMaster()) { delete fModelData; fModelData = nullptr; }
}
@@ -101,7 +95,7 @@ G4PAIPhotModel::~G4PAIPhotModel()
void G4PAIPhotModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if(fVerbose > 0)
if(fVerbose > 1)
{
G4cout<<"G4PAIPhotModel::Initialise for "<<p->GetParticleName()<<G4endl;
}
@@ -110,9 +104,6 @@ void G4PAIPhotModel::Initialise(const G4ParticleDefinition* p,
if( IsMaster() )
{
InitialiseElementSelectors(p, cuts);
delete fModelData;
fMaterialCutsCoupleVector.clear();
@@ -143,10 +134,9 @@ void G4PAIPhotModel::Initialise(const G4ParticleDefinition* p,
{
G4Material* mat = (*theMaterialTable)[jMat];
const G4MaterialCutsCouple* cutCouple = reg->FindCouple(mat);
//G4cout << "Couple <" << fCutCouple << G4endl;
if(cutCouple)
if(nullptr != cutCouple)
{
if(fVerbose>0)
if(fVerbose > 1)
{
G4cout << "Reg <" <<curReg->GetName() << "> mat <"
<< mat->GetName() << "> fCouple= "
@@ -178,6 +168,7 @@ void G4PAIPhotModel::Initialise(const G4ParticleDefinition* p,
}
}
}
InitialiseElementSelectors(p, cuts);
}
}
@@ -210,10 +201,9 @@ G4double G4PAIPhotModel::ComputeDEDXPerVolume(const G4Material*,
if(0 > coupleIndex) { return 0.0; }
G4double cut = std::min(MaxSecondaryEnergy(p, kineticEnergy), cutEnergy);
G4double scaledTkin = kineticEnergy*fRatio;
return fChargeSquare*fModelData->DEDXPerVolume(coupleIndex, scaledTkin, cut);
G4double dedx = fChargeSquare*fModelData->DEDXPerVolume(coupleIndex, scaledTkin, cut);
return dedx;
}
/////////////////////////////////////////////////////////////////////////
@@ -225,18 +215,15 @@ G4double G4PAIPhotModel::CrossSectionPerVolume( const G4Material*,
G4double maxEnergy )
{
G4int coupleIndex = FindCoupleIndex(CurrentCouple());
if(0 > coupleIndex) return 0.0;
if(0 > coupleIndex) { return 0.0; }
G4double tmax = std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
if(tmax <= cutEnergy) return 0.0;
if(tmax <= cutEnergy) { return 0.0; }
G4double scaledTkin = kineticEnergy*fRatio;
G4double xsc = fChargeSquare*fModelData->CrossSectionPerVolume(coupleIndex,
scaledTkin,
cutEnergy, tmax);
return xsc;
G4double xs = fChargeSquare*fModelData->CrossSectionPerVolume(coupleIndex,
scaledTkin, cutEnergy, tmax);
return xs;
}
///////////////////////////////////////////////////////////////////////////
@@ -277,15 +264,15 @@ void G4PAIPhotModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
if( deltaTkin <= 0. && fVerbose > 0)
{
G4cout<<"G4PAIPhotModel::SampleSecondary e- deltaTkin = "<<deltaTkin<<G4endl;
G4cout<<"G4PAIPhotModel::SampleSecondary e- deltaTkin = "<<deltaTkin<<G4endl;
}
if( deltaTkin <= 0.) return;
if( deltaTkin <= 0.) { return; }
if( deltaTkin > tmax) deltaTkin = tmax;
if( deltaTkin > tmax) { deltaTkin = tmax; }
const G4Element* anElement = SelectTargetAtom(matCC,fParticle,kineticEnergy,
dp->GetLogKineticEnergy());
G4int Z = G4lrint(anElement->GetZ());
G4int Z = anElement->GetZasInt();
auto deltaRay = new G4DynamicParticle(fElectron,
GetAngularDistribution()->SampleDirection(dp, deltaTkin,
@@ -300,7 +287,6 @@ void G4PAIPhotModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
{
fParticleChange->SetProposedKineticEnergy(0.0);
fParticleChange->ProposeLocalEnergyDeposit(kineticEnergy+deltaTkin);
// fParticleChange->ProposeTrackStatus(fStopAndKill);
return;
}
else
@@ -375,22 +361,18 @@ G4double G4PAIPhotModel::SampleFluctuations(
SetParticle(aParticle->GetDefinition());
// G4cout << "G4PAIPhotModel::SampleFluctuations step(mm)= "<< step/mm
// << " Eloss(keV)= " << eloss/keV << " in "
// << matCC->GetMaterial()->GetName() << G4endl;
G4double Tkin = aParticle->GetKineticEnergy();
G4double scaledTkin = Tkin*fRatio;
G4double loss = fModelData->SampleAlongStepPhotonTransfer(coupleIndex, Tkin,
scaledTkin,
step*fChargeSquare);
loss += fModelData->SampleAlongStepPlasmonTransfer(coupleIndex, Tkin,
scaledTkin,
step*fChargeSquare);
scaledTkin,
step*fChargeSquare);
loss += fModelData->SampleAlongStepPlasmonTransfer(coupleIndex, Tkin,
scaledTkin, step*fChargeSquare);
// G4cout<<" PAIPhotModel::SampleFluctuations loss = "<<loss/keV<<" keV, on step = "
// <<step/mm<<" mm"<<G4endl;
@@ -1102,10 +1102,6 @@ G4double G4PAIxSection::GetPhotonRange( G4double energy1 )
energy3 = energy2*energy1;
energy4 = energy3*energy1;
// G4double* SandiaCof = fSandia->GetSandiaCofForMaterialPAI(energy1);
// result = SandiaCof[0]/energy1+SandiaCof[1]/energy2+SandiaCof[2]/energy3+SandiaCof[3]/energy4;
// result *= fDensity;
for( i = 1; i <= fIntervalNumber; i++ )
{
if( energy1 < fEnergyInterval[i]) break;
@@ -1222,23 +1218,18 @@ G4double G4PAIxSection::RePartDielectricConst(G4double enb)
// simplified Allison's equation
//
G4double G4PAIxSection::DifPAIxSection( G4int i ,
G4double betaGammaSq )
G4double G4PAIxSection::DifPAIxSection( G4int i , G4double betaGammaSq )
{
G4double cof,x1,x2,x3,x4,x5,x6,x7,x8,result;
G4double betaBohr = fine_structure_const;
// G4double betaBohr2 = fine_structure_const*fine_structure_const;
// G4double betaBohr3 = betaBohr*betaBohr2; // *4.0;
G4double be2 = betaGammaSq/(1 + betaGammaSq);
G4double beta = sqrt(be2);
// G4double be3 = beta*be2;
G4double beta = std::sqrt(be2);
cof = 1.;
x1 = log(2*electron_mass_c2/fSplineEnergy[i]);
x1 = std::log(2*electron_mass_c2/fSplineEnergy[i]);
if( betaGammaSq < 0.01 ) x2 = log(be2);
if( betaGammaSq < 0.01 ) x2 = std::log(be2);
else
{
x2 = -log( (1/betaGammaSq - fRePartDielectricConst[i])*
@@ -1259,12 +1250,9 @@ G4double G4PAIxSection::DifPAIxSection( G4int i ,
x7 = atan2(fImPartDielectricConst[i],x3);
x6 = x5 * x7;
}
// if(fImPartDielectricConst[i] == 0) x6 = 0.;
x4 = ((x1 + x2)*fImPartDielectricConst[i] + x6)/hbarc;
// if( x4 < 0.0 ) x4 = 0.0;
x8 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
@@ -1278,18 +1266,10 @@ G4double G4PAIxSection::DifPAIxSection( G4int i ,
G4double lowCof = fLowEnergyCof; // 6.0 ; // Ar ~ 4.; -> fLowCof as f(Z1,Z2)?
result *= (1 - exp(-beta/betaBohr/lowCof));
// result *= (1 - exp(-be2/betaBohr2/lowCof));
// result *= (1 - exp(-be3/betaBohr3/lowCof)); // ~ be for be<<betaBohr
// result *= (1 - exp(-be4/betaBohr4/lowCof));
if(fDensity >= 0.1)
result *= (1 - std::exp(-beta/betaBohr/lowCof));
if(x8 >= 0.0)
{
result /= x8;
result /= x8;
}
return result;
@@ -1306,13 +1286,13 @@ G4double G4PAIxSection::PAIdNdxCerenkov( G4int i ,
G4double be2, betaBohr2, cofBetaBohr;
cofBetaBohr = 4.0;
betaBohr2 = fine_structure_const*fine_structure_const;
G4double betaBohr4 = betaBohr2*betaBohr2*cofBetaBohr;
betaBohr2 = fine_structure_const*fine_structure_const;
G4double betaBohr4 = betaBohr2*betaBohr2*cofBetaBohr;
be2 = betaGammaSq/(1 + betaGammaSq);
G4double be4 = be2*be2;
if( betaGammaSq < 0.01 ) logarithm = log(1.0+betaGammaSq); // 0.0;
if( betaGammaSq < 0.01 ) logarithm = std::log(1.0+betaGammaSq); // 0.0;
else
{
logarithm = -log( (1/betaGammaSq - fRePartDielectricConst[i])*
@@ -1332,7 +1312,7 @@ G4double G4PAIxSection::PAIdNdxCerenkov( G4int i ,
be2*((1.0 +fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i]);
if( x3 == 0.0 ) argument = 0.5*pi;
else argument = atan2(fImPartDielectricConst[i],x3);
else argument = std::atan2(fImPartDielectricConst[i],x3);
argument *= x5 ;
}
dNdxC = ( logarithm*fImPartDielectricConst[i] + argument )/hbarc;
@@ -1341,13 +1321,13 @@ G4double G4PAIxSection::PAIdNdxCerenkov( G4int i ,
dNdxC *= fine_structure_const/be2/pi;
dNdxC *= (1-exp(-be4/betaBohr4));
dNdxC *= (1-std::exp(-be4/betaBohr4));
if(fDensity >= 0.1)
modul2 = (1.0 + fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
if(modul2 >= 0.0)
{
modul2 = (1.0 + fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
dNdxC /= modul2;
dNdxC /= modul2;
}
return dNdxC;
@@ -1397,7 +1377,7 @@ G4double G4PAIxSection::PAIdNdxMM( G4int i ,
dNdxC *= fine_structure_const/be2/pi;
dNdxC *= (1-exp(-be4/betaBohr4));
dNdxC *= (1-std::exp(-be4/betaBohr4));
return dNdxC;
} // end of PAIdNdxMM
@@ -1416,26 +1396,23 @@ G4double G4PAIxSection::PAIdNdxPlasmon( G4int i ,
betaBohr = fine_structure_const;
be2 = betaGammaSq/(1 + betaGammaSq);
G4double beta = sqrt(be2);
G4double beta = std::sqrt(be2);
resonance = log(2*electron_mass_c2*be2/fSplineEnergy[i]);
resonance = std::log(2*electron_mass_c2*be2/fSplineEnergy[i]);
resonance *= fImPartDielectricConst[i]/hbarc;
dNdxP = ( resonance + cof*fIntegralTerm[i]/fSplineEnergy[i]/fSplineEnergy[i] );
if( dNdxP < 1.0e-8 ) dNdxP = 1.0e-8;
dNdxP *= fine_structure_const/be2/pi;
dNdxP *= (1 - exp(-beta/betaBohr/fLowEnergyCof));
dNdxP *= (1 - std::exp(-beta/betaBohr/fLowEnergyCof));
// dNdxP *= (1-exp(-be4/betaBohr4));
if( fDensity >= 0.1 )
modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
if( modul2 >= 0.0 )
{
modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
dNdxP /= modul2;
}
return dNdxP;
@@ -1463,18 +1440,17 @@ G4double G4PAIxSection::PAIdNdxResonance( G4int i ,
resonance = log(2*electron_mass_c2*be2/fSplineEnergy[i]);
resonance *= fImPartDielectricConst[i]/hbarc;
dNdxP = resonance;
if( dNdxP < 1.0e-8 ) dNdxP = 1.0e-8;
dNdxP *= fine_structure_const/be2/pi;
dNdxP *= (1-exp(-be4/betaBohr4));
dNdxP *= (1 - std::exp(-be4/betaBohr4));
if( fDensity >= 0.1 )
modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
if( modul2 >= 0.0 )
{
modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
dNdxP /= modul2;
}
return dNdxP;
@@ -1655,8 +1631,9 @@ G4double G4PAIxSection::SumOverInterval( G4int i )
if(fVerbose>0) G4cout<<"SumOverInterval, a = "<<a<<"; c = "<<c<<G4endl;
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.;
if( std::abs(a) < 1.e-6 )
{
@@ -1669,7 +1646,7 @@ G4double G4PAIxSection::SumOverInterval( G4int i )
a += 1.;
if( std::abs(a) < 1.e-6 )
{
fIntegralPAIxSection[0] += b*log(x1/x0);
fIntegralPAIxSection[0] += b*log(x1/x0);
}
else
{
@@ -1695,8 +1672,10 @@ G4double G4PAIxSection::SumOverIntervaldEdx( G4int i )
yy1 = fDifPAIxSection[i+1];
c = x1/x0;
a = log10(yy1/y0)/log10(c);
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 2;
if(a == 0)
{
@@ -1732,7 +1711,9 @@ G4double G4PAIxSection::SumOverInterCerenkov( G4int i )
c = x1/x0;
a = log10(yy1/y0)/log10(c);
b = y0/pow(x0,a);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if(a == 0) result = b*log(c);
@@ -1769,8 +1750,9 @@ G4double G4PAIxSection::SumOverInterMM( G4int i )
c = x1/x0;
//G4cout<<" c = "<<c<< " yy1/y0= " << yy1/y0 <<G4endl;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.0;
if(a == 0) result = b*log(c);
@@ -1801,11 +1783,11 @@ G4double G4PAIxSection::SumOverInterPlasmon( G4int i )
y0 = fdNdxPlasmon[i];
yy1 = fdNdxPlasmon[i+1];
c =x1/x0;
c = x1/x0;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.0;
if(a == 0) result = b*log(x1/x0);
@@ -1838,9 +1820,9 @@ G4double G4PAIxSection::SumOverInterResonance( G4int i )
yy1 = fdNdxResonance[i+1];
c =x1/x0;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.0;
if(a == 0) result = b*log(x1/x0);
@@ -1873,12 +1855,11 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
if(a > 10.0) return 0.;
if(fVerbose>0) G4cout<<"SumOverBorder, a = "<<a<<G4endl;
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); // pow(10.,b);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.;
if( std::abs(a) < 1.e-6 )
@@ -1903,11 +1884,12 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
y0 = fDifPAIxSection[i - 1];
yy1 = fDifPAIxSection[i - 2];
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.;
if( std::abs(a) < 1.e-6 )
{
@@ -1932,10 +1914,9 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
///////////////////////////////////////////////////////////////////////
G4double G4PAIxSection::SumOverBorderdEdx( G4int i ,
G4double en0 )
G4double G4PAIxSection::SumOverBorderdEdx( G4int i, G4double en0 )
{
G4double x0,x1,y0,yy1,a,b,/*c,*/d,e0,result;
G4double x0,x1,y0,yy1,a,b,d,e0,result;
e0 = en0;
x0 = fSplineEnergy[i];
@@ -1943,12 +1924,11 @@ G4double G4PAIxSection::SumOverBorderdEdx( G4int i ,
y0 = fDifPAIxSection[i];
yy1 = fDifPAIxSection[i+1];
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
if(a > 10.0) return 0.;
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); // pow(10.,b);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 2;
if(a == 0)
@@ -1967,8 +1947,10 @@ G4double G4PAIxSection::SumOverBorderdEdx( G4int i ,
// c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 2;
if(a == 0)
{
@@ -1987,8 +1969,7 @@ G4double G4PAIxSection::SumOverBorderdEdx( G4int i ,
// Integration of Cerenkov cross-section for the case of
// passing across border between intervals
G4double G4PAIxSection::SumOverBordCerenkov( G4int i ,
G4double en0 )
G4double G4PAIxSection::SumOverBordCerenkov( G4int i, G4double en0 )
{
G4double x0,x1,y0,yy1,a,b,e0,c,d,result;
@@ -1998,15 +1979,15 @@ G4double G4PAIxSection::SumOverBordCerenkov( G4int i ,
y0 = fdNdxCerenkov[i];
yy1 = fdNdxCerenkov[i+1];
// G4cout<<G4endl;
// G4cout<<"SumBordC, i = "<<i<<"; en0 = "<<en0<<"; x0 ="<<x0<<"; x1 = "<<x1
// <<"; y0 = "<<y0<<"; yy1 = "<<yy1<<G4endl;
//G4cout<<"SumBordC, i = "<<i<<"; en0 = "<<en0<<"; x0 ="<<x0<<"; x1 = "<<x1
//<<"; y0 = "<<y0<<"; yy1 = "<<yy1<<G4endl;
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); // pow(10.,b0);
//G4cout << " a= " << a << " c=" << c << G4endl;
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result = b*log(x0/e0);
@@ -2016,8 +1997,6 @@ G4double G4PAIxSection::SumOverBordCerenkov( G4int i ,
if( a == 0 ) fIntegralCerenkov[0] += b*log(x0/e0);
else fIntegralCerenkov[0] += y0*(x0*x0 - e0*e0*pow(d,a-2))/a;
// G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "<<b<<"; result = "<<result<<G4endl;
x0 = fSplineEnergy[i - 1];
x1 = fSplineEnergy[i - 2];
y0 = fdNdxCerenkov[i - 1];
@@ -2028,23 +2007,21 @@ G4double G4PAIxSection::SumOverBordCerenkov( G4int i ,
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); // pow(10.,b0);
a = log10(yy1/y0)/log10(c);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result += b*log(e0/x0);
else result += y0*(e0*pow(d,a-1) - x0 )/a;
a += 1.0;
if( a == 0 ) fIntegralCerenkov[0] += b*log(e0/x0);
else fIntegralCerenkov[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
// G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "
// <<b<<"; result = "<<result<<G4endl;
if( a == 0 ) fIntegralCerenkov[0] += b*log(e0/x0);
else fIntegralCerenkov[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
//G4cout<<" a="<< a <<" b="<< b <<" result="<<result<<G4endl;
return result;
}
///////////////////////////////////////////////////////////////////////////////
@@ -2052,8 +2029,7 @@ G4double G4PAIxSection::SumOverBordCerenkov( G4int i ,
// Integration of MM-Cerenkov cross-section for the case of
// passing across border between intervals
G4double G4PAIxSection::SumOverBordMM( G4int i ,
G4double en0 )
G4double G4PAIxSection::SumOverBordMM( G4int i, G4double en0 )
{
G4double x0,x1,y0,yy1,a,b,e0,c,d,result;
@@ -2063,15 +2039,14 @@ G4double G4PAIxSection::SumOverBordMM( G4int i ,
y0 = fdNdxMM[i];
yy1 = fdNdxMM[i+1];
// G4cout<<G4endl;
// G4cout<<"SumBordC, i = "<<i<<"; en0 = "<<en0<<"; x0 ="<<x0<<"; x1 = "<<x1
// <<"; y0 = "<<y0<<"; yy1 = "<<yy1<<G4endl;
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); // pow(10.,b0);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result = b*log(x0/e0);
@@ -2081,7 +2056,7 @@ G4double G4PAIxSection::SumOverBordMM( G4int i ,
if( a == 0 ) fIntegralMM[0] += b*log(x0/e0);
else fIntegralMM[0] += y0*(x0*x0 - e0*e0*pow(d,a-2))/a;
// G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "<<b<<"; result = "<<result<<G4endl;
// G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "<<b<<"; result = "<<result<<G4endl;
x0 = fSplineEnergy[i - 1];
x1 = fSplineEnergy[i - 2];
@@ -2094,16 +2069,17 @@ G4double G4PAIxSection::SumOverBordMM( G4int i ,
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); // pow(10.,b0);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result += b*log(e0/x0);
else result += y0*(e0*pow(d,a-1) - x0 )/a;
a += 1.0;
if( a == 0 ) fIntegralMM[0] += b*log(e0/x0);
else fIntegralMM[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
if( a == 0 ) fIntegralMM[0] += b*log(e0/x0);
else fIntegralMM[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
// G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "
// <<b<<"; result = "<<result<<G4endl;
@@ -2131,9 +2107,9 @@ G4double G4PAIxSection::SumOverBordPlasmon( G4int i ,
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); //pow(10.,b);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result = b*log(x0/e0);
@@ -2151,8 +2127,9 @@ G4double G4PAIxSection::SumOverBordPlasmon( G4int i ,
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(c);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);// pow(10.,b0);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result += b*log(e0/x0);
@@ -2163,7 +2140,6 @@ G4double G4PAIxSection::SumOverBordPlasmon( G4int i ,
else fIntegralPlasmon[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
return result;
}
///////////////////////////////////////////////////////////////////////////////
@@ -2185,9 +2161,9 @@ G4double G4PAIxSection::SumOverBordResonance( G4int i ,
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(c);
if(a > 10.0) return 0.;
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a); //pow(10.,b);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result = b*log(x0/e0);
@@ -2205,16 +2181,17 @@ G4double G4PAIxSection::SumOverBordResonance( G4int i ,
c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(c);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);// pow(10.,b0);
if(a > 20.0) b = 0.0;
else b = y0/pow(x0,a);
a += 1.0;
if( a == 0 ) result += b*log(e0/x0);
else result += y0*(e0*pow(d,a-1) - x0)/a;
a += 1.0;
if( a == 0 ) fIntegralResonance[0] += b*log(e0/x0);
else fIntegralResonance[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
if( a == 0 ) fIntegralResonance[0] += b*log(e0/x0);
else fIntegralResonance[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
return result;
@@ -2234,7 +2211,7 @@ G4double G4PAIxSection::GetStepEnergyLoss( G4double step )
meanNumber = fIntegralPAIxSection[1]*step;
numOfCollisions = G4Poisson(meanNumber);
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl;
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl;
while(numOfCollisions)
{
@@ -2261,7 +2238,7 @@ G4double G4PAIxSection::GetEnergyTransfer()
for( iTransfer = 1; iTransfer <= fSplineNumber; iTransfer++ )
{
if( position >= fIntegralPAIxSection[iTransfer] ) break;
if( position >= fIntegralPAIxSection[iTransfer] ) break;
}
if(iTransfer > fSplineNumber) iTransfer--;
@@ -2369,7 +2346,7 @@ G4double G4PAIxSection::GetMMEnergyTransfer()
for( iTransfer = 1; iTransfer <= fSplineNumber; iTransfer++ )
{
if( position >= fIntegralMM[iTransfer] ) break;
if( position >= fIntegralMM[iTransfer] ) break;
}
if(iTransfer > fSplineNumber) iTransfer--;
@@ -2423,7 +2400,7 @@ G4double G4PAIxSection::GetPlasmonEnergyTransfer()
for( iTransfer = 1; iTransfer <= fSplineNumber; iTransfer++ )
{
if( position >= fIntegralPlasmon[iTransfer] ) break;
if( position >= fIntegralPlasmon[iTransfer] ) break;
}
if(iTransfer > fSplineNumber) iTransfer--;
@@ -2478,7 +2455,7 @@ G4double G4PAIxSection::GetResonanceEnergyTransfer()
for( iTransfer = 1; iTransfer <= fSplineNumber; iTransfer++ )
{
if( position >= fIntegralResonance[iTransfer] ) break;
if( position >= fIntegralResonance[iTransfer] ) break;
}
if(iTransfer > fSplineNumber) iTransfer--;
@@ -2506,7 +2483,7 @@ G4double G4PAIxSection::GetRutherfordEnergyTransfer()
for( iTransfer = 1; iTransfer <= fSplineNumber; iTransfer++ )
{
if( position >= (fIntegralPlasmon[iTransfer]-fIntegralResonance[iTransfer]) ) break;
if( position >= (fIntegralPlasmon[iTransfer]-fIntegralResonance[iTransfer]) ) break;
}
if(iTransfer > fSplineNumber) iTransfer--;
@@ -81,8 +81,8 @@ G4PAIySection::G4PAIySection()
betaBohr = fine_structure_const;
G4double cofBetaBohr = 4.0;
G4double betaBohr2 = fine_structure_const*fine_structure_const;
betaBohr4 = betaBohr2*betaBohr2*cofBetaBohr;
G4double betaBohr2 = fine_structure_const*fine_structure_const;
betaBohr4 = betaBohr2*betaBohr2*cofBetaBohr;
fSplineEnergy = G4DataVector(fMaxSplineSize,0.0);
fRePartDielectricConst = G4DataVector(fMaxSplineSize,0.0);
@@ -371,12 +371,12 @@ void G4PAIySection::NormShift(G4double betaGammaSq)
// G4cout<<"fNormalizationCof = "<<fNormalizationCof<<G4endl;
// Calculation of PAI differrential cross-section (1/(keV*cm))
// in the energy points near borders of energy intervals
// Calculation of PAI differrential cross-section (1/(keV*cm))
// in the energy points near borders of energy intervals
for(G4int k=1; k<=fIntervalNumber-1; ++k)
for(G4int k=1; k<=fIntervalNumber-1; ++k)
{
for(j=1; j<=2; ++j)
for(j=1; j<=2; ++j)
{
i = (k-1)*2 + j;
fImPartDielectricConst[i] = fNormalizationCof*
@@ -412,8 +412,8 @@ void G4PAIySection::SplainPAI(G4double betaGammaSq)
++i;
continue;
}
// Shifting of arrayes for inserting the geometrical
// average of 'i' and 'i+1' energy points to 'i+1' place
// Shifting of arrayes for inserting the geometrical
// average of 'i' and 'i+1' energy points to 'i+1' place
fSplineNumber++;
for(G4int j = fSplineNumber; j >= i+2; j-- )
@@ -435,15 +435,15 @@ void G4PAIySection::SplainPAI(G4double betaGammaSq)
G4double en1 = sqrt(x1*x2);
fSplineEnergy[i+1] = en1;
// Calculation of logarithmic linear approximation
// in this (enr) energy point, which number is 'i+1' now
// Calculation of logarithmic linear approximation
// in this (enr) energy point, which number is 'i+1' now
G4double a = log10(y2/yy1)/log10(x2/x1);
G4double b = log10(yy1) - a*log10(x1);
G4double y = a*log10(en1) + b;
y = pow(10.,y);
// Calculation of the PAI dif. cross-section at this point
// Calculation of the PAI dif. cross-section at this point
fImPartDielectricConst[i+1] = fNormalizationCof*
ImPartDielectricConst(k,fSplineEnergy[i+1]);
@@ -508,8 +508,7 @@ G4double G4PAIySection::RutherfordIntegral( G4int k,
// Imaginary part of dielectric constant
// (G4int k - interval number, G4double en1 - energy point)
G4double G4PAIySection::ImPartDielectricConst( G4int k ,
G4double energy1 )
G4double G4PAIySection::ImPartDielectricConst( G4int k, G4double energy1 )
{
G4double energy2,energy3,energy4,result;
@@ -547,7 +546,7 @@ G4double G4PAIySection::RePartDielectricConst(G4double enb)
xx2 = x2 - x0;
xx12 = xx2/xx1;
if(xx12<0)
if(xx12<0.)
{
xx12 = -xx12;
}
@@ -589,14 +588,9 @@ G4double G4PAIySection::RePartDielectricConst(G4double enb)
G4double G4PAIySection::DifPAIySection( G4int i ,
G4double betaGammaSq )
{
G4double beta, be2,cof,x1,x2,x3,x4,x5,x6,x7,x8,result;
//G4double beta, be4;
//G4double be4;
// G4double betaBohr2 = fine_structure_const*fine_structure_const;
// G4double betaBohr4 = betaBohr2*betaBohr2*4.0;
G4double beta, be2,cof,x1,x2,x3,x4,x5,x6,x7,x8,result;
be2 = betaGammaSq/(1 + betaGammaSq);
//be4 = be2*be2;
beta = sqrt(be2);
beta = std::sqrt(be2);
cof = 1;
x1 = log(2*electron_mass_c2/fSplineEnergy[i]);
@@ -618,32 +612,24 @@ G4double G4PAIySection::DifPAIySection( G4int i ,
be2*((1 +fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i]);
x7 = atan2(fImPartDielectricConst[i],x3);
x7 = std::atan2(fImPartDielectricConst[i],x3);
x6 = x5 * x7;
}
// if(fImPartDielectricConst[i] == 0) x6 = 0;
x4 = ((x1 + x2)*fImPartDielectricConst[i] + x6)/hbarc;
// if( x4 < 0.0 ) x4 = 0.0;
x8 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
result = (x4 + cof*fIntegralTerm[i]/fSplineEnergy[i]/fSplineEnergy[i]);
result = std::max(result, 1.0e-8);
result *= fine_structure_const/be2/pi;
result *= fine_structure_const/(be2*pi);
// low energy correction
G4double lowCof = fLowEnergyCof; // 6.0 ; // Ar ~ 4.; -> fLowCof as f(Z1,Z2)?
result *= (1 - exp(-beta/betaBohr/lowCof));
// result *= (1-exp(-beta/betaBohr))*(1-exp(-beta/betaBohr));
// result *= (1-exp(-be2/betaBohr2));
// result *= (1-exp(-be4/betaBohr4));
// if(fDensity >= 0.1)
result *= (1 - std::exp(-beta/(betaBohr*lowCof)));
if(x8 > 0.)
{
result /= x8;
result /= x8;
}
return result;
@@ -653,24 +639,21 @@ G4double G4PAIySection::DifPAIySection( G4int i ,
//
// Calculation od dN/dx of collisions with creation of Cerenkov pseudo-photons
G4double G4PAIySection::PAIdNdxCerenkov( G4int i ,
G4double betaGammaSq )
G4double G4PAIySection::PAIdNdxCerenkov( G4int i, G4double betaGammaSq )
{
G4double logarithm, x3, x5, argument, modul2, dNdxC;
G4double be2, be4;
//G4double cof = 1.0;
be2 = betaGammaSq/(1 + betaGammaSq);
be4 = be2*be2;
if( betaGammaSq < 0.01 ) logarithm = log(1.0+betaGammaSq); // 0.0;
else
{
logarithm = -log( (1/betaGammaSq - fRePartDielectricConst[i])*
logarithm = -std::log( (1/betaGammaSq - fRePartDielectricConst[i])*
(1/betaGammaSq - fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i] )*0.5;
logarithm += log(1+1.0/betaGammaSq);
logarithm += std::log(1+1.0/betaGammaSq);
}
if( fImPartDielectricConst[i] == 0.0 || betaGammaSq < 0.01 )
@@ -684,7 +667,7 @@ G4double G4PAIySection::PAIdNdxCerenkov( G4int i ,
be2*((1.0 +fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i]);
if( x3 == 0.0 ) argument = 0.5*pi;
else argument = atan2(fImPartDielectricConst[i],x3);
else argument = std::atan2(fImPartDielectricConst[i],x3);
argument *= x5 ;
}
dNdxC = ( logarithm*fImPartDielectricConst[i] + argument )/hbarc;
@@ -693,10 +676,8 @@ G4double G4PAIySection::PAIdNdxCerenkov( G4int i ,
dNdxC *= fine_structure_const/be2/pi;
dNdxC *= (1-exp(-be4/betaBohr4));
dNdxC *= (1 - std::exp(-be4/betaBohr4));
// if(fDensity >= 0.1)
// {
modul2 = (1.0 + fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
if(modul2 > 0.)
@@ -712,8 +693,7 @@ G4double G4PAIySection::PAIdNdxCerenkov( G4int i ,
// Calculation od dN/dx of collisions with creation of longitudinal EM
// excitations (plasmons, delta-electrons)
G4double G4PAIySection::PAIdNdxPlasmon( G4int i ,
G4double betaGammaSq )
G4double G4PAIySection::PAIdNdxPlasmon( G4int i, G4double betaGammaSq )
{
G4double cof, resonance, modul2, dNdxP;
G4double be2, be4;
@@ -723,7 +703,7 @@ G4double G4PAIySection::PAIdNdxPlasmon( G4int i ,
be2 = betaGammaSq/(1 + betaGammaSq);
be4 = be2*be2;
resonance = log(2*electron_mass_c2*be2/fSplineEnergy[i]);
resonance = std::log(2*electron_mass_c2*be2/fSplineEnergy[i]);
resonance *= fImPartDielectricConst[i]/hbarc;
dNdxP = ( resonance + cof*fIntegralTerm[i]/fSplineEnergy[i]/fSplineEnergy[i] );
@@ -731,10 +711,8 @@ G4double G4PAIySection::PAIdNdxPlasmon( G4int i ,
dNdxP = std::max(dNdxP, 1.0e-8);
dNdxP *= fine_structure_const/be2/pi;
dNdxP *= (1-exp(-be4/betaBohr4));
dNdxP *= (1 - std::exp(-be4/betaBohr4));
// if( fDensity >= 0.1 )
// {
modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
fImPartDielectricConst[i]*fImPartDielectricConst[i];
if(modul2 > 0.)
@@ -831,7 +809,6 @@ void G4PAIySection::IntegralPlasmon()
k--;
}
}
} // end of IntegralPlasmon
//////////////////////////////////////////////////////////////////////
@@ -856,8 +833,10 @@ G4double G4PAIySection::SumOverInterval( G4int i )
//G4cout << "c= " << c << " y0= " << y0 << " yy1= " << yy1 << G4endl;
a = log10(yy1/y0)/log10(c);
//G4cout << "a= " << a << G4endl;
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1;
if(a == 0)
{
@@ -895,8 +874,10 @@ G4double G4PAIySection::SumOverIntervaldEdx( G4int i )
yy1 = fDifPAIySection[i+1];
c = x1/x0;
a = log10(yy1/y0)/log10(c);
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 2;
if(a == 0)
{
@@ -990,7 +971,7 @@ G4double G4PAIySection::SumOverInterPlasmon( G4int i )
G4double G4PAIySection::SumOverBorder( G4int i ,
G4double en0 )
{
G4double x0,x1,y0,yy1,a,/*c,*/d,e0,result;
G4double x0,x1,y0,yy1,a,d,e0,result;
e0 = en0;
x0 = fSplineEnergy[i];
@@ -998,7 +979,6 @@ G4double G4PAIySection::SumOverBorder( G4int i ,
y0 = fDifPAIySection[i];
yy1 = fDifPAIySection[i+1];
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
@@ -1031,8 +1011,10 @@ G4double G4PAIySection::SumOverBorder( G4int i ,
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 1;
if(a == 0)
{
@@ -1068,7 +1050,6 @@ G4double G4PAIySection::SumOverBorderdEdx( G4int i ,
y0 = fDifPAIySection[i];
yy1 = fDifPAIySection[i+1];
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
@@ -1089,10 +1070,10 @@ G4double G4PAIySection::SumOverBorderdEdx( G4int i ,
y0 = fDifPAIySection[i - 1];
yy1 = fDifPAIySection[i - 2];
//c = x1/x0;
d = e0/x0;
a = log10(yy1/y0)/log10(x1/x0);
b = 0.0;
if(a < 20.) b = y0/pow(x0,a);
a += 2;
@@ -1105,7 +1086,6 @@ G4double G4PAIySection::SumOverBorderdEdx( G4int i ,
result += y0*(e0*e0*pow(d,a-2) - x0*x0)/a;
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1174,7 +1154,6 @@ G4double G4PAIySection::SumOverBordCerenkov( G4int i ,
//G4cout<<"a = "<<a<<"; b = "<<b<<"; result = "<<result<<G4endl;
return result;
}
///////////////////////////////////////////////////////////////////////////////
@@ -67,6 +67,7 @@
#include "G4ModifiedTsai.hh"
#include "G4Exp.hh"
#include "G4Pow.hh"
#include "G4AutoLock.hh"
const G4int G4PairProductionRelModel::gMaxZet = 120;
@@ -110,6 +111,11 @@ std::vector<G4PairProductionRelModel::ElementData*> G4PairProductionRelModel::gE
// LPM supression functions evaluated at initialisation time
G4PairProductionRelModel::LPMFuncs G4PairProductionRelModel::gLPMFuncs;
namespace
{
G4Mutex thePairProdRelMutex = G4MUTEX_INITIALIZER;
}
// CTR
G4PairProductionRelModel::G4PairProductionRelModel(const G4ParticleDefinition*,
const G4String& nam)
@@ -129,12 +135,10 @@ G4PairProductionRelModel::G4PairProductionRelModel(const G4ParticleDefinition*,
// DTR
G4PairProductionRelModel::~G4PairProductionRelModel()
{
if (IsMaster()) {
if (isFirstInstance) {
// clear ElementData container
for (std::size_t iz = 0; iz < gElementData.size(); ++iz) {
if (gElementData[iz]) delete gElementData[iz];
}
gElementData.clear();
for (auto const & ptr : gElementData) { delete ptr; }
gElementData.clear();
// clear LPMFunctions (if any)
if (fIsUseLPMCorrection) {
gLPMFuncs.fLPMFuncG.clear();
@@ -147,17 +151,26 @@ G4PairProductionRelModel::~G4PairProductionRelModel()
void G4PairProductionRelModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if (IsMaster()) {
if(nullptr == fParticleChange) { fParticleChange = GetParticleChangeForGamma(); }
if (gElementData.empty()) {
// init element data and LPM funcs
if (IsMaster()) {
InitialiseElementData();
if (fIsUseLPMCorrection) {
InitLPMFunctions();
}
G4AutoLock l(&thePairProdRelMutex);
if (gElementData.empty()) {
isFirstInstance = true;
gElementData.resize(gMaxZet+1, nullptr);
}
l.unlock();
}
// static data should be initialised only in the one instance
if(isFirstInstance) {
InitialiseElementData();
if (fIsUseLPMCorrection) {
InitLPMFunctions();
}
}
if(!fParticleChange) { fParticleChange = GetParticleChangeForGamma(); }
if(IsMaster() && LowEnergyLimit() < HighEnergyLimit()) {
// element selectors should be initialised in the master thread
if (IsMaster()) {
InitialiseElementSelectors(p, cuts);
}
}
@@ -165,9 +178,7 @@ void G4PairProductionRelModel::Initialise(const G4ParticleDefinition* p,
void G4PairProductionRelModel::InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel* masterModel)
{
if(LowEnergyLimit() < HighEnergyLimit()) {
SetElementSelectors(masterModel->GetElementSelectors());
}
SetElementSelectors(masterModel->GetElementSelectors());
}
G4double G4PairProductionRelModel::ComputeXSectionPerAtom(G4double gammaEnergy,
@@ -497,17 +508,11 @@ G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
// should be called only by the master and at initialisation
void G4PairProductionRelModel::InitialiseElementData()
{
G4int size = (G4int)gElementData.size();
if (size < gMaxZet+1) {
gElementData.resize(gMaxZet+1, nullptr);
}
// create for all elements that are in the detector
const G4ElementTable* elemTable = G4Element::GetElementTable();
std::size_t numElems = (*elemTable).size();
for (std::size_t ie = 0; ie < numElems; ++ie) {
const G4Element* elem = (*elemTable)[ie];
const G4int iz = std::min(gMaxZet, elem->GetZasInt());
if (!gElementData[iz]) { // create it if doesn't exist yet
auto elemTable = G4Element::GetElementTable();
for (auto const & elem : *elemTable) {
const G4int iz = std::min(gMaxZet, elem->GetZasInt());
if (nullptr == gElementData[iz]) { // create it if doesn't exist yet
const G4double logZ13 = elem->GetIonisation()->GetlogZ3();
const G4double Z13 = elem->GetIonisation()->GetZ3();
const G4double fc = elem->GetfCoulomb();
@@ -47,6 +47,7 @@
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "Randomize.hh"
#include "G4EmParameters.hh"
#include "G4String.hh"
@@ -333,13 +334,7 @@ void G4SBBremTable::InitSamplingTables() {
// should be called only from LoadSamplingTables(G4int) and once
void G4SBBremTable::LoadSTGrid() {
const char* path = G4FindDataDir("G4LEDATA");
if (!path) {
G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
FatalException, "Environment variable G4LEDATA not defined");
return;
}
const G4String fname = G4String(path) + "/brem_SB/SBTables/grid";
const G4String fname = G4EmParameters::Instance()->GetDirLEDATA() + "/brem_SB/SBTables/grid";
std::ifstream infile(fname,std::ios::in);
if (!infile.is_open()) {
G4String msgc = "Cannot open file: " + fname;
@@ -391,13 +386,8 @@ void G4SBBremTable::LoadSamplingTables(G4int iz) {
}
// load data for a given Z only once
iz = std::max(std::min(fMaxZet, iz),1);
const char* path = G4FindDataDir("G4LEDATA");
if (!path) {
G4Exception("G4SBBremTable::LoadSamplingTables()","em0006",
FatalException, "Environment variable G4LEDATA not defined");
return;
}
const G4String fname = G4String(path) + "/brem_SB/SBTables/sTableSB_"
const G4String fname = G4EmParameters::Instance()->GetDirLEDATA() + "/brem_SB/SBTables/sTableSB_"
+ std::to_string(iz);
std::istringstream infile(std::ios::in);
// read the compressed data file into the stream
@@ -77,7 +77,6 @@
G4Physics2DVector* G4SeltzerBergerModel::gSBDCSData[] = { nullptr };
G4SBBremTable* G4SeltzerBergerModel::gSBSamplingTable = nullptr;
G4double G4SeltzerBergerModel::gYLimitData[] = { 0.0 };
G4String G4SeltzerBergerModel::gDataDirectory = "";
namespace
{
@@ -94,14 +93,13 @@ G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
{
fLowestKinEnergy = 1.0*keV;
SetLowEnergyLimit(fLowestKinEnergy);
SetLPMFlag(false);
SetAngularDistribution(new G4ModifiedTsai());
}
G4SeltzerBergerModel::~G4SeltzerBergerModel()
{
// delete SB-DCS data per Z
if (IsMaster()) {
if (isFirstInstance) {
for (std::size_t iz = 0; iz < gMaxZet; ++iz) {
if (gSBDCSData[iz]) {
delete gSBDCSData[iz];
@@ -118,72 +116,48 @@ G4SeltzerBergerModel::~G4SeltzerBergerModel()
void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if (p) {
SetParticle(p);
}
fIsUseSamplingTables = G4EmParameters::Instance()->EnableSamplingTable();
// Access to elements
if (IsMaster()) {
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
for(G4int j=0; j<numOfCouples; ++j) {
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
auto elmVec = mat->GetElementVector();
for (auto & elm : *elmVec) {
G4int Z = std::max(1,std::min(elm->GetZasInt(), gMaxZet-1));
// load SB-DCS data for this atomic number if it has not been loaded yet
if (gSBDCSData[Z] == nullptr) ReadData(Z);
}
// initialise static tables for the Seltzer-Berger model
if (0.0 == gYLimitData[0]) {
G4AutoLock l(&theSBMutex);
if (0.0 == gYLimitData[0]) {
isFirstInstance = true;
gYLimitData[0] = 1.0;
}
// elem.selectr. only for master: base class init-local will set for workers
if (LowEnergyLimit() < HighEnergyLimit()) {
InitialiseElementSelectors(p,cuts);
l.unlock();
}
// initialise base class
G4eBremsstrahlungRelModel::Initialise(p, cuts);
// initialisation per element is done only once
if (isFirstInstance) {
auto elemTable = G4Element::GetElementTable();
for (auto const & elm : *elemTable) {
G4int Z = std::max(1,std::min(elm->GetZasInt(), gMaxZet-1));
// load SB-DCS data for this atomic number if it has not been loaded yet
if (gSBDCSData[Z] == nullptr) ReadData(Z);
}
// init sampling tables if it was requested
if (fIsUseSamplingTables) {
if (!gSBSamplingTable) {
if (nullptr == gSBSamplingTable) {
gSBSamplingTable = new G4SBBremTable();
}
gSBSamplingTable->Initialize(std::max(fLowestKinEnergy,LowEnergyLimit()),
gSBSamplingTable->Initialize(std::max(fLowestKinEnergy, LowEnergyLimit()),
HighEnergyLimit());
}
}
//
if (!fParticleChange) { fParticleChange = GetParticleChangeForLoss(); }
if (GetTripletModel()) {
GetTripletModel()->Initialise(p, cuts);
fIsScatOffElectron = true;
}
}
const G4String& G4SeltzerBergerModel::FindDirectoryPath()
{
// check environment variable
// build the complete string identifying the file with the data set
if(gDataDirectory.empty()) {
const char* path = G4FindDataDir("G4LEDATA");
if (path) {
std::ostringstream ost;
ost << path << "/brem_SB/br";
gDataDirectory = ost.str();
} else {
G4Exception("G4SeltzerBergerModel::FindDirectoryPath()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
}
}
return gDataDirectory;
}
void G4SeltzerBergerModel::ReadData(G4int Z) {
// return if it has been already loaded
if (gSBDCSData[Z] != nullptr) return;
G4AutoLock l(&theSBMutex);
if (gSBDCSData[Z] == nullptr) {
std::ostringstream ost;
ost << FindDirectoryPath() << Z;
ost << G4EmParameters::Instance()->GetDirLEDATA() << "/brem_SB/br" << Z;
std::ifstream fin(ost.str().c_str());
if (!fin.is_open()) {
G4ExceptionDescription ed;
@@ -210,7 +184,6 @@ void G4SeltzerBergerModel::ReadData(G4int Z) {
delete v;
}
}
l.unlock();
}
G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
@@ -227,7 +200,9 @@ G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
// NOTE: fCurrentIZ should have been set before.
fCurrentIZ = std::max(std::min(fCurrentIZ, gMaxZet-1), 1);
if (nullptr == gSBDCSData[fCurrentIZ]) {
G4AutoLock l(&theSBMutex);
ReadData(fCurrentIZ);
l.unlock();
}
// NOTE: SetupForMaterial should have been called before!
const G4double pt2 = fPrimaryKinEnergy*(fPrimaryKinEnergy+2.*kMC2);
@@ -412,6 +387,7 @@ void G4SeltzerBergerModel::SetupForMaterial(const G4ParticleDefinition*,
fPrimaryKinEnergy = kineticEnergy;
fPrimaryTotalEnergy = kineticEnergy+CLHEP::electron_mass_c2;
fDensityCorr = fDensityFactor*fPrimaryTotalEnergy*fPrimaryTotalEnergy;
fIsLPMActive = LPMFlag();
// flag for the base class
fIsLPMActive = false;
}
@@ -91,7 +91,7 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
tlimitminfix2 = 1.*CLHEP::nm;
stepmin = tlimitminfix;
smallstep = 1.e10;
currentRange = 0. ;
currentRange = 0.;
rangeinit = 0.;
tlimit = 1.e10*CLHEP::mm;
tlimitmin = 10.*tlimitminfix;
@@ -99,20 +99,13 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
geombig = tgeom;
geommin = 1.e-3*CLHEP::mm;
geomlimit = geombig;
presafety = 0.*CLHEP::mm;
particle = nullptr;
presafety = 0.;
positron = G4Positron::Positron();
rndmEngineMod = G4Random::getTheEngine();
firstStep = true;
insideskin = false;
latDisplasmentbackup = false;
dispAlg96 = true;
drr = 0.35;
finalr = 10.*CLHEP::um;
drr = 0.35;
finalr = 10.*CLHEP::um;
tlow = 5.*CLHEP::keV;
invmev = 1.0/CLHEP::MeV;
@@ -124,10 +117,6 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
currentKinEnergy = currentRadLength = lambda0 = lambdaeff = tPathLength
= zPathLength = par1 = par2 = par3 = rndmarray[0] = rndmarray[1] = 0;
currentLogKinEnergy = LOG_EKIN_MIN;
idx = 0;
fParticleChange = nullptr;
couple = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -151,8 +140,12 @@ void G4UrbanMscModel::Initialise(const G4ParticleDefinition* p,
InitialiseParameters(p);
latDisplasmentbackup = latDisplasment;
dispAlg96 = G4EmParameters::Instance()->LateralDisplacementAlg96();
fPosiCorrection = G4EmParameters::Instance()->MscPositronCorrection();
// if model is locked parameters should be defined via Set methods
if(!IsLocked()) {
dispAlg96 = G4EmParameters::Instance()->LateralDisplacementAlg96();
fPosiCorrection = G4EmParameters::Instance()->MscPositronCorrection();
}
// initialise cache only once
if(0 == msc.size()) {
@@ -461,9 +454,12 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
<< " range= " <<currentRange<< " lambda= "<<lambda0
<<G4endl;
*/
presafety = (stepStatus == fGeomBoundary) ? sp->GetSafety()
: ComputeSafety(sp->GetPosition(), tPathLength);
// stop here if small step
if(tPathLength < tlimitminfix) {
// stop here if small step or range is less than safety
if((tPathLength == currentRange && tPathLength < presafety) ||
tPathLength < tlimitminfix) {
latDisplasment = false;
return ConvertTrueToGeom(tPathLength, currentMinimalStep);
}
@@ -475,8 +471,6 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
// for muons, hadrons
: currentRange*msc[idx]->doverrb;
presafety = (stepStatus == fGeomBoundary) ? sp->GetSafety()
: ComputeSafety(sp->GetPosition(),tPathLength);
/*
G4cout << "G4Urban::StepLimit tPathLength= "
<<tPathLength<<" safety= " << presafety
@@ -783,6 +777,8 @@ G4UrbanMscModel::SampleScattering(const G4ThreeVector& oldDirection,
G4double /*safety*/)
{
fDisplacement.set(0.0,0.0,0.0);
if(tPathLength >= currentRange) { return fDisplacement; }
G4double kinEnergy = currentKinEnergy;
if (tPathLength > currentRange*dtrl) {
kinEnergy = GetEnergy(particle,currentRange-tPathLength,couple);
@@ -48,24 +48,19 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4int Z[17] = {
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 26};
//const G4int Z[17] = {
// 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 26};
const G4double A[17] = {
7, 9, 11, 12, 14, 16, 19, 20, 23, 24, 27, 28, 31, 32, 35, 40, 56};
G4WaterStopping::G4WaterStopping(G4EmCorrections* corr, G4bool splineFlag)
G4WaterStopping::G4WaterStopping()
{
spline = splineFlag;
dedx.reserve(17);
Initialise(corr);
Initialise();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4WaterStopping::~G4WaterStopping() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4WaterStopping::GetElectronicDEDX(G4int iz, G4double energy)
{
G4double res = 0.0;
@@ -100,7 +95,7 @@ void G4WaterStopping::AddData(const G4double* energy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4WaterStopping::Initialise(G4EmCorrections* corr)
void G4WaterStopping::Initialise()
{
//..Reduced energies
static const G4double E[53] = {0.025,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.1,0.15,0.2,0.25,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1,1.5,2,2.5,3,4,5,6,7,8,9,10,15,20,25,30,40,50,60,70,80,90,100,150,200,250,300,400,500,600,700,800,900,1000};
@@ -142,10 +137,4 @@ void G4WaterStopping::Initialise(G4EmCorrections* corr)
static const G4double G4_WATER_Fe [53]={6.5394, 7.3060, 8.7367, 10.0690, 11.3310, 12.5470, 13.7280, 14.8780, 15.9980, 21.1160, 25.4850, 29.1260, 32.0640, 36.1770, 38.6920, 40.2760, 41.2950, 41.9530, 42.3710, 42.6210, 42.5910, 41.6900, 40.5190, 39.2690, 36.8000, 34.5040, 32.4190, 30.5410, 28.8480, 27.3170, 25.9310, 20.6170, 17.0680, 14.5540, 12.6930, 10.1410, 8.4892, 7.3402, 6.4976, 5.8545, 5.3479, 4.9387, 3.6892, 3.0503, 2.6620, 2.4014, 2.0756, 1.8825, 1.7569, 1.6702, 1.6079, 1.5619, 1.5267};
AddData(E,G4_WATER_Fe,factor);
if(nullptr != corr) {
for(G4int i=0; i<17; ++i) {
corr->AddStoppingData(Z[i], A[i], "G4_WATER", dedx[i]);
}
}
}
@@ -94,7 +94,6 @@ G4eBremsstrahlung::InitialiseEnergyLossProcess(const G4ParticleDefinition*,
G4double energyLimit = std::min(EmModel(0)->HighEnergyLimit(), CLHEP::GeV);
EmModel(0)->SetHighEnergyLimit(energyLimit);
EmModel(0)->SetSecondaryThreshold(param->BremsstrahlungTh());
EmModel(0)->SetLPMFlag(false);
AddEmModel(1, EmModel(0), fm);
if(emax > energyLimit) {
@@ -104,7 +103,6 @@ G4eBremsstrahlung::InitialiseEnergyLossProcess(const G4ParticleDefinition*,
EmModel(1)->SetLowEnergyLimit(energyLimit);
EmModel(1)->SetHighEnergyLimit(emax);
EmModel(1)->SetSecondaryThreshold(param->BremsstrahlungTh());
EmModel(1)->SetLPMFlag(param->LPM());
AddEmModel(1, EmModel(1), fm);
}
isInitialised = true;
@@ -70,6 +70,8 @@
#include "G4ModifiedTsai.hh"
#include "G4Exp.hh"
#include "G4Log.hh"
#include "G4EmParameters.hh"
#include "G4AutoLock.hh"
const G4int G4eBremsstrahlungRelModel::gMaxZet = 120;
@@ -114,6 +116,11 @@ G4eBremsstrahlungRelModel::LPMFuncs G4eBremsstrahlungRelModel::gLPMFuncs;
// special data structure per element i.e. per Z
std::vector<G4eBremsstrahlungRelModel::ElementData*> G4eBremsstrahlungRelModel::gElementData;
namespace
{
G4Mutex theBremRelMutex = G4MUTEX_INITIALIZER;
}
G4eBremsstrahlungRelModel::G4eBremsstrahlungRelModel(const G4ParticleDefinition* p,
const G4String& nam)
: G4VEmModel(nam)
@@ -125,9 +132,6 @@ G4eBremsstrahlungRelModel::G4eBremsstrahlungRelModel(const G4ParticleDefinition*
//
fLPMEnergyThreshold = 1.e+39;
fLPMEnergy = 0.;
SetLPMFlag(true);
//
SetAngularDistribution(new G4ModifiedTsai());
//
if (nullptr != p) {
@@ -137,16 +141,12 @@ G4eBremsstrahlungRelModel::G4eBremsstrahlungRelModel(const G4ParticleDefinition*
G4eBremsstrahlungRelModel::~G4eBremsstrahlungRelModel()
{
if (IsMaster()) {
if (fIsFirstInstance) {
// clear ElementData container
for (std::size_t iz = 0; iz < gElementData.size(); ++iz) {
if (nullptr != gElementData[iz]) {
delete gElementData[iz];
}
}
for (auto const & ptr : gElementData) { delete ptr; }
gElementData.clear();
// clear LPMFunctions (if any)
if (LPMFlag()) {
if (fUseLPM) {
gLPMFuncs.fLPMFuncG.clear();
gLPMFuncs.fLPMFuncPhi.clear();
gLPMFuncs.fIsInitialized = false;
@@ -157,18 +157,33 @@ G4eBremsstrahlungRelModel::~G4eBremsstrahlungRelModel()
void G4eBremsstrahlungRelModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if (nullptr != p) {
// parameters in each thread
if (fPrimaryParticle != p) {
SetParticle(p);
}
fUseLPM = G4EmParameters::Instance()->LPM();
fCurrentIZ = 0;
// init element data and precompute LPM functions (only if lpmflag is true)
if (IsMaster()) {
InitialiseElementData();
if (LPMFlag()) { InitLPMFunctions(); }
if (LowEnergyLimit() < HighEnergyLimit()) {
InitialiseElementSelectors(p, cuts);
// init static element data and precompute LPM functions only once
// for all treads and derived classes
if (gElementData.empty()) {
G4AutoLock l(&theBremRelMutex);
if (gElementData.empty()) {
fIsFirstInstance = true;
gElementData.resize(gMaxZet+1, nullptr);
}
l.unlock();
}
if (fIsFirstInstance) {
InitialiseElementData();
if (fUseLPM) { InitLPMFunctions(); }
}
// element selectors are initialized in the master thread
if (IsMaster()) {
InitialiseElementSelectors(p, cuts);
}
// initialisation in all threads
if (nullptr == fParticleChange) {
fParticleChange = GetParticleChangeForLoss();
}
@@ -181,9 +196,7 @@ void G4eBremsstrahlungRelModel::Initialise(const G4ParticleDefinition* p,
void G4eBremsstrahlungRelModel::InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel* masterModel)
{
if (LowEnergyLimit() < HighEnergyLimit()) {
SetElementSelectors(masterModel->GetElementSelectors());
}
SetElementSelectors(masterModel->GetElementSelectors());
}
void G4eBremsstrahlungRelModel::SetParticle(const G4ParticleDefinition* p)
@@ -203,7 +216,7 @@ void G4eBremsstrahlungRelModel::SetupForMaterial(const G4ParticleDefinition*,
fDensityFactor = gMigdalConstant*mat->GetElectronDensity();
fLPMEnergy = gLPMconstant*mat->GetRadlen();
// threshold for LPM effect (i.e. below which LPM hidden by density effect)
if (LPMFlag()) {
if (fUseLPM) {
fLPMEnergyThreshold = std::sqrt(fDensityFactor)*fLPMEnergy;
} else {
fLPMEnergyThreshold = 1.e+39; // i.e. do not use LPM effect
@@ -213,7 +226,7 @@ void G4eBremsstrahlungRelModel::SetupForMaterial(const G4ParticleDefinition*,
fPrimaryTotalEnergy = kineticEnergy+fPrimaryParticleMass;
fDensityCorr = fDensityFactor*fPrimaryTotalEnergy*fPrimaryTotalEnergy;
// set activation flag for LPM effects in the DCS
fIsLPMActive = (fPrimaryTotalEnergy>fLPMEnergyThreshold);
fIsLPMActive = (fPrimaryTotalEnergy>fLPMEnergyThreshold);
}
// minimum primary (e-/e+) energy at which discrete interaction is possible
@@ -618,18 +631,12 @@ G4eBremsstrahlungRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vd
void G4eBremsstrahlungRelModel::InitialiseElementData()
{
const G4int size = (G4int)gElementData.size();
if (size < gMaxZet+1) {
gElementData.resize(gMaxZet+1, nullptr);
}
// create for all elements that are in the detector
const G4ElementTable* elemTable = G4Element::GetElementTable();
std::size_t numElems = (*elemTable).size();
for (std::size_t ielem=0; ielem<numElems; ++ielem) {
const G4Element* elem = (*elemTable)[ielem];
const G4double zet = elem->GetZ();
const G4int izet = std::min(G4lrint(zet),gMaxZet);
if (!gElementData[izet]) {
auto elemTable = G4Element::GetElementTable();
for (auto const & elem : *elemTable) {
const G4double zet = elem->GetZ();
const G4int izet = std::min(elem->GetZasInt(), gMaxZet);
if (nullptr == gElementData[izet]) {
auto elemData = new ElementData();
const G4double fc = elem->GetfCoulomb();
G4double Fel = 1.;
@@ -66,30 +66,15 @@
using namespace std;
G4eCoulombScatteringModel::G4eCoulombScatteringModel(G4bool combined)
: G4VEmModel("eCoulombScattering"),
cosThetaMin(1.0),
cosThetaMax(-1.0),
isCombined(combined)
: G4VEmModel("eCoulombScattering"), isCombined(combined)
{
fParticleChange = nullptr;
fNistManager = G4NistManager::Instance();
theIonTable = G4ParticleTable::GetParticleTable()->GetIonTable();
theProton = G4Proton::Proton();
currentMaterial = nullptr;
fixedCut = -1.0;
pCuts = nullptr;
recoilThreshold = 0.0; // by default does not work
particle = nullptr;
currentCouple = nullptr;
wokvi = new G4WentzelOKandVIxSection(isCombined);
currentMaterialIndex = 0;
mass = CLHEP::proton_mass_c2;
elecRatio = 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -107,12 +92,16 @@ void G4eCoulombScatteringModel::Initialise(const G4ParticleDefinition* part,
SetupParticle(part);
currentCouple = nullptr;
G4double tet = PolarAngleLimit();
// defined theta limit between single and multiple scattering
if(isCombined) {
cosThetaMin = 1.0;
G4double tet = PolarAngleLimit();
if(tet >= pi) { cosThetaMin = -1.0; }
else if(tet > 0.0) { cosThetaMin = cos(tet); }
if(tet >= CLHEP::pi) { cosThetaMin = -1.0; }
else if(tet > 0.0) { cosThetaMin = std::cos(tet); }
// single scattering without multiple
} else if(tet > 0.0) {
cosThetaMin = std::cos(std::min(tet, CLHEP::pi));
}
wokvi->Initialise(part, cosThetaMin);
@@ -176,7 +165,7 @@ G4double G4eCoulombScatteringModel::ComputeCrossSectionPerAtom(
G4double Z, G4double,
G4double cutEnergy, G4double)
{
/*
/*
G4cout << "### G4eCoulombScatteringModel::ComputeCrossSectionPerAtom for "
<< p->GetParticleName()<<" Z= "<<Z<<" e(MeV)= "<< kinEnergy/MeV
<< G4endl;
@@ -41,7 +41,7 @@
// -------------------------------------------------------------------
#include "G4eDPWAElasticDCS.hh"
#include "G4EmParameters.hh"
#include "G4Physics2DVector.hh"
#include "zlib.h"
@@ -502,16 +502,9 @@ G4double G4eDPWAElasticDCS::SampleMu(std::size_t izet, std::size_t ie, G4double
const G4String& G4eDPWAElasticDCS::FindDirectoryPath() {
// check environment variable
if (gDataDirectory.empty()) {
const char* path = G4FindDataDir("G4LEDATA");
if (path) {
std::ostringstream ost;
ost << path << "/dpwa/";
gDataDirectory = ost.str();
} else {
G4Exception("G4eDPWAElasticDCS::FindDirectoryPath()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
}
std::ostringstream ost;
ost << G4EmParameters::Instance()->GetDirLEDATA() << "/dpwa/";
gDataDirectory = ost.str();
}
return gDataDirectory;
}
@@ -60,22 +60,15 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4hIonisation::G4hIonisation(const G4String& name)
: G4VEnergyLossProcess(name),
isInitialised(false)
: G4VEnergyLossProcess(name)
{
SetProcessSubType(fIonisation);
SetSecondaryParticle(G4Electron::Electron());
mass = 0.0;
ratio = 0.0;
eth = 2*CLHEP::MeV;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4hIonisation::~G4hIonisation() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4hIonisation::IsApplicable(const G4ParticleDefinition&)
{
return true;
@@ -179,7 +172,7 @@ void G4hIonisation::InitialiseEnergyLossProcess(
void G4hIonisation::ProcessDescription(std::ostream& out) const
{
out << " Ionisation";
out << " Hadron ionisation";
G4VEnergyLossProcess::ProcessDescription(out);
}
@@ -69,32 +69,22 @@
#include "G4BraggIonModel.hh"
#include "G4BetheBlochModel.hh"
#include "G4LossTableManager.hh"
#include "G4WaterStopping.hh"
#include "G4EmCorrections.hh"
#include "G4EmParameters.hh"
#include "G4EmStandUtil.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ionIonisation::G4ionIonisation(const G4String& name)
: G4VEnergyLossProcess(name),
theParticle(nullptr),
isInitialised(false),
stopDataActive(false)
: G4VEnergyLossProcess(name)
{
SetLinearLossLimit(0.02);
SetProcessSubType(fIonisation);
SetSecondaryParticle(G4Electron::Electron());
corr = G4LossTableManager::Instance()->EmCorrections();
eth = 2*CLHEP::MeV;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ionIonisation::~G4ionIonisation() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4ionIonisation::IsApplicable(const G4ParticleDefinition&)
{
return true;
@@ -167,40 +157,9 @@ void G4ionIonisation::InitialiseEnergyLossProcess(
emax = std::max(emax, eth*10);
EmModel(1)->SetHighEnergyLimit(emax);
AddEmModel(2, EmModel(1), FluctModel());
// Add ion stoping tables for Generic Ion if the default
// model is used (with eth ~= 2 MeV)
if(part == ion && (EmModel(1)->GetName() == "BetheBloch" ||
EmModel(1)->GetName() == "BetheBlochGasIon")) {
stopDataActive = true;
G4WaterStopping ws(corr, true);
corr->SetIonisationModels(EmModel(0), EmModel(1));
}
}
isInitialised = true;
}
// reinitialisation of corrections for the new run
if(part == ion) { corr->InitialiseForNewRun(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ionIonisation::StreamProcessInfo(std::ostream& out) const
{
if (stopDataActive && G4GenericIon::GenericIon() == theParticle) {
out << " Stopping Power data for "
<< corr->GetNumberOfStoppingVectors()
<< " ion/material pairs" << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ionIonisation::AddStoppingData(G4int Z, G4int A,
const G4String& mname,
G4PhysicsVector* dVector)
{
corr->AddStoppingData(Z, A, mname, dVector);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....