Import Geant4 11.2.0 source tree
This commit is contained in:
@@ -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(<bMutex);
|
||||
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(<bMutex);
|
||||
#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 = ∂
|
||||
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......
|
||||
|
||||
Reference in New Issue
Block a user