Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -40,11 +39,12 @@
|
||||
// Modifications:
|
||||
//
|
||||
// 24.07.2018 Introduced possibility to use sampling tables to sample the
|
||||
// emitted photon energy (instead of using rejectio) from the Seltzer-
|
||||
// Berger scalled DCS for bremsstrahlung photon emission. Using these
|
||||
// sampling tables option gives faster(30-70%) final state generation
|
||||
// than the original rejection but takes some extra memory (+ ~6MB in
|
||||
// the case of the full CMS detector). (M Novak)
|
||||
// emitted photon energy (instead of using rejectio) from the
|
||||
// Seltzer-Berger scalled DCS for bremsstrahlung photon emission.
|
||||
// Using these sampling tables option gives faster(30-70%) final
|
||||
// state generation than the original rejection but takes some
|
||||
// extra memory (+ ~6MB in the case of the full CMS detector).
|
||||
// (M Novak)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -61,21 +61,32 @@
|
||||
#include "G4ModifiedTsai.hh"
|
||||
//#include "G4DipBustGenerator.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
#include "G4Physics2DVector.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Log.hh"
|
||||
|
||||
#include "G4ios.hh"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
G4Physics2DVector* G4SeltzerBergerModel::gSBDCSData[] = { nullptr };
|
||||
G4SBBremTable* G4SeltzerBergerModel::gSBSamplingTable = nullptr;
|
||||
G4double G4SeltzerBergerModel::gYLimitData[] = { 0.0 };
|
||||
G4String G4SeltzerBergerModel::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4SeltzerBergerModel::theSBMutex = G4MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
|
||||
G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
const G4String& nam)
|
||||
: G4eBremsstrahlungRelModel(p,nam), fIsUseBicubicInterpolation(false),
|
||||
fIsUseSamplingTables(true), fNumWarnings(0), fIndx(0), fIndy(0)
|
||||
{
|
||||
@@ -83,7 +94,6 @@ G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
|
||||
SetLowEnergyLimit(fLowestKinEnergy);
|
||||
SetLPMFlag(false);
|
||||
SetAngularDistribution(new G4ModifiedTsai());
|
||||
//SetAngularDistribution(new G4DipBustGenerator());
|
||||
}
|
||||
|
||||
G4SeltzerBergerModel::~G4SeltzerBergerModel()
|
||||
@@ -104,7 +114,7 @@ G4SeltzerBergerModel::~G4SeltzerBergerModel()
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector& cuts)
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
if (p) {
|
||||
SetParticle(p);
|
||||
@@ -112,17 +122,17 @@ void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
fIsUseSamplingTables = G4EmParameters::Instance()->EnableSamplingTable();
|
||||
// Access to elements
|
||||
if (IsMaster()) {
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4LEDATA");
|
||||
const G4ElementTable* theElemTable = G4Element::GetElementTable();
|
||||
size_t numOfElem = G4Element::GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int izet =
|
||||
std::max(1,std::min(((*theElemTable)[ie])->GetZasInt(), gMaxZet-1));
|
||||
// load SB-DCS data for this atomic number if it has not been loaded yet
|
||||
if (!gSBDCSData[izet]) {
|
||||
ReadData(izet, path);
|
||||
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), gMaxZet-1));
|
||||
// load SB-DCS data for this atomic number if it has not been loaded yet
|
||||
InitialiseForElement(nullptr, Z);
|
||||
}
|
||||
}
|
||||
// elem.selectr. only for master: base class init-local will set for workers
|
||||
@@ -146,26 +156,32 @@ void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
}
|
||||
}
|
||||
|
||||
G4String G4SeltzerBergerModel::DirectoryPath() const {
|
||||
return "/brem_SB/br";
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
// return if it has been already loaded
|
||||
if (gSBDCSData[izet]) {
|
||||
return;
|
||||
}
|
||||
const char* datadir = path;
|
||||
if (!datadir) {
|
||||
datadir = getenv("G4LEDATA");
|
||||
if (!datadir) {
|
||||
G4Exception("G4SeltzerBergerModel::ReadData()","em0006",FatalException,
|
||||
const G4String& G4SeltzerBergerModel::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
const char* path = std::getenv("G4LEDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/brem_SB/br";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4SeltzerBergerModel::FindDirectoryPath()","em0006",
|
||||
FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::ReadData(G4int Z) {
|
||||
// return if it has been already loaded
|
||||
if (gSBDCSData[Z]) {
|
||||
return;
|
||||
}
|
||||
std::ostringstream ost;
|
||||
ost << datadir << DirectoryPath() << izet;
|
||||
ost << FindDirectoryPath() << Z;
|
||||
std::ifstream fin(ost.str().c_str());
|
||||
if (!fin.is_open()) {
|
||||
G4ExceptionDescription ed;
|
||||
@@ -180,9 +196,9 @@ void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
G4Physics2DVector* v = new G4Physics2DVector();
|
||||
if (v->Retrieve(fin)) {
|
||||
v->SetBicubicInterpolation(fIsUseBicubicInterpolation);
|
||||
gSBDCSData[izet] = v;
|
||||
static const G4double emaxlog = 4*G4Log(10.);
|
||||
gYLimitData[izet] = v->Value(0.97, emaxlog, fIndx, fIndy);
|
||||
gYLimitData[Z] = v->Value(0.97, emaxlog, fIndx, fIndy);
|
||||
gSBDCSData[Z] = v;
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Bremsstrahlung data file <" << ost.str().c_str()
|
||||
@@ -191,13 +207,10 @@ void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
ed,"G4LEDATA version should be G4EMLOW6.23 or later.");
|
||||
delete v;
|
||||
}
|
||||
// G4cout << dataSB[Z] << G4endl;
|
||||
}
|
||||
|
||||
G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
G4double dxsec = 0.0;
|
||||
if (gammaEnergy < 0.0 || fPrimaryKinEnergy <= 0.0) {
|
||||
return dxsec;
|
||||
@@ -212,14 +225,6 @@ G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
|
||||
if (!gSBDCSData[fCurrentIZ]) {
|
||||
InitialiseForElement(nullptr, fCurrentIZ);
|
||||
}
|
||||
/*
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Bremsstrahlung data for Z= " << Z
|
||||
<< " are not initialized!";
|
||||
G4Exception("G4SeltzerBergerModel::ComputeDXSectionPerAtom()","em0005",
|
||||
FatalException, ed,
|
||||
"G4LEDATA version should be G4EMLOW6.23 or later.");
|
||||
*/
|
||||
// NOTE: SetupForMaterial should have been called before!
|
||||
const G4double pt2 = fPrimaryKinEnergy*(fPrimaryKinEnergy+2.*kMC2);
|
||||
const G4double invb2 = fPrimaryTotalEnergy*fPrimaryTotalEnergy/pt2;
|
||||
@@ -251,7 +256,6 @@ G4SeltzerBergerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
const G4double kinEnergy = dp->GetKineticEnergy();
|
||||
const G4double logKinEnergy = dp->GetLogKineticEnergy();
|
||||
const G4double tmin = std::min(cutEnergy, kinEnergy);
|
||||
@@ -292,7 +296,8 @@ G4SeltzerBergerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
vdp->push_back(gamma);
|
||||
//
|
||||
// compute post-interaction kinematics of the primary e-/e+
|
||||
G4ThreeVector dir = (totMomentum*dp->GetMomentumDirection()-gammaEnergy*gamDir).unit();
|
||||
G4ThreeVector dir =
|
||||
(totMomentum*dp->GetMomentumDirection()-gammaEnergy*gamDir).unit();
|
||||
const G4double finalE = kinEnergy - gammaEnergy;
|
||||
/*
|
||||
G4cout << "### G4SBModel: v= "
|
||||
@@ -323,8 +328,6 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
const G4double tmin,
|
||||
const G4double tmax)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
// min max of the transformed variable: x(k) = ln(k^2+k_p^2) that is in
|
||||
// [ln(k_c^2+k_p^2), ln(E_k^2+k_p^2)]
|
||||
const G4double xmin = G4Log(tmin*tmin+fDensityCorr);
|
||||
@@ -333,24 +336,19 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
// majoranta
|
||||
const G4double x0 = tmin/kinEnergy;
|
||||
G4double vmax;
|
||||
if (fCurrentIZ < 93) {
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.02;
|
||||
} else {
|
||||
// reset cashed x and y indices
|
||||
fIndx = 0;
|
||||
fIndy = 0;
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.2;
|
||||
if (!gSBDCSData[fCurrentIZ]) {
|
||||
InitialiseForElement(nullptr, fCurrentIZ);
|
||||
}
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.02;
|
||||
//
|
||||
static const G4double kEPeakLim = 300.*CLHEP::MeV;
|
||||
static const G4double kELowLim = 20.*CLHEP::keV;
|
||||
// majoranta corrected for e-
|
||||
if (fIsElectron && x0 < 0.97 && ((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
|
||||
const G4double ylim = std::min(gYLimitData[fCurrentIZ],
|
||||
if (fIsElectron && x0 < 0.97 &&
|
||||
((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
|
||||
G4double ylim = std::min(gYLimitData[fCurrentIZ],
|
||||
1.1*gSBDCSData[fCurrentIZ]->Value(0.97,y,fIndx,fIndy));
|
||||
if (ylim > vmax) {
|
||||
vmax = ylim;
|
||||
}
|
||||
vmax = std::max(vmax, ylim);
|
||||
}
|
||||
if (x0 < 0.05) {
|
||||
vmax *= 1.2;
|
||||
@@ -363,7 +361,8 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
G4double gammaEnergy, v;
|
||||
for (G4int nn = 0; nn < kNCountMax; ++nn) {
|
||||
rndmEngine->flatArray(2, rndm);
|
||||
gammaEnergy = std::sqrt(std::max(G4Exp(xmin + rndm[0]*xrange)-fDensityCorr,0.));
|
||||
gammaEnergy =
|
||||
std::sqrt(std::max(G4Exp(xmin + rndm[0]*xrange)-fDensityCorr,0.));
|
||||
v = gSBDCSData[fCurrentIZ]->Value(gammaEnergy/kinEnergy, y, fIndx, fIndy);
|
||||
// e+ correction
|
||||
if (!fIsElectron) {
|
||||
@@ -401,21 +400,25 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
return gammaEnergy;
|
||||
}
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex SeltzerBergerModel1Mutex = G4MUTEX_INITIALIZER; }
|
||||
void G4SeltzerBergerModel::InitialiseForElement(const G4ParticleDefinition*,
|
||||
G4int izet)
|
||||
G4int Z)
|
||||
{
|
||||
G4AutoLock l(&SeltzerBergerModel1Mutex);
|
||||
// G4cout << "G4SeltzerBergerModel::InitialiseForElement Z= " << Z << G4endl;
|
||||
if (!gSBDCSData[izet]) {
|
||||
ReadData(izet);
|
||||
}
|
||||
if (!gSBDCSData[Z]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&theSBMutex);
|
||||
if (!gSBDCSData[Z]) {
|
||||
#endif
|
||||
ReadData(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&theSBMutex);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::SetupForMaterial(const G4ParticleDefinition*,
|
||||
const G4Material* mat,
|
||||
G4double kineticEnergy)
|
||||
const G4Material* mat,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
fDensityFactor = gMigdalConstant*mat->GetElectronDensity();
|
||||
// calculate threshold for density effect: gamma*k_p = sqrt(fDensityCorr)
|
||||
|
||||
Reference in New Issue
Block a user