Import Geant4 11.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2023-12-08 10:43:34 +01:00
parent dd1f179cda
commit 860a2b92bf
3962 changed files with 139318 additions and 164259 deletions
@@ -6,6 +6,55 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2022-12-01 John Allison (emutils-V11-01-25)
- G4EmParametersMessenger:
- Fix "/process/eloss/setFluctModel" - change "eloss" to "eLoss".
## 2023-11-08 V.Ivanchenko (emutils-V11-01-24)
- G4VEmModel - fixed memory leak at exit
## 2023-11-07 V.Ivanchenko (emutils-V11-01-23)
- G4EmSaturation - fixed problem #2572 (txenglish@lanl.gov)
## 2023-11-03 J.Hahnfeld (emutils-V11-01-22)
- `G4TransportationWithMsc`: Initialize all members.
## 2023-10-27 D.Sawkey (emutils-V11-01-21)
- G4OpticalParameters: set default verbosity to 1.
## 2023-10-23 J.Hahnfeld (emutils-V11-01-20)
- Add SingleScattering option to `G4TransportationWithMsc`.
## 2023-10-20 J.Hahnfeld (emutils-V11-01-19)
- `G4TransportationWithMsc`: Always update momentum direction.
## 2023-10-10 V.Ivanchenko (emutils-V11-01-18)
- G4VEmModel - restore SetLPMFlag(..) method to allow build of CMSSW with the
Geant4 master and G4HepEm version of CMSSW; no change of any result
is expected; added warning about use of obsolete method.
## 2023-10-06 V.Ivanchenko (emutils-V11-01-17)
- G4VEmModel - use std::size_t in all places
- G4EmParameters - added Get/Set method for a new integer number used
for logarithmic bin search in free vector
- G4EmParametersMessanger - added UI command "/process/em/nForFreeVector"
- G4LossTableManager - apply modified interface to G4LossTableBuilder
- G4LossTableBuilder - define logarithmic seach method for inverse range table
- G4EmCorrection - introduce "const" to all variables if possible, reduce
number of "if" statements, substitute "isMaster" flag by the new flag
"isInitializer", use CLHEP prefix.
EM testing suite show identical results, expected minor speed-up.
## 2023-10-04 D.Sawkey (emutils-V11-01-16)
- G4OpticalParameters: Removed unused scintillation declarations. Responding
to issue #182
## 2023-09-19 H.Burkhardt (emutils-V11-01-15)
- G4EmProcessSubType - new fGammaReflection = 26
## 2023-09-04 V.Ivanchenko (emutils-V11-01-14)
- G4VEmModel - do not destruct G4ElementData, do not define LPM flag
## 2023-06-16 V.Ivanchenko (emutils-V11-01-13)
- G4LossTableManager - fixed trivial Coverity report
@@ -53,8 +53,6 @@
#ifndef G4EmCorrections_h
#define G4EmCorrections_h 1
#include <CLHEP/Units/PhysicalConstants.h>
#include "globals.hh"
#include "G4ionEffectiveCharge.hh"
#include "G4Material.hh"
@@ -72,68 +70,72 @@ class G4EmCorrections
public:
explicit G4EmCorrections(G4int verb, G4bool master);
explicit G4EmCorrections(G4int verb);
~G4EmCorrections();
G4double HighOrderCorrections(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy,
G4double cutEnergy);
const G4double kineticEnergy,
const G4double cutEnergy);
G4double IonHighOrderCorrections(const G4ParticleDefinition*,
const G4MaterialCutsCouple*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double ComputeIonCorrections(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double IonBarkasCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double Bethe(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double SpinCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double KShellCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double LShellCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double ShellCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double ShellCorrectionSTD(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double DensityCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double BarkasCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy,
const G4bool isInitialized = false);
G4double BlochCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy,
const G4bool isInitialized = false);
G4double MottCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy,
const G4bool isInitialized = false);
void AddStoppingData(G4int Z, G4int A, const G4String& materialName,
void AddStoppingData(const G4int Z, const G4int A,
const G4String& materialName,
G4PhysicsVector* dVector);
void InitialiseForNewRun();
@@ -141,17 +143,17 @@ public:
// effective charge correction using stopping power data
G4double EffectiveChargeCorrection(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
// effective charge of an ion
inline G4double GetParticleCharge(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
inline
G4double EffectiveChargeSquareRatio(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
// ionisation models for ions
inline void SetIonisationModels(G4VEmModel* mod1 = nullptr,
@@ -173,20 +175,22 @@ private:
void SetupKinematics(const G4ParticleDefinition*,
const G4Material*,
G4double kineticEnergy);
const G4double kineticEnergy);
G4double KShell(G4double theta, G4double eta);
G4double KShell(const G4double theta, const G4double eta);
G4double LShell(G4double theta, G4double eta);
G4double LShell(const G4double theta, const G4double eta);
G4int Index(G4double x, const G4double* y, G4int n) const;
G4int Index(const G4double x, const G4double* y, const G4int n) const;
G4double Value(G4double xv, G4double x1, G4double x2,
G4double y1, G4double y2) const;
G4double Value(const G4double xv, const G4double x1, const G4double x2,
const G4double y1, const G4double y2) const;
G4double Value2(G4double xv, G4double yv, G4double x1, G4double x2,
G4double y1, G4double y2, G4double z11, G4double z21,
G4double z12, G4double z22) const;
G4double Value2(const G4double xv, const G4double yv,
const G4double x1, const G4double x2,
const G4double y1, const G4double y2,
const G4double z11, const G4double z21,
const G4double z12, const G4double z22) const;
G4Pow* g4calc;
G4IonTable* ionTable;
@@ -220,6 +224,7 @@ private:
G4double eCorrMax;
std::size_t ncouples = 0;
std::size_t idxBarkas = 0;
G4int nK = 20;
G4int nL = 26;
G4int nEtaK = 29;
@@ -233,7 +238,7 @@ private:
G4int currentZ = 0;
G4int verbose;
G4bool isMaster;
G4bool isInitializer = false;
std::vector<G4int> Zion;
std::vector<G4int> Aion;
@@ -258,13 +263,14 @@ private:
static const G4double UL[26];
static G4double VL[26];
static G4double sWmaxBarkas;
static G4PhysicsFreeVector* sBarkasCorr;
static G4PhysicsFreeVector* sThetaK;
static G4PhysicsFreeVector* sThetaL;
};
inline G4int
G4EmCorrections::Index(G4double x, const G4double* y, G4int n) const
G4EmCorrections::Index(const G4double x, const G4double* y, const G4int n) const
{
G4int iddd = n-1;
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
@@ -272,17 +278,18 @@ G4EmCorrections::Index(G4double x, const G4double* y, G4int n) const
return iddd;
}
inline G4double G4EmCorrections::Value(G4double xv, G4double x1, G4double x2,
G4double y1, G4double y2) const
inline G4double G4EmCorrections::Value(const G4double xv, const G4double x1,
const G4double x2,
const G4double y1, const G4double y2) const
{
return y1 + (y2 - y1)*(xv - x1)/(x2 - x1);
}
inline G4double G4EmCorrections::Value2(G4double xv, G4double yv,
G4double x1, G4double x2,
G4double y1, G4double y2,
G4double z11, G4double z21,
G4double z12, G4double z22) const
inline G4double G4EmCorrections::Value2(const G4double xv, const G4double yv,
const G4double x1, const G4double x2,
const G4double y1, const G4double y2,
const G4double z11, const G4double z21,
const G4double z12, const G4double z22) const
{
return ( z11*(x2-xv)*(y2-yv) + z22*(xv-x1)*(yv-y1) +
z12*(x2-xv)*(yv-y1) + z21*(xv-x1)*(y2-yv) )
@@ -304,7 +311,7 @@ inline G4int G4EmCorrections::GetNumberOfStoppingVectors() const
inline G4double
G4EmCorrections::GetParticleCharge(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
const G4double kineticEnergy)
{
return effCharge.EffectiveCharge(p,mat,kineticEnergy);
}
@@ -312,7 +319,7 @@ G4EmCorrections::GetParticleCharge(const G4ParticleDefinition* p,
inline G4double
G4EmCorrections::EffectiveChargeSquareRatio(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
const G4double kineticEnergy)
{
return effCharge.EffectiveChargeSquareRatio(p,mat,kineticEnergy);
}
@@ -306,6 +306,9 @@ public:
void SetWorkerVerbose(G4int val);
G4int WorkerVerbose() const;
void SetNumberForFreeVector(G4int val);
G4int NumberForFreeVector() const;
void SetTransportationWithMsc(G4TransportationWithMscType val);
G4TransportationWithMscType TransportationWithMsc() const;
@@ -457,6 +460,7 @@ private:
G4int nbinsPerDecade;
G4int verbose;
G4int workerVerbose;
G4int nForFreeVector;
G4int tripletConv; // 5d model triplet generation type
G4TransportationWithMscType fTransportationWithMsc;
@@ -133,6 +133,7 @@ private:
G4UIcmdWithAnInteger* verCmd;
G4UIcmdWithAnInteger* ver1Cmd;
G4UIcmdWithAnInteger* ver2Cmd;
G4UIcmdWithAnInteger* nFreeCmd;
G4UIcmdWithAnInteger* tripletCmd;
G4UIcmdWithAString* transWithMscCmd;
@@ -67,6 +67,7 @@ enum G4EmProcessSubType
fScintillation = 22,
fSynchrotronRadiation = 23,
fTransitionRadiation = 24,
fGammaReflection = 26,
fSurfaceReflection = 25,
fDarkBremsstrahlung = 40,
@@ -51,7 +51,6 @@
#include <vector>
#include "globals.hh"
#include "G4PhysicsTable.hh"
#include "G4Threading.hh"
class G4VEmModel;
class G4ParticleDefinition;
@@ -103,8 +102,8 @@ public:
inline void SetBaseMaterialActive(G4bool flag);
G4LossTableBuilder & operator=(const G4LossTableBuilder &right) = delete;
G4LossTableBuilder(const G4LossTableBuilder&) = delete;
G4LossTableBuilder & operator=(const G4LossTableBuilder &right) = delete;
G4LossTableBuilder(const G4LossTableBuilder&) = delete;
private:
@@ -114,14 +113,11 @@ private:
G4bool isInitialized = false;
G4bool baseMatFlag = false;
G4bool isBaseMatActive = true;
G4bool isMaster;
G4bool isInitializer = false;
static std::vector<G4double>* theDensityFactor;
static std::vector<G4int>* theDensityIdx;
static std::vector<G4bool>* theFlag;
#ifdef G4MULTITHREADED
static G4Mutex ltbMutex;
#endif
};
inline void G4LossTableBuilder::SetSplineFlag(G4bool flag)
@@ -146,8 +146,6 @@ class G4OpticalParameters
G4bool GetScintStackPhotons() const;
void SetScintVerboseLevel(G4int);
G4int GetScintVerboseLevel() const;
void SetScintEnhancedTimeConstants(G4bool);
G4bool GetScintEnhancedTimeConstants() const;
// WLS
void SetWLSTimeProfile(const G4String&);
@@ -39,58 +39,76 @@
#include <vector>
class G4DataVector;
class G4EmDataHandler;
class G4EmModelManager;
class G4LossTableManager;
class G4ParticleChangeForGamma;
class G4ParticleChangeForMSC;
class G4ParticleDefinition;
class G4PhysicsTable;
class G4Region;
class G4VEmModel;
class G4VEnergyLossProcess;
class G4VMscModel;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class G4TransportationWithMsc : public G4Transportation
{
public:
enum class ScatteringType
{
MultipleScattering,
};
public:
enum class ScatteringType
{
MultipleScattering,
SingleScattering,
};
explicit G4TransportationWithMsc(ScatteringType type, G4int verbosity = 0);
explicit G4TransportationWithMsc(ScatteringType type, G4int verbosity = 0);
~G4TransportationWithMsc() override;
~G4TransportationWithMsc() override;
inline void SetMultipleSteps(G4bool val);
inline G4bool MultipleSteps() const;
inline void SetMultipleSteps(G4bool val);
inline G4bool MultipleSteps() const;
void AddMscModel(G4VMscModel* mscModel, G4int order = 0,
const G4Region* region = nullptr);
void AddMscModel(G4VMscModel* mscModel, G4int order = 0, const G4Region* region = nullptr);
public:
void PreparePhysicsTable(const G4ParticleDefinition& part) override;
void BuildPhysicsTable(const G4ParticleDefinition& part) override;
void AddSSModel(G4VEmModel* model, G4int order = 0, const G4Region* region = nullptr);
void StartTracking(G4Track* track) override;
public:
void PreparePhysicsTable(const G4ParticleDefinition& part) override;
void BuildPhysicsTable(const G4ParticleDefinition& part) override;
G4double AlongStepGetPhysicalInteractionLength(
const G4Track& track, G4double previousStepSize,
G4double currentMinimumStep, G4double& proposedSafety,
G4GPILSelection* selection) override;
void StartTracking(G4Track* track) override;
private:
const ScatteringType fType;
G4bool fMultipleSteps = false;
G4double AlongStepGetPhysicalInteractionLength(const G4Track& track, G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection) override;
G4LossTableManager* fEmManager;
G4EmModelManager* fModelManager;
const G4ParticleDefinition* fFirstParticle = nullptr;
private:
const ScatteringType fType;
G4bool fMultipleSteps = false;
// For ScatteringType::MultipleScattering
G4ParticleChangeForMSC* fParticleChangeForMSC = nullptr;
G4LossTableManager* fEmManager;
G4EmModelManager* fModelManager;
G4DynamicParticle* fSubStepDynamicParticle;
G4Track* fSubStepTrack;
G4Step* fSubStep;
// Not initialized in the constructor, but later in PreparePhysicsTable or StartTracking.
const G4DataVector* fCuts = nullptr;
const G4ParticleDefinition* fFirstParticle = nullptr;
G4VEnergyLossProcess* fIonisation = nullptr;
// For ScatteringType::MultipleScattering
G4ParticleChangeForMSC* fParticleChangeForMSC = nullptr;
// For ScatteringType::SingleScattering
G4EmDataHandler* fEmData = nullptr;
G4PhysicsTable* fLambdaTable = nullptr;
G4ParticleChangeForGamma* fParticleChangeForSS = nullptr;
std::vector<G4DynamicParticle*>* fSecondariesSS = nullptr;
G4DynamicParticle* fSubStepDynamicParticle;
G4Track* fSubStepTrack;
G4Step* fSubStep;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -317,10 +317,6 @@ public:
void SetCrossSectionTable(G4PhysicsTable*, G4bool isLocal);
G4bool LPMFlag() const;
void SetLPMFlag(G4bool val);
inline G4ElementData* GetElementData();
inline G4PhysicsTable* GetCrossSectionTable();
@@ -393,6 +389,10 @@ public:
inline void SetLocked(G4bool);
// obsolete method
[[deprecated("Use G4EmParameters::Instance()->SetLPM instead")]]
void SetLPMFlag(G4bool);
// hide assignment operator
G4VEmModel & operator=(const G4VEmModel &right) = delete;
G4VEmModel(const G4VEmModel&) = delete;
@@ -441,8 +441,8 @@ private:
protected:
size_t currentCoupleIndex = 0;
size_t basedCoupleIndex = 0;
std::size_t currentCoupleIndex = 0;
std::size_t basedCoupleIndex = 0;
G4bool lossFlucFlag = true;
private:
@@ -56,7 +56,6 @@
//
#include "G4EmCorrections.hh"
#include "Randomize.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleTable.hh"
@@ -103,13 +102,14 @@ const G4double G4EmCorrections::UL[] = {0.1215, 0.5265, 0.8411, 1.0878, 1.2828,
1.9508, 1.9696, 1.9836, 1.9890, 1.9935,
2.0001, 2.0039, 2.0053, 2.0049, 2.0040, 2.0028};
G4double G4EmCorrections::VL[] = {0.0};
G4double G4EmCorrections::sWmaxBarkas = 10.0;
G4PhysicsFreeVector* G4EmCorrections::sBarkasCorr = nullptr;
G4PhysicsFreeVector* G4EmCorrections::sThetaK = nullptr;
G4PhysicsFreeVector* G4EmCorrections::sThetaL = nullptr;
G4EmCorrections::G4EmCorrections(G4int verb, G4bool master)
: verbose(verb), isMaster(master)
G4EmCorrections::G4EmCorrections(G4int verb)
: verbose(verb)
{
eth = 2.0*CLHEP::MeV;
eCorrMin = 25.*CLHEP::keV;
@@ -119,15 +119,18 @@ G4EmCorrections::G4EmCorrections(G4int verb, G4bool master)
g4calc = G4Pow::GetInstance();
// fill vectors
if(isMaster) { Initialise(); }
if (nullptr == sBarkasCorr) {
Initialise();
isInitializer = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmCorrections::~G4EmCorrections()
{
for(G4int i=0; i<nIons; ++i) { delete stopData[i]; }
if(isMaster) {
for (G4int i=0; i<nIons; ++i) { delete stopData[i]; }
if (isInitializer) {
delete sBarkasCorr;
delete sThetaK;
delete sThetaL;
@@ -137,7 +140,7 @@ G4EmCorrections::~G4EmCorrections()
void G4EmCorrections::SetupKinematics(const G4ParticleDefinition* p,
const G4Material* mat,
G4double kineticEnergy)
const G4double kineticEnergy)
{
if(kineticEnergy != kinEnergy || p != particle) {
particle = p;
@@ -149,7 +152,7 @@ void G4EmCorrections::SetupKinematics(const G4ParticleDefinition* p,
beta2 = bg2/(gamma*gamma);
beta = std::sqrt(beta2);
ba2 = beta2/alpha2;
G4double ratio = CLHEP::electron_mass_c2/mass;
const G4double ratio = CLHEP::electron_mass_c2/mass;
tmax = 2.0*CLHEP::electron_mass_c2*bg2
/(1. + 2.0*gamma*ratio + ratio*ratio);
charge = p->GetPDGCharge()*inveplus;
@@ -168,7 +171,7 @@ void G4EmCorrections::SetupKinematics(const G4ParticleDefinition* p,
G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e, G4double)
const G4double e, const G4double)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
@@ -180,11 +183,11 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
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);
const G4double Barkas = BarkasCorrection(p, mat, e, true);
const G4double Bloch = BlochCorrection(p, mat, e, true);
const G4double Mott = MottCorrection(p, mat, e, true);
G4double sum = (2.0*(Barkas + Bloch) + Mott);
G4double sum = 2.0*(Barkas + Bloch) + Mott;
if(verbose > 1) {
G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
@@ -195,7 +198,7 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
<< " Lshell= " << LShellCorrection(p, mat, e)
<< " " << mat->GetName() << G4endl;
}
sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
sum *= material->GetElectronDensity()*q2*CLHEP::twopi_mc2_rcl2/beta2;
return sum;
}
@@ -203,17 +206,18 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
G4double G4EmCorrections::IonBarkasCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
return 2.0*BarkasCorrection(p, mat, e)*
material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
SetupKinematics(p, mat, e);
return 2.0*BarkasCorrection(p, mat, e, true)*
material->GetElectronDensity() * q2 * CLHEP::twopi_mc2_rcl2 /beta2;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
@@ -224,9 +228,9 @@ G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
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);
const G4double Barkas = BarkasCorrection (p, mat, e, true);
const G4double Bloch = BlochCorrection (p, mat, e, true);
const G4double Mott = MottCorrection (p, mat, e, true);
G4double sum = 2.0*(Barkas*(charge - 1.0)/charge + Bloch) + Mott;
@@ -235,7 +239,7 @@ G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
<< " Bloch= " << Bloch << " Mott= " << Mott
<< " Sum= " << sum << G4endl;
}
sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
sum *= material->GetElectronDensity() * q2 * CLHEP::twopi_mc2_rcl2 /beta2;
if(verbose > 1) { G4cout << " Sum= " << sum << G4endl; }
return sum;
@@ -245,7 +249,7 @@ G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
const G4MaterialCutsCouple* couple,
G4double e)
const G4double e)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
@@ -256,13 +260,12 @@ G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
G4double sum = 0.0;
if(ionHEModel) {
if(nullptr != ionHEModel) {
G4int Z = G4lrint(p->GetPDGCharge()*inveplus);
if(Z >= 100) Z = 99;
else if(Z < 1) Z = 1;
Z = std::max(std::min(Z, 99), 1);
G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
G4int ionPDG = p->GetPDGEncoding();
const G4double ethscaled = eth*p->GetPDGMass()/CLHEP::proton_mass_c2;
const G4int ionPDG = p->GetPDGEncoding();
if(thcorr.find(ionPDG)==thcorr.end()) { // Not found: fill the map
std::vector<G4double> v;
for(std::size_t i=0; i<ncouples; ++i){
@@ -271,16 +274,7 @@ G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
thcorr.insert(std::pair< G4int, std::vector<G4double> >(ionPDG,v));
}
//G4cout << " map size=" << thcorr.size() << G4endl;
//for(std::map< G4int, std::vector<G4double> >::iterator
// it = thcorr.begin(); it != thcorr.end(); ++it){
// G4cout << "\t map element: first (key)=" << it->first
// << "\t second (vector): vec size=" << (it->second).size() << G4endl;
// for(std::size_t i=0; i<(it->second).size(); ++i){
// G4cout << "\t \t vec element: [" << i << "]=" << (it->second)[i]
//<< G4endl; } }
G4double rest = (thcorr.find(ionPDG)->second)[couple->GetIndex()];
const G4double rest = (thcorr.find(ionPDG)->second)[couple->GetIndex()];
sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e;
@@ -295,7 +289,7 @@ G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
G4double G4EmCorrections::Bethe(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
SetupKinematics(p, mat, e);
const G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
@@ -307,7 +301,7 @@ G4double G4EmCorrections::Bethe(const G4ParticleDefinition* p,
G4double G4EmCorrections::SpinCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
SetupKinematics(p, mat, e);
const G4double dedx = 0.5*tmax/(kinEnergy + mass);
@@ -318,7 +312,7 @@ G4double G4EmCorrections::SpinCorrection(const G4ParticleDefinition* p,
G4double G4EmCorrections:: KShellCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
SetupKinematics(p, mat, e);
G4double term = 0.0;
@@ -332,9 +326,8 @@ G4double G4EmCorrections:: KShellCorrection(const G4ParticleDefinition* p,
f = 0.5;
Z2 = 1.0;
}
G4double eta = ba2/Z2;
G4double tet = Z2*(1. + Z2*0.25*alpha2);
if(11 < iz) { tet = sThetaK->Value(Z); }
const G4double eta = ba2/Z2;
const G4double tet = (11 < iz) ? sThetaK->Value(Z) : Z2*(1. + Z2*0.25*alpha2);
term += f*atomDensity[i]*KShell(tet,eta)/Z;
}
@@ -347,31 +340,29 @@ G4double G4EmCorrections:: KShellCorrection(const G4ParticleDefinition* p,
G4double G4EmCorrections:: LShellCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
SetupKinematics(p, mat, e);
G4double term = 0.0;
for (G4int i = 0; i<numberOfElements; ++i) {
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = (*theElementVector)[i]->GetZasInt();
const G4double Z = (*theElementVector)[i]->GetZ();
const G4int iz = (*theElementVector)[i]->GetZasInt();
if(2 < iz) {
G4double Zeff = Z - ZD[10];
if(iz < 10) { Zeff = Z - ZD[iz]; }
G4double Z2= Zeff*Zeff;
G4double f = 0.125;
G4double eta = ba2/Z2;
const G4double Zeff = (iz < 10) ? Z - ZD[iz] : Z - ZD[10];
const G4double Z2= Zeff*Zeff;
const G4double eta = ba2/Z2;
G4double tet = sThetaL->Value(Z);
G4int nmax = std::min(4,G4AtomicShells::GetNumberOfShells(iz));
for(G4int j=1; j<nmax; ++j) {
G4int nmax = std::min(4, G4AtomicShells::GetNumberOfShells(iz));
for (G4int j=1; j<nmax; ++j) {
G4int ne = G4AtomicShells::GetNumberOfElectrons(iz,j);
if(15 >= iz) {
if(3 > j) { tet = 0.25*Z2*(1.0 + 5*Z2*alpha2/16.); }
else { tet = 0.25*Z2*(1.0 + Z2*alpha2/16.); }
if (15 >= iz) {
tet = (3 > j) ? 0.25*Z2*(1.0 + 5*Z2*alpha2/16.) :
0.25*Z2*(1.0 + Z2*alpha2/16.);
}
//G4cout << " LShell: j= " << j << " ne= " << ne << " e(eV)= " << e/eV
// << " ThetaL= " << tet << G4endl;
term += f*ne*atomDensity[i]*LShell(tet,eta)/Z;
term += 0.125*ne*atomDensity[i]*LShell(tet,eta)/Z;
}
}
}
@@ -383,7 +374,7 @@ G4double G4EmCorrections:: LShellCorrection(const G4ParticleDefinition* p,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCorrections::KShell(G4double tet, G4double eta)
G4double G4EmCorrections::KShell(const G4double tet, const G4double eta)
{
G4double corr = 0.0;
@@ -403,7 +394,7 @@ G4double G4EmCorrections::KShell(G4double tet, G4double eta)
} else {
itet = Index(x, TheK, nK);
}
// assimptotic case
// asymptotic case
if(eta >= Eta[nEtaK-1]) {
corr =
(Value(x, TheK[itet], TheK[itet+1], UK[itet], UK[itet+1]) +
@@ -412,7 +403,7 @@ G4double G4EmCorrections::KShell(G4double tet, G4double eta)
} else {
G4double y = eta;
if(eta < Eta[0]) {
y = Eta[0];
y = Eta[0];
} else {
ieta = Index(y, Eta, nEtaK);
}
@@ -431,7 +422,7 @@ G4double G4EmCorrections::KShell(G4double tet, G4double eta)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCorrections::LShell(G4double tet, G4double eta)
G4double G4EmCorrections::LShell(const G4double tet, const G4double eta)
{
G4double corr = 0.0;
@@ -452,7 +443,7 @@ G4double G4EmCorrections::LShell(G4double tet, G4double eta)
itet = Index(x, TheL, nL);
}
// assimptotic case
// asymptotic case
if(eta >= Eta[nEtaL-1]) {
corr = (Value(x, TheL[itet], TheL[itet+1], UL[itet], UL[itet+1])
+ Value(x, TheL[itet], TheL[itet+1], VL[itet], VL[itet+1])/eta
@@ -481,7 +472,7 @@ G4double G4EmCorrections::LShell(G4double tet, G4double eta)
G4double G4EmCorrections::ShellCorrectionSTD(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
SetupKinematics(p, mat, e);
G4double taulim= 8.0*MeV/mass;
@@ -515,19 +506,18 @@ G4double G4EmCorrections::ShellCorrectionSTD(const G4ParticleDefinition* p,
G4double G4EmCorrections::ShellCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double ekin)
const G4double ekin)
{
SetupKinematics(p, mat, ekin);
G4double term = 0.0;
//G4cout << "### G4EmCorrections::ShellCorrection " << mat->GetName()
// << " " << ekin/MeV << " MeV " << G4endl;
// << " " << ekin/MeV << " MeV " << G4endl;
for (G4int i = 0; i<numberOfElements; ++i) {
G4double res = 0.0;
G4double res0 = 0.0;
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = (*theElementVector)[i]->GetZasInt();
const G4double Z = (*theElementVector)[i]->GetZ();
const G4int iz = (*theElementVector)[i]->GetZasInt();
G4double Z2= (Z-0.3)*(Z-0.3);
G4double f = 1.0;
if(1 == iz) {
@@ -535,34 +525,33 @@ G4double G4EmCorrections::ShellCorrection(const G4ParticleDefinition* p,
Z2 = 1.0;
}
G4double eta = ba2/Z2;
G4double tet = Z2*(1. + Z2*0.25*alpha2);
if(11 < iz) { tet = sThetaK->Value(Z); }
G4double tet = (11 < iz) ? sThetaK->Value(Z) : Z2*(1. + Z2*0.25*alpha2);
res0 = f*KShell(tet,eta);
res += res0;
//G4cout << " Z= " << iz << " Shell 0" << " tet= " << tet
// << " eta= " << eta << " resK= " << res0 << G4endl;
if(2 < iz) {
G4double Zeff = Z - ZD[10];
if(iz < 10) { Zeff = Z - ZD[iz]; }
const G4double Zeff = (iz < 10) ? Z - ZD[iz] : Z - ZD[10];
Z2= Zeff*Zeff;
eta = ba2/Z2;
f = 0.125;
tet = sThetaL->Value(Z);
G4int ntot = G4AtomicShells::GetNumberOfShells(iz);
G4int nmax = std::min(4, ntot);
f = 0.125;
const G4int ntot = G4AtomicShells::GetNumberOfShells(iz);
const G4int nmax = std::min(4, ntot);
G4double norm = 0.0;
G4double eshell = 0.0;
for(G4int j=1; j<nmax; ++j) {
G4int ne = G4AtomicShells::GetNumberOfElectrons(iz,j);
if(15 >= iz) {
if(3 > j) { tet = 0.25*Z2*(1.0 + 5*Z2*alpha2/16.); }
else { tet = 0.25*Z2*(1.0 + Z2*alpha2/16.); }
tet = (3 > j) ? 0.25*Z2*(1.0 + 5*Z2*alpha2/16.) :
0.25*Z2*(1.0 + Z2*alpha2/16.);
}
norm += ne;
eshell += tet*ne;
res0 = f*ne*LShell(tet,eta);
res += res0;
//G4cout << " Z= " << iz << " Shell " << j << " Ne= " << ne
//G4cout << " Zeff= " << Zeff << " Shell " << j << " Ne= " << ne
// << " tet= " << tet << " eta= " << eta
// << " resL= " << res0 << G4endl;
}
@@ -610,7 +599,7 @@ G4double G4EmCorrections::ShellCorrection(const G4ParticleDefinition* p,
}
term /= material->GetTotNbOfAtomsPerVolume();
//G4cout << "# Shell Correction= " << term << G4endl;
//G4cout << "##Shell Correction=" << term << G4endl;
return term;
}
@@ -618,7 +607,7 @@ G4double G4EmCorrections::ShellCorrection(const G4ParticleDefinition* p,
G4double G4EmCorrections::DensityCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e)
{
SetupKinematics(p, mat, e);
@@ -645,32 +634,30 @@ G4double G4EmCorrections::DensityCorrection(const G4ParticleDefinition* p,
G4double G4EmCorrections::BarkasCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e,
const G4bool isInitialized)
{
// . 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 pp. 2393-2397
// valid for kineticEnergy > 0.5 MeV
SetupKinematics(p, mat, e);
if (!isInitialized) { SetupKinematics(p, mat, e); }
G4double BarkasTerm = 0.0;
for (G4int i = 0; i<numberOfElements; ++i) {
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = (*theElementVector)[i]->GetZasInt();
const G4int iz = (*theElementVector)[i]->GetZasInt();
if(iz == 47) {
BarkasTerm += atomDensity[i]*0.006812*G4Exp(-G4Log(beta)*0.9);
} else if(iz >= 64) {
BarkasTerm += atomDensity[i]*0.002833*G4Exp(-G4Log(beta)*1.2);
} else {
G4double X = ba2 / Z;
const G4double Z = (*theElementVector)[i]->GetZ();
const G4double X = ba2 / Z;
G4double b = 1.3;
if(1 == iz) {
if(material->GetName() == "G4_lH2") { b = 0.6; }
else { b = 1.8; }
}
if(1 == iz) { b = (material->GetName() == "G4_lH2") ? 0.6 : 1.8; }
else if(2 == iz) { b = 0.6; }
else if(10 >= iz) { b = 1.8; }
else if(17 >= iz) { b = 1.4; }
@@ -678,12 +665,10 @@ G4double G4EmCorrections::BarkasCorrection(const G4ParticleDefinition* p,
else if(25 >= iz) { b = 1.4; }
else if(50 >= iz) { b = 1.35;}
G4double W = b/std::sqrt(X);
const G4double W = b/std::sqrt(X);
G4double val = sBarkasCorr->Value(W);
if(W > sBarkasCorr->Energy(46)) {
val *= sBarkasCorr->Energy(46)/W;
}
G4double val = sBarkasCorr->Value(W, idxBarkas);
if (W > sWmaxBarkas) { val *= (sWmaxBarkas/W); }
// G4cout << "i= " << i << " b= " << b << " W= " << W
// << " Z= " << Z << " X= " << X << " val= " << val<< G4endl;
BarkasTerm += val*atomDensity[i] / (std::sqrt(Z*X)*X);
@@ -699,9 +684,10 @@ G4double G4EmCorrections::BarkasCorrection(const G4ParticleDefinition* p,
G4double G4EmCorrections::BlochCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e,
const G4bool isInitialized)
{
SetupKinematics(p, mat, e);
if (!isInitialized) { SetupKinematics(p, mat, e); }
G4double y2 = q2/ba2;
@@ -715,19 +701,18 @@ G4double G4EmCorrections::BlochCorrection(const G4ParticleDefinition* p,
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (del > 0.01*term);
G4double res = -y2*term;
return res;
return -y2*term;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCorrections::MottCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
const G4double e,
const G4bool isInitialized)
{
SetupKinematics(p, mat, e);
G4double mterm = CLHEP::pi*fine_structure_const*beta*charge;
return mterm;
if (!isInitialized) { SetupKinematics(p, mat, e); }
return CLHEP::pi*CLHEP::fine_structure_const*beta*charge;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -735,7 +720,7 @@ G4double G4EmCorrections::MottCorrection(const G4ParticleDefinition* p,
G4double
G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double ekin)
const G4double ekin)
{
G4double factor = 1.0;
if(p->GetPDGCharge() <= 2.5*CLHEP::eplus || nIons <= 0) { return factor; }
@@ -784,7 +769,7 @@ G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition* p,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmCorrections::AddStoppingData(G4int Z, G4int A,
void G4EmCorrections::AddStoppingData(const G4int Z, const G4int A,
const G4String& mname,
G4PhysicsVector* dVector)
{
@@ -959,27 +944,27 @@ void G4EmCorrections::Initialise()
sBarkasCorr = new G4PhysicsFreeVector(47, false);
for(i=0; i<47; ++i) { sBarkasCorr->PutValues(i, fTable[i][0], fTable[i][1]); }
static const G4double SK[20] = {1.9477, 1.9232, 1.8996, 1.8550, 1.8137,
const G4double SK[20] = {1.9477, 1.9232, 1.8996, 1.8550, 1.8137,
1.7754, 1.7396, 1.7223, 1.7063, 1.6752,
1.6461, 1.6189, 1.5933, 1.5811, 1.5693,
1.5467, 1.5254, 1.5053, 1.4863, 1.4772};
static const G4double TK[20] = {2.5222, 2.5125, 2.5026, 2.4821, 2.4608,
const G4double TK[20] = {2.5222, 2.5125, 2.5026, 2.4821, 2.4608,
2.4388, 2.4163, 2.4044, 2.3933, 2.3701,
2.3466, 2.3229, 2.2992, 2.2872, 2.2753,
2.2515, 2.2277, 2.2040, 2.1804, 2.1686};
static const G4double SL[26] = {15.3343, 13.9389, 12.7909, 11.8343, 11.0283,
const G4double SL[26] = {15.3343, 13.9389, 12.7909, 11.8343, 11.0283,
10.3424, 10.0371, 9.7537, 9.2443, 8.8005,
8.4114, 8.0683, 7.9117, 7.7641, 7.4931,
7.2506, 7.0327, 6.8362, 6.7452, 6.6584,
6.4969, 6.3498, 6.2154, 6.0923, 6.0345, 5.9792};
static const G4double TL[26] = {35.0669, 33.4344, 32.0073, 30.7466, 29.6226,
const G4double TL[26] = {35.0669, 33.4344, 32.0073, 30.7466, 29.6226,
28.6128, 28.1449, 27.6991, 26.8674, 26.1061,
25.4058, 24.7587, 24.4531, 24.1583, 23.5992,
23.0771, 22.5880, 22.1285, 21.9090, 21.6958,
21.2872, 20.9006, 20.5341, 20.1859, 20.0183, 19.8546};
static const G4double bk1[29][11] = {
const G4double bk1[29][11] = {
{0.005, 1.34782E-8, 1.46132E-8, 1.72179E-8, 2.03521E-8, 2.41370E-8, 2.87247E-8, 3.13778E-8, 3.43072E-8, 4.11274E-8, 4.94946E-8},
{0.007, 6.87555E-8, 7.44373E-8, 8.74397E-8, 1.03022E-7, 1.21760E-7, 1.44370E-7, 1.57398E-7, 1.71747E-7, 2.05023E-7, 2.45620E-7},
{0.01, 3.78413E-7, 4.08831E-7, 4.78154E-7, 5.60760E-7, 6.59478E-7, 7.77847E-7, 8.45709E-7, 9.20187E-7, 1.09192E-6, 1.29981E-6},
@@ -1011,7 +996,7 @@ void G4EmCorrections::Initialise()
{10.0, 5.32590, 5.35848, 5.42560, 5.49547, 5.56830, 5.64429, 5.68353, 5.72366, 5.80666, 5.89359}
};
static const G4double bk2[29][11] = {
const G4double bk2[29][11] = {
{0.005, 5.98040E-8, 7.25636E-8, 8.00602E-8, 8.84294E-8, 1.08253E-7, 1.33148E-7, 1.64573E-7, 2.04459E-7, 2.28346E-7, 2.55370E-7},
{0.007, 2.95345E-7, 3.56497E-7, 3.92247E-7, 4.32017E-7, 5.25688E-7, 6.42391E-7, 7.88464E-7, 9.72171E-7, 1.08140E-6, 1.20435E-6},
{0.01, 1.55232E-6, 1.86011E-6, 2.03881E-6, 2.23662E-6, 2.69889E-6, 3.26860E-6, 3.26860E-6, 4.84882E-6, 5.36428E-6, 5.94048E-6},
@@ -1043,7 +1028,7 @@ void G4EmCorrections::Initialise()
{10.0, 5.98474, 6.08046, 6.13015, 6.18112, 6.28715, 6.39903, 6.51728, 6.64249, 6.70792, 6.77535}
};
static const G4double bls1[28][10] = {
const G4double bls1[28][10] = {
{0.005, 2.4111E-4, 2.5612E-4, 2.7202E-4, 3.0658E-4, 3.4511E-4, 3.8795E-4, 4.3542E-4, 4.6100E-4, 4.8786E-4},
{0.007, 6.3947E-4, 6.7058E-4, 7.0295E-4, 7.7167E-4, 8.4592E-4, 9.2605E-4, 1.0125E-3, 1.0583E-3, 1.1058E-3},
{0.01, 1.5469E-3, 1.6036E-3, 1.6622E-3, 1.7856E-3, 1.9181E-3, 2.1615E-3, 2.3178E-3, 2.4019E-3, 2.4904E-3},
@@ -1074,7 +1059,7 @@ void G4EmCorrections::Initialise()
{7.0, 6.8634, 6.9194, 6.9767, 7.0957, 7.2208, 7.3526, 7.4915, 7.5639, 7.6384}
};
static const G4double bls2[28][10] = {
const G4double bls2[28][10] = {
{0.005, 5.4561E-4, 6.0905E-4, 6.7863E-4, 7.5494E-4, 7.9587E-4, 8.3883E-4, 9.3160E-4, 1.0352E-3, 1.1529E-3},
{0.007, 1.2068E-3, 1.3170E-3, 1.4377E-3, 1.5719E-3, 1.6451E-3, 1.7231E-3, 1.8969E-3, 2.1009E-3, 2.3459E-3},
{0.01, 2.6832E-3, 2.9017E-3, 3.1534E-3, 3.4479E-3, 3.6149E-3, 3.7976E-3, 4.2187E-3, 4.7320E-3, 5.3636E-3},
@@ -1105,7 +1090,7 @@ void G4EmCorrections::Initialise()
{7.0, 7.7938, 7.9588, 8.1342, 8.3211, 8.4193, 8.5209, 8.7350, 8.9651, 9.2133}
};
static const G4double bls3[28][9] = {
const G4double bls3[28][9] = {
{0.005, 1.2895E-3, 1.3670E-3, 1.4524E-3, 1.6524E-3, 1.9078E-3, 2.2414E-3, 2.6889E-3, 3.3006E-3},
{0.007, 2.6467E-3, 2.8242E-3, 3.0238E-3, 3.5045E-3, 4.1260E-3, 4.9376E-3, 6.0050E-3, 7.4152E-3},
{0.01, 6.1472E-3, 6.6086E-3, 7.1246E-3, 8.3491E-3, 9.8871E-3, 1.1822E-2, 1.4261E-2, 1.7335E-2},
@@ -1136,7 +1121,7 @@ void G4EmCorrections::Initialise()
{7.0, 9.4819, 9.6248, 9.7739, 10.0926, 10.4423, 10.8282, 11.2565, 11.7356}
};
static const G4double bll1[28][10] = {
const G4double bll1[28][10] = {
{0.005, 3.6324E-5, 4.0609E-5, 4.5430E-5, 5.6969E-5, 7.1625E-5, 9.0279E-5, 1.1407E-4, 1.2834E-4, 1.4447E-4},
{0.007, 1.8110E-4, 2.0001E-4, 2.2099E-4, 2.7006E-4, 3.3049E-4, 4.0498E-4, 4.9688E-4, 5.5061E-4, 6.1032E-4},
{0.01, 8.6524E-4, 9.4223E-4, 1.0262E-3, 1.2178E-3, 1.4459E-3, 1.7174E-3, 2.0405E-3, 2.2245E-3, 2.4252E-3},
@@ -1167,7 +1152,7 @@ void G4EmCorrections::Initialise()
{7.0, 7.7362, 7.8079, 7.8821, 8.0383, 8.2061, 8.3866, 8.5816, 8.6850, 8.7927}
};
static const G4double bll2[28][10] = {
const G4double bll2[28][10] = {
{0.005, 1.8339E-4, 2.3330E-4, 2.9738E-4, 3.7977E-4, 4.2945E-4, 4.8582E-4, 6.2244E-4, 7.9858E-4, 1.0258E-3},
{0.007, 7.5042E-4, 9.2355E-4, 1.1375E-3, 1.4021E-3, 1.5570E-3, 1.7292E-3, 2.1335E-3, 2.6335E-3, 3.2515E-3},
{0.01, 2.8829E-3, 3.4275E-3, 4.0758E-3, 4.8457E-3, 5.2839E-3, 5.7617E-3, 6.8504E-3, 8.1442E-3, 9.6816E-3},
@@ -1198,7 +1183,7 @@ void G4EmCorrections::Initialise()
{7.0, 9.0221, 9.2724, 9.5464, 9.8477, 10.0099, 10.1805, 10.5499, 10.9622, 11.4250}
};
static const G4double bll3[28][9] = {
const G4double bll3[28][9] = {
{0.005, 1.3190E-3, 1.4961E-3, 1.6974E-3, 2.1858E-3, 2.8163E-3, 3.6302E-3, 4.6814E-3, 6.0395E-3},
{0.007, 4.0158E-3, 4.4623E-3, 4.9592E-3, 6.1257E-3, 7.5675E-3, 9.3502E-3, 1.1556E-2, 1.4290E-2},
{0.01, 1.1509E-2, 1.2548E-2, 1.3681E-2, 1.6263E-2, 1.9336E-2, 2.2999E-2, 2.7370E-2, 3.2603E-2},
@@ -1279,23 +1264,23 @@ void G4EmCorrections::Initialise()
}
}
static const G4double xzk[34] = { 11.7711,
const G4double xzk[34] = { 11.7711,
13.3669, 15.5762, 17.1715, 18.7667, 20.8523, 23.0606, 24.901, 26.9861, 29.4394, 31.77,
34.3457, 37.4119, 40.3555, 42.3177, 44.7705, 47.2234, 50.78, 53.8458, 56.4214, 58.3834,
60.9586, 63.6567, 66.5998, 68.807, 71.8728, 74.5706, 77.3911, 81.8056, 85.7297, 89.8988,
93.4549, 96.2753, 99.709};
static const G4double yzk[34] = { 0.70663,
const G4double yzk[34] = { 0.70663,
0.72033, 0.73651, 0.74647, 0.75518, 0.76388, 0.77258, 0.78129, 0.78625, 0.7937, 0.79991,
0.80611, 0.8123, 0.8185, 0.82097, 0.82467, 0.82838, 0.83457, 0.83702, 0.84198, 0.8432,
0.84565, 0.84936, 0.85181, 0.85303, 0.85548, 0.85794, 0.8604, 0.86283, 0.86527, 0.86646,
0.86891, 0.87011, 0.87381};
static const G4double xzl[36] = { 15.5102,
const G4double xzl[36] = { 15.5102,
16.7347, 17.9592, 19.551, 21.0204, 22.6122, 24.9388, 27.3878, 29.5918, 31.3061, 32.898,
34.4898, 36.2041, 38.4082, 40.3674, 42.5714, 44.898, 47.4694, 49.9184, 52.7347, 55.9184,
59.3469, 61.9184, 64.6122, 67.4286, 71.4694, 75.2653, 78.3265, 81.2653, 85.551, 88.7347,
91.551, 94.2449, 96.449, 98.4082, 99.7551};
static const G4double yzl[36] = { 0.29875,
const G4double yzl[36] = { 0.29875,
0.31746, 0.33368, 0.35239, 0.36985, 0.38732, 0.41102, 0.43472, 0.45343, 0.4659, 0.47713,
0.4896, 0.50083, 0.51331, 0.52328, 0.53077, 0.54075, 0.54823, 0.55572, 0.56445, 0.57193,
0.58191, 0.5869, 0.59189, 0.60062, 0.60686, 0.61435, 0.61809, 0.62183, 0.62931, 0.6343,
@@ -164,6 +164,7 @@ void G4EmParameters::Initialise()
nbinsPerDecade = 7;
verbose = 1;
workerVerbose = 0;
nForFreeVector = 2;
tripletConv = 0;
fTransportationWithMsc = G4TransportationWithMscType::fDisabled;
@@ -998,6 +999,17 @@ G4int G4EmParameters::WorkerVerbose() const
return workerVerbose;
}
void G4EmParameters::SetNumberForFreeVector(G4int val)
{
if(IsLocked()) { return; }
nForFreeVector = val;
}
G4int G4EmParameters::NumberForFreeVector() const
{
return nForFreeVector;
}
void G4EmParameters::SetTransportationWithMsc(G4TransportationWithMscType val)
{
if(IsLocked()) { return; }
@@ -384,6 +384,13 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
ver2Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
ver2Cmd->SetToBeBroadcasted(false);
nFreeCmd = new G4UIcmdWithAnInteger("/process/em/nForFreeVector",this);
nFreeCmd->SetGuidance("Set number for logarithmic bin search algorithm");
nFreeCmd->SetParameterName("nFree",true);
nFreeCmd->SetDefaultValue(2);
nFreeCmd->AvailableForStates(G4State_PreInit);
nFreeCmd->SetToBeBroadcasted(false);
transWithMscCmd = new G4UIcmdWithAString("/process/em/transportationWithMsc",this);
transWithMscCmd->SetGuidance("Enable/disable the G4TransportationWithMsc process");
transWithMscCmd->SetParameterName("trans",true);
@@ -424,7 +431,7 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
ssCmd->AvailableForStates(G4State_PreInit);
ssCmd->SetToBeBroadcasted(false);
fluc1Cmd = new G4UIcmdWithAString("/process/eloss/setFluctModel",this);
fluc1Cmd = new G4UIcmdWithAString("/process/eLoss/setFluctModel",this);
fluc1Cmd->SetGuidance("Define type of energy loss fluctuation model");
fluc1Cmd->SetParameterName("Fluc1",true);
fluc1Cmd->SetCandidates("Dummy Universal Urban");
@@ -511,6 +518,7 @@ G4EmParametersMessenger::~G4EmParametersMessenger()
delete ver1Cmd;
delete ver2Cmd;
delete transWithMscCmd;
delete nFreeCmd;
delete tripletCmd;
delete mscCmd;
@@ -638,6 +646,8 @@ void G4EmParametersMessenger::SetNewValue(G4UIcommand* command,
theParameters->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
} else if (command == ver2Cmd) {
theParameters->SetWorkerVerbose(ver2Cmd->GetNewIntValue(newValue));
} else if (command == nFreeCmd) {
theParameters->SetNumberForFreeVector(nFreeCmd->GetNewIntValue(newValue));
} else if (command == dumpCmd) {
theParameters->SetIsPrintedFlag(false);
theParameters->Dump();
@@ -217,13 +217,13 @@ void G4EmSaturation::InitialiseBirksCoefficient(const G4Material* mat)
std::size_t nelm = mat->GetNumberOfElements();
for (std::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;
G4int Z = elm->GetZasInt();
G4double w = theAtomNumDensityVector[i];
curRatio += w/nist->GetAtomicMassAmu(Z);
curChargeSq += (Z*Z)*w;
norm += w;
}
curRatio *= proton_mass_c2/norm;
curRatio *= (CLHEP::proton_mass_c2/norm);
curChargeSq /= norm;
// store results
@@ -69,33 +69,23 @@
std::vector<G4double>* G4LossTableBuilder::theDensityFactor = nullptr;
std::vector<G4int>* G4LossTableBuilder::theDensityIdx = nullptr;
std::vector<G4bool>* G4LossTableBuilder::theFlag = nullptr;
#ifdef G4MULTITHREADED
G4Mutex G4LossTableBuilder::ltbMutex = G4MUTEX_INITIALIZER;
#endif
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4LossTableBuilder::G4LossTableBuilder(G4bool master) : isMaster(master)
G4LossTableBuilder::G4LossTableBuilder(G4bool master)
{
theParameters = G4EmParameters::Instance();
if(nullptr == theFlag) {
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&ltbMutex);
if(nullptr == theFlag) {
#endif
if(!isMaster) {
G4ExceptionDescription ed;
ed << "Initialisation called from a worker thread ";
G4Exception("G4LossTableBuilder: ", "em0001",
JustWarning, ed);
}
theDensityFactor = new std::vector<G4double>;
theDensityIdx = new std::vector<G4int>;
theFlag = new std::vector<G4bool>;
#ifdef G4MULTITHREADED
if (nullptr == theFlag) {
if (!master) {
G4ExceptionDescription ed;
ed << "The table builder is instantiated in a worker thread ";
G4Exception("G4LossTableBuilder::G4LossTableBuilder ", "em0001",
JustWarning, ed);
}
G4MUTEXUNLOCK(&ltbMutex);
#endif
theDensityFactor = new std::vector<G4double>;
theDensityIdx = new std::vector<G4int>;
theFlag = new std::vector<G4bool>;
isInitializer = true;
}
}
@@ -103,7 +93,7 @@ G4LossTableBuilder::G4LossTableBuilder(G4bool master) : isMaster(master)
G4LossTableBuilder::~G4LossTableBuilder()
{
if(isMaster) {
if (isInitializer) {
delete theDensityFactor;
delete theDensityIdx;
delete theFlag;
@@ -131,7 +121,7 @@ const std::vector<G4double>* G4LossTableBuilder::GetDensityFactors() const
G4bool G4LossTableBuilder::GetFlag(std::size_t idx)
{
if(theFlag->empty()) { InitialiseBaseMaterials(); }
if (theFlag->empty()) { InitialiseBaseMaterials(); }
return (idx < theFlag->size()) ? (*theFlag)[idx] : false;
}
@@ -139,7 +129,7 @@ G4bool G4LossTableBuilder::GetFlag(std::size_t idx)
G4bool G4LossTableBuilder::GetBaseMaterialFlag()
{
if(theFlag->empty()) { InitialiseBaseMaterials(); }
if (theFlag->empty()) { InitialiseBaseMaterials(); }
return baseMatFlag;
}
@@ -275,14 +265,15 @@ G4LossTableBuilder::BuildInverseRangeTable(const G4PhysicsTable* rangeTable,
std::size_t npoints = pv->GetVectorLength();
delete (*invRangeTable)[i];
auto v = new G4PhysicsFreeVector(npoints,splineFlag);
auto v = new G4PhysicsFreeVector(npoints, splineFlag);
for (std::size_t j=0; j<npoints; ++j) {
G4double e = pv->Energy(j);
G4double r = (*pv)[j];
v->PutValues(j,r,e);
}
if(splineFlag) { v->FillSecondDerivatives(); }
if (splineFlag) { v->FillSecondDerivatives(); }
v->EnableLogBinSearch(theParameters->NumberForFreeVector());
G4PhysicsTableHelper::SetPhysicsVector(invRangeTable, i, v);
}
@@ -294,7 +285,7 @@ G4LossTableBuilder::BuildInverseRangeTable(const G4PhysicsTable* rangeTable,
void G4LossTableBuilder::InitialiseBaseMaterials(const G4PhysicsTable* table)
{
if(!isMaster) { return; }
if(!isInitializer) { return; }
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
std::size_t nCouples = theCoupleTable->GetTableSize();
@@ -86,7 +86,7 @@ G4ThreadLocal G4LossTableManager* G4LossTableManager::instance = nullptr;
G4LossTableManager* G4LossTableManager::Instance()
{
if(!instance) {
if(nullptr == instance) {
static G4ThreadLocalSingleton<G4LossTableManager> inst;
instance = inst.Instance();
}
@@ -140,7 +140,7 @@ G4LossTableManager::G4LossTableManager()
isMaster = false;
}
tableBuilder = new G4LossTableBuilder(isMaster);
emCorrections = new G4EmCorrections(verbose, isMaster);
emCorrections = new G4EmCorrections(verbose);
std::size_t n = 70;
loss_vector.reserve(n);
@@ -99,11 +99,11 @@ void G4OpticalParameters::SetDefaults()
void G4OpticalParameters::Initialise()
{
verboseLevel = 0;
verboseLevel = 1;
cerenkovStackPhotons = true;
cerenkovTrackSecondariesFirst = true;
cerenkovVerboseLevel = 0;
cerenkovVerboseLevel = 1;
cerenkovMaxPhotons = 100;
cerenkovMaxBetaChange = 10.;
@@ -112,22 +112,22 @@ void G4OpticalParameters::Initialise()
scintStackPhotons = true;
scintFiniteRiseTime = false;
scintTrackSecondariesFirst = true;
scintVerboseLevel = 0;
scintVerboseLevel = 1;
wlsTimeProfileName = "delta";
wlsVerboseLevel = 0;
wlsVerboseLevel = 1;
wls2TimeProfileName = "delta";
wls2VerboseLevel = 0;
wls2VerboseLevel = 1;
absorptionVerboseLevel = 0;
absorptionVerboseLevel = 1;
rayleighVerboseLevel = 0;
rayleighVerboseLevel = 1;
mieVerboseLevel = 0;
mieVerboseLevel = 1;
boundaryInvokeSD = false;
boundaryVerboseLevel = 0;
boundaryVerboseLevel = 1;
processActivation["OpRayleigh"] = true;
processActivation["OpBoundary"] = true;
@@ -39,51 +39,52 @@
#include "G4TransportationWithMsc.hh"
#include "G4DynamicParticle.hh"
#include "G4Electron.hh"
#include "G4EmConfigurator.hh"
#include "G4EmDataHandler.hh"
#include "G4LossTableBuilder.hh"
#include "G4LossTableManager.hh"
#include "G4EmConfigurator.hh"
#include "G4VMscModel.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4ParticleChangeForMSC.hh"
#include "G4DynamicParticle.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4PhysicsVector.hh"
#include "G4ProductionCutsTable.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4StepStatus.hh"
#include "G4Track.hh"
#include "G4Electron.hh"
#include "G4PhysicalConstants.hh"
#include "G4VMscModel.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
static constexpr G4double kLowestKinEnergy = 10 * CLHEP::eV;
static constexpr G4double kGeomMin = 0.05 * CLHEP::nm;
static constexpr G4double kLowestKinEnergy = 10 * CLHEP::eV;
static constexpr G4double kGeomMin = 0.05 * CLHEP::nm;
static constexpr G4double kMinDisplacement2 = kGeomMin * kGeomMin;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4TransportationWithMsc::G4TransportationWithMsc(ScatteringType type,
G4int verbosity)
: G4Transportation(verbosity, "TransportationWithMsc")
, fType(type)
G4TransportationWithMsc::G4TransportationWithMsc(ScatteringType type, G4int verbosity)
: G4Transportation(verbosity, "TransportationWithMsc"), fType(type)
{
SetVerboseLevel(1);
fEmManager = G4LossTableManager::Instance();
fEmManager = G4LossTableManager::Instance();
fModelManager = new G4EmModelManager;
if(type == ScatteringType::MultipleScattering)
{
if (type == ScatteringType::MultipleScattering) {
fParticleChangeForMSC = new G4ParticleChangeForMSC;
}
else if (type == ScatteringType::SingleScattering) {
fParticleChangeForSS = new G4ParticleChangeForGamma;
fSecondariesSS = new std::vector<G4DynamicParticle*>;
}
G4ThreeVector zero;
fSubStepDynamicParticle =
new G4DynamicParticle(G4Electron::Definition(), zero);
fSubStepDynamicParticle = new G4DynamicParticle(G4Electron::Definition(), zero);
fSubStepTrack = new G4Track(fSubStepDynamicParticle, 0, zero);
fSubStep = new G4Step;
fSubStep = new G4Step;
fSubStepTrack->SetStep(fSubStep);
}
@@ -93,6 +94,9 @@ G4TransportationWithMsc::~G4TransportationWithMsc()
{
delete fModelManager;
delete fParticleChangeForMSC;
delete fEmData;
delete fParticleChangeForSS;
delete fSecondariesSS;
// fSubStepDynamicParticle is owned and also deleted by fSubStepTrack!
delete fSubStepTrack;
@@ -104,10 +108,8 @@ G4TransportationWithMsc::~G4TransportationWithMsc()
void G4TransportationWithMsc::AddMscModel(G4VMscModel* mscModel, G4int order,
const G4Region* region)
{
if(fType != ScatteringType::MultipleScattering)
{
G4Exception("G4TransportationWithMsc::AddMscModel", "em0051",
FatalException,
if (fType != ScatteringType::MultipleScattering) {
G4Exception("G4TransportationWithMsc::AddMscModel", "em0051", FatalException,
"not allowed unless type == MultipleScattering");
}
@@ -117,89 +119,129 @@ void G4TransportationWithMsc::AddMscModel(G4VMscModel* mscModel, G4int order,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4TransportationWithMsc::PreparePhysicsTable(
const G4ParticleDefinition& part)
void G4TransportationWithMsc::AddSSModel(G4VEmModel* model, G4int order, const G4Region* region)
{
if(nullptr == fFirstParticle)
{
if (fType != ScatteringType::SingleScattering) {
G4Exception("G4TransportationWithMsc::AddSSModel", "em0051", FatalException,
"not allowed unless type == SingleScattering");
}
fModelManager->AddEmModel(order, model, nullptr, region);
model->SetPolarAngleLimit(0.0);
model->SetParticleChange(fParticleChangeForSS);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4TransportationWithMsc::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if (nullptr == fFirstParticle) {
fFirstParticle = &part;
G4VMultipleScattering* ptr = nullptr;
auto emConfigurator = fEmManager->EmConfigurator();
emConfigurator->PrepareModels(&part, ptr, this);
}
if(fFirstParticle == &part)
{
G4bool master = fEmManager->IsMaster();
G4LossTableBuilder* bld = fEmManager->GetTableBuilder();
G4bool baseMat = bld->GetBaseMaterialFlag();
if (fFirstParticle == &part) {
G4bool master = fEmManager->IsMaster();
G4LossTableBuilder* bld = fEmManager->GetTableBuilder();
G4bool baseMat = bld->GetBaseMaterialFlag();
const auto* theParameters = G4EmParameters::Instance();
if(master)
{
if (master) {
SetVerboseLevel(theParameters->Verbose());
}
else
{
else {
SetVerboseLevel(theParameters->WorkerVerbose());
}
const G4int numberOfModels = fModelManager->NumberOfModels();
if(fType == ScatteringType::MultipleScattering)
{
for(G4int i = 0; i < numberOfModels; ++i)
{
if (fType == ScatteringType::MultipleScattering) {
for (G4int i = 0; i < numberOfModels; ++i) {
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
msc->SetMasterThread(master);
msc->SetPolarAngleLimit(theParameters->MscThetaLimit());
G4double emax =
std::min(msc->HighEnergyLimit(), theParameters->MaxKinEnergy());
G4double emax = std::min(msc->HighEnergyLimit(), theParameters->MaxKinEnergy());
msc->SetHighEnergyLimit(emax);
msc->SetUseBaseMaterials(baseMat);
}
}
else if (fType == ScatteringType::SingleScattering) {
if (master) {
if (fEmData == nullptr) {
fEmData = new G4EmDataHandler(2);
}
fModelManager->Initialise(fFirstParticle, G4Electron::Electron(),
verboseLevel);
fLambdaTable = fEmData->MakeTable(0);
bld->InitialiseBaseMaterials(fLambdaTable);
}
}
fCuts = fModelManager->Initialise(fFirstParticle, G4Electron::Electron(), verboseLevel);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4TransportationWithMsc::BuildPhysicsTable(
const G4ParticleDefinition& part)
void G4TransportationWithMsc::BuildPhysicsTable(const G4ParticleDefinition& part)
{
if(fFirstParticle == &part)
{
if (fFirstParticle == &part) {
fEmManager->BuildPhysicsTable(fFirstParticle);
if(!fEmManager->IsMaster())
{
const auto masterProcess =
static_cast<const G4TransportationWithMsc*>(GetMasterProcess());
if (fEmManager->IsMaster()) {
if (fType == ScatteringType::SingleScattering) {
const auto* theParameters = G4EmParameters::Instance();
G4LossTableBuilder* bld = fEmManager->GetTableBuilder();
const G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
std::size_t numOfCouples = theCoupleTable->GetTableSize();
G4double emin = theParameters->MinKinEnergy();
G4double emax = theParameters->MaxKinEnergy();
G4double scale = emax / emin;
G4int nbin = theParameters->NumberOfBinsPerDecade() * G4lrint(std::log10(scale));
scale = nbin / G4Log(scale);
G4int bin = G4lrint(scale * G4Log(emax / emin));
bin = std::max(bin, 5);
for (std::size_t i = 0; i < numOfCouples; ++i) {
if (!bld->GetFlag(i)) continue;
// Create physics vector and fill it
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple((G4int)i);
auto* aVector = new G4PhysicsLogVector(emin, emax, bin, /*splineFlag*/ true);
fModelManager->FillLambdaVector(aVector, couple, /*startNull*/ false);
aVector->FillSecondDerivatives();
G4PhysicsTableHelper::SetPhysicsVector(fLambdaTable, i, aVector);
}
}
}
else {
const auto masterProcess = static_cast<const G4TransportationWithMsc*>(GetMasterProcess());
// Initialisation of models.
const G4int numberOfModels = fModelManager->NumberOfModels();
if(fType == ScatteringType::MultipleScattering)
{
for(G4int i = 0; i < numberOfModels; ++i)
{
if (fType == ScatteringType::MultipleScattering) {
for (G4int i = 0; i < numberOfModels; ++i) {
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
auto msc0 =
static_cast<G4VMscModel*>(masterProcess->fModelManager->GetModel(i));
auto msc0 = static_cast<G4VMscModel*>(masterProcess->fModelManager->GetModel(i));
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
msc->InitialiseLocal(fFirstParticle, msc0);
}
}
else if (fType == ScatteringType::SingleScattering) {
this->fLambdaTable = masterProcess->fLambdaTable;
}
}
}
if(!G4EmParameters::Instance()->IsPrintLocked() && verboseLevel > 0)
{
if (!G4EmParameters::Instance()->IsPrintLocked() && verboseLevel > 0) {
G4cout << G4endl;
G4cout << GetProcessName() << ": for " << part.GetParticleName();
if(fMultipleSteps)
{
if (fMultipleSteps) {
G4cout << " (multipleSteps: 1)";
}
G4cout << G4endl;
@@ -212,18 +254,16 @@ void G4TransportationWithMsc::BuildPhysicsTable(
void G4TransportationWithMsc::StartTracking(G4Track* track)
{
auto* currParticle = track->GetParticleDefinition();
auto* ionisation = fEmManager->GetEnergyLossProcess(currParticle);
fIonisation = fEmManager->GetEnergyLossProcess(currParticle);
fSubStepDynamicParticle->SetDefinition(currParticle);
const G4int numberOfModels = fModelManager->NumberOfModels();
if(fType == ScatteringType::MultipleScattering)
{
for(G4int i = 0; i < numberOfModels; ++i)
{
if (fType == ScatteringType::MultipleScattering) {
for (G4int i = 0; i < numberOfModels; ++i) {
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
msc->StartTracking(track);
msc->SetIonisation(ionisation, currParticle);
msc->SetIonisation(fIonisation, currParticle);
}
}
@@ -233,42 +273,38 @@ void G4TransportationWithMsc::StartTracking(G4Track* track)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
const G4Track& track, G4double previousStepSize, G4double currentMinimumStep,
G4double& proposedSafety, G4GPILSelection* selection)
G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection)
{
*selection = NotCandidateForSelection;
const G4double physStepLimit = currentMinimumStep;
switch(fType)
{
switch (fType) {
case ScatteringType::MultipleScattering: {
// Select the MSC model for the current kinetic energy.
G4VMscModel* mscModel = nullptr;
const G4double ekin = track.GetKineticEnergy();
const auto* couple = track.GetMaterialCutsCouple();
G4VMscModel* mscModel = nullptr;
const G4double ekin = track.GetKineticEnergy();
const auto* couple = track.GetMaterialCutsCouple();
const auto* particleDefinition = track.GetParticleDefinition();
if(physStepLimit > kGeomMin)
{
if (physStepLimit > kGeomMin) {
G4double ekinForSelection = ekin;
G4double pdgMass = particleDefinition->GetPDGMass();
if(pdgMass > CLHEP::GeV)
{
G4double pdgMass = particleDefinition->GetPDGMass();
if (pdgMass > CLHEP::GeV) {
ekinForSelection *= proton_mass_c2 / pdgMass;
}
if(ekinForSelection >= kLowestKinEnergy)
{
if (ekinForSelection >= kLowestKinEnergy) {
mscModel = static_cast<G4VMscModel*>(
fModelManager->SelectModel(ekinForSelection, couple->GetIndex()));
if(mscModel == nullptr)
{
G4Exception("G4TransportationWithMsc::AlongStepGPIL", "em0052",
FatalException, "no MSC model found");
if (mscModel == nullptr) {
G4Exception("G4TransportationWithMsc::AlongStepGPIL", "em0052", FatalException,
"no MSC model found");
}
if(!mscModel->IsActive(ekinForSelection))
{
if (!mscModel->IsActive(ekinForSelection)) {
mscModel = nullptr;
}
}
@@ -276,8 +312,7 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
// Call the MSC model to potentially limit the step and convert to
// geometric path length.
if(mscModel != nullptr)
{
if (mscModel != nullptr) {
mscModel->SetCurrentCouple(couple);
// Use the provided track for the first step.
@@ -286,56 +321,46 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
G4double currentSafety = proposedSafety;
G4double currentEnergy = ekin;
G4double stepLimitLeft = physStepLimit;
G4double stepLimitLeft = physStepLimit;
G4double totalGeometryStepLength = 0, totalTruePathLength = 0;
G4bool firstStep = true, continueStepping = fMultipleSteps;
do
{
do {
G4double gPathLength = stepLimitLeft;
G4double tPathLength =
mscModel->ComputeTruePathLengthLimit(*currentTrackPtr, gPathLength);
G4bool mscLimitsStep = (tPathLength < stepLimitLeft);
if(!fMultipleSteps && mscLimitsStep)
{
if (!fMultipleSteps && mscLimitsStep) {
// MSC limits the step.
*selection = CandidateForSelection;
}
if(!firstStep)
{
if (!firstStep) {
// Move the navigator to where the previous step ended.
fLinearNavigator->LocateGlobalPointWithinVolume(
fTransportEndPosition);
fLinearNavigator->LocateGlobalPointWithinVolume(fTransportEndPosition);
}
G4GPILSelection transportSelection;
G4double geometryStepLength =
G4Transportation::AlongStepGetPhysicalInteractionLength(
*currentTrackPtr, previousStepSize, gPathLength, currentSafety,
&transportSelection);
if(geometryStepLength < gPathLength)
{
G4double geometryStepLength = G4Transportation::AlongStepGetPhysicalInteractionLength(
*currentTrackPtr, previousStepSize, gPathLength, currentSafety, &transportSelection);
if (geometryStepLength < gPathLength) {
// Transportation limits the step, ie the track hit a boundary.
*selection = CandidateForSelection;
*selection = CandidateForSelection;
continueStepping = false;
}
if(fTransportEndKineticEnergy != currentEnergy)
{
if (fTransportEndKineticEnergy != currentEnergy) {
// Field propagation changed the energy, it's not possible to
// estimate the continuous energy loss and continue stepping.
continueStepping = false;
}
if(firstStep)
{
if (firstStep) {
proposedSafety = currentSafety;
}
totalGeometryStepLength += geometryStepLength;
// Sample MSC direction change and displacement.
const G4double range =
mscModel->GetRange(particleDefinition, currentEnergy, couple);
const G4double range = mscModel->GetRange(particleDefinition, currentEnergy, couple);
tPathLength = mscModel->ComputeTrueStepLength(geometryStepLength);
@@ -343,27 +368,23 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
tPathLength = std::min(tPathLength, stepLimitLeft);
totalTruePathLength += tPathLength;
if(*selection != CandidateForSelection && !mscLimitsStep)
{
if (*selection != CandidateForSelection && !mscLimitsStep) {
// If neither MSC nor transportation limits the step, we got the
// distance we want - make sure we exit the loop.
continueStepping = false;
}
else if(tPathLength >= range)
{
else if (tPathLength >= range) {
// The particle will stop, exit the loop.
continueStepping = false;
}
else
{
else {
stepLimitLeft -= tPathLength;
}
// Do not sample scattering at the last or at a small step.
if(tPathLength < range && tPathLength > kGeomMin)
{
if (tPathLength < range && tPathLength > kGeomMin) {
static constexpr G4double minSafety = 1.20 * CLHEP::nm;
static constexpr G4double sFact = 0.99;
static constexpr G4double sFact = 0.99;
// The call to SampleScattering() *may* directly fill in the changed
// direction into fParticleChangeForMSC, so we have to:
@@ -372,74 +393,61 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
// 2) Call SampleScattering(), which *may* change it.
const G4ThreeVector displacement =
mscModel->SampleScattering(fTransportEndMomentumDir, minSafety);
// 3) Get the changed direction and inform G4Transportation.
fMomentumChanged = true;
// 3) Get the changed direction.
fTransportEndMomentumDir = *fParticleChangeForMSC->GetProposedMomentumDirection();
const G4double r2 = displacement.mag2();
if(r2 > kMinDisplacement2)
{
if (r2 > kMinDisplacement2) {
G4bool positionChanged = true;
G4double dispR = std::sqrt(r2);
G4double postSafety = sFact * fpSafetyHelper->ComputeSafety(
fTransportEndPosition, dispR);
G4double dispR = std::sqrt(r2);
G4double postSafety =
sFact * fpSafetyHelper->ComputeSafety(fTransportEndPosition, dispR);
// Far away from geometry boundary
if(postSafety > 0.0 && dispR <= postSafety)
{
if (postSafety > 0.0 && dispR <= postSafety) {
fTransportEndPosition += displacement;
// Near the boundary
}
else
{
else {
// displaced point is definitely within the volume
if(dispR < postSafety)
{
if (dispR < postSafety) {
fTransportEndPosition += displacement;
// reduced displacement
}
else if(postSafety > kGeomMin)
{
else if (postSafety > kGeomMin) {
fTransportEndPosition += displacement * (postSafety / dispR);
// very small postSafety
}
else
{
else {
positionChanged = false;
}
}
if(positionChanged)
{
if (positionChanged) {
fpSafetyHelper->ReLocateWithinVolume(fTransportEndPosition);
}
}
}
if(continueStepping)
{
if (continueStepping) {
// Update safety according to the geometry distance.
if(currentSafety < fEndPointDistance)
{
if (currentSafety < fEndPointDistance) {
currentSafety = 0;
}
else
{
else {
currentSafety -= fEndPointDistance;
}
// Update the kinetic energy according to the continuous loss.
currentEnergy = mscModel->GetEnergy(particleDefinition,
range - tPathLength, couple);
currentEnergy = mscModel->GetEnergy(particleDefinition, range - tPathLength, couple);
// From now on, use the track that we can update below.
currentTrackPtr = fSubStepTrack;
fSubStepDynamicParticle->SetKineticEnergy(currentEnergy);
fSubStepDynamicParticle->SetMomentumDirection(
fTransportEndMomentumDir);
fSubStepDynamicParticle->SetMomentumDirection(fTransportEndMomentumDir);
fSubStepTrack->SetPosition(fTransportEndPosition);
G4StepPoint& subPreStepPoint = *fSubStep->GetPreStepPoint();
@@ -449,14 +457,13 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
subPreStepPoint.SetStepStatus(fAlongStepDoItProc);
}
firstStep = false;
} while(continueStepping);
} while (continueStepping);
// Note: currentEnergy is only updated if continueStepping is true.
// In case field propagation changed the energy, this flag is
// immediately set to false and currentEnergy is still equal to the
// initial kinetic energy stored in ekin.
if(currentEnergy != ekin)
{
if (currentEnergy != ekin) {
// If field propagation didn't change the energy and we potentially
// did multiple steps, reset the energy that G4Transportation will
// propose to not subtract the energy loss twice.
@@ -464,13 +471,192 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
// Also ask for the range again with the initial energy so it is
// correctly cached in the G4VEnergyLossProcess.
// FIXME: Asking for a range should never change the cached values!
(void) mscModel->GetRange(particleDefinition, ekin, couple);
(void)mscModel->GetRange(particleDefinition, ekin, couple);
}
fParticleChange.ProposeTrueStepLength(totalTruePathLength);
// Inform G4Transportation that the momentum might have changed due
// to scattering. We do this unconditionally to avoid the situation
// where the last step is done without MSC and G4Transportation reset
// the flag, for example when running without field.
fMomentumChanged = true;
return totalGeometryStepLength;
}
break;
}
case ScatteringType::SingleScattering: {
// Select the model for the current kinetic energy.
const G4double ekin = track.GetKineticEnergy();
const auto* couple = track.GetMaterialCutsCouple();
const auto* particleDefinition = track.GetParticleDefinition();
G4double ekinForSelection = ekin;
G4double pdgMass = particleDefinition->GetPDGMass();
if (pdgMass > CLHEP::GeV) {
ekinForSelection *= proton_mass_c2 / pdgMass;
}
G4VEmModel* currentModel = fModelManager->SelectModel(ekinForSelection, couple->GetIndex());
if (currentModel == nullptr) {
G4Exception("G4TransportationWithMsc::AlongStepGPIL", "em0052", FatalException,
"no scattering model found");
}
if (!currentModel->IsActive(ekinForSelection)) {
currentModel = nullptr;
}
if (currentModel != nullptr) {
currentModel->SetCurrentCouple(couple);
G4int coupleIndex = couple->GetIndex();
// Compute mean free path.
G4double logEkin = track.GetDynamicParticle()->GetLogKineticEnergy();
G4double lambda = ((*fLambdaTable)[coupleIndex])->LogVectorValue(ekin, logEkin);
if (lambda > 0.0) {
// Assume that the mean free path and dE/dx are constant along the
// step, which is a valid approximation for most cases.
G4double meanFreePath = 1.0 / lambda;
G4double dedx = fIonisation->GetDEDX(ekin, couple);
G4double currentSafety = proposedSafety;
G4double currentEnergy = ekin;
// Use the provided track for the first step.
const G4Track* currentTrackPtr = &track;
G4double stepLimitLeft = physStepLimit;
G4double totalStepLength = 0;
G4bool firstStep = true, continueStepping = fMultipleSteps;
do {
G4double interactionLength = meanFreePath * -G4Log(G4UniformRand());
G4bool ssLimitsStep = (interactionLength < stepLimitLeft);
G4double gPathLength = stepLimitLeft;
if (ssLimitsStep) {
if (!fMultipleSteps) {
// Scattering limits the step.
*selection = CandidateForSelection;
}
gPathLength = interactionLength;
}
if (!firstStep) {
// Move the navigator to where the previous step ended.
fLinearNavigator->LocateGlobalPointWithinVolume(fTransportEndPosition);
}
G4GPILSelection transportSelection;
G4double geometryStepLength = G4Transportation::AlongStepGetPhysicalInteractionLength(
*currentTrackPtr, previousStepSize, gPathLength, currentSafety, &transportSelection);
if (geometryStepLength < gPathLength) {
// Transportation limits the step, ie the track hit a boundary.
*selection = CandidateForSelection;
ssLimitsStep = false;
continueStepping = false;
}
if (fTransportEndKineticEnergy != currentEnergy) {
// Field propagation changed the energy, it's not possible to
// estimate the continuous energy loss and continue stepping.
continueStepping = false;
}
if (firstStep) {
proposedSafety = currentSafety;
}
totalStepLength += geometryStepLength;
if (*selection != CandidateForSelection && !ssLimitsStep) {
// If neither scattering nor transportation limits the step, we
// got the distance we want - make sure we exit the loop.
continueStepping = false;
}
else {
stepLimitLeft -= geometryStepLength;
}
// Update the kinetic energy according to the continuous loss.
G4double energyAfterLinearLoss =
fTransportEndKineticEnergy - geometryStepLength * dedx;
if (ssLimitsStep) {
fSubStepDynamicParticle->SetKineticEnergy(energyAfterLinearLoss);
// The call to SampleSecondaries() directly fills in the changed
// direction into fParticleChangeForSS, so we have to:
// 1) Set the momentum direction in dynamic particle.
fSubStepDynamicParticle->SetMomentumDirection(fTransportEndMomentumDir);
// 2) Call SampleSecondaries(), which changes the direction.
currentModel->SampleSecondaries(fSecondariesSS, couple, fSubStepDynamicParticle,
(*fCuts)[coupleIndex]);
// 3) Get the changed direction.
fTransportEndMomentumDir = fParticleChangeForSS->GetProposedMomentumDirection();
// Check that the model neither created secondaries nor proposed
// a local energy deposit because this process does not know how
// to handle these cases.
if (fSecondariesSS->size() > 0) {
G4Exception("G4TransportationWithMsc::AlongStepGPIL", "em0053", FatalException,
"scattering model created secondaries");
}
if (fParticleChangeForSS->GetLocalEnergyDeposit() > 0) {
G4Exception("G4TransportationWithMsc::AlongStepGPIL", "em0053", FatalException,
"scattering model proposed energy deposit");
}
}
if (continueStepping) {
// Update safety according to the geometry distance.
if (currentSafety < fEndPointDistance) {
currentSafety = 0;
}
else {
currentSafety -= fEndPointDistance;
}
// Update the energy taking continuous loss into account.
currentEnergy = energyAfterLinearLoss;
// From now on, use the track that we can update below.
currentTrackPtr = fSubStepTrack;
fSubStepDynamicParticle->SetKineticEnergy(currentEnergy);
fSubStepDynamicParticle->SetMomentumDirection(fTransportEndMomentumDir);
fSubStepTrack->SetPosition(fTransportEndPosition);
G4StepPoint& subPreStepPoint = *fSubStep->GetPreStepPoint();
subPreStepPoint.SetMaterialCutsCouple(couple);
subPreStepPoint.SetPosition(fTransportEndPosition);
subPreStepPoint.SetSafety(currentSafety);
subPreStepPoint.SetStepStatus(fAlongStepDoItProc);
}
firstStep = false;
} while (continueStepping);
// Note: currentEnergy is only updated if continueStepping is true.
// In case field propagation changed the energy, this flag is
// immediately set to false and currentEnergy is still equal to the
// initial kinetic energy stored in ekin.
if (currentEnergy != ekin) {
// If field propagation didn't change the energy and we potentially
// did multiple steps, reset the energy that G4Transportation will
// propose to not subtract the energy loss twice.
fTransportEndKineticEnergy = ekin;
}
fParticleChange.ProposeTrueStepLength(totalStepLength);
// Inform G4Transportation that the momentum might have changed due
// to scattering, even if there is no field.
fMomentumChanged = true;
return totalStepLength;
}
}
break;
}
}
@@ -97,10 +97,6 @@ G4VEmModel::~G4VEmModel()
delete xSectionTable;
xSectionTable = nullptr;
}
if(isMaster && fElementData != nullptr) {
delete fElementData;
fElementData = nullptr;
}
fEmManager->DeRegister(this);
}
@@ -141,6 +137,7 @@ void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* part,
{
if(highLimit <= lowLimit) { return; }
G4EmUtility::InitialiseElementSelectors(this,part,cuts,lowLimit,highLimit);
localElmSelectors = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -409,16 +406,17 @@ void G4VEmModel::SetCrossSectionTable(G4PhysicsTable* p, G4bool isLocal)
localTable = isLocal;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4VEmModel::LPMFlag() const
{
return G4EmParameters::Instance()->LPM();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmModel::SetLPMFlag(G4bool val)
void G4VEmModel::SetLPMFlag(G4bool)
{
G4EmParameters::Instance()->SetLPM(val);
if (G4EmParameters::Instance()->Verbose() > 0) {
G4ExceptionDescription ed;
ed << "The obsolete method SetLPMFlag(..) of the model class " << GetName()
<< " is called. Please, use G4EmParameters::Instance()->SetLPM(..)"
<< " instead";
G4Exception("G4VEmModel::SetLPMFlag", "em0001", JustWarning, ed);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......