Import Geant4 9.2.0 source tree
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4DummyModel.cc,v 1.3 2007/05/22 17:31:58 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4ElectronIonPair.cc,v 1.2 2008/10/17 14:46:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4ElectronIonPair
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 08.07.2008
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4ElectronIonPair.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4StepPoint.hh"
|
||||
#include "G4VProcess.hh"
|
||||
#include "G4ProcessType.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4ElectronIonPair::G4ElectronIonPair()
|
||||
{
|
||||
verbose = 1;
|
||||
curMaterial = 0;
|
||||
curMeanEnergy = 0.0;
|
||||
nMaterials = 0;
|
||||
Initialise();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4ElectronIonPair::~G4ElectronIonPair()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4ElectronIonPair::MeanNumberOfIonsAlongStep(
|
||||
const G4ParticleDefinition* part,
|
||||
const G4Material* material,
|
||||
G4double edep,
|
||||
G4double niel)
|
||||
{
|
||||
G4double nion = 0.0;
|
||||
|
||||
// NIEL does not provide ionisation clusters
|
||||
if(edep > niel) {
|
||||
|
||||
// neutral particles do not produce ionisation along step
|
||||
if(part->GetPDGCharge() != 0.0) {
|
||||
|
||||
// select material
|
||||
if(material != curMaterial) {
|
||||
curMaterial = material;
|
||||
curMeanEnergy = material->GetIonisation()->GetMeanEnergyPerIonPair();
|
||||
|
||||
// if mean energy is not defined then look into G4 DB
|
||||
if(0.0 == curMeanEnergy) {
|
||||
curMeanEnergy = FindG4MeanEnergyPerIonPair(material);
|
||||
}
|
||||
}
|
||||
if(curMeanEnergy > 0.0) nion = (edep - niel)/curMeanEnergy;
|
||||
}
|
||||
}
|
||||
return nion;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
std::vector<G4ThreeVector>*
|
||||
G4ElectronIonPair::SampleIonsAlongStep(const G4ThreeVector& prePos,
|
||||
const G4ThreeVector& postPos,
|
||||
G4double meanion)
|
||||
{
|
||||
std::vector<G4ThreeVector>* v = new std::vector<G4ThreeVector>;
|
||||
|
||||
G4double sig = 0.2*std::sqrt(meanion);
|
||||
G4int nion = G4int(G4RandGauss::shoot(meanion,sig) + 0.5);
|
||||
|
||||
// sample ionisation along step
|
||||
if(nion > 0) {
|
||||
|
||||
G4ThreeVector deltaPos = postPos - prePos;
|
||||
for(G4int i=0; i<nion; i++) {
|
||||
v->push_back( prePos + deltaPos*G4UniformRand() );
|
||||
}
|
||||
if(verbose > 1 ) {
|
||||
G4cout << "### G4ElectronIonPair::SampleIonisationPoints: "
|
||||
<< v->size() << " ion pairs are added" << G4endl;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4ElectronIonPair::ResidualeChargePostStep(const G4ParticleDefinition*,
|
||||
const G4TrackVector*,
|
||||
G4int subType)
|
||||
{
|
||||
G4int nholes = 0;
|
||||
|
||||
if(2 == subType || 12 == subType || 13 == subType) nholes = 1;
|
||||
return nholes;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4ElectronIonPair::FindG4MeanEnergyPerIonPair(const G4Material* mat)
|
||||
{
|
||||
G4String name = mat->GetName();
|
||||
G4double res = 0.0;
|
||||
|
||||
// is this material in the vector?
|
||||
for(G4int j=0; j<nMaterials; j++) {
|
||||
if(name == g4MatNames[j]) {
|
||||
res = g4MatData[j];
|
||||
mat->GetIonisation()->SetMeanEnergyPerIonPair(res);
|
||||
if(verbose > 0) {
|
||||
G4cout << "### G4ElectronIonPair::FindG4MeanEnergyPerIonPair for "
|
||||
<< name << " Epair= " << res/eV << " eV is set"
|
||||
<< G4endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4ElectronIonPair:: DumpMeanEnergyPerIonPair()
|
||||
{
|
||||
G4int nmat = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
|
||||
if(nmat > 0) {
|
||||
G4cout << "### G4ElectronIonPair: mean energy per ion pair avalable:" << G4endl;
|
||||
for(G4int i=0; i<nmat; i++) {
|
||||
const G4Material* mat = (*mtable)[i];
|
||||
G4double x = mat->GetIonisation()->GetMeanEnergyPerIonPair();
|
||||
if(x > 0.0) {
|
||||
G4cout << " " << mat->GetName() << " Epair= "
|
||||
<< x/eV << " eV" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4ElectronIonPair::DumpG4MeanEnergyPerIonPair()
|
||||
{
|
||||
if(nMaterials > 0) {
|
||||
G4cout << "### G4ElectronIonPair: mean energy per ion pair "
|
||||
<< " for Geant4 materials" << G4endl;
|
||||
for(G4int i=0; i<nMaterials; i++) {
|
||||
G4cout << " " << g4MatNames[i] << " Epair= "
|
||||
<< g4MatData[i]/eV << " eV" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4ElectronIonPair::Initialise()
|
||||
{
|
||||
// ICRU Report 31, 1979
|
||||
g4MatNames.push_back("G4_Si");
|
||||
g4MatData.push_back(3.62*eV);
|
||||
|
||||
g4MatNames.push_back("G4_Ge");
|
||||
g4MatData.push_back(2.97*eV);
|
||||
|
||||
g4MatNames.push_back("G4_He");
|
||||
g4MatData.push_back(44.4*eV);
|
||||
|
||||
g4MatNames.push_back("G4_N");
|
||||
g4MatData.push_back(36.4*eV);
|
||||
|
||||
g4MatNames.push_back("G4_O");
|
||||
g4MatData.push_back(32.3*eV);
|
||||
|
||||
g4MatNames.push_back("G4_Ne");
|
||||
g4MatData.push_back(36.8*eV);
|
||||
|
||||
g4MatNames.push_back("G4_Ar");
|
||||
g4MatData.push_back(26.34*eV);
|
||||
|
||||
g4MatNames.push_back("G4_Kr");
|
||||
g4MatData.push_back(24.1*eV);
|
||||
|
||||
g4MatNames.push_back("G4_Xe");
|
||||
g4MatData.push_back(21.6*eV);
|
||||
|
||||
g4MatNames.push_back("G4_lAr");
|
||||
g4MatData.push_back(23.6*eV);
|
||||
|
||||
g4MatNames.push_back("G4_lKr");
|
||||
g4MatData.push_back(20.5*eV);
|
||||
|
||||
g4MatNames.push_back("G4_lXe");
|
||||
g4MatData.push_back(15.6*eV);
|
||||
|
||||
g4MatNames.push_back("G4_AIR");
|
||||
g4MatData.push_back(35.1*eV);
|
||||
|
||||
nMaterials = g4MatData.size();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmCalculator.cc,v 1.37 2007/08/16 15:55:42 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4EmCalculator.cc,v 1.44 2008/08/03 18:47:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -54,6 +54,7 @@
|
||||
// 27.10.2006 Change test energy to access lowEnergy model from
|
||||
// 10 keV to 1 keV (V. Ivanchenko)
|
||||
// 15.03.2007 Add ComputeEnergyCutFromRangeCut methods (V.Ivanchenko)
|
||||
// 21.04.2008 Updated computations for ions (V.Ivanchenko)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -125,6 +126,20 @@ G4double G4EmCalculator::GetDEDX(G4double kinEnergy, const G4ParticleDefinition*
|
||||
const G4MaterialCutsCouple* couple = FindCouple(mat, region);
|
||||
if(couple && UpdateParticle(p, kinEnergy) ) {
|
||||
res = manager->GetDEDX(p, kinEnergy, couple);
|
||||
if(isIon) {
|
||||
G4double eth = 2.0*MeV/massRatio;
|
||||
if(kinEnergy > eth) {
|
||||
G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy);
|
||||
G4double x2 = corr->ComputeIonCorrections(p,mat,eth);
|
||||
res += x1 - x2*eth/kinEnergy;
|
||||
/*
|
||||
G4cout << "### GetDEDX: E= " << kinEnergy << " res= " << res
|
||||
<< " x1= " << x1 << " x2= " << x2
|
||||
<< " del= " << x1 - x2*eth/kinEnergy << G4endl;;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if(verbose>0) {
|
||||
G4cout << "G4EmCalculator::GetDEDX: E(MeV)= " << kinEnergy/MeV
|
||||
<< " DEDX(MeV/mm)= " << res*mm/MeV
|
||||
@@ -405,31 +420,21 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
if(baseParticle) {
|
||||
res = currentModel->ComputeDEDXPerVolume(
|
||||
mat, baseParticle, escaled, cut) * chargeSquare;
|
||||
if(verbose > 1)
|
||||
if(verbose > 1) {
|
||||
G4cout << baseParticle->GetParticleName()
|
||||
<< " Escaled(MeV)= " << escaled;
|
||||
}
|
||||
} else {
|
||||
res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
|
||||
if(verbose > 1) G4cout << " no basePart E(MeV)= " << kinEnergy;
|
||||
}
|
||||
if(verbose > 1)
|
||||
if(verbose > 1) {
|
||||
G4cout << " DEDX(MeV/mm)= " << res*mm/MeV
|
||||
<< " DEDX(MeV*cm^2/g)= "
|
||||
<< res*gram/(MeV*cm2*mat->GetDensity())
|
||||
<< G4endl;
|
||||
|
||||
if(isIon) {
|
||||
if(currentModel->HighEnergyLimit() > 100.*MeV)
|
||||
res += corr->HighOrderCorrections(p,mat,kinEnergy);
|
||||
else
|
||||
res *= corr->EffectiveChargeCorrection(p,mat,kinEnergy);
|
||||
if(verbose > 1)
|
||||
G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
|
||||
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
// emulate boundary region for different parameterisations
|
||||
G4double eth = currentModel->LowEnergyLimit();
|
||||
// G4cout << "massRatio= " << massRatio << " eth= " << eth << G4endl;
|
||||
@@ -446,15 +451,32 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
res1 = currentModel->ComputeDEDXPerVolume(mat, p, eth, cut);
|
||||
res0 = loweModel->ComputeDEDXPerVolume(mat, p, eth, cut);
|
||||
}
|
||||
if(verbose > 1)
|
||||
if(verbose > 1) {
|
||||
G4cout << "At boundary energy(MeV)= " << eth/MeV
|
||||
<< " DEDX(MeV/mm)= " << res1*mm/MeV
|
||||
<< G4endl;
|
||||
if(isIon) res1 += corr->HighOrderCorrections(p,mat,eth/massRatio);
|
||||
//G4cout << "eth= " << eth << " escaled= " << escaled
|
||||
// << " res0= " << res0 << " res1= "
|
||||
// << res1 << " q2= " << chargeSquare << G4endl;
|
||||
}
|
||||
/*
|
||||
G4cout << "eth= " << eth << " escaled= " << escaled
|
||||
<< " res0= " << res0 << " res1= "
|
||||
<< res1 << " q2= " << chargeSquare << G4endl;
|
||||
*/
|
||||
res *= (1.0 + (res0/res1 - 1.0)*eth/escaled);
|
||||
|
||||
if(isIon) {
|
||||
G4double ethscaled = eth/massRatio;
|
||||
if(kinEnergy > ethscaled) {
|
||||
G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy);
|
||||
G4double x2 = corr->ComputeIonCorrections(p,mat,ethscaled);
|
||||
res += x1 - x2*ethscaled/kinEnergy;
|
||||
}
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
|
||||
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(verbose > 0) {
|
||||
@@ -506,8 +528,10 @@ G4double G4EmCalculator::ComputeElectronicDEDX(G4double kinEnergy, const G4Strin
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4ParticleDefinition* part,
|
||||
const G4Material* mat, G4double cut)
|
||||
G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4Material* mat,
|
||||
G4double cut)
|
||||
{
|
||||
G4double dedx = ComputeElectronicDEDX(kinEnergy,part,mat,cut);
|
||||
if(mass > 700.*MeV) dedx += ComputeNuclearDEDX(kinEnergy,part,mat);
|
||||
@@ -516,8 +540,10 @@ G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4ParticleDe
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4String& part,
|
||||
const G4String& mat, G4double cut)
|
||||
G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
|
||||
const G4String& part,
|
||||
const G4String& mat,
|
||||
G4double cut)
|
||||
{
|
||||
return ComputeTotalDEDX(kinEnergy,FindParticle(part),FindMaterial(mat),cut);
|
||||
}
|
||||
@@ -754,10 +780,12 @@ G4bool G4EmCalculator::UpdateParticle(const G4ParticleDefinition* p,
|
||||
}
|
||||
if(isIon) {
|
||||
chargeSquare =
|
||||
ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy);
|
||||
if(currentProcess)
|
||||
ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy)
|
||||
* corr->EffectiveChargeCorrection(p,currentMaterial,kinEnergy);
|
||||
if(currentProcess) {
|
||||
currentProcess->SetDynamicMassCharge(massRatio,chargeSquare);
|
||||
// G4cout << "massR= " << massRatio << " q2= " << chargeSquare << G4endl;
|
||||
//G4cout << "NewP: massR= " << massRatio << " q2= " << chargeSquare << G4endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmConfigurator.cc,v 1.3 2008/11/21 12:30:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class
|
||||
//
|
||||
// File name: G4EmConfigurator
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 14.07.2008
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// This class provides configuration EM models for
|
||||
// particles/processes/regions
|
||||
//
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4EmConfigurator.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4VProcess.hh"
|
||||
#include "G4ProcessVector.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4DummyModel.hh"
|
||||
#include "G4VEnergyLossProcess.hh"
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4VMultipleScattering.hh"
|
||||
|
||||
enum PType {unknown=0, eloss, discrete, msc};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmConfigurator::G4EmConfigurator()
|
||||
{
|
||||
index = 1;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmConfigurator::~G4EmConfigurator()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmConfigurator::AddExtraEmModel(const G4String& particleName,
|
||||
G4VEmModel* em,
|
||||
G4VEmFluctuationModel* fm)
|
||||
{
|
||||
particleList.push_back(particleName);
|
||||
modelList.push_back(em);
|
||||
flucModelList.push_back(fm);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmConfigurator::AddModelForRegion(const G4String& particleName,
|
||||
const G4String& processName,
|
||||
const G4String& modelName,
|
||||
const G4String& regionName,
|
||||
G4double emin, G4double emax,
|
||||
const G4String& flucModelName)
|
||||
{
|
||||
particles.push_back(particleName);
|
||||
processes.push_back(processName);
|
||||
models.push_back(modelName);
|
||||
regions.push_back(regionName);
|
||||
flucModels.push_back(flucModelName);
|
||||
lowEnergy.push_back(emin);
|
||||
highEnergy.push_back(emax);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmConfigurator::SetExtraEmModel(const G4String& particleName,
|
||||
const G4String& processName,
|
||||
G4VEmModel* mod,
|
||||
const G4String& regionName,
|
||||
G4double emin,
|
||||
G4double emax,
|
||||
G4VEmFluctuationModel* fm)
|
||||
{
|
||||
AddExtraEmModel(particleName, mod, fm);
|
||||
G4String fname = "";
|
||||
if(fm) fname = fm->GetName();
|
||||
AddModelForRegion(particleName, processName, mod->GetName(), regionName,
|
||||
emin, emax, fname);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmConfigurator::AddModels()
|
||||
{
|
||||
size_t n = particles.size();
|
||||
//G4cout << " G4EmConfigurator::AddModels n= " << n << G4endl;
|
||||
if(n > 0) {
|
||||
for(size_t i=0; i<n; i++) {
|
||||
SetModelForRegion(particles[i],processes[i],models[i],regions[i],
|
||||
flucModels[i],lowEnergy[i],highEnergy[i]);
|
||||
}
|
||||
}
|
||||
particles.clear();
|
||||
processes.clear();
|
||||
models.clear();
|
||||
flucModels.clear();
|
||||
regions.clear();
|
||||
lowEnergy.clear();
|
||||
highEnergy.clear();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmConfigurator::SetModelForRegion(const G4String& particleName,
|
||||
const G4String& processName,
|
||||
const G4String& modelName,
|
||||
const G4String& regionName,
|
||||
const G4String& flucModelName,
|
||||
G4double emin, G4double emax)
|
||||
{
|
||||
//G4cout << " G4EmConfigurator::SetModelForRegion" << G4endl;
|
||||
|
||||
// new set
|
||||
index--;
|
||||
|
||||
G4ParticleTable::G4PTblDicIterator* theParticleIterator =
|
||||
G4ParticleTable::GetParticleTable()->GetIterator();
|
||||
|
||||
theParticleIterator->reset();
|
||||
while( (*theParticleIterator)() ) {
|
||||
const G4ParticleDefinition* part = theParticleIterator->value();
|
||||
|
||||
//G4cout << particleName << " " << part->GetParticleName() << G4endl;
|
||||
|
||||
if(particleName == part->GetParticleName() ||
|
||||
(particleName == "charged" && part->GetPDGCharge() != 0.0) ) {
|
||||
|
||||
|
||||
// search for process
|
||||
G4ProcessManager* pmanager = part->GetProcessManager();
|
||||
G4ProcessVector* plist = pmanager->GetProcessList();
|
||||
G4int np = pmanager->GetProcessListLength();
|
||||
|
||||
//G4cout << processName << " in list of " << np << G4endl;
|
||||
|
||||
G4VProcess* proc = 0;
|
||||
for(G4int i=0; i<np; i++) {
|
||||
if(processName == (*plist)[i]->GetProcessName()) {
|
||||
proc = (*plist)[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!proc) {
|
||||
G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
|
||||
<< processName << "> for " << particleName << G4endl;
|
||||
|
||||
} else {
|
||||
|
||||
// classify process
|
||||
PType ptype = discrete;
|
||||
G4int ii = proc->GetProcessSubType();
|
||||
if(10 == ii) ptype = msc;
|
||||
else if(2 <= ii && 4 >= ii) ptype = eloss;
|
||||
|
||||
// find out model
|
||||
G4VEmModel* mod = 0;
|
||||
G4VEmFluctuationModel* fluc = 0;
|
||||
|
||||
G4int nm = modelList.size();
|
||||
//G4cout << "Search model " << modelName << " in " << nm << G4endl;
|
||||
|
||||
for(G4int i=0; i<nm; i++) {
|
||||
if(modelName == modelList[i]->GetName() &&
|
||||
(particleList[i] == "" || particleList[i] == particleName) ) {
|
||||
mod = modelList[i];
|
||||
fluc = flucModelList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if("dummy" == modelName) mod = new G4DummyModel();
|
||||
|
||||
if(!mod) {
|
||||
G4cout << "### G4EmConfigurator WARNING: fails to find a model <"
|
||||
<< modelName << "> for process <"
|
||||
<< processName << "> and " << particleName
|
||||
<< G4endl;
|
||||
if(flucModelName != "")
|
||||
G4cout << " fluctuation model <"
|
||||
<< flucModelName << G4endl;
|
||||
} else {
|
||||
|
||||
// search for region
|
||||
G4Region* reg = 0;
|
||||
G4RegionStore* regStore = G4RegionStore::GetInstance();
|
||||
G4String r = regionName;
|
||||
if(r == "" || r == "world" || r == "World") r = "DefaultRegionForTheWorld";
|
||||
reg = regStore->GetRegion(r, true);
|
||||
if(!reg) {
|
||||
G4cout << "### G4EmConfigurator WARNING: fails to find a region <"
|
||||
<< r << "> for model <" << modelName << "> of the process "
|
||||
<< processName << " and " << particleName << G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// energy limits
|
||||
G4double e1 = std::max(emin,mod->LowEnergyLimit());
|
||||
G4double e2 = std::min(emax,mod->HighEnergyLimit());
|
||||
if(e2 < e1) e2 = e1;
|
||||
mod->SetLowEnergyLimit(e1);
|
||||
mod->SetHighEnergyLimit(e2);
|
||||
|
||||
//G4cout << "e1= " << e1 << " e2= " << e2 << G4endl;
|
||||
|
||||
// added model
|
||||
if(ptype == eloss) {
|
||||
G4VEnergyLossProcess* p = reinterpret_cast<G4VEnergyLossProcess*>(proc);
|
||||
p->AddEmModel(index,mod,fluc,reg);
|
||||
//G4cout << "### Added eloss model order= " << index << " for "
|
||||
// << particleName << " and " << processName << " " << mod << G4endl;
|
||||
} else if(ptype == discrete) {
|
||||
G4VEmProcess* p = reinterpret_cast<G4VEmProcess*>(proc);
|
||||
p->AddEmModel(index,mod,reg);
|
||||
} else if(ptype == msc) {
|
||||
G4VMultipleScattering* p = reinterpret_cast<G4VMultipleScattering*>(proc);
|
||||
p->AddEmModel(index,mod,reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmCorrections.cc,v 1.22 2007/05/18 18:39:55 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4EmCorrections.cc,v 1.51 2008/12/18 13:01:44 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -43,6 +43,9 @@
|
||||
// 13.05.2006 V.Ivanchenko Add corrections for ion stopping
|
||||
// 08.05.2007 V.Ivanchenko Use G4IonTable for ion mass instead of NistTable to avoid
|
||||
// division by zero
|
||||
// 29.02.2008 V.Ivanchenko use expantions for log and power function
|
||||
// 21.04.2008 Updated computations for ions (V.Ivanchenko)
|
||||
// 20.05.2008 Removed Finite Size correction (V.Ivanchenko)
|
||||
//
|
||||
//
|
||||
// Class Description:
|
||||
@@ -55,30 +58,39 @@
|
||||
|
||||
#include "G4EmCorrections.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4LPhysicsFreeVector.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmCorrections::G4EmCorrections()
|
||||
{
|
||||
Initialise();
|
||||
particle = 0;
|
||||
curParticle= 0;
|
||||
material = 0;
|
||||
curMaterial= 0;
|
||||
curVector = 0;
|
||||
kinEnergy = 0.0;
|
||||
ionModel = 0;
|
||||
ionLEModel = 0;
|
||||
ionHEModel = 0;
|
||||
nIons = 0;
|
||||
verbose = 1;
|
||||
ncouples = 0;
|
||||
massFactor = 1.0;
|
||||
eth = 2.0*MeV;
|
||||
nbinCorr = 20;
|
||||
eCorrMin = 25.*keV;
|
||||
eCorrMax = 250.*MeV;
|
||||
nist = G4NistManager::Instance();
|
||||
ionTable = G4ParticleTable::GetParticleTable()->GetIonTable();
|
||||
Initialise();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -92,7 +104,7 @@ G4EmCorrections::~G4EmCorrections()
|
||||
|
||||
G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
G4double e, G4double)
|
||||
{
|
||||
// . Z^3 Barkas effect in the stopping power of matter for charged particles
|
||||
// J.C Ashley and R.H.Ritchie
|
||||
@@ -107,13 +119,12 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
|
||||
G4double Barkas = BarkasCorrection (p, mat, e);
|
||||
G4double Bloch = BlochCorrection (p, mat, e);
|
||||
G4double Mott = MottCorrection (p, mat, e);
|
||||
G4double FSize = FiniteSizeCorrection (p, mat, e);
|
||||
|
||||
G4double sum = (2.0*(Barkas + Bloch) + FSize + Mott);
|
||||
G4double sum = (2.0*(Barkas + Bloch) + Mott);
|
||||
|
||||
if(verbose > 1)
|
||||
G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
|
||||
<< " Bloch= " << Bloch << " Mott= " << Mott << " Fsize= " << FSize
|
||||
<< " Bloch= " << Bloch << " Mott= " << Mott
|
||||
<< " Sum= " << sum << G4endl;
|
||||
|
||||
sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
|
||||
@@ -122,6 +133,98 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::IonBarkasCorrection(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
{
|
||||
// . Z^3 Barkas effect in the stopping power of matter for charged particles
|
||||
// J.C Ashley and R.H.Ritchie
|
||||
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
|
||||
// and ICRU49 report
|
||||
// valid for kineticEnergy < 0.5 MeV
|
||||
|
||||
SetupKinematics(p, mat, e);
|
||||
G4double res = 0.0;
|
||||
if(tau > 0.0)
|
||||
res = 2.0*BarkasCorrection(p, mat, e)*
|
||||
material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
|
||||
return res;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
{
|
||||
// . Z^3 Barkas effect in the stopping power of matter for charged particles
|
||||
// J.C Ashley and R.H.Ritchie
|
||||
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
|
||||
// and ICRU49 report
|
||||
// valid for kineticEnergy < 0.5 MeV
|
||||
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
|
||||
SetupKinematics(p, mat, e);
|
||||
if(tau <= 0.0) return 0.0;
|
||||
|
||||
G4double Barkas = BarkasCorrection (p, mat, e);
|
||||
G4double Bloch = BlochCorrection (p, mat, e);
|
||||
G4double Mott = MottCorrection (p, mat, e);
|
||||
|
||||
G4double sum = 2.0*(Barkas*(charge - 1.0)/charge + Bloch) + Mott;
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
|
||||
<< " Bloch= " << Bloch << " Mott= " << Mott
|
||||
<< " Sum= " << sum << G4endl;
|
||||
}
|
||||
sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
|
||||
|
||||
if(verbose > 1) G4cout << " Sum= " << sum << G4endl;
|
||||
return sum;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double e)
|
||||
{
|
||||
// . Z^3 Barkas effect in the stopping power of matter for charged particles
|
||||
// J.C Ashley and R.H.Ritchie
|
||||
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
|
||||
// and ICRU49 report
|
||||
// valid for kineticEnergy < 0.5 MeV
|
||||
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
|
||||
|
||||
G4double sum = 0.0;
|
||||
|
||||
if(ionHEModel) {
|
||||
G4int Z = G4int(p->GetPDGCharge()/eplus + 0.5);
|
||||
if(Z >= 100) Z = 99;
|
||||
else if(Z < 1) Z = 1;
|
||||
|
||||
// fill vector
|
||||
if(thcorr[Z].size() == 0) {
|
||||
thcorr[Z].resize(ncouples);
|
||||
G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
|
||||
|
||||
for(size_t i=0; i<ncouples; i++) {
|
||||
(thcorr[Z])[i] = ethscaled*ComputeIonCorrections(p, currmat[i], ethscaled);
|
||||
//G4cout << i << ". ethscaled= " << ethscaled
|
||||
//<< " corr= " << (thcorr[Z])[i]/ethscaled << G4endl;
|
||||
}
|
||||
}
|
||||
G4double rest = (thcorr[Z])[couple->GetIndex()];
|
||||
|
||||
sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e;
|
||||
|
||||
if(verbose > 1) G4cout << " Sum= " << sum << " dSum= " << rest/e << G4endl;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::Bethe(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
@@ -225,7 +328,8 @@ G4double G4EmCorrections::KShell(G4double tet, G4double eta)
|
||||
if(eta < Eta[0]) y = Eta[0];
|
||||
G4int ieta = Index(y, Eta, nEtaK);
|
||||
corr = Value2(x, y, TheK[itet], TheK[itet+1], Eta[ieta], Eta[ieta+1],
|
||||
CK[itet][ieta], CK[itet+1][ieta], CK[itet][ieta+1], CK[itet+1][ieta+1]);
|
||||
CK[itet][ieta], CK[itet+1][ieta],
|
||||
CK[itet][ieta+1], CK[itet+1][ieta+1]);
|
||||
//G4cout << " x= " <<x<<" y= "<<y<<" tet= " <<TheK[itet]
|
||||
//<<" "<< TheK[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
|
||||
// <<" CK= " << CK[itet][ieta]<<" "<< CK[itet+1][ieta]
|
||||
@@ -438,7 +542,8 @@ G4double G4EmCorrections::BarkasCorrection(const G4ParticleDefinition* p,
|
||||
else if(W >= engBarkas[46]) val = corBarkas[46]*engBarkas[46]/W;
|
||||
else {
|
||||
G4int iw = Index(W, engBarkas, 47);
|
||||
val = Value(W, engBarkas[iw], engBarkas[iw+1], corBarkas[iw], corBarkas[iw+1]);
|
||||
val = Value(W, engBarkas[iw], engBarkas[iw+1],
|
||||
corBarkas[iw], corBarkas[iw+1]);
|
||||
}
|
||||
// G4cout << "i= " << i << " b= " << b << " W= " << W
|
||||
// << " Z= " << Z << " X= " << X << " val= " << val<< G4endl;
|
||||
@@ -474,111 +579,16 @@ G4double G4EmCorrections::BlochCorrection(const G4ParticleDefinition* p,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::MottCorrection(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
{
|
||||
SetupKinematics(p, mat, e);
|
||||
G4double mterm = pi*fine_structure_const*beta*charge;
|
||||
/*
|
||||
G4double mterm = 0.0;
|
||||
if(beta > 0.0) {
|
||||
|
||||
// Estimation of mean square root of the ionisation potential
|
||||
G4double Zeff = 0.0;
|
||||
G4double norm = 0.0;
|
||||
|
||||
for (G4int i = 0; i<numberOfElements; i++) {
|
||||
G4double Z = (*theElementVector)[i]->GetZ();
|
||||
Zeff += Z*atomDensity[i];
|
||||
norm += atomDensity[i];
|
||||
}
|
||||
Zeff *= (2.0/norm);
|
||||
G4double ze1 = std::log(Zeff);
|
||||
G4double eexc= material->GetIonisation()->GetMeanExcitationEnergy()*ze1*ze1/Zeff;
|
||||
|
||||
G4double invbeta = 1.0/beta;
|
||||
G4double invbeta2= invbeta*invbeta;
|
||||
G4double za = charge*fine_structure_const;
|
||||
G4double za2 = za*za;
|
||||
G4double za3 = za2*za;
|
||||
G4double x = za*invbeta;
|
||||
G4double cosx;
|
||||
if(x < COSEB[13]) {
|
||||
G4int i = Index(x,COSEB,14);
|
||||
cosx = Value(x,COSEB[i], COSEB[i+1],COSXI[i],COSXI[i+1]);
|
||||
} else {
|
||||
cosx = COSXI[13]*COSEB[13]/x;
|
||||
}
|
||||
|
||||
mterm =
|
||||
za*beta*(1.725 + pi*cosx*(0.52 - 2.0*std::sqrt(eexc/(2.0*electron_mass_c2*bg2))));
|
||||
+ za2*(3.246 - 0.451*beta2)
|
||||
+ za3*(1.522*beta + 0.987*invbeta)
|
||||
+ za2*za2*(4.569 - 0.494*beta2 - 2.696*invbeta2)
|
||||
+ za3*za2*(1.254*beta + 0.222*invbeta - 1.17*invbeta*invbeta2);
|
||||
}
|
||||
*/
|
||||
G4double mterm = CLHEP::pi*fine_structure_const*beta*charge;
|
||||
return mterm;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::FiniteSizeCorrection(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e)
|
||||
// Finite size corrections are parameterized according to
|
||||
// J.D.Jackson Phys. Rev. D59 (1998) 017301
|
||||
{
|
||||
SetupKinematics(p, mat, e);
|
||||
G4double term = 0.0;
|
||||
|
||||
//Leptons
|
||||
if(p->GetLeptonNumber() != 0) {
|
||||
G4double x = tmax/(e + mass);
|
||||
term = x*x;
|
||||
|
||||
// Pions and Kaons
|
||||
} else if(p->GetPDGSpin() == 0.0 && q2 < 1.5) {
|
||||
G4double xpi = 0.736*GeV;
|
||||
G4double x = 2.0*electron_mass_c2*tmax0/(xpi*xpi);
|
||||
term = -std::log(1.0 + x);
|
||||
|
||||
// Protons and baryons
|
||||
} else if(q2 < 1.5) {
|
||||
G4double xp = 0.8426*GeV;
|
||||
G4double x = 2.0*electron_mass_c2*tmax0/(xp*xp);
|
||||
G4double ksi2 = 2.79285*2.79285;
|
||||
term = -x*(1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) - std::log(1.0 + x);
|
||||
G4double b = xp*0.5/mass;
|
||||
G4double c = xp*mass/(electron_mass_c2*(mass + e));
|
||||
G4double lb = b*b;
|
||||
G4double lb2= lb*lb;
|
||||
G4double nu = 0.5*c*c;
|
||||
G4double x1 = 1.0 + x;
|
||||
G4double x2 = x1*x1;
|
||||
G4double l1 = 1.0 - lb;
|
||||
G4double l2 = l1*l1;
|
||||
G4double lx = 1.0 + lb*x;
|
||||
G4double ia = lb2*(lx*std::log(lx/x1)/x + l1 -
|
||||
0.5*x*l2/(lb*x1) +
|
||||
x*(3.0 + 2.0*x)*l2*l1/(6.0*x2*lb2))/(l2*l2);
|
||||
G4double ib = x*x*(3.0 + x)/(6.0*x2*x1);
|
||||
term += lb*((ksi2 - 1.0)*ia + nu*ksi2*ib);
|
||||
// G4cout << "Proton F= " << term << " ia= " << ia << " ib= " << ib << " lb= " << lb<< G4endl;
|
||||
|
||||
//ions
|
||||
} else {
|
||||
G4double xp = 0.8426*GeV/std::pow(mass/proton_mass_c2,-0.33333333);
|
||||
G4double x = 2.0*electron_mass_c2*tmax0/(xp*xp);
|
||||
term = -std::log(1.0 + x);
|
||||
//G4cout << "Ion F= " << term << G4endl;
|
||||
}
|
||||
|
||||
return term;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::NuclearDEDX(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double e,
|
||||
@@ -616,23 +626,29 @@ G4double G4EmCorrections::NuclearStoppingPower(G4double kineticEnergy,
|
||||
G4double nloss = 0.0;
|
||||
|
||||
G4double rm;
|
||||
if(z1 > 1.5) rm = (m1 + m2) * ( std::pow(z1, .23) + std::pow(z2, .23) ) ;
|
||||
else rm = (m1 + m2) * std::pow(z2, 0.333333);
|
||||
if(z1 > 1.5) rm = (m1 + m2) * ( Z23[G4int(z1)] + Z23[G4int(z2)] ) ;
|
||||
else rm = (m1 + m2) * nist->GetZ13(G4int(z2));
|
||||
|
||||
G4double er = 32.536 * m2 * energy / ( z1 * z2 * rm ) ; // reduced energy
|
||||
|
||||
for (G4int i=1; i<104; i++)
|
||||
|
||||
if (er >= ed[0]) nloss = a[0];
|
||||
else {
|
||||
// the table is inverse in energy
|
||||
for (G4int i=102; i>=0; i--)
|
||||
{
|
||||
if (er > ed[i]) {
|
||||
nloss = (a[i] - a[i-1])*(er-ed[i-1])/(ed[i] - ed[i-1]) + a[i-1];
|
||||
if (er <= ed[i]) {
|
||||
nloss = (a[i] - a[i+1])*(er - ed[i+1])/(ed[i] - ed[i+1]) + a[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stragling
|
||||
if(lossFlucFlag) {
|
||||
// G4double sig = 4.0 * m1 * m2 / ((m1 + m2)*(m1 + m2)*
|
||||
// (4.0 + 0.197*std::pow(er,-1.6991)+6.584*std::pow(er,-1.0494))) ;
|
||||
G4double sig = 4.0 * m1 * m2 / ((m1 + m2)*(m1 + m2)*
|
||||
(4.0 + 0.197*std::pow(er,-1.6991)+6.584*std::pow(er,-1.0494))) ;
|
||||
(4.0 + 0.197/(er*er) + 6.584/er));
|
||||
|
||||
nloss *= G4RandGauss::shoot(1.0,sig) ;
|
||||
}
|
||||
@@ -646,56 +662,57 @@ G4double G4EmCorrections::NuclearStoppingPower(G4double kineticEnergy,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4ionEffectiveCharge* G4EmCorrections::GetIonEffectiveCharge(G4VEmModel* m)
|
||||
{
|
||||
if(m) ionModel = m;
|
||||
return &effCharge;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4EmCorrections::GetNumberOfStoppingVectors()
|
||||
{
|
||||
return nIons;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double ekin)
|
||||
{
|
||||
G4double factor = 1.0;
|
||||
if(p->GetPDGCharge() <= 2.5*eplus) return factor;
|
||||
if(verbose > 1)
|
||||
G4cout << "EffectiveChargeCorrection: " << p->GetParticleName() << " in " << mat->GetName()
|
||||
if(p->GetPDGCharge() <= 2.5*eplus || nIons <= 0) return factor;
|
||||
/*
|
||||
if(verbose > 1) {
|
||||
G4cout << "EffectiveChargeCorrection: " << p->GetParticleName()
|
||||
<< " in " << mat->GetName()
|
||||
<< " ekin(MeV)= " << ekin/MeV << G4endl;
|
||||
}
|
||||
*/
|
||||
if(p != curParticle || mat != curMaterial) {
|
||||
curParticle = p;
|
||||
curMaterial = 0;
|
||||
curMaterial = mat;
|
||||
curVector = 0;
|
||||
G4int Z = p->GetAtomicNumber();
|
||||
G4int A = p->GetAtomicMass();
|
||||
if(verbose > 1) G4cout << "Zion= " << Z << " Aion= " << A << G4endl;
|
||||
massFactor = proton_mass_c2/ionTable->GetIonMass(Z,A);
|
||||
idx = 0;
|
||||
for(; idx<nIons; idx++) {
|
||||
if(Z == Zion[idx] && A == Aion[idx]) {
|
||||
if(materialList[idx] == mat) {
|
||||
curMaterial = mat;
|
||||
curVector = stopData[idx];
|
||||
break;
|
||||
} else if(materialList[idx] == 0) {
|
||||
if(materialName[idx] == mat->GetName())
|
||||
curVector = InitialiseMaterial(mat);
|
||||
}
|
||||
currentZ = p->GetAtomicNumber();
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4EmCorrections::EffectiveChargeCorrection: Zion= "
|
||||
<< currentZ << " Aion= " << p->GetPDGMass()/amu_c2 << G4endl;
|
||||
}
|
||||
massFactor = proton_mass_c2/p->GetPDGMass();
|
||||
idx = -1;
|
||||
G4int dz = 1000;
|
||||
|
||||
for(G4int i=0; i<nIons; i++) {
|
||||
if(materialList[i] == mat) {
|
||||
G4int delz = currentZ - Zion[i];
|
||||
if(delz < 0) delz = -delz;
|
||||
if(delz < dz) {
|
||||
idx = i;
|
||||
dz = delz;
|
||||
if(0 == delz) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// G4cout << " idx= " << idx << " dz= " << dz << G4endl;
|
||||
if(idx > 0) {
|
||||
if(!ionList[idx]) BuildCorrectionVector();
|
||||
if(ionList[idx]) curVector = stopData[idx];
|
||||
}
|
||||
}
|
||||
if(curVector) {
|
||||
G4bool b;
|
||||
factor = curVector->GetValue(ekin*massFactor,b);
|
||||
if(verbose > 1) {
|
||||
G4cout << "E= " << ekin << " factor= " << factor << " massfactor= "
|
||||
<< massFactor << G4endl;
|
||||
}
|
||||
}
|
||||
if(verbose > 1) G4cout << " factor= " << factor << G4endl;
|
||||
return factor;
|
||||
}
|
||||
|
||||
@@ -703,69 +720,122 @@ G4double G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition*
|
||||
|
||||
void G4EmCorrections::AddStoppingData(G4int Z, G4int A,
|
||||
const G4String& mname,
|
||||
G4PhysicsVector& dVector)
|
||||
G4PhysicsVector* dVector)
|
||||
{
|
||||
idx = 0;
|
||||
for(; idx<nIons; idx++) {
|
||||
if(Z == Zion[idx] && A == Aion[idx] && mname == materialName[idx])
|
||||
break;
|
||||
G4int i = 0;
|
||||
for(; i<nIons; i++) {
|
||||
if(Z == Zion[i] && A == Aion[i] && mname == materialName[i]) break;
|
||||
}
|
||||
if(idx == nIons) {
|
||||
if(i == nIons) {
|
||||
Zion.push_back(Z);
|
||||
Aion.push_back(A);
|
||||
materialName.push_back(mname);
|
||||
materialList.push_back(0);
|
||||
stopData.push_back(0);
|
||||
ionList.push_back(0);
|
||||
stopData.push_back(dVector);
|
||||
nIons++;
|
||||
} else {
|
||||
if(stopData[idx]) delete stopData[idx];
|
||||
if(verbose>1) {
|
||||
G4cout << "AddStoppingData Z= " << Z << " A= " << A << " " << mname
|
||||
<< " idx= " << i << G4endl;
|
||||
}
|
||||
}
|
||||
size_t nbins = dVector.GetVectorLength();
|
||||
size_t n = 0;
|
||||
for(; n<nbins; n++) {
|
||||
if(dVector.GetLowEdgeEnergy(n) > 2.0*MeV) break;
|
||||
}
|
||||
if(n < nbins) nbins = n + 1;
|
||||
G4LPhysicsFreeVector* v =
|
||||
new G4LPhysicsFreeVector(nbins,
|
||||
dVector.GetLowEdgeEnergy(0),
|
||||
dVector.GetLowEdgeEnergy(nbins-1));
|
||||
G4bool b;
|
||||
for(size_t i=0; i<nbins; i++) {
|
||||
G4double e = dVector.GetLowEdgeEnergy(i);
|
||||
G4double dedx = dVector.GetValue(e, b);
|
||||
v->PutValues(i, e, dedx);
|
||||
}
|
||||
// G4cout << *v << G4endl;
|
||||
stopData[idx] = v;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PhysicsVector* G4EmCorrections::InitialiseMaterial(const G4Material* mat)
|
||||
void G4EmCorrections::BuildCorrectionVector()
|
||||
{
|
||||
G4PhysicsVector* v = 0;
|
||||
const G4Material* m = nist->FindOrBuildMaterial(materialName[idx],false);
|
||||
if(m) {
|
||||
materialList[idx] = m;
|
||||
curMaterial = mat;
|
||||
v = stopData[idx];
|
||||
size_t nbins = v->GetVectorLength();
|
||||
const G4ParticleDefinition* p = G4Proton::Proton();
|
||||
if(verbose>1) G4cout << "G4ionIonisation::InitialiseMaterial Stooping data for "
|
||||
<< materialName[idx] << G4endl;
|
||||
G4bool b;
|
||||
for(size_t i=0; i<nbins; i++) {
|
||||
G4double e = v->GetLowEdgeEnergy(i);
|
||||
G4double dedx = v->GetValue(e, b);
|
||||
G4double dedx1= ionModel->ComputeDEDXPerVolume(mat, p, e, e)*
|
||||
effCharge.EffectiveChargeSquareRatio(curParticle,mat,e/massFactor);
|
||||
v->PutValue(i, dedx/dedx1);
|
||||
if(verbose>1) G4cout << " E(meV)= " << e/MeV << " Correction= " << dedx/dedx1
|
||||
<< " " << dedx << " " << dedx1 << G4endl;
|
||||
if(!ionLEModel || !ionHEModel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const G4ParticleDefinition* ion = curParticle;
|
||||
G4int Z = Zion[idx];
|
||||
if(currentZ != Z) {
|
||||
ion = G4ParticleTable::GetParticleTable()->FindIon(Z, Aion[idx], 0, Z);
|
||||
}
|
||||
//G4cout << "BuildCorrectionVector: idx= " << idx << " Z= " << Z
|
||||
// << " curZ= " << currentZ << G4endl;
|
||||
|
||||
// G4double A = nist->GetAtomicMassAmu(Z);
|
||||
G4double A = G4double(ion->GetBaryonNumber());
|
||||
G4PhysicsVector* v = stopData[idx];
|
||||
|
||||
const G4ParticleDefinition* p = G4GenericIon::GenericIon();
|
||||
G4double massRatio = proton_mass_c2/ion->GetPDGMass();
|
||||
|
||||
if(verbose>1) {
|
||||
G4cout << "BuildCorrectionVector: Stopping for "
|
||||
<< curParticle->GetParticleName() << " in "
|
||||
<< materialName[idx] << " Ion Z= " << Z << " A= " << A
|
||||
<< " massRatio= " << massRatio << G4endl;
|
||||
}
|
||||
G4bool b;
|
||||
|
||||
G4PhysicsLogVector* vv =
|
||||
new G4PhysicsLogVector(eCorrMin,eCorrMax,nbinCorr);
|
||||
vv->SetSpline(true);
|
||||
G4double e, eion, dedx, dedx1;
|
||||
G4double eth0 = v->GetLowEdgeEnergy(0);
|
||||
G4double escal = eth/massRatio;
|
||||
G4double qe =
|
||||
effCharge.EffectiveChargeSquareRatio(ion, curMaterial, escal);
|
||||
G4double dedxt =
|
||||
ionLEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe;
|
||||
G4double dedx1t =
|
||||
ionHEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe
|
||||
+ ComputeIonCorrections(curParticle, curMaterial, escal);
|
||||
G4double rest = escal*(dedxt - dedx1t);
|
||||
//G4cout << "Escal(MeV)= "<<escal<<" dedxt0= " <<dedxt
|
||||
// << " dedxt1= " << dedx1t << G4endl;
|
||||
|
||||
for(G4int i=0; i<nbinCorr; i++) {
|
||||
e = vv->GetLowEdgeEnergy(i);
|
||||
escal = e/massRatio;
|
||||
eion = escal/A;
|
||||
if(eion <= eth0) {
|
||||
dedx = v->GetValue(eth0, b)*std::sqrt(eion/eth0);
|
||||
} else {
|
||||
dedx = v->GetValue(eion, b);
|
||||
}
|
||||
qe = effCharge.EffectiveChargeSquareRatio(curParticle,curMaterial,escal);
|
||||
if(e <= eth) {
|
||||
dedx1 = ionLEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe;
|
||||
} else {
|
||||
dedx1 = ionHEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe +
|
||||
ComputeIonCorrections(curParticle, curMaterial, escal) + rest/escal;
|
||||
}
|
||||
vv->PutValue(i, dedx/dedx1);
|
||||
if(verbose>1) {
|
||||
G4cout << " E(meV)= " << e/MeV << " Correction= " << dedx/dedx1
|
||||
<< " " << dedx << " " << dedx1
|
||||
<< " massF= " << massFactor << G4endl;
|
||||
}
|
||||
}
|
||||
delete v;
|
||||
ionList[idx] = ion;
|
||||
stopData[idx] = vv;
|
||||
if(verbose>1) G4cout << "End data set " << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmCorrections::InitialiseForNewRun()
|
||||
{
|
||||
G4ProductionCutsTable* tb = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
ncouples = tb->GetTableSize();
|
||||
if(currmat.size() != ncouples) {
|
||||
currmat.resize(ncouples);
|
||||
size_t i;
|
||||
for(i=0; i<100; i++) {thcorr[i].clear();}
|
||||
for(i=0; i<ncouples; i++) {
|
||||
currmat[i] = tb->GetMaterialCutsCouple(i)->GetMaterial();
|
||||
G4String nam = currmat[i]->GetName();
|
||||
for(G4int j=0; j<nIons; j++) {
|
||||
if(nam == materialName[j]) { materialList[j] = currmat[i]; }
|
||||
}
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -1412,6 +1482,10 @@ void G4EmCorrections::Initialise()
|
||||
COSEB[i] = coseb[i];
|
||||
COSXI[i] = cosxi[i];
|
||||
}
|
||||
|
||||
for(i=1; i<100; i++) {
|
||||
Z23[i] = std::pow(G4double(i),0.23);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmElementSelector.cc,v 1.4 2008/08/21 18:53:32 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4EmElementSelector
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 29.05.2008
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Generic helper class for the random selection of an element
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4EmElementSelector.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmElementSelector::G4EmElementSelector(G4VEmModel* mod,
|
||||
const G4Material* mat,
|
||||
G4int bins,
|
||||
G4double emin,
|
||||
G4double emax,
|
||||
G4bool spline):
|
||||
model(mod), material(mat), nbins(bins), cutEnergy(-1.0),
|
||||
lowEnergy(emin), highEnergy(emax)
|
||||
{
|
||||
G4int n = material->GetNumberOfElements();
|
||||
nElmMinusOne = n - 1;
|
||||
theElementVector = material->GetElementVector();
|
||||
if(nElmMinusOne > 0) {
|
||||
for(G4int i=0; i<nElmMinusOne; i++) {
|
||||
G4PhysicsLogVector* v = new G4PhysicsLogVector(lowEnergy,highEnergy,nbins);
|
||||
v->SetSpline(spline);
|
||||
xSections.push_back(v);
|
||||
}
|
||||
}
|
||||
//G4cout << "G4EmElementSelector for " << mat->GetName() << " n= " << n << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmElementSelector::~G4EmElementSelector()
|
||||
{
|
||||
if(nElmMinusOne > 0) {
|
||||
for(G4int i=0; i<nElmMinusOne; i++) {
|
||||
delete xSections[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmElementSelector::Initialise(const G4ParticleDefinition* part,
|
||||
G4double cut)
|
||||
{
|
||||
//G4cout << "G4EmElementSelector initialise for " << material->GetName() << G4endl;
|
||||
if(0 == nElmMinusOne || cut == cutEnergy) return;
|
||||
|
||||
cutEnergy = cut;
|
||||
//G4cout << "cut(keV)= " << cut/keV << G4endl;
|
||||
G4double cross;
|
||||
|
||||
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4int i;
|
||||
G4int n = nElmMinusOne + 1;
|
||||
G4double* xsec = new G4double[n];
|
||||
|
||||
// loop over bins
|
||||
for(G4int j=0; j<nbins; j++) {
|
||||
G4double e = (xSections[0])->GetLowEdgeEnergy(j);
|
||||
model->SetupForMaterial(part, material, e);
|
||||
cross = 0.0;
|
||||
//G4cout << "j= " << j << " e(MeV)= " << e/MeV << G4endl;
|
||||
for (i=0; i<n; i++) {
|
||||
cross += theAtomNumDensityVector[i]*
|
||||
model->ComputeCrossSectionPerAtom(part, (*theElementVector)[i], e,
|
||||
cutEnergy, e);
|
||||
xsec[i] = cross;
|
||||
}
|
||||
if(DBL_MIN >= cross) cross = 1.0;
|
||||
// normalise cross section sum
|
||||
for (i=0; i<nElmMinusOne; i++) {
|
||||
xSections[i]->PutValue(j, xsec[i]/cross);
|
||||
//G4cout << "i= " << i << " xs= " << xsec[i]/cross << G4endl;
|
||||
}
|
||||
}
|
||||
delete [] xsec;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmElementSelector::Dump(const G4ParticleDefinition* part)
|
||||
{
|
||||
G4cout << "======== G4EmElementSelector for the " << model->GetName();
|
||||
if(part) G4cout << " and " << part->GetParticleName();
|
||||
G4cout << " for " << material->GetName() << " ========" << G4endl;
|
||||
if(0 < nElmMinusOne) {
|
||||
for(G4int i=0; i<nElmMinusOne; i++) {
|
||||
G4cout << " " << (*theElementVector)[i]->GetName() << " : " << G4endl;
|
||||
G4cout << *(xSections[i]) << G4endl;
|
||||
}
|
||||
}
|
||||
G4cout << "Last Element in element vector"
|
||||
<< (*theElementVector)[nElmMinusOne]->GetName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmModelManager.cc,v 1.40 2007/11/09 11:35:54 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4EmModelManager.cc,v 1.46 2008/10/13 14:56:56 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -77,15 +77,18 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& list, G4DataVector& lowE)
|
||||
G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& indx,
|
||||
G4DataVector& lowE, const G4Region* reg)
|
||||
{
|
||||
nModelsForRegion = nMod;
|
||||
theListOfModelIndexes = new G4int [nModelsForRegion];
|
||||
lowKineticEnergy = new G4double [nModelsForRegion];
|
||||
lowKineticEnergy = new G4double [nModelsForRegion+1];
|
||||
for (G4int i=0; i<nModelsForRegion; i++) {
|
||||
theListOfModelIndexes[i] = list[i];
|
||||
theListOfModelIndexes[i] = indx[i];
|
||||
lowKineticEnergy[i] = lowE[i];
|
||||
}
|
||||
lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion];
|
||||
theRegion = reg;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -98,7 +101,6 @@ G4RegionModels::~G4RegionModels()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
@@ -106,10 +108,10 @@ G4RegionModels::~G4RegionModels()
|
||||
#include "G4Positron.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -127,7 +129,6 @@ G4EmModelManager::G4EmModelManager():
|
||||
flucModels.clear();
|
||||
regions.clear();
|
||||
orderOfModels.clear();
|
||||
upperEkin.clear();
|
||||
maxCutInRange = 12.*cm;
|
||||
maxSubCutInRange = 0.7*mm;
|
||||
theGamma = G4Gamma::Gamma();
|
||||
@@ -138,41 +139,7 @@ G4EmModelManager::G4EmModelManager():
|
||||
|
||||
G4EmModelManager::~G4EmModelManager()
|
||||
{
|
||||
G4int i,j;
|
||||
Clear();
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager:: delete models ";
|
||||
if(particle) G4cout << " for " << particle->GetParticleName();
|
||||
G4cout << " nModels=" << nEmModels <<G4endl;
|
||||
}
|
||||
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
orderOfModels[i] = 1;
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
if (orderOfModels[i]) {
|
||||
orderOfModels[i] = 0;
|
||||
for(j = i+1; j<nEmModels; j++) {
|
||||
if(models[i] == models[j]) orderOfModels[j] = 0;
|
||||
}
|
||||
G4String nam = models[i]->GetName();
|
||||
if(nam != "PAI" && nam != "PAIModel" ) delete models[i];
|
||||
}
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
orderOfModels[i] = 1;
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
if (orderOfModels[i]) {
|
||||
orderOfModels[i] = 0;
|
||||
for(j = i+1; j<nEmModels; j++) {
|
||||
if(flucModels[i] == flucModels[j]) orderOfModels[j] = 0;
|
||||
}
|
||||
delete flucModels[i];
|
||||
}
|
||||
}
|
||||
if(1 < verboseLevel)
|
||||
G4cout << "G4EmModelManager:: models are deleted!" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -180,14 +147,11 @@ G4EmModelManager::~G4EmModelManager()
|
||||
void G4EmModelManager::Clear()
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::Clear()";
|
||||
if(particle) G4cout << " for " << particle->GetParticleName();
|
||||
G4cout << G4endl;
|
||||
G4cout << "G4EmModelManager::Clear()" << G4endl;
|
||||
}
|
||||
|
||||
theCuts.clear();
|
||||
theSubCuts.clear();
|
||||
upperEkin.clear();
|
||||
if(idxOfRegionModels) delete [] idxOfRegionModels;
|
||||
if(setOfRegionModels && nRegions) {
|
||||
for(G4int i=0; i<nRegions; i++) {
|
||||
@@ -214,21 +178,6 @@ void G4EmModelManager::AddEmModel(G4int num, G4VEmModel* p,
|
||||
regions.push_back(r);
|
||||
orderOfModels.push_back(num);
|
||||
p->DefineForRegion(r);
|
||||
if (nEmModels>0) {
|
||||
G4int idx = nEmModels;
|
||||
do {idx--;} while (idx && num < orderOfModels[idx]);
|
||||
if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;
|
||||
if (idx < nEmModels) {
|
||||
models[nEmModels] = models[idx];
|
||||
flucModels[nEmModels] = flucModels[idx];
|
||||
regions[nEmModels] = regions[idx];
|
||||
orderOfModels[nEmModels] = orderOfModels[idx];
|
||||
models[idx] = p;
|
||||
flucModels[idx] = fm;
|
||||
regions[idx] = r;
|
||||
orderOfModels[idx] = num;
|
||||
}
|
||||
}
|
||||
nEmModels++;
|
||||
}
|
||||
|
||||
@@ -253,14 +202,17 @@ void G4EmModelManager::UpdateEmModel(const G4String& nam,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VEmModel* G4EmModelManager::GetModel(G4int i)
|
||||
G4VEmModel* G4EmModelManager::GetModel(G4int i, G4bool ver)
|
||||
{
|
||||
G4VEmModel* m = 0;
|
||||
if(i >= 0 && i < nEmModels) m = models[i];
|
||||
else if(verboseLevel > 0)
|
||||
if(i >= 0 && i < nEmModels) {m = models[i];}
|
||||
else if(verboseLevel > 0 && ver) {
|
||||
G4cout << "G4EmModelManager::GetModel WARNING: "
|
||||
<< "index " << i << " is wrong Nmodels= "
|
||||
<< nEmModels << G4endl;
|
||||
<< nEmModels;
|
||||
if(particle) G4cout << " for " << particle->GetParticleName();
|
||||
G4cout<< G4endl;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -268,8 +220,8 @@ G4VEmModel* G4EmModelManager::GetModel(G4int i)
|
||||
|
||||
const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ParticleDefinition* sp,
|
||||
G4double theMinSubRange,
|
||||
G4int val)
|
||||
G4double theMinSubRange,
|
||||
G4int val)
|
||||
{
|
||||
verboseLevel = val;
|
||||
if(1 < verboseLevel) {
|
||||
@@ -292,8 +244,8 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
// Identify the list of regions with different set of models
|
||||
nRegions = 1;
|
||||
std::vector<const G4Region*> set;
|
||||
set.push_back(world);
|
||||
std::vector<const G4Region*> setr;
|
||||
setr.push_back(world);
|
||||
G4bool isWorld = false;
|
||||
|
||||
for (G4int ii=0; ii<nEmModels; ii++) {
|
||||
@@ -305,11 +257,11 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
G4bool newRegion = true;
|
||||
if (nRegions>1) {
|
||||
for (G4int j=1; j<nRegions; j++) {
|
||||
if ( r == set[j] ) newRegion = false;
|
||||
if ( r == setr[j] ) newRegion = false;
|
||||
}
|
||||
}
|
||||
if (newRegion) {
|
||||
set.push_back(r);
|
||||
setr.push_back(r);
|
||||
nRegions++;
|
||||
}
|
||||
}
|
||||
@@ -321,21 +273,18 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
idxOfRegionModels = new G4int[numOfCouples+1];
|
||||
idxOfRegionModels[numOfCouples] = 0;
|
||||
setOfRegionModels = new G4RegionModels*[nRegions];
|
||||
upperEkin.resize(nEmModels);
|
||||
|
||||
std::vector<G4int> modelAtRegion(nEmModels);
|
||||
std::vector<G4int> modelOrd(nEmModels);
|
||||
G4DataVector eLow(nEmModels);
|
||||
G4DataVector eHigh(nEmModels);
|
||||
G4int nmax = nEmModels;
|
||||
|
||||
// Order models for regions
|
||||
for (G4int reg=0; reg<nRegions; reg++) {
|
||||
const G4Region* region = set[reg];
|
||||
|
||||
const G4Region* region = setr[reg];
|
||||
G4int n = 0;
|
||||
|
||||
std::vector<G4int> modelAtRegion;
|
||||
G4DataVector eLow;
|
||||
G4DataVector eHigh;
|
||||
modelAtRegion.clear();
|
||||
eLow.clear();
|
||||
eHigh.clear();
|
||||
|
||||
if(isWorld || 0 < reg) {
|
||||
|
||||
for (G4int ii=0; ii<nEmModels; ii++) {
|
||||
@@ -345,7 +294,10 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
G4double tmin = model->LowEnergyLimit();
|
||||
G4double tmax = model->HighEnergyLimit();
|
||||
if (n>0) tmin = std::max(tmin, eHigh[n-1]);
|
||||
G4int ord = orderOfModels[ii];
|
||||
G4bool push = true;
|
||||
G4bool insert = false;
|
||||
G4int idx = n;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Model #" << ii
|
||||
@@ -354,16 +306,104 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
G4cout << "> "
|
||||
<< " tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< "; order= " << orderOfModels[ii]
|
||||
<< "; order= " << ord
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if (n == 0) n++;
|
||||
else {
|
||||
tmin = std::min(tmin, eHigh[n-1]);
|
||||
if(tmin >= tmax) push = false;
|
||||
else {
|
||||
|
||||
if (tmin < tmax) {
|
||||
modelAtRegion.push_back(ii);
|
||||
eLow.push_back(tmin);
|
||||
eHigh.push_back(tmax);
|
||||
upperEkin[ii] = tmax;
|
||||
n++;
|
||||
// high energy model
|
||||
if(tmin == eHigh[n-1] && tmax > eHigh[n-1]) n++;
|
||||
else if (tmax > eHigh[n-1]) {
|
||||
|
||||
// compare order of models
|
||||
for(G4int k = n-1; k>=0; k--) {
|
||||
|
||||
if (ord >= modelOrd[k]) {
|
||||
tmin = std::max(tmin, eHigh[k]);
|
||||
if(k < n-1) n = k + 2;
|
||||
break;
|
||||
} else if (tmin > eLow[k]) {
|
||||
eHigh[k] = tmin;
|
||||
n = k + 2;
|
||||
break;
|
||||
} else if (tmin == eLow[k]) {
|
||||
n = k + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(tmin < eLow[0]) n = 1;
|
||||
idx = n - 1;
|
||||
|
||||
// low energy model
|
||||
} else {
|
||||
|
||||
tmax = std::max(tmax, eLow[0]);
|
||||
insert = true;
|
||||
push = false;
|
||||
idx = 0;
|
||||
if(tmax <= eLow[0]) tmax = eLow[0];
|
||||
else {
|
||||
|
||||
for(G4int k=0; k<n; k++) {
|
||||
|
||||
if (ord >= modelOrd[k]) {
|
||||
if(k == 0) {
|
||||
if(tmin < eLow[0]) tmax = eLow[0];
|
||||
else insert = false;
|
||||
break;
|
||||
} else {
|
||||
insert = false;
|
||||
break;
|
||||
}
|
||||
} else if(tmax < eHigh[k]) {
|
||||
idx = k;
|
||||
if(k > 0) tmin = eLow[k];
|
||||
eLow[k] = tmax;
|
||||
break;
|
||||
} else if(tmax == eHigh[k]) {
|
||||
insert = false;
|
||||
push = true;
|
||||
idx = k;
|
||||
if(k > 0) tmin = eLow[k];
|
||||
else tmin = std::min(tmin,eLow[0]);
|
||||
break;
|
||||
} else {
|
||||
modelAtRegion[k] = ii;
|
||||
modelOrd[k] = ord;
|
||||
if(k == 0) eLow[idx] = std::min(tmin,eLow[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(insert && idx < n) n++;
|
||||
else insert = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(n > nmax) {
|
||||
nmax = n;
|
||||
modelAtRegion.resize(nmax);
|
||||
modelOrd.resize(nmax);
|
||||
eLow.resize(nmax);
|
||||
eHigh.resize(nmax);
|
||||
}
|
||||
if(insert) {
|
||||
for(G4int k=n-2; k>=idx; k--) {
|
||||
modelAtRegion[k+1] = modelAtRegion[k];
|
||||
modelOrd[k+1] = modelOrd[k];
|
||||
eLow[k+1] = eLow[k];
|
||||
eHigh[k+1] = eHigh[k];
|
||||
}
|
||||
}
|
||||
if (push || insert) {
|
||||
modelAtRegion[idx] = ii;
|
||||
modelOrd[idx] = ord;
|
||||
eLow[idx] = tmin;
|
||||
eHigh[idx] = tmax;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,18 +413,19 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
modelAtRegion.push_back(nEmModels);
|
||||
eLow.push_back(0.0);
|
||||
eHigh.push_back(DBL_MAX);
|
||||
upperEkin.push_back(DBL_MAX);
|
||||
}
|
||||
eLow[0] = 0.0;
|
||||
if(n >= nmax) eLow.resize(nmax+1);
|
||||
eLow[n] = eHigh[n-1];
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "New G4RegionModels set with " << n << " models for region <";
|
||||
if (region) G4cout << region->GetName();
|
||||
G4cout << "> Elow(MeV)= ";
|
||||
for(G4int ii=0; ii<n; ii++) {G4cout << eLow[ii]/MeV << " ";}
|
||||
for(G4int ii=0; ii<=n; ii++) {G4cout << eLow[ii]/MeV << " ";}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow);
|
||||
G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow, region);
|
||||
setOfRegionModels[reg] = rm;
|
||||
}
|
||||
|
||||
@@ -398,7 +439,7 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ProductionCuts* pcuts = couple->GetProductionCuts();
|
||||
|
||||
G4int reg = nRegions;
|
||||
do {reg--;} while (reg>0 && pcuts != (set[reg]->GetProductionCuts()));
|
||||
do {reg--;} while (reg>0 && pcuts != (setr[reg]->GetProductionCuts()));
|
||||
idxOfRegionModels[i] = reg;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
@@ -473,11 +514,6 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
G4EmTableType tType)
|
||||
{
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor;
|
||||
G4DataVector dedxLow;
|
||||
G4DataVector dedxHigh;
|
||||
|
||||
G4double e;
|
||||
|
||||
size_t i = couple->GetIndex();
|
||||
@@ -490,8 +526,8 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::FillDEDXVector() for "
|
||||
<< couple->GetMaterial()->GetName()
|
||||
<< " Ecut(MeV)= " << cut
|
||||
<< " Esubcut(MeV)= " << subcut
|
||||
<< " cut(MeV)= " << cut
|
||||
<< " subcut(MeV)= " << subcut
|
||||
<< " Type " << tType
|
||||
<< " for " << particle->GetParticleName()
|
||||
<< G4endl;
|
||||
@@ -500,9 +536,12 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
dedxLow.resize(nmod);
|
||||
dedxHigh.resize(nmod);
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor(nmod);
|
||||
G4DataVector eLow(nmod+1);
|
||||
G4DataVector dedxLow(nmod);
|
||||
G4DataVector dedxHigh(nmod);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
@@ -511,44 +550,66 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
// calculate factors to provide continuity of energy loss
|
||||
|
||||
|
||||
factor[0] = 1.0;
|
||||
G4int j;
|
||||
|
||||
G4int totBinsLoss = aVector->GetVectorLength();
|
||||
|
||||
dedxLow[0] = 0.0;
|
||||
dedxLow[0] = 0.0;
|
||||
eLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
e = regModels->LowEdgeEnergy(1);
|
||||
eLow[1] = e;
|
||||
G4VEmModel* model = models[regModels->ModelIndex(0)];
|
||||
dedxHigh[0] = 0.0;
|
||||
if(model && cut > subcut) {
|
||||
dedxHigh[0] = model->ComputeDEDX(couple,particle,e,cut);
|
||||
if(subcut > 0.0)
|
||||
if(subcut > 0.0) {
|
||||
dedxHigh[0] -= model->ComputeDEDX(couple,particle,e,subcut);
|
||||
}
|
||||
}
|
||||
if(nmod > 1) {
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
e = regModels->LowEdgeEnergy(j);
|
||||
eLow[j] = e;
|
||||
G4int idx = regModels->ModelIndex(j);
|
||||
|
||||
dedxLow[j] = models[idx]->ComputeDEDX(couple,particle,e,cut);
|
||||
if(subcut > 0.0)
|
||||
if(subcut > 0.0) {
|
||||
dedxLow[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut);
|
||||
}
|
||||
if(subcut == cut) dedxLow[j] = 0.0;
|
||||
|
||||
e = upperEkin[idx];
|
||||
e = regModels->LowEdgeEnergy(j+1);
|
||||
eLow[j+1] = e;
|
||||
dedxHigh[j] = models[idx]->ComputeDEDX(couple,particle,e,cut);
|
||||
if(subcut > 0.0)
|
||||
if(subcut > 0.0) {
|
||||
dedxHigh[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut);
|
||||
}
|
||||
if(subcut == cut) dedxHigh[j] = 0.0;
|
||||
}
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << " model #0"
|
||||
<< " dedx(" << eLow[0] << ")= " << dedxLow[0]
|
||||
<< " dedx(" << eLow[1] << ")= " << dedxHigh[0]
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
if(dedxLow[j] > 0.0) {
|
||||
factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0)*eLow[j];
|
||||
} else factor[j] = 0.0;
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << " model #" << j
|
||||
<< " dedx(" << eLow[j] << ")= " << dedxLow[j]
|
||||
<< " dedx(" << eLow[j+1] << ")= " << dedxHigh[j]
|
||||
<< " factor= " << factor[j]/eLow[j]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(2 < verboseLevel) {
|
||||
@@ -564,11 +625,11 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
if (nmod > 1 && e > eLow[1]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
|
||||
fac *= (1.0 + factor[k]/e);
|
||||
} while (k+1 < nmod && e > eLow[k+1]);
|
||||
}
|
||||
|
||||
model = models[regModels->ModelIndex(k)];
|
||||
@@ -601,11 +662,6 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
G4bool startFromNull,
|
||||
G4EmTableType tType)
|
||||
{
|
||||
// vectors to provide continues cross section
|
||||
G4DataVector factor;
|
||||
G4DataVector sigmaLow;
|
||||
G4DataVector sigmaHigh;
|
||||
|
||||
G4double e;
|
||||
|
||||
size_t i = couple->GetIndex();
|
||||
@@ -629,9 +685,12 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
sigmaLow.resize(nmod);
|
||||
sigmaHigh.resize(nmod);
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor(nmod);
|
||||
G4DataVector eLow(nmod+1);
|
||||
G4DataVector sigmaLow(nmod);
|
||||
G4DataVector sigmaHigh(nmod);
|
||||
|
||||
if(2 < verboseLevel) {
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
@@ -643,9 +702,11 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
G4int j;
|
||||
G4int totBinsLambda = aVector->GetVectorLength();
|
||||
|
||||
sigmaLow[0] = 0.0;
|
||||
sigmaLow[0] = 0.0;
|
||||
eLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
e = regModels->LowEdgeEnergy(1);
|
||||
eLow[1] = e;
|
||||
G4VEmModel* model = models[regModels->ModelIndex(0)];
|
||||
sigmaHigh[0] = 0.0;
|
||||
if(model) sigmaHigh[0] = model->CrossSection(couple,particle,e,cut,tmax);
|
||||
@@ -667,22 +728,32 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
sigmaLow[j] =
|
||||
models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
sigmaHigh[j] =
|
||||
models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax);
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << " model #" << j << " eUp= " << e
|
||||
<< " sigmaUp= " << sigmaHigh[j]
|
||||
<< " sigmaDown= " << sigmaLow[j]
|
||||
<< G4endl;
|
||||
}
|
||||
e = regModels->LowEdgeEnergy(j);
|
||||
eLow[j] = e;
|
||||
G4int idx = regModels->ModelIndex(j);
|
||||
|
||||
sigmaLow[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax);
|
||||
e = regModels->LowEdgeEnergy(j+1);
|
||||
eLow[j+1] = e;
|
||||
sigmaHigh[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax);
|
||||
}
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << " model #0"
|
||||
<< " sigma(" << eLow[0] << ")= " << sigmaLow[0]
|
||||
<< " sigma(" << eLow[1] << ")= " << sigmaHigh[0]
|
||||
<< G4endl;
|
||||
}
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
if(sigmaLow[j] > 0.0) {
|
||||
factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0)*eLow[j];
|
||||
} else factor[j] = 0.0;
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << " model #" << j
|
||||
<< " sigma(" << eLow[j] << ")= " << sigmaLow[j]
|
||||
<< " sigma(" << eLow[j+1] << ")= " << sigmaHigh[j]
|
||||
<< " factor= " << factor[j]/eLow[j]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,11 +765,11 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
G4double fac = 1.0;
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
if (nmod > 1 && e > eLow[1]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
|
||||
fac *= (1.0 + factor[k]/e);
|
||||
} while ( k+1 < nmod && e > eLow[k+1] );
|
||||
}
|
||||
|
||||
model = models[regModels->ModelIndex(k)];
|
||||
@@ -720,3 +791,30 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::DumpModelList(G4int verb)
|
||||
{
|
||||
if(verb == 0) return;
|
||||
for(G4int i=0; i<nRegions; i++) {
|
||||
G4RegionModels* r = setOfRegionModels[i];
|
||||
const G4Region* reg = r->Region();
|
||||
if(verb > 1 || nRegions > 1) {
|
||||
}
|
||||
G4int n = r->NumberOfModels();
|
||||
if(verb > 1 || n > 0) {
|
||||
G4cout << " ===== EM models for the G4Region " << reg->GetName()
|
||||
<< " ======" << G4endl;;
|
||||
for(G4int j=0; j<n; j++) {
|
||||
const G4VEmModel* m = models[r->ModelIndex(j)];
|
||||
G4cout << std::setw(20);
|
||||
G4cout << m->GetName() << " : Emin= "
|
||||
<< std::setw(10) << G4BestUnit(r->LowEdgeEnergy(j),"Energy")
|
||||
<< " Emax= "
|
||||
<< G4BestUnit(r->LowEdgeEnergy(j+1),"Energy")
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmMultiModel.cc,v 1.6 2007/05/22 17:31:58 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmProcessOptions.cc,v 1.22 2007/11/07 18:38:49 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4EmProcessOptions.cc,v 1.24 2008/04/17 10:33:27 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -476,6 +476,25 @@ void G4EmProcessOptions::SetMscGeomFactor(G4double val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmProcessOptions::SetPolarAngleLimit(G4double val)
|
||||
{
|
||||
const std::vector<G4VMultipleScattering*>& u =
|
||||
theManager->GetMultipleScatteringVector();
|
||||
std::vector<G4VMultipleScattering*>::const_iterator itm;
|
||||
for(itm = u.begin(); itm != u.end(); itm++) {
|
||||
if(*itm) (*itm)->SetPolarAngleLimit(val);
|
||||
}
|
||||
const std::vector<G4VEmProcess*>& w =
|
||||
theManager->GetEmProcessVector();
|
||||
std::vector<G4VEmProcess*>::const_iterator itp;
|
||||
for(itp = w.begin(); itp != w.end(); itp++) {
|
||||
G4VEmProcess* q = *itp;
|
||||
if(q) q->SetPolarAngleLimit(val);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmProcessOptions::SetLPMFlag(G4bool val)
|
||||
{
|
||||
theManager->SetLPMFlag(val);
|
||||
@@ -483,6 +502,13 @@ void G4EmProcessOptions::SetLPMFlag(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmProcessOptions::SetSplineFlag(G4bool val)
|
||||
{
|
||||
theManager->SetSplineFlag(val);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmProcessOptions::SetLinearLossLimit(G4double val)
|
||||
{
|
||||
theManager->SetLinearLossLimit(val);
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmSaturation.cc,v 1.9 2008/11/12 15:37:33 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4EmSaturation
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 18.02.2008
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4EmSaturation.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmSaturation::G4EmSaturation()
|
||||
{
|
||||
verbose = 1;
|
||||
manager = 0;
|
||||
curMaterial = 0;
|
||||
curBirks = 0.0;
|
||||
curRatio = 1.0;
|
||||
curChargeSq = 1.0;
|
||||
nMaterials = 0;
|
||||
Initialise();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmSaturation::~G4EmSaturation()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmSaturation::VisibleEnergyDeposition(
|
||||
const G4ParticleDefinition* p,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double length,
|
||||
G4double edep,
|
||||
G4double niel)
|
||||
{
|
||||
if(edep <= 0.0) return 0.0;
|
||||
|
||||
G4double evis = edep;
|
||||
G4double bfactor = FindBirksCoefficient(couple->GetMaterial());
|
||||
|
||||
if(bfactor > 0.0) {
|
||||
|
||||
// atomic relaxations
|
||||
if(p == gamma) {
|
||||
evis /= (1.0 + bfactor*edep/manager->GetRange(electron,edep,couple));
|
||||
|
||||
// energy loss
|
||||
} else {
|
||||
|
||||
// protections
|
||||
G4double nloss = niel;
|
||||
if(nloss < 0.0) nloss = 0.0;
|
||||
G4double eloss = edep - nloss;
|
||||
if(p == neutron || eloss < 0.0 || length <= 0.0) {
|
||||
nloss = edep;
|
||||
eloss = 0.0;
|
||||
}
|
||||
|
||||
// continues energy loss
|
||||
if(eloss > 0.0) eloss /= (1.0 + bfactor*eloss/length);
|
||||
|
||||
// non-ionizing energy loss
|
||||
if(nloss > 0.0) {
|
||||
G4double escaled = nloss*curRatio;
|
||||
G4double s = manager->GetRange(proton,escaled,couple)/curChargeSq;
|
||||
nloss /= (1.0 + bfactor*nloss/s);
|
||||
}
|
||||
|
||||
evis = eloss + nloss;
|
||||
}
|
||||
}
|
||||
|
||||
return evis;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmSaturation::FindG4BirksCoefficient(const G4Material* mat)
|
||||
{
|
||||
G4String name = mat->GetName();
|
||||
// is this material in the vector?
|
||||
|
||||
for(G4int j=0; j<nG4Birks; j++) {
|
||||
if(name == g4MatNames[j]) {
|
||||
if(verbose > 0)
|
||||
G4cout << "### G4EmSaturation::FindG4BirksCoefficient for "
|
||||
<< name << " is " << g4MatData[j]*MeV/mm << " mm/MeV "
|
||||
<< G4endl;
|
||||
return g4MatData[j];
|
||||
}
|
||||
}
|
||||
return FindBirksCoefficient(mat);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmSaturation::FindBirksCoefficient(const G4Material* mat)
|
||||
{
|
||||
if(mat == curMaterial) return curBirks;
|
||||
|
||||
curMaterial = mat;
|
||||
curBirks = 0.0;
|
||||
curRatio = 1.0;
|
||||
curChargeSq = 1.0;
|
||||
|
||||
// seach in the run-time list
|
||||
for(G4int i=0; i<nMaterials; i++) {
|
||||
if(mat == matPointers[i]) {
|
||||
curBirks = mat->GetIonisation()->GetBirksConstant();
|
||||
curRatio = massFactors[i];
|
||||
curChargeSq = effCharges[i];
|
||||
return curBirks;
|
||||
}
|
||||
}
|
||||
|
||||
if(!manager) {
|
||||
manager = G4LossTableManager::Instance();
|
||||
nist = G4NistManager::Instance();
|
||||
gamma = G4Gamma::Gamma();
|
||||
electron= G4Electron::Electron();
|
||||
proton = G4Proton::Proton();
|
||||
neutron = G4Neutron::Neutron();
|
||||
}
|
||||
|
||||
G4String name = mat->GetName();
|
||||
curBirks = mat->GetIonisation()->GetBirksConstant();
|
||||
|
||||
// material has no Birks coeffitient defined
|
||||
// seach in the Geant4 list
|
||||
if(curBirks == 0.0) {
|
||||
for(G4int j=0; j<nG4Birks; j++) {
|
||||
if(name == g4MatNames[j]) {
|
||||
mat->GetIonisation()->SetBirksConstant(g4MatData[j]);
|
||||
curBirks = g4MatData[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(curBirks == 0.0 && verbose > 0) {
|
||||
G4cout << "### G4EmSaturation::FindBirksCoefficient fails "
|
||||
" for material " << name << G4endl;
|
||||
}
|
||||
|
||||
// compute mean mass ratio
|
||||
curRatio = 0.0;
|
||||
curChargeSq = 0.0;
|
||||
G4double norm = 0.0;
|
||||
const G4ElementVector* theElementVector = mat->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = mat->GetVecNbOfAtomsPerVolume();
|
||||
size_t nelm = mat->GetNumberOfElements();
|
||||
for (size_t i=0; i<nelm; i++) {
|
||||
const G4Element* elm = (*theElementVector)[i];
|
||||
G4double Z = elm->GetZ();
|
||||
G4double w = Z*Z*theAtomNumDensityVector[i];
|
||||
curRatio += w/nist->GetAtomicMassAmu(G4int(Z));
|
||||
curChargeSq = Z*Z*w;
|
||||
norm += w;
|
||||
}
|
||||
curRatio *= proton_mass_c2/norm;
|
||||
curChargeSq /= norm;
|
||||
|
||||
// store results
|
||||
matPointers.push_back(mat);
|
||||
matNames.push_back(name);
|
||||
massFactors.push_back(curRatio);
|
||||
effCharges.push_back(curChargeSq);
|
||||
nMaterials++;
|
||||
if(curBirks > 0.0 && verbose > 0) {
|
||||
G4cout << "### G4EmSaturation::FindBirksCoefficient Birks coefficient for "
|
||||
<< name << " " << curBirks*MeV/mm << " mm/MeV" << G4endl;
|
||||
}
|
||||
return curBirks;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmSaturation::DumpBirksCoefficients()
|
||||
{
|
||||
if(nMaterials > 0) {
|
||||
G4cout << "### Birks coeffitients used in run time" << G4endl;
|
||||
for(G4int i=0; i<nMaterials; i++) {
|
||||
G4double br = matPointers[i]->GetIonisation()->GetBirksConstant();
|
||||
G4cout << " " << matNames[i] << " "
|
||||
<< br*MeV/mm << " mm/MeV" << " "
|
||||
<< br*matPointers[i]->GetDensity()*MeV*cm2/g
|
||||
<< " g/cm^2/MeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmSaturation::DumpG4BirksCoefficients()
|
||||
{
|
||||
if(nG4Birks > 0) {
|
||||
G4cout << "### Birks coeffitients for Geant4 materials" << G4endl;
|
||||
for(G4int i=0; i<nG4Birks; i++) {
|
||||
G4cout << " " << g4MatNames[i] << " "
|
||||
<< g4MatData[i]*MeV/mm << " mm/MeV" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmSaturation::Initialise()
|
||||
{
|
||||
// M.Hirschberg et al., IEEE Trans. Nuc. Sci. 39 (1992) 511
|
||||
// SCSN-38 kB = 0.00842 g/cm^2/MeV; rho = 1.06 g/cm^3
|
||||
g4MatNames.push_back("G4_POLYSTYRENE");
|
||||
g4MatData.push_back(0.07943*mm/MeV);
|
||||
|
||||
// C.Fabjan (private communication)
|
||||
// kB = 0.006 g/cm^2/MeV; rho = 7.13 g/cm^3
|
||||
g4MatNames.push_back("G4_BGO");
|
||||
g4MatData.push_back(0.008415*mm/MeV);
|
||||
|
||||
// A.Ribon analysis of publications
|
||||
// Scallettar et al., Phys. Rev. A25 (1982) 2419.
|
||||
// NIM A 523 (2004) 275.
|
||||
// kB = 0.022 g/cm^2/MeV; rho = 1.396 g/cm^3;
|
||||
// ATLAS Efield = 10 kV/cm provide the strongest effect
|
||||
g4MatNames.push_back("G4_lAr");
|
||||
g4MatData.push_back(0.1576*mm/MeV);
|
||||
|
||||
//G4_BARIUM_FLUORIDE
|
||||
//G4_CESIUM_IODIDE
|
||||
//G4_GEL_PHOTO_EMULSION
|
||||
//G4_PHOTO_EMULSION
|
||||
//G4_PLASTIC_SC_VINYLTOLUENE
|
||||
//G4_SODIUM_IODIDE
|
||||
//G4_STILBENE
|
||||
//G4_lAr
|
||||
//G4_PbWO4
|
||||
//G4_Lucite
|
||||
|
||||
nG4Birks = g4MatData.size();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EnergyLossMessenger.cc,v 1.29 2007/06/11 14:56:51 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4EnergyLossMessenger.cc,v 1.35 2008/10/20 13:27:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -48,6 +48,7 @@
|
||||
// is needed after the command (V.Ivanchenko)
|
||||
// 16-03-07 modify /process/eLoss/minsubsec command (V.Ivanchenko)
|
||||
// 18-05-07 add /process/msc directory and commands (V.Ivanchenko)
|
||||
// 11-03-08 add /process/em directory and commands (V.Ivanchenko)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -83,6 +84,8 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
|
||||
eLossDirectory->SetGuidance("Commands for EM processes.");
|
||||
mscDirectory = new G4UIdirectory("/process/msc/");
|
||||
mscDirectory->SetGuidance("Commands for EM scattering processes.");
|
||||
emDirectory = new G4UIdirectory("/process/em/");
|
||||
emDirectory->SetGuidance("General commands for EM processes.");
|
||||
|
||||
RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/rndmStep",this);
|
||||
RndmStepCmd->SetGuidance("Randomize the proposed step by eLoss.");
|
||||
@@ -145,81 +148,104 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
|
||||
MaxEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this);
|
||||
IntegCmd->SetGuidance("Switch true/false the integration of cross section over step.");
|
||||
IntegCmd->SetGuidance("Switch true/false the integral option");
|
||||
IntegCmd->SetParameterName("integ",true);
|
||||
IntegCmd->SetDefaultValue(true);
|
||||
IntegCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
rangeCmd = new G4UIcmdWithABool("/process/eLoss/CSDARange",this);
|
||||
rangeCmd->SetGuidance("Switch true/false the precise range calculation.");
|
||||
rangeCmd->SetGuidance("Switch true/false the CSDA range calculation");
|
||||
rangeCmd->SetParameterName("range",true);
|
||||
rangeCmd->SetDefaultValue(true);
|
||||
rangeCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
lpmCmd = new G4UIcmdWithABool("/process/eLoss/LPM",this);
|
||||
lpmCmd->SetGuidance("Switch true/false the LPM effect calculation.");
|
||||
lpmCmd->SetGuidance("The flag of the LPM effect calculation");
|
||||
lpmCmd->SetParameterName("lpm",true);
|
||||
lpmCmd->SetDefaultValue(true);
|
||||
lpmCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
splCmd = new G4UIcmdWithABool("/process/em/spline",this);
|
||||
splCmd->SetGuidance("The flag of usage spline for Physics Vectors");
|
||||
splCmd->SetParameterName("spl",true);
|
||||
splCmd->SetDefaultValue(false);
|
||||
splCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
aplCmd = new G4UIcmdWithABool("/process/em/applyCuts",this);
|
||||
aplCmd->SetGuidance("The flag to Apply Cuts for gamma processes");
|
||||
aplCmd->SetParameterName("apl",true);
|
||||
aplCmd->SetDefaultValue(false);
|
||||
aplCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
dedxCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsDEDX",this);
|
||||
dedxCmd->SetGuidance("Set number of bins for DEDX tables.");
|
||||
dedxCmd->SetGuidance("Set number of bins for DEDX tables");
|
||||
dedxCmd->SetParameterName("binsDEDX",true);
|
||||
dedxCmd->SetDefaultValue(120);
|
||||
dedxCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
lamCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsLambda",this);
|
||||
lamCmd->SetGuidance("Set number of bins for Lambda tables.");
|
||||
lamCmd->SetGuidance("Set number of bins for Lambda tables");
|
||||
lamCmd->SetParameterName("binsL",true);
|
||||
lamCmd->SetDefaultValue(120);
|
||||
lamCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
verCmd = new G4UIcmdWithAnInteger("/process/eLoss/verbose",this);
|
||||
verCmd->SetGuidance("Set verbose level for EM physics.");
|
||||
verCmd->SetGuidance("Set verbose level for EM physics");
|
||||
verCmd->SetParameterName("verb",true);
|
||||
verCmd->SetDefaultValue(1);
|
||||
verCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
ver1Cmd = new G4UIcmdWithAnInteger("/process/em/verbose",this);
|
||||
ver1Cmd->SetGuidance("Set verbose level for EM physics");
|
||||
ver1Cmd->SetParameterName("verb1",true);
|
||||
ver1Cmd->SetDefaultValue(1);
|
||||
ver1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
lllCmd = new G4UIcmdWithADouble("/process/eLoss/linLossLimit",this);
|
||||
lllCmd->SetGuidance("Set linearLossLimit parameter.");
|
||||
lllCmd->SetGuidance("Set linearLossLimit parameter");
|
||||
lllCmd->SetParameterName("linlim",true);
|
||||
lllCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
labCmd = new G4UIcmdWithADouble("/process/eLoss/lambdaFactor",this);
|
||||
labCmd->SetGuidance("Set lambdaFactor parameter.");
|
||||
labCmd = new G4UIcmdWithADouble("/process/eLoss/LambdaFactor",this);
|
||||
labCmd->SetGuidance("Set lambdaFactor parameter for integral option");
|
||||
labCmd->SetParameterName("Fl",true);
|
||||
labCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
mscCmd = new G4UIcmdWithAString("/process/msc/StepLimit",this);
|
||||
mscCmd->SetGuidance("Set msc step limitation type.");
|
||||
mscCmd->SetGuidance("Set msc step limitation type");
|
||||
mscCmd->SetParameterName("StepLim",true);
|
||||
mscCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
latCmd = new G4UIcmdWithABool("/process/msc/LateralDisplacement",this);
|
||||
latCmd->SetGuidance("Switch true/false sampling of latra dislacent.");
|
||||
latCmd->SetGuidance("Set flag of sampling of lateral displacement");
|
||||
latCmd->SetParameterName("lat",true);
|
||||
latCmd->SetDefaultValue(true);
|
||||
latCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
frCmd = new G4UIcmdWithADouble("/process/msc/RangeFactor",this);
|
||||
frCmd->SetGuidance("Set RangeFactor parameter for msc process.");
|
||||
frCmd->SetGuidance("Set RangeFactor parameter for msc processes");
|
||||
frCmd->SetParameterName("Fr",true);
|
||||
frCmd->SetRange("Fr>0");
|
||||
frCmd->SetDefaultValue(0.02);
|
||||
frCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
fgCmd = new G4UIcmdWithADouble("/process/msc/GeomFactor",this);
|
||||
fgCmd->SetGuidance("Set GeomFactor parameter for msc process.");
|
||||
fgCmd->SetGuidance("Set GeomFactor parameter for msc processes");
|
||||
fgCmd->SetParameterName("Fg",true);
|
||||
fgCmd->SetRange("Fg>0");
|
||||
fgCmd->SetDefaultValue(3.5);
|
||||
fgCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
skinCmd = new G4UIcmdWithADouble("/process/msc/Skin",this);
|
||||
skinCmd->SetGuidance("Set skin parameter for multiple scattering.");
|
||||
skinCmd->SetGuidance("Set skin parameter for msc processes");
|
||||
skinCmd->SetParameterName("skin",true);
|
||||
skinCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
angCmd = new G4UIcmdWithADoubleAndUnit("/process/msc/ThetaLimit",this);
|
||||
angCmd->SetGuidance("Set the limit on the polar angle");
|
||||
angCmd->SetParameterName("theta",true);
|
||||
angCmd->SetUnitCategory("Angle");
|
||||
angCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -234,13 +260,17 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
|
||||
delete StepFuncCmd;
|
||||
delete eLossDirectory;
|
||||
delete mscDirectory;
|
||||
delete emDirectory;
|
||||
delete MinEnCmd;
|
||||
delete MaxEnCmd;
|
||||
delete IntegCmd;
|
||||
delete rangeCmd;
|
||||
delete lpmCmd;
|
||||
delete splCmd;
|
||||
delete aplCmd;
|
||||
delete latCmd;
|
||||
delete verCmd;
|
||||
delete ver1Cmd;
|
||||
delete mscCmd;
|
||||
delete dedxCmd;
|
||||
delete frCmd;
|
||||
@@ -249,6 +279,7 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
|
||||
delete lamCmd;
|
||||
delete labCmd;
|
||||
delete skinCmd;
|
||||
delete angCmd;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -316,9 +347,9 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
}
|
||||
|
||||
if (command == IntegCmd)
|
||||
if (command == IntegCmd) {
|
||||
opt->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
|
||||
|
||||
}
|
||||
if (command == rangeCmd) {
|
||||
opt->SetBuildCSDARange(rangeCmd->GetNewBoolValue(newValue));
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
@@ -329,20 +360,32 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
}
|
||||
|
||||
if (command == splCmd) {
|
||||
opt->SetSplineFlag(splCmd->GetNewBoolValue(newValue));
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
}
|
||||
|
||||
if (command == aplCmd) {
|
||||
opt->SetApplyCuts(aplCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == latCmd) {
|
||||
opt->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue));
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
}
|
||||
|
||||
if (command == verCmd)
|
||||
if (command == verCmd) {
|
||||
opt->SetVerbose(verCmd->GetNewIntValue(newValue));
|
||||
|
||||
if (command == lllCmd)
|
||||
}
|
||||
if (command == ver1Cmd) {
|
||||
opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
|
||||
}
|
||||
if (command == lllCmd) {
|
||||
opt->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue));
|
||||
|
||||
if (command == labCmd)
|
||||
}
|
||||
if (command == labCmd) {
|
||||
opt->SetLambdaFactor(labCmd->GetNewDoubleValue(newValue));
|
||||
|
||||
}
|
||||
if (command == skinCmd) {
|
||||
opt->SetSkin(skinCmd->GetNewDoubleValue(newValue));
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
@@ -363,6 +406,10 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
opt->SetMscGeomFactor(fgCmd->GetNewDoubleValue(newValue));
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
}
|
||||
if (command == angCmd) {
|
||||
opt->SetPolarAngleLimit(angCmd->GetNewDoubleValue(newValue));
|
||||
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EnergyLossTables.cc,v 1.33 2006/06/29 19:55:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4EnergyLossTables.cc,v 1.34 2008/07/08 10:57:22 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// first version created by P.Urban , 06/04/1998
|
||||
@@ -997,12 +997,13 @@ void G4EnergyLossTables::CPRWarning()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle, const G4String& q)
|
||||
void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle,
|
||||
const G4String& q)
|
||||
{
|
||||
G4String s = "G4EnergyLossTables:: " + q + " table not found for "
|
||||
+ aParticle->GetParticleName() + "!";
|
||||
G4Exception(s);
|
||||
exit(1);
|
||||
G4String s = " " + q + " table not found for "
|
||||
+ aParticle->GetParticleName() + " !";
|
||||
G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01",
|
||||
FatalException, s);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LossTableBuilder.cc,v 1.24 2007/02/16 11:59:35 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4LossTableBuilder.cc,v 1.27 2008/07/22 15:55:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -63,7 +63,9 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LossTableBuilder::G4LossTableBuilder()
|
||||
{}
|
||||
{
|
||||
splineFlag = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -72,8 +74,9 @@ G4LossTableBuilder::~G4LossTableBuilder()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
|
||||
const std::vector<G4PhysicsTable*>& list)
|
||||
void
|
||||
G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
|
||||
const std::vector<G4PhysicsTable*>& list)
|
||||
{
|
||||
size_t n_processes = list.size();
|
||||
if(1 >= n_processes) return;
|
||||
@@ -90,6 +93,7 @@ void G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
|
||||
for (size_t i=0; i<n_vectors; i++) {
|
||||
|
||||
pv = new G4PhysicsLogVector(elow, ehigh, nbins);
|
||||
pv->SetSpline(splineFlag);
|
||||
for (size_t j=0; j<nbins; j++) {
|
||||
G4double dedx = 0.0;
|
||||
G4double energy = pv->GetLowEdgeEnergy(j);
|
||||
@@ -127,6 +131,7 @@ void G4LossTableBuilder::BuildRangeTable(const G4PhysicsTable* dedxTable,
|
||||
G4double ehigh = pv->GetLowEdgeEnergy(nbins);
|
||||
G4double dedx1 = pv->GetValue(elow, b);
|
||||
|
||||
// protection for specific cases dedx=0
|
||||
if(dedx1 == 0.0) {
|
||||
for (size_t k=1; k<nbins; k++) {
|
||||
bin0++;
|
||||
@@ -137,39 +142,29 @@ void G4LossTableBuilder::BuildRangeTable(const G4PhysicsTable* dedxTable,
|
||||
nbins -= bin0;
|
||||
}
|
||||
|
||||
// initialisation of a new vector
|
||||
G4PhysicsLogVector* v = new G4PhysicsLogVector(elow, ehigh, nbins);
|
||||
v->SetSpline(splineFlag);
|
||||
|
||||
// assumed dedx proportional to beta
|
||||
G4double range = 2.*elow/dedx1;
|
||||
//G4double range = elow/dedx1;
|
||||
v->PutValue(0,range);
|
||||
G4double energy1 = elow;
|
||||
|
||||
for (size_t j=1; j<nbins; j++) {
|
||||
|
||||
G4double energy2 = pv->GetLowEdgeEnergy(j+bin0);
|
||||
G4double dedx2 = pv->GetValue(energy2, b);
|
||||
G4double de = (energy2 - energy1) * del;
|
||||
G4double energy = energy1 - de*0.5;
|
||||
|
||||
G4bool yes = true;
|
||||
//G4bool yes = false;
|
||||
if(dedx1 < DBL_MIN || dedx2 < DBL_MIN) yes = false;
|
||||
|
||||
G4double fac, f;
|
||||
|
||||
if(yes) fac = std::log(dedx2/dedx1)/std::log(energy2/energy1);
|
||||
else fac = (dedx2 - dedx1)/(energy2 - energy1);
|
||||
|
||||
G4double energy = energy2 + de*0.5;
|
||||
for (size_t k=0; k<n; k++) {
|
||||
energy += de;
|
||||
if(yes) f = dedx1*std::exp(fac*std::log(energy/energy1));
|
||||
else f = dedx1 + fac*(energy - energy1);
|
||||
if(f > DBL_MIN) range += de/f;
|
||||
}
|
||||
energy -= de;
|
||||
dedx1 = pv->GetValue(energy, b);
|
||||
if(dedx1 > 0.0) range += de/dedx1;
|
||||
}
|
||||
|
||||
// G4cout << "Range i= " <<i << " j= " << j << G4endl;
|
||||
v->PutValue(j,range);
|
||||
energy1 = energy2;
|
||||
dedx1 = dedx2;
|
||||
}
|
||||
G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v);
|
||||
}
|
||||
@@ -196,16 +191,16 @@ void G4LossTableBuilder::BuildInverseRangeTable(const G4PhysicsTable* rangeTable
|
||||
G4double ehigh = pv->GetLowEdgeEnergy(nbins-1);
|
||||
G4double rlow = pv->GetValue(elow, b);
|
||||
G4double rhigh = pv->GetValue(ehigh, b);
|
||||
|
||||
rhigh *= std::exp(std::log(rhigh/rlow)/((G4double)(nbins-1)));
|
||||
|
||||
|
||||
G4LPhysicsFreeVector* v = new G4LPhysicsFreeVector(nbins,rlow,rhigh);
|
||||
v->SetSpline(splineFlag);
|
||||
|
||||
for (size_t j=0; j<nbins; j++) {
|
||||
G4double e = pv->GetLowEdgeEnergy(j);
|
||||
G4double r = pv->GetValue(e, b);
|
||||
v->PutValues(j,r,e);
|
||||
}
|
||||
v->PutValues(nbins,rhigh+rlow,ehigh);
|
||||
|
||||
G4PhysicsTableHelper::SetPhysicsVector(invRangeTable, i, v);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LossTableManager.cc,v 1.84 2007/06/14 07:28:48 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4LossTableManager.cc,v 1.95 2008/11/13 18:23:39 schaelic Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -69,6 +69,7 @@
|
||||
// left ionisation table for further usage (VI)
|
||||
// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
|
||||
// 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
|
||||
// 21-02-08 Add G4EmSaturation (V.Ivanchenko)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -90,6 +91,7 @@
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4PhysicsTableHelper.hh"
|
||||
#include "G4EmCorrections.hh"
|
||||
#include "G4EmSaturation.hh"
|
||||
#include "G4EmTableType.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
|
||||
@@ -115,16 +117,25 @@ G4LossTableManager::~G4LossTableManager()
|
||||
}
|
||||
size_t msc = msc_vector.size();
|
||||
for (size_t j=0; j<msc; j++) {
|
||||
if(msc_vector[j] ) delete msc_vector[j];
|
||||
if( msc_vector[j] ) delete msc_vector[j];
|
||||
}
|
||||
size_t emp = emp_vector.size();
|
||||
for (size_t k=0; k<emp; k++) {
|
||||
if(emp_vector[k] ) delete emp_vector[k];
|
||||
if( emp_vector[k] ) delete emp_vector[k];
|
||||
}
|
||||
size_t mod = mod_vector.size();
|
||||
for (size_t a=0; a<mod; a++) {
|
||||
if( mod_vector[a] ) delete mod_vector[a];
|
||||
}
|
||||
size_t fmod = fmod_vector.size();
|
||||
for (size_t b=0; b<fmod; b++) {
|
||||
if( fmod_vector[b] ) delete fmod_vector[b];
|
||||
}
|
||||
Clear();
|
||||
delete theMessenger;
|
||||
delete tableBuilder;
|
||||
delete emCorrections;
|
||||
delete emSaturation;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -151,6 +162,7 @@ G4LossTableManager::G4LossTableManager()
|
||||
theElectron = G4Electron::Electron();
|
||||
tableBuilder = new G4LossTableBuilder();
|
||||
emCorrections= new G4EmCorrections();
|
||||
emSaturation = new G4EmSaturation();
|
||||
integral = true;
|
||||
integralActive = false;
|
||||
buildCSDARange = false;
|
||||
@@ -159,8 +171,10 @@ G4LossTableManager::G4LossTableManager()
|
||||
maxEnergyForMuonsActive = false;
|
||||
stepFunctionActive = false;
|
||||
flagLPM = true;
|
||||
splineFlag = true;
|
||||
bremsTh = DBL_MAX;
|
||||
verbose = 1;
|
||||
tableBuilder->SetSplineFlag(splineFlag);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -225,9 +239,10 @@ void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
|
||||
void G4LossTableManager::Register(G4VMultipleScattering* p)
|
||||
{
|
||||
msc_vector.push_back(p);
|
||||
if(verbose > 1)
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
|
||||
<< p->GetProcessName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -245,9 +260,10 @@ void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
|
||||
void G4LossTableManager::Register(G4VEmProcess* p)
|
||||
{
|
||||
emp_vector.push_back(p);
|
||||
if(verbose > 1)
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4LossTableManager::Register G4VEmProcess : "
|
||||
<< p->GetProcessName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -262,6 +278,48 @@ void G4LossTableManager::DeRegister(G4VEmProcess* p)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::Register(G4VEmModel* p)
|
||||
{
|
||||
mod_vector.push_back(p);
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4LossTableManager::Register G4VEmModel : "
|
||||
<< p->GetName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VEmModel* p)
|
||||
{
|
||||
size_t n = mod_vector.size();
|
||||
for (size_t i=0; i<n; i++) {
|
||||
if(mod_vector[i] == p) mod_vector[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::Register(G4VEmFluctuationModel* p)
|
||||
{
|
||||
fmod_vector.push_back(p);
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
|
||||
<< p->GetName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p)
|
||||
{
|
||||
size_t n = fmod_vector.size();
|
||||
for (size_t i=0; i<n; i++) {
|
||||
if(fmod_vector[i] == p) fmod_vector[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::RegisterIon(const G4ParticleDefinition* ion,
|
||||
G4VEnergyLossProcess* p)
|
||||
{
|
||||
@@ -363,10 +421,11 @@ G4EnergyLossMessenger* G4LossTableManager::GetMessenger()
|
||||
void G4LossTableManager::ParticleHaveNoLoss(
|
||||
const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
G4String s = "G4LossTableManager:: dE/dx table not found for "
|
||||
+ aParticle->GetParticleName() + "!";
|
||||
G4Exception(s);
|
||||
exit(1);
|
||||
G4String s = " dE/dx table not found for "
|
||||
+ aParticle->GetParticleName() + " !";
|
||||
G4Exception("G4LossTableManager::ParticleHaveNoLoss", "EM01",
|
||||
FatalException, s);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -475,7 +534,8 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
for (i=0; i<n_loss; i++) {
|
||||
p = loss_vector[i];
|
||||
if (p && aParticle == part_vector[i] && !tables_are_built[i]) {
|
||||
if (p->IsIonisationProcess() && isActive[i] || !em || (em && !isActive[iem]) ) {
|
||||
if ((p->IsIonisationProcess() && isActive[i]) ||
|
||||
!em || (em && !isActive[iem]) ) {
|
||||
em = p;
|
||||
iem= i;
|
||||
}
|
||||
@@ -508,7 +568,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
|
||||
dedx = em->IonisationTable();
|
||||
if (1 < n_dedx) {
|
||||
em->SetDEDXTable(dedx, fIonisation);
|
||||
em->SetDEDXTable(dedx, fIsIonisation);
|
||||
dedx = 0;
|
||||
dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
|
||||
tableBuilder->BuildDEDXTable(dedx, t_list);
|
||||
@@ -559,7 +619,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
if (0 < nSubRegions) {
|
||||
G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
|
||||
if (1 < listSub.size()) {
|
||||
em->SetDEDXTable(dedxSub, fSubIonisation);
|
||||
em->SetDEDXTable(dedxSub, fIsSubIonisation);
|
||||
dedxSub = 0;
|
||||
dedxSub = G4PhysicsTableHelper::PreparePhysicsTable(dedxSub);
|
||||
tableBuilder->BuildDEDXTable(dedxSub, listSub);
|
||||
@@ -828,6 +888,21 @@ G4bool G4LossTableManager::LPMFlag() const
|
||||
return flagLPM;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::SetSplineFlag(G4bool val)
|
||||
{
|
||||
splineFlag = val;
|
||||
tableBuilder->SetSplineFlag(splineFlag);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4bool G4LossTableManager::SplineFlag() const
|
||||
{
|
||||
return splineFlag;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LossTableManager::SetBremsstrahlungTh(G4double val)
|
||||
@@ -842,4 +917,18 @@ G4double G4LossTableManager::BremsstrahlungTh() const
|
||||
return bremsTh;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmCorrections* G4LossTableManager::EmCorrections()
|
||||
{
|
||||
return emCorrections;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmSaturation* G4LossTableManager::EmSaturation()
|
||||
{
|
||||
return emSaturation;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4VEmFluctuationModel.cc,v 1.2 2006/06/29 19:55:15 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4VEmFluctuationModel.cc,v 1.3 2008/07/15 16:56:39 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -48,16 +48,20 @@
|
||||
//
|
||||
|
||||
#include "G4VEmFluctuationModel.hh"
|
||||
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VEmFluctuationModel::G4VEmFluctuationModel(const G4String& nam)
|
||||
: name(nam)
|
||||
{}
|
||||
{
|
||||
G4LossTableManager::Instance()->Register(this);
|
||||
}
|
||||
|
||||
G4VEmFluctuationModel::~G4VEmFluctuationModel()
|
||||
{}
|
||||
{
|
||||
G4LossTableManager::Instance()->DeRegister(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4VEmModel.cc,v 1.8 2007/09/25 10:19:07 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4VEmModel.cc,v 1.20 2008/11/13 23:13:18 schaelic Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -50,35 +50,55 @@
|
||||
//
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VEmModel::G4VEmModel(const G4String& nam):
|
||||
lowLimit(0.1*keV), highLimit(100.0*TeV), fluc(0), name(nam), pParticleChange(0)
|
||||
{}
|
||||
fluc(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV),
|
||||
polarAngleLimit(0.0),secondaryThreshold(DBL_MAX),theLPMflag(false),
|
||||
pParticleChange(0),nuclearStopping(false),nsec(5)
|
||||
{
|
||||
xsec.resize(nsec);
|
||||
nSelectors = 0;
|
||||
G4LossTableManager::Instance()->Register(this);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VEmModel::~G4VEmModel()
|
||||
{}
|
||||
{
|
||||
G4LossTableManager::Instance()->DeRegister(this);
|
||||
G4int n = elmSelectors.size();
|
||||
if(n > 0) {
|
||||
for(G4int i=0; i<n; i++) {
|
||||
delete elmSelectors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double emin,
|
||||
G4double emax)
|
||||
G4double ekin,
|
||||
G4double emin,
|
||||
G4double emax)
|
||||
{
|
||||
SetupForMaterial(p, material, ekin);
|
||||
G4double cross = 0.0;
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
|
||||
size_t nelm = material->GetNumberOfElements();
|
||||
for (size_t i=0; i<nelm; i++) {
|
||||
const G4Element* elm = (*theElementVector)[i];
|
||||
G4int nelm = material->GetNumberOfElements();
|
||||
if(nelm > nsec) {
|
||||
xsec.resize(nelm);
|
||||
nsec = nelm;
|
||||
}
|
||||
for (G4int i=0; i<nelm; i++) {
|
||||
cross += theAtomNumDensityVector[i]*
|
||||
ComputeCrossSectionPerAtom(p,ekin,elm->GetZ(),elm->GetN(),emin,emax);
|
||||
ComputeCrossSectionPerAtom(p,(*theElementVector)[i],ekin,emin,emax);
|
||||
xsec[i] = cross;
|
||||
}
|
||||
return cross;
|
||||
@@ -87,10 +107,10 @@ G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double ekin,
|
||||
const G4Material* material,
|
||||
G4double emin,
|
||||
G4double emax)
|
||||
G4double emin,
|
||||
G4double emax)
|
||||
{
|
||||
G4double mfp = DBL_MAX;
|
||||
G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax);
|
||||
@@ -100,4 +120,45 @@ G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
G4int nbins = G4int(std::log10(highLimit/lowLimit) + 0.5);
|
||||
if(nbins < 3) nbins = 3;
|
||||
G4bool spline = G4LossTableManager::Instance()->SplineFlag();
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
// prepare vector
|
||||
if(numOfCouples > nSelectors) {
|
||||
elmSelectors.resize(numOfCouples);
|
||||
nSelectors = numOfCouples;
|
||||
}
|
||||
|
||||
// initialise vector
|
||||
for(G4int i=0; i<numOfCouples; i++) {
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4int idx = couple->GetIndex();
|
||||
|
||||
// selector already exist check if should be deleted
|
||||
G4bool create = true;
|
||||
if(elmSelectors[i]) {
|
||||
if(material == elmSelectors[i]->GetMaterial()) create = false;
|
||||
else delete elmSelectors[i];
|
||||
}
|
||||
if(create) {
|
||||
elmSelectors[i] = new G4EmElementSelector(this,material,nbins,
|
||||
lowLimit,highLimit,spline);
|
||||
}
|
||||
elmSelectors[i]->Initialise(p, cuts[idx]);
|
||||
//elmSelectors[i]->Dump(p);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4VEmProcess.cc,v 1.48 2007/10/29 08:38:58 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4VEmProcess.cc,v 1.60 2008/10/17 14:46:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -81,25 +81,34 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
|
||||
G4VDiscreteProcess(name, type),
|
||||
selectedModel(0),
|
||||
G4VDiscreteProcess(name, type),
|
||||
secondaryParticle(0),
|
||||
buildLambdaTable(true),
|
||||
theLambdaTable(0),
|
||||
theEnergyOfCrossSectionMax(0),
|
||||
theCrossSectionMax(0),
|
||||
particle(0),
|
||||
secondaryParticle(0),
|
||||
nLambdaBins(90),
|
||||
lambdaFactor(0.8),
|
||||
currentCouple(0),
|
||||
integral(false),
|
||||
buildLambdaTable(true),
|
||||
applyCuts(false),
|
||||
startFromNull(true),
|
||||
nRegions(0)
|
||||
nRegions(0),
|
||||
selectedModel(0),
|
||||
particle(0),
|
||||
currentCouple(0)
|
||||
{
|
||||
SetVerboseLevel(1);
|
||||
|
||||
// Size of tables assuming spline
|
||||
minKinEnergy = 0.1*keV;
|
||||
maxKinEnergy = 100.0*GeV;
|
||||
maxKinEnergy = 100.0*TeV;
|
||||
nLambdaBins = 84;
|
||||
|
||||
// default lambda factor
|
||||
lambdaFactor = 0.8;
|
||||
|
||||
// default limit on polar angle
|
||||
polarAngleLimit = 0.0;
|
||||
|
||||
// particle types
|
||||
theGamma = G4Gamma::Gamma();
|
||||
theElectron = G4Electron::Electron();
|
||||
thePositron = G4Positron::Positron();
|
||||
@@ -372,7 +381,8 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
if (e < (*theCutsElectron)[currentMaterialIndex]) good = false;
|
||||
|
||||
} else if (p == thePositron) {
|
||||
if (e < (*theCutsPositron)[currentMaterialIndex]) {
|
||||
if (electron_mass_c2 < (*theCutsGamma)[currentMaterialIndex] &&
|
||||
e < (*theCutsPositron)[currentMaterialIndex]) {
|
||||
good = false;
|
||||
e += 2.0*electron_mass_c2;
|
||||
}
|
||||
@@ -396,42 +406,34 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
void G4VEmProcess::PrintInfoDefinition()
|
||||
{
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << G4endl << GetProcessName() << ": " ;
|
||||
G4cout << G4endl << GetProcessName() << ": for "
|
||||
<< particle->GetParticleName();
|
||||
if(integral) G4cout << ", integral: 1 ";
|
||||
if(applyCuts) G4cout << ", applyCuts: 1 ";
|
||||
G4cout << " SubType= " << GetProcessSubType() << G4endl;
|
||||
if(buildLambdaTable) {
|
||||
G4cout << " Lambda tables from "
|
||||
<< G4BestUnit(minKinEnergy,"Energy")
|
||||
<< " to "
|
||||
<< G4BestUnit(maxKinEnergy,"Energy")
|
||||
<< " in " << nLambdaBins << " bins, spline: "
|
||||
<< (G4LossTableManager::Instance())->SplineFlag()
|
||||
<< G4endl;
|
||||
}
|
||||
PrintInfo();
|
||||
if(integral) {
|
||||
G4cout << " Integral mode is used "<< G4endl;
|
||||
}
|
||||
modelManager->DumpModelList(verboseLevel);
|
||||
}
|
||||
|
||||
if (!buildLambdaTable) return;
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << " tables are built for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl
|
||||
<< " Lambda tables from "
|
||||
<< G4BestUnit(minKinEnergy,"Energy")
|
||||
<< " to "
|
||||
<< G4BestUnit(maxKinEnergy,"Energy")
|
||||
<< " in " << nLambdaBins << " bins."
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "Tables are built for " << particle->GetParticleName()
|
||||
<< G4endl;
|
||||
|
||||
if(verboseLevel > 2) {
|
||||
G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
|
||||
if(verboseLevel > 2 && buildLambdaTable) {
|
||||
G4cout << " LambdaTable address= " << theLambdaTable << G4endl;
|
||||
if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VEmProcess::MicroscopicCrossSection(G4double kineticEnergy,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
// Cross section per atom is calculated
|
||||
DefineMaterial(couple);
|
||||
@@ -440,8 +442,6 @@ G4double G4VEmProcess::MicroscopicCrossSection(G4double kineticEnergy,
|
||||
if(theLambdaTable) {
|
||||
cross = (((*theLambdaTable)[currentMaterialIndex])->
|
||||
GetValue(kineticEnergy, b));
|
||||
|
||||
cross /= currentMaterial->GetTotNbOfAtomsPerVolume();
|
||||
} else {
|
||||
G4VEmModel* model = SelectModel(kineticEnergy);
|
||||
cross =
|
||||
@@ -507,6 +507,10 @@ G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
|
||||
<< filename << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
if((G4LossTableManager::Instance())->SplineFlag()) {
|
||||
size_t n = theLambdaTable->length();
|
||||
for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
|
||||
}
|
||||
} else {
|
||||
if (1 < verboseLevel) {
|
||||
G4cout << "Lambda table for " << particleName << " in file <"
|
||||
@@ -567,6 +571,7 @@ G4PhysicsVector* G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple*)
|
||||
{
|
||||
G4PhysicsVector* v =
|
||||
new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
|
||||
v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4VEnergyLoss.cc,v 1.46 2006/06/29 19:55:21 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4VMscModel.cc,v 1.4 2008/03/10 18:39:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4VMscModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 07.03.2008
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// General interface to msc models
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4VMscModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VMscModel::G4VMscModel(const G4String& nam):
|
||||
G4VEmModel(nam),
|
||||
facrange(0.02),
|
||||
facgeom(2.5),
|
||||
facsafety(0.25),
|
||||
skin(3.0),
|
||||
dtrl(0.05),
|
||||
lambdalimit(mm),
|
||||
steppingAlgorithm(fUseSafety),
|
||||
samplez(false),
|
||||
latDisplasment(true)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VMscModel::~G4VMscModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4VMultipleScattering.cc,v 1.47 2007/11/09 11:35:54 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4VMultipleScattering.cc,v 1.60 2008/11/20 20:32:40 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -54,6 +54,7 @@
|
||||
// 27-10-05 introduce virtual function MscStepLimitation() (V.Ivanchenko)
|
||||
// 12-04-07 Add verbosity at destruction (V.Ivanchenko)
|
||||
// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
|
||||
// 11-03-08 Set skin value does not effect step limit type (V.Ivanchenko)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -84,23 +85,30 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType type):
|
||||
G4VContinuousDiscreteProcess(name, type),
|
||||
G4VMultipleScattering::G4VMultipleScattering(const G4String& name,
|
||||
G4ProcessType type):
|
||||
G4VContinuousDiscreteProcess(name, type),
|
||||
buildLambdaTable(true),
|
||||
theLambdaTable(0),
|
||||
firstParticle(0),
|
||||
currentParticle(0),
|
||||
currentCouple(0),
|
||||
nBins(120),
|
||||
stepLimit(fUseSafety),
|
||||
skin(0.0),
|
||||
skin(3.0),
|
||||
facrange(0.02),
|
||||
facgeom(2.5),
|
||||
latDisplasment(true),
|
||||
buildLambdaTable(true)
|
||||
currentParticle(0),
|
||||
currentCouple(0)
|
||||
{
|
||||
SetVerboseLevel(1);
|
||||
SetProcessSubType(fMultipleScattering);
|
||||
|
||||
// Size of tables assuming spline
|
||||
minKinEnergy = 0.1*keV;
|
||||
maxKinEnergy = 100.0*TeV;
|
||||
SetVerboseLevel(1);
|
||||
nBins = 84;
|
||||
|
||||
// default limit on polar angle
|
||||
polarAngleLimit = 0.0;
|
||||
|
||||
pParticleChange = &fParticleChange;
|
||||
|
||||
@@ -113,9 +121,10 @@ G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType
|
||||
|
||||
G4VMultipleScattering::~G4VMultipleScattering()
|
||||
{
|
||||
if(1 < verboseLevel)
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4VMultipleScattering destruct " << GetProcessName()
|
||||
<< G4endl;
|
||||
}
|
||||
delete modelManager;
|
||||
if (theLambdaTable) {
|
||||
theLambdaTable->clearAndDestroy();
|
||||
@@ -130,7 +139,6 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
G4String num = part.GetParticleName();
|
||||
if(1 < verboseLevel) {
|
||||
// G4cout << "========================================================" << G4endl;
|
||||
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << num
|
||||
@@ -147,7 +155,8 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
|
||||
if (theLambdaTable->GetFlag(i)) {
|
||||
// create physics vector and fill it
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
G4PhysicsVector* aVector = PhysicsVector(couple);
|
||||
modelManager->FillLambdaVector(aVector, couple, false);
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
|
||||
@@ -161,7 +170,8 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
}
|
||||
}
|
||||
if(verboseLevel>0 && ( num == "e-" || num == "mu+" ||
|
||||
num == "proton" || num == "pi-" || num == "GenericIon")) {
|
||||
num == "proton" || num == "pi-" ||
|
||||
num == "GenericIon")) {
|
||||
PrintInfoDefinition();
|
||||
if(2 < verboseLevel && theLambdaTable) G4cout << *theLambdaTable << G4endl;
|
||||
}
|
||||
@@ -181,14 +191,16 @@ void G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part
|
||||
if (!firstParticle) {
|
||||
currentCouple = 0;
|
||||
if(part.GetParticleType() == "nucleus" &&
|
||||
part.GetParticleSubType() == "generic")
|
||||
firstParticle = G4GenericIon::GenericIon();
|
||||
else firstParticle = ∂
|
||||
part.GetParticleSubType() == "generic") {
|
||||
firstParticle = G4GenericIon::GenericIon();
|
||||
} else {
|
||||
firstParticle = ∂
|
||||
}
|
||||
|
||||
currentParticle = ∂
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
// G4cout << "========================================================" << G4endl;
|
||||
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
@@ -216,20 +228,21 @@ void G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part
|
||||
void G4VMultipleScattering::PrintInfoDefinition()
|
||||
{
|
||||
if (0 < verboseLevel) {
|
||||
G4cout << G4endl << GetProcessName() << ": Model variant of multiple scattering "
|
||||
<< "for " << firstParticle->GetParticleName()
|
||||
G4cout << G4endl << GetProcessName()
|
||||
<< ": for " << firstParticle->GetParticleName()
|
||||
<< " SubType= " << GetProcessSubType()
|
||||
<< G4endl;
|
||||
if (theLambdaTable) {
|
||||
G4cout << " Lambda tables from "
|
||||
<< G4BestUnit(MinKinEnergy(),"Energy")
|
||||
<< " to "
|
||||
<< G4BestUnit(MaxKinEnergy(),"Energy")
|
||||
<< " in " << nBins << " bins."
|
||||
<< " in " << nBins << " bins, spline: "
|
||||
<< (G4LossTableManager::Instance())->SplineFlag()
|
||||
<< G4endl;
|
||||
}
|
||||
G4cout << " LateralDisplacementFlag= " << latDisplasment
|
||||
<< " Skin= " << skin << G4endl;
|
||||
PrintInfo();
|
||||
modelManager->DumpModelList(verboseLevel);
|
||||
if (2 < verboseLevel) {
|
||||
G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
|
||||
if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
|
||||
@@ -241,15 +254,17 @@ void G4VMultipleScattering::PrintInfoDefinition()
|
||||
|
||||
G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double,
|
||||
G4double currentMinimalStep,
|
||||
G4double& currentSafety,
|
||||
G4GPILSelection* selection)
|
||||
{
|
||||
// get Step limit proposed by the process
|
||||
valueGPILSelectionMSC = NotCandidateForSelection;
|
||||
G4double steplength = GetMscContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimalStep,currentSafety);
|
||||
G4double steplength = GetMscContinuousStepLimit(track,
|
||||
track.GetKineticEnergy(),
|
||||
currentMinimalStep,
|
||||
currentSafety);
|
||||
// G4cout << "StepLimit= " << steplength << G4endl;
|
||||
// set return value for G4GPILSelection
|
||||
*selection = valueGPILSelectionMSC;
|
||||
@@ -314,6 +329,7 @@ G4PhysicsVector* G4VMultipleScattering::PhysicsVector(const G4MaterialCutsCouple
|
||||
G4int nbins = 3;
|
||||
if( couple->IsUsed() ) nbins = nBins;
|
||||
G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nbins);
|
||||
v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -371,6 +387,10 @@ G4bool G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition* p
|
||||
<< filename << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
if((G4LossTableManager::Instance())->SplineFlag()) {
|
||||
size_t n = theLambdaTable->length();
|
||||
for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
|
||||
}
|
||||
} else {
|
||||
if (1 < verboseLevel) {
|
||||
G4cout << "Lambda table for " << part->GetParticleName() << " in file <"
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4ionEffectiveCharge.cc,v 1.17 2007/09/27 17:08:58 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-01 $
|
||||
// $Id: G4ionEffectiveCharge.cc,v 1.24 2008/12/18 13:01:46 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -53,19 +53,24 @@
|
||||
|
||||
#include "G4ionEffectiveCharge.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4ionEffectiveCharge::G4ionEffectiveCharge()
|
||||
{
|
||||
chargeCorrection = 1.0;
|
||||
energyHighLimit = 10.0*MeV;
|
||||
energyHighLimit = 20.0*MeV;
|
||||
energyLowLimit = 1.0*keV;
|
||||
energyBohr = 25.*keV;
|
||||
massFactor = amu_c2/(proton_mass_c2*keV);
|
||||
minCharge = 0.1;
|
||||
minCharge = 1.0;
|
||||
lastPart = 0;
|
||||
lastMat = 0;
|
||||
lastKinEnergy = 0.0;
|
||||
effCharge = eplus;
|
||||
nist = G4NistManager::Instance();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -77,13 +82,21 @@ G4ionEffectiveCharge::~G4ionEffectiveCharge()
|
||||
|
||||
G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
if(p == lastPart && material == lastMat && kineticEnergy == lastKinEnergy)
|
||||
return effCharge;
|
||||
|
||||
lastPart = p;
|
||||
lastMat = material;
|
||||
lastKinEnergy = kineticEnergy;
|
||||
|
||||
G4double mass = p->GetPDGMass();
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double Zi = charge/eplus;
|
||||
|
||||
chargeCorrection = 1.0;
|
||||
effCharge = charge;
|
||||
|
||||
// The aproximation of ion effective charge from:
|
||||
// J.F.Ziegler, J.P. Biersack, U. Littmark
|
||||
@@ -93,16 +106,15 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
G4double reducedEnergy = kineticEnergy * proton_mass_c2/mass ;
|
||||
if( reducedEnergy > Zi*energyHighLimit || Zi < 1.5 || !material) return charge;
|
||||
|
||||
static G4double c[6] = {0.2865, 0.1266, -0.001429,
|
||||
0.02402,-0.01135, 0.001475} ;
|
||||
|
||||
G4double z = material->GetIonisation()->GetZeffective();
|
||||
reducedEnergy = std::max(reducedEnergy,energyLowLimit);
|
||||
G4double q;
|
||||
// reducedEnergy = std::max(reducedEnergy,energyLowLimit);
|
||||
|
||||
// Helium ion case
|
||||
if( Zi < 2.5 ) {
|
||||
|
||||
static G4double c[6] = {0.2865, 0.1266, -0.001429,
|
||||
0.02402,-0.01135, 0.001475} ;
|
||||
|
||||
G4double Q = std::max(0.0,std::log(reducedEnergy*massFactor));
|
||||
G4double x = c[0];
|
||||
G4double y = 1.0;
|
||||
@@ -119,23 +131,25 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
G4double tt = ( 0.007 + 0.00005 * z );
|
||||
if(tq2 < 0.2) tt *= (1.0 - tq2 + 0.5*tq2*tq2);
|
||||
else tt *= std::exp(-tq2);
|
||||
q = (1.0 + tt) * std::sqrt(ex);
|
||||
|
||||
effCharge = charge*(1.0 + tt) * std::sqrt(ex);
|
||||
|
||||
// Heavy ion case
|
||||
} else {
|
||||
|
||||
G4double z23 = std::pow(z, 0.666666);
|
||||
G4double zi13 = std::pow(Zi, 0.333333);
|
||||
G4double y;
|
||||
// = nist->GetZ13(z);
|
||||
//G4double z23 = y*y;
|
||||
G4double zi13 = nist->GetZ13(Zi);
|
||||
G4double zi23 = zi13*zi13;
|
||||
G4double e = std::max(reducedEnergy,energyBohr/z23);
|
||||
// G4double e = std::max(reducedEnergy,energyBohr/z23);
|
||||
//G4double e = reducedEnergy;
|
||||
|
||||
// v1 is ion velocity in vF unit
|
||||
G4double eF = material->GetIonisation()->GetFermiEnergy();
|
||||
G4double v1sq = e/eF;
|
||||
G4double v1sq = reducedEnergy/eF;
|
||||
G4double vFsq = eF/energyBohr;
|
||||
G4double vF = std::sqrt(vFsq);
|
||||
|
||||
G4double y ;
|
||||
G4double vF = std::sqrt(eF/energyBohr);
|
||||
|
||||
// Faster than Fermi velocity
|
||||
if ( v1sq > 1.0 ) {
|
||||
@@ -143,18 +157,33 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
|
||||
// Slower than Fermi velocity
|
||||
} else {
|
||||
y = 0.6923 * vF * (1.0 + 0.666666*v1sq + v1sq*v1sq/15.0) / zi23 ;
|
||||
y = 0.692308 * vF * (1.0 + 0.666666*v1sq + v1sq*v1sq/15.0) / zi23 ;
|
||||
}
|
||||
|
||||
G4double q;
|
||||
G4double y3 = std::pow(y, 0.3) ;
|
||||
// G4cout << "y= " << y << " y3= " << y3 << " v1= " << v1 << " vF= " << vF << G4endl;
|
||||
// G4cout<<"y= "<<y<<" y3= "<<y3<<" v1= "<<v1<<" vF= "<<vF<<G4endl;
|
||||
q = 1.0 - std::exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ;
|
||||
|
||||
//y *= 0.77;
|
||||
//y *= (0.75 + 0.52/Zi);
|
||||
|
||||
// q = 1.0 - std::exp(-0.95*std::sqrt(reducedEnergy/energyBohr)/zi23);
|
||||
//if( y < 0.2 ) q = y*(1.0 - 0.5*y);
|
||||
//else q = 1.0 - std::exp(-y);
|
||||
|
||||
G4double qmin = minCharge/Zi;
|
||||
|
||||
if(q < qmin) q = qmin;
|
||||
|
||||
effCharge = q*charge;
|
||||
|
||||
/*
|
||||
G4double x1 = 1.0*effCharge*(1.0 - 0.132*std::log(y))/(y*std::sqrt(z));
|
||||
G4double x2 = 0.1*effCharge*effCharge*energyBohr/reducedEnergy;
|
||||
|
||||
chargeCorrection = 1.0 + x1 - x2;
|
||||
|
||||
G4cout << "x1= "<<x1<<" x2= "<< x2<<" corr= "<<chargeCorrection<<G4endl;
|
||||
*/
|
||||
|
||||
G4double tq = 7.6 - std::log(reducedEnergy/keV);
|
||||
G4double tq2= tq*tq;
|
||||
@@ -169,7 +198,7 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
// Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
|
||||
|
||||
G4double lambda = 10.0 * vF / (zi13 * (6.0 + q));
|
||||
if(q < 0.2) lambda *= (1.0 - 0.666666*q - 0.444444*q*q);
|
||||
if(q < 0.2) lambda *= (1.0 - 0.66666667*q - q*q/9.0);
|
||||
else lambda *= std::pow(1.0-q, 0.666666);
|
||||
|
||||
G4double lambda2 = lambda*lambda;
|
||||
@@ -179,11 +208,12 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
else xx *= std::log(1.0 + lambda2);
|
||||
|
||||
chargeCorrection = sq * (1.0 + xx);
|
||||
|
||||
}
|
||||
// G4cout << "G4ionEffectiveCharge: charge= " << charge << " q= " << q
|
||||
// << " chargeCor= " << chargeCorrection
|
||||
// << " e(MeV)= " << kineticEnergy/MeV << G4endl;
|
||||
return q*charge;
|
||||
return effCharge;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
Reference in New Issue
Block a user