Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -17,6 +17,72 @@ committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
|
||||
06 November 19: V.Ivanchenko (emstand-V10-05-26)
|
||||
- G4ESTARStopping, G4GSMottCorrection, G4GSPWACorrections,
|
||||
G4GoudsmitSaundersonTable, G4SBBremTable, G4SeltzerBergerModel
|
||||
minor cleanup: getenv -> std::getenv, use G4Element::GetZasInt()
|
||||
|
||||
05 November 19: V.Ivanchenko (emstand-V10-05-25)
|
||||
- G4UrbanMscModel - fixed problem introduced in emstand-V10-05-22
|
||||
which affect Opt3 EM physics
|
||||
|
||||
31 October 19: V.Ivanchenko (emstand-V10-05-24)
|
||||
- G4SeltzerBergerModel, G4ICRU49NuclearStoppingModel - cosmetic
|
||||
modifications - more safe initialisation in the MT mode
|
||||
|
||||
24 October 19: I.Semeniouk (emstand-V10-05-23)
|
||||
- G4BetheHeitler5DModel - new parameters set for muon (30% speed up),
|
||||
nuclear threshold calculation.
|
||||
|
||||
23 October 19: V.Ivanchenko (emstand-V10-05-22)
|
||||
- G4UrbanMscModel - (L.Urban) minor cleanup, should not affect results
|
||||
|
||||
18 October 19: I.Semeniouk (emstand-V10-05-21)
|
||||
- G4BetheHeitler5DModel Add gamma conversion to mu+ mu- mode
|
||||
|
||||
16 October 19: D.Sawkey (emstand-V10-05-20)
|
||||
- G4eplusAnnihilation: set secondary weight correctly using bias manager.
|
||||
|
||||
1 October 19: V.Ivanchenko (emstand-V10-05-19)
|
||||
- G4UrbanMscModel, G4GoudsmitSaundersonMscModel, G4WentzelVIModel -
|
||||
use lambdalimit and facsafety from the base class G4VMscModel
|
||||
|
||||
2 September 19: M.Novak (emstand-V10-05-18)
|
||||
- G4PairProductionRelModel, G4GammaConversion - The high energy model for e-/e+
|
||||
pair production has been extended down to threshold (2mc^2) such that it
|
||||
gives results (both x-section and final state) identical to those produced
|
||||
by the low energy (G4BetheHeitlerModel). Since this new version of the
|
||||
high energy model can describe e-/e+ pair production from threshold up to
|
||||
PeV (LPM effects are included) the G4BetheHeitlerModel was removed from the
|
||||
G4GammaConversion process.
|
||||
|
||||
29 August 19: V.Ivanchenko (emstand-V10-05-17)
|
||||
- G4UrbanMscModel - L.Urban modified step limit parameters:
|
||||
lambdalimit to 0.5 mm; facsafety to 0.67.
|
||||
|
||||
24 August 19: V.Ivanchenko (emstand-V10-05-16)
|
||||
- G4UrbanMscModel - L.Urban modified step limit parameters:
|
||||
lambdalimit from 1 mm to 0.4 mm; facsafety from 0.6 to 0.7.
|
||||
- G4WentzelOKadriVIxSection, G4WentzelVIModel - return previous
|
||||
parameterisation of screening parameter
|
||||
|
||||
14 August 19: V.Ivanchenko (emstand-V10-05-15)
|
||||
- G4hCoulombScatteringModel, G4hCoulombScatteringModel - removed
|
||||
unused headers
|
||||
|
||||
25 July 19: V.Ivanchenko (emstand-V10-05-14)
|
||||
- G4SeltzerBergerModel - during initialisation data files uploaded
|
||||
only data for elements used in geometry, lazy initialisation
|
||||
of the data is also available (may be used in unit tests)
|
||||
|
||||
20 July 19: V.Ivanchenko (emstand-V10-05-13)
|
||||
- G4WentzelOKandVIxSection - modified parameterisation of screening
|
||||
parameter for e+-, which affect backscattering at low energies
|
||||
making results closer to data
|
||||
- G4ScreeningMottCrossSection, G4eSingleCoulombScatteringModel
|
||||
optimized code and data structure; fixed floating point exception
|
||||
for low energy; use C++11 patterns
|
||||
|
||||
28 May 19: V.Ivanchenko (emstand-V10-05-12)
|
||||
- G4UrbanMscModel - L.Urban modified lateral displacement sampling
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
// version (Denis Bernard)
|
||||
// 04-06-18 Performance optimization of the final state sampling (M. Novak)
|
||||
// 10-04-19 CLHEP for boost and rotation, remove local functions (IgS)
|
||||
// 02-09-19 Set base class to be G4PairProductionRelModel that can provide
|
||||
// accurate sections now from threshold to very high energies
|
||||
// including the LPM effect. (M. Novak)
|
||||
// 14-10-19 Muon's pair genaration in SampleSecondaries
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -53,11 +57,11 @@
|
||||
#ifndef G4BetheHeitler5DModel_h
|
||||
#define G4BetheHeitler5DModel_h 1
|
||||
|
||||
#include "G4BetheHeitlerModel.hh"
|
||||
#include "G4PairProductionRelModel.hh"
|
||||
|
||||
class G4IonTable;
|
||||
|
||||
class G4BetheHeitler5DModel : public G4BetheHeitlerModel
|
||||
class G4BetheHeitler5DModel : public G4PairProductionRelModel
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -77,6 +81,10 @@ public:
|
||||
|
||||
inline void SetVerbose(G4int val) { fVerbose = val; }
|
||||
|
||||
// Only e+, e+ or mu+, mu- pairs supported
|
||||
void SetLeptonPair(const G4ParticleDefinition* p1,
|
||||
const G4ParticleDefinition* p2);
|
||||
|
||||
private:
|
||||
|
||||
// hide assignment operator
|
||||
@@ -86,10 +94,20 @@ private:
|
||||
G4double MaxDiffCrossSection(const G4double* par, G4double eZ,
|
||||
G4double e, G4double loge) const;
|
||||
|
||||
inline void SetConversionMode(G4int to) { fConvMode = to; }
|
||||
|
||||
G4IonTable* theIonTable;
|
||||
|
||||
G4int fVerbose;
|
||||
G4int fConversionType;
|
||||
G4bool iraw;
|
||||
|
||||
const G4ParticleDefinition* fLepton1;
|
||||
const G4ParticleDefinition* fLepton2;
|
||||
|
||||
G4int fConvMode;
|
||||
const G4ParticleDefinition* fTheMuPlus;
|
||||
const G4ParticleDefinition* fTheMuMinus;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -201,7 +201,6 @@ private:
|
||||
G4double rangeinit;
|
||||
G4double geombig;
|
||||
G4double geomlimit;
|
||||
G4double lambdalimit;
|
||||
G4double tlimit;
|
||||
G4double tgeom;
|
||||
//
|
||||
|
||||
@@ -108,6 +108,7 @@ protected:
|
||||
inline G4double ScreenFunction2(const G4double delta);
|
||||
inline void ScreenFunction12(const G4double delta, G4double &f1, G4double &f2);
|
||||
// helper methods for cross-section computation under different approximations
|
||||
G4double ComputeParametrizedXSectionPerAtom(G4double gammaEnergy, G4double Z);
|
||||
G4double ComputeXSectionPerAtom(G4double gammaEnergy, G4double Z);
|
||||
G4double ComputeDXSectionPerAtom(G4double eplusEnergy, G4double gammaEnergy,
|
||||
G4double Z);
|
||||
@@ -124,7 +125,8 @@ private:
|
||||
G4double fCoulomb;
|
||||
G4double fLradEl;
|
||||
G4double fDeltaFactor;
|
||||
G4double fDeltaMax;
|
||||
G4double fDeltaMaxLow;
|
||||
G4double fDeltaMaxHigh;
|
||||
G4double fEtaValue;
|
||||
G4double fLPMVarS1Cond;
|
||||
G4double fLPMILVarS1Cond;
|
||||
@@ -176,6 +178,9 @@ protected:
|
||||
//
|
||||
G4double fLPMEnergy;
|
||||
//
|
||||
G4double fParametrizedXSectionThreshold;
|
||||
G4double fCoulombCorrectionThreshold;
|
||||
//
|
||||
G4Pow* fG4Calc;
|
||||
G4ParticleDefinition* fTheGamma;
|
||||
G4ParticleDefinition* fTheElectron;
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
// 3) Nuclear Form Factor:
|
||||
// A.V. Butkevich et al. Nucl. Instr. Meth. A488 (2002), 282-294.
|
||||
//
|
||||
// ------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
#ifndef G4ScreeningMottCrossSection_h
|
||||
@@ -67,13 +67,12 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include <vector>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
static const G4int DIM = 750;
|
||||
static const G4int DIMMOTT = 750;
|
||||
|
||||
class G4NistManager;
|
||||
class G4Pow;
|
||||
@@ -85,35 +84,29 @@ public:
|
||||
|
||||
explicit G4ScreeningMottCrossSection();
|
||||
|
||||
virtual ~G4ScreeningMottCrossSection();
|
||||
~G4ScreeningMottCrossSection();
|
||||
|
||||
void Initialise(const G4ParticleDefinition*, G4double cosThetaLim);
|
||||
|
||||
inline void SetupParticle(const G4ParticleDefinition*);
|
||||
void SetupKinematic(G4double kinEnergy, G4int Z);
|
||||
|
||||
G4double NuclearCrossSection(G4int, G4int);
|
||||
G4ThreeVector GetNewDirection();
|
||||
G4double NuclearCrossSection(G4int form, G4int fast);
|
||||
G4double GetScatteringAngle(G4int form, G4int fast);
|
||||
|
||||
inline G4double GetMom2CM()const;
|
||||
inline G4double GetMom2Lab()const;
|
||||
inline G4double GetTrec() const;
|
||||
inline G4double GetScreeningCoefficient() const;
|
||||
inline G4double GetTotalCross() const;
|
||||
G4double RatioMottRutherford(G4double tet);
|
||||
G4double RatioMottRutherfordCosT(G4double sin2t2);
|
||||
|
||||
G4double McFcorrection(G4double);
|
||||
G4double RatioMottRutherford(G4double);
|
||||
G4double RatioMottRutherfordCosT(G4double);
|
||||
G4double FormFactor2ExpHof(G4double);
|
||||
G4double FormFactor2Gauss(G4double);
|
||||
G4double FormFactor2UniformHelm(G4double);
|
||||
G4double GetScatteringAngle(G4int, G4int);
|
||||
G4double SetDifferentialXSection(G4double, G4double, G4int);
|
||||
G4double McFcorrection(G4double sin2t2);
|
||||
inline void SetupParticle(const G4ParticleDefinition*);
|
||||
|
||||
private:
|
||||
|
||||
inline G4double GetScreeningAngle();
|
||||
void SetScreeningCoefficient();
|
||||
G4double ComputeAngle(G4int idx, G4double& rand);
|
||||
|
||||
G4double FormFactor2ExpHof(G4double sin2t2);
|
||||
G4double FormFactor2Gauss(G4double sin2t2);
|
||||
G4double FormFactor2UniformHelm(G4double sin2t2);
|
||||
G4double DifferentialXSection(G4int idx, G4int form);
|
||||
|
||||
G4double GetTransitionRandom();
|
||||
|
||||
@@ -124,6 +117,8 @@ private:
|
||||
G4NistManager* fNistManager;
|
||||
G4Pow* fG4pow;
|
||||
|
||||
const G4ParticleDefinition* particle;
|
||||
|
||||
G4double fTotalCross;
|
||||
//cost - min - max
|
||||
G4double cosThetaMin;// def 1.0
|
||||
@@ -136,9 +131,6 @@ private:
|
||||
G4double ecut;
|
||||
G4double etag;
|
||||
|
||||
// projectile........................
|
||||
const G4ParticleDefinition* particle;
|
||||
|
||||
G4double spin;
|
||||
G4double mass;
|
||||
|
||||
@@ -155,20 +147,19 @@ private:
|
||||
G4double beta;
|
||||
G4double gamma;
|
||||
|
||||
// target nucleus
|
||||
G4int targetZ;
|
||||
G4int targetA;
|
||||
G4double targetMass;
|
||||
G4double Trec;
|
||||
G4double As;
|
||||
|
||||
//constants
|
||||
G4double alpha;
|
||||
G4double htc2;
|
||||
G4double e2;
|
||||
|
||||
//angle
|
||||
G4double cross[DIM];
|
||||
// target nucleus
|
||||
G4double targetMass;
|
||||
G4double As;
|
||||
G4int targetZ;
|
||||
G4int targetA;
|
||||
|
||||
// working array
|
||||
std::vector<G4double> cross;
|
||||
};
|
||||
|
||||
|
||||
@@ -183,49 +174,6 @@ void G4ScreeningMottCrossSection::SetupParticle(const G4ParticleDefinition* p)
|
||||
if(0.0 != spin) { spin = 0.5; }
|
||||
tkin = 0.0;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4double G4ScreeningMottCrossSection::GetMom2CM() const
|
||||
{
|
||||
return mom2;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
inline G4double G4ScreeningMottCrossSection::GetMom2Lab() const
|
||||
{
|
||||
return momLab2;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4double G4ScreeningMottCrossSection::GetTrec() const
|
||||
{
|
||||
return Trec;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4double G4ScreeningMottCrossSection::GetScreeningCoefficient() const
|
||||
{
|
||||
return As;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4double G4ScreeningMottCrossSection::GetTotalCross() const
|
||||
{
|
||||
return fTotalCross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4double G4ScreeningMottCrossSection::GetScreeningAngle()
|
||||
{
|
||||
G4double screenangle=2.*std::asin(std::sqrt(As));
|
||||
return std::min(screenangle, CLHEP::pi);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -38,11 +38,12 @@
|
||||
// Modifications:
|
||||
//
|
||||
// 24.07.2018 Introduced possibility to use sampling tables to sample the
|
||||
// emitted photon energy (instead of using rejectio) from the Seltzer-
|
||||
// Berger scalled DCS for bremsstrahlung photon emission. Using these
|
||||
// sampling tables option gives faster(30-70%) final state generation
|
||||
// than the original rejection but takes some extra memory (+ ~6MB in
|
||||
// the case of the full CMS detector). (M Novak)
|
||||
// emitted photon energy (instead of using rejectio) from the
|
||||
// Seltzer-Berger scalled DCS for bremsstrahlung photon emission.
|
||||
// Using these sampling tables option gives faster(30-70%) final
|
||||
// state generation than the original rejection but takes some
|
||||
// extra memory (+ ~6MB in the case of the full CMS detector).
|
||||
// (M Novak)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -60,6 +61,7 @@
|
||||
|
||||
#include "G4eBremsstrahlungRelModel.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Threading.hh"
|
||||
|
||||
class G4Physics2DVector;
|
||||
class G4SBBremTable;
|
||||
@@ -72,34 +74,34 @@ public:
|
||||
explicit G4SeltzerBergerModel(const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "eBremSB");
|
||||
|
||||
virtual ~G4SeltzerBergerModel();
|
||||
~G4SeltzerBergerModel() override;
|
||||
|
||||
virtual void Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&) override;
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
|
||||
|
||||
virtual void InitialiseForElement(const G4ParticleDefinition*,
|
||||
G4int Z) override;
|
||||
void InitialiseForElement(const G4ParticleDefinition*, G4int Z) override;
|
||||
|
||||
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy) override;
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy) override;
|
||||
|
||||
virtual void SetupForMaterial(const G4ParticleDefinition*,
|
||||
const G4Material*,G4double) override;
|
||||
void SetupForMaterial(const G4ParticleDefinition*,
|
||||
const G4Material*, G4double) override;
|
||||
|
||||
inline void SetBicubicInterpolationFlag(G4bool val) { fIsUseBicubicInterpolation = val; }
|
||||
inline void SetBicubicInterpolationFlag(G4bool val)
|
||||
{ fIsUseBicubicInterpolation = val; };
|
||||
|
||||
protected:
|
||||
|
||||
virtual G4double ComputeDXSectionPerAtom(G4double gammaEnergy) override;
|
||||
|
||||
virtual G4String DirectoryPath() const;
|
||||
G4double ComputeDXSectionPerAtom(G4double gammaEnergy) override;
|
||||
|
||||
private:
|
||||
|
||||
void ReadData(G4int izet, const char* path = nullptr);
|
||||
//
|
||||
void ReadData(G4int Z);
|
||||
|
||||
const G4String& FindDirectoryPath();
|
||||
|
||||
G4double SampleEnergyTransfer(const G4double kineticEnergy,
|
||||
const G4double logKineticEnergy,
|
||||
@@ -107,16 +109,15 @@ private:
|
||||
const G4double emax);
|
||||
|
||||
// hide assignment operator and cctr
|
||||
G4SeltzerBergerModel & operator=(const G4SeltzerBergerModel &right) = delete;
|
||||
G4SeltzerBergerModel(const G4SeltzerBergerModel&) = delete;
|
||||
|
||||
private:
|
||||
G4SeltzerBergerModel & operator=(const G4SeltzerBergerModel &right);
|
||||
G4SeltzerBergerModel(const G4SeltzerBergerModel&);
|
||||
|
||||
static constexpr G4int gMaxZet = 101;
|
||||
static constexpr G4double gExpNumLimit = -12.;
|
||||
static G4double gYLimitData[gMaxZet];
|
||||
static G4Physics2DVector* gSBDCSData[gMaxZet];
|
||||
static G4SBBremTable* gSBSamplingTable;
|
||||
static G4String gDataDirectory;
|
||||
|
||||
G4bool fIsUseBicubicInterpolation;
|
||||
G4bool fIsUseSamplingTables;
|
||||
@@ -125,6 +126,11 @@ private:
|
||||
|
||||
size_t fIndx;
|
||||
size_t fIndy;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
static G4Mutex theSBMutex;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -74,14 +74,14 @@ public:
|
||||
|
||||
explicit G4UrbanMscModel(const G4String& nam = "UrbanMsc");
|
||||
|
||||
virtual ~G4UrbanMscModel();
|
||||
~G4UrbanMscModel() override;
|
||||
|
||||
virtual void Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&) override;
|
||||
void Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&) override;
|
||||
|
||||
virtual void StartTracking(G4Track*) override;
|
||||
void StartTracking(G4Track*) override;
|
||||
|
||||
virtual G4double
|
||||
G4double
|
||||
ComputeCrossSectionPerAtom(const G4ParticleDefinition* particle,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,
|
||||
@@ -89,16 +89,15 @@ public:
|
||||
G4double cut =0.,
|
||||
G4double emax=DBL_MAX) override;
|
||||
|
||||
virtual G4ThreeVector& SampleScattering(const G4ThreeVector&,
|
||||
G4double safety) override;
|
||||
G4ThreeVector& SampleScattering(const G4ThreeVector&,
|
||||
G4double safety) override;
|
||||
|
||||
virtual G4double
|
||||
ComputeTruePathLengthLimit(const G4Track& track,
|
||||
G4double& currentMinimalStep) override;
|
||||
G4double ComputeTruePathLengthLimit(const G4Track& track,
|
||||
G4double& currentMinimalStep) override;
|
||||
|
||||
virtual G4double ComputeGeomPathLength(G4double truePathLength) override;
|
||||
G4double ComputeGeomPathLength(G4double truePathLength) override;
|
||||
|
||||
virtual G4double ComputeTrueStepLength(G4double geomStepLength) override;
|
||||
G4double ComputeTrueStepLength(G4double geomStepLength) override;
|
||||
|
||||
G4double ComputeTheta0(G4double truePathLength, G4double KineticEnergy);
|
||||
|
||||
@@ -133,7 +132,7 @@ private:
|
||||
|
||||
G4double mass;
|
||||
G4double charge,ChargeSquare;
|
||||
G4double masslimite,lambdalimit,fr;
|
||||
G4double masslimite,fr;
|
||||
|
||||
G4double taubig;
|
||||
G4double tausmall;
|
||||
@@ -177,7 +176,7 @@ private:
|
||||
G4bool firstStep;
|
||||
G4bool insideskin;
|
||||
|
||||
G4bool latDisplasmentbackup ;
|
||||
G4bool latDisplasmentbackup;
|
||||
G4bool dispAlg96;
|
||||
|
||||
G4double rangecut;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
// (ANR-13-BS05-0002).
|
||||
//
|
||||
// Reference: Nucl. Instrum. Meth. A 899 (2018) 85 (arXiv:1802.08253 [hep-ph])
|
||||
// Nucl. Instrum. Meth., A 936 (2019) 290
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -104,6 +105,8 @@
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4MuonPlus.hh"
|
||||
#include "G4MuonMinus.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
|
||||
@@ -117,15 +120,31 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4RotationMatrix.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// // Q : Use enum G4EmProcessSubType hire ?
|
||||
// enum G45DConversionMode
|
||||
// {
|
||||
// kEPair, kMuPair
|
||||
// };
|
||||
|
||||
const G4int kEPair = 0;
|
||||
const G4int kMuPair = 1;
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BetheHeitler5DModel::G4BetheHeitler5DModel(const G4ParticleDefinition* pd,
|
||||
const G4String& nam)
|
||||
: G4BetheHeitlerModel(pd, nam), fVerbose(1), fConversionType(0), iraw(false)
|
||||
: G4PairProductionRelModel(pd, nam),fVerbose(1),fConversionType(0),
|
||||
iraw(false),
|
||||
fLepton1(G4Electron::Definition()),fLepton2(G4Positron::Definition()),
|
||||
fConvMode(kEPair),
|
||||
fTheMuPlus(G4MuonPlus::Definition()),fTheMuMinus(G4MuonMinus::Definition())
|
||||
{
|
||||
SetLowEnergyLimit(2*CLHEP::electron_mass_c2);
|
||||
theIonTable = G4IonTable::GetIonTable();
|
||||
//Q: Do we need this on Model
|
||||
SetLowEnergyLimit(2*fTheElectron->GetPDGMass());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -138,7 +157,7 @@ G4BetheHeitler5DModel::~G4BetheHeitler5DModel()
|
||||
void G4BetheHeitler5DModel::Initialise(const G4ParticleDefinition* part,
|
||||
const G4DataVector& vec)
|
||||
{
|
||||
G4BetheHeitlerModel::Initialise(part, vec);
|
||||
G4PairProductionRelModel::Initialise(part, vec);
|
||||
|
||||
G4EmParameters* theManager = G4EmParameters::Instance();
|
||||
// place to initialise model parameters
|
||||
@@ -156,6 +175,90 @@ void G4BetheHeitler5DModel::Initialise(const G4ParticleDefinition* part,
|
||||
iraw = theManager->OnIsolated();
|
||||
// G4cout << "BH5DModel::Initialise verbose " << fVerbose
|
||||
// << " isolated " << iraw << " ctype "<< fConversionType << G4endl;
|
||||
|
||||
//Q: Do we need this on Model
|
||||
// The Leptons defined via SetLeptonPair(..) method
|
||||
SetLowEnergyLimit(2*CLHEP::electron_mass_c2);
|
||||
|
||||
if (fConvMode == kEPair) {
|
||||
assert(fLepton1->GetPDGEncoding() == fTheElectron->GetPDGEncoding()) ;
|
||||
if (fVerbose > 3)
|
||||
G4cout << "BH5DModel::Initialise conversion to e+ e-" << G4endl;
|
||||
}
|
||||
|
||||
if (fConvMode == kMuPair) {
|
||||
assert(fLepton1->GetPDGEncoding() == fTheMuMinus->GetPDGEncoding()) ;
|
||||
if (fVerbose > 3)
|
||||
G4cout << "BH5DModel::Initialise conversion to mu+ mu-" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BetheHeitler5DModel::SetLeptonPair(const G4ParticleDefinition* p1,
|
||||
const G4ParticleDefinition* p2)
|
||||
{
|
||||
// Lepton1 - nagative charged particle
|
||||
if ( p1->GetPDGEncoding() < 0 ){
|
||||
if ( p1->GetPDGEncoding() ==
|
||||
G4Positron::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kEPair);
|
||||
fLepton1 = p2;
|
||||
fLepton2 = p1;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to e+ e-"
|
||||
<< G4endl;
|
||||
} else if ( p1->GetPDGEncoding() ==
|
||||
G4MuonPlus::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kMuPair);
|
||||
fLepton1 = p2;
|
||||
fLepton2 = p1;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to mu+ mu-"
|
||||
<< G4endl;
|
||||
} else {
|
||||
// Exception
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Model not applicable to particle(s) "
|
||||
<< p1->GetParticleName() << ", "
|
||||
<< p2->GetParticleName();
|
||||
G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0002",
|
||||
FatalException, ed);
|
||||
}
|
||||
} else {
|
||||
if ( p1->GetPDGEncoding() ==
|
||||
G4Electron::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kEPair);
|
||||
fLepton1 = p1;
|
||||
fLepton2 = p2;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to e+ e-"
|
||||
<< G4endl;
|
||||
} else if ( p1->GetPDGEncoding() ==
|
||||
G4MuonMinus::Definition()->GetPDGEncoding() ) {
|
||||
SetConversionMode(kMuPair);
|
||||
fLepton1 = p1;
|
||||
fLepton2 = p2;
|
||||
// if (fVerbose)
|
||||
G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to mu+ mu-"
|
||||
<< G4endl;
|
||||
} else {
|
||||
// Exception
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Model not applicable to particle(s) "
|
||||
<< p1->GetParticleName() << ", "
|
||||
<< p2->GetParticleName();
|
||||
G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0002",
|
||||
FatalException, ed);
|
||||
}
|
||||
}
|
||||
if ( fLepton1->GetPDGEncoding() != fLepton2->GetAntiPDGEncoding() ) {
|
||||
G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0007",
|
||||
FatalErrorInArgument, "pair must be particle, antiparticle ");
|
||||
G4cerr << "BH5DModel::SetLeptonPair BAD paricle/anti particle pair"
|
||||
<< fLepton1->GetParticleName() << ", "
|
||||
<< fLepton2->GetParticleName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -181,9 +284,12 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
{
|
||||
// MeV
|
||||
static const G4double ElectronMass = CLHEP::electron_mass_c2;
|
||||
static const G4double ElectronMass2 = ElectronMass*ElectronMass;
|
||||
|
||||
const G4double LeptonMass = fLepton1->GetPDGMass();
|
||||
const G4double LeptonMass2 = LeptonMass*LeptonMass;
|
||||
|
||||
static const G4double alpha0 = CLHEP::fine_structure_const;
|
||||
// mm
|
||||
// mm
|
||||
static const G4double r0 = CLHEP::classic_electr_radius;
|
||||
// mbarn
|
||||
static const G4double r02 = r0*r0*1.e+25;
|
||||
@@ -192,25 +298,45 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
// static const G4double factor1 = pow((6.0 * pi),(1.0/3.0))/(8.*alpha0*ElectronMass);
|
||||
static const G4double factor1 = 2.66134007899/(8.*alpha0*ElectronMass);
|
||||
//
|
||||
static const G4double PairInvMassMin = 2.*ElectronMass;
|
||||
G4double PairInvMassMin = 2.*LeptonMass;
|
||||
G4double TrThreshold = 2.0 * ( (LeptonMass2)/ElectronMass + LeptonMass);
|
||||
|
||||
//
|
||||
static const G4double nu[10] = { 0.0227436, 0.0582046, 3.0322675, 2.8275065,
|
||||
-0.0034004, 1.1212766, 1.8989468, 68.3492750,
|
||||
0.0211186, 14.4 };
|
||||
static const G4double tr[10] = { 0.0332350, 4.3942537, 2.8515925, 2.6351695,
|
||||
-0.0031510, 1.5737305, 1.8104647, 20.6434021,
|
||||
-0.0272586, 28.9};
|
||||
static const G4double nu[2][10] = {
|
||||
//electron
|
||||
{ 0.0227436, 0.0582046, 3.0322675, 2.8275065, -0.0034004,
|
||||
1.1212766, 1.8989468, 68.3492750, 0.0211186, 14.4},
|
||||
//muon
|
||||
{0.67810E-06, 0.86037E+05, 2.0008395, 1.6739719, -0.0057279,
|
||||
1.4222, 0.0, 263230.0, 0.0521, 51.1338}
|
||||
};
|
||||
static const G4double tr[2][10] = {
|
||||
//electron
|
||||
{ 0.0332350, 4.3942537, 2.8515925, 2.6351695, -0.0031510,
|
||||
1.5737305, 1.8104647, 20.6434021, -0.0272586, 28.9},
|
||||
//muon
|
||||
{0.10382E-03, 0.14408E+17, 4.1368679, 3.2662121, -0.0163091,
|
||||
0.0000, 0.0, 0.0, 0.0000, 1.0000}
|
||||
};
|
||||
//
|
||||
static const G4double para[3][2] = { {11., -16.},{-1.17, -2.95},{-2., -0.5} };
|
||||
static const G4double para[2][3][2] = {
|
||||
//electron
|
||||
{ {11., -16.},{-1.17, -2.95},{-2., -0.5} },
|
||||
//muon
|
||||
{ {17.5, 1.},{-1.17, -2.95},{2., 6.} }
|
||||
};
|
||||
//
|
||||
static const G4double correctionIndex = 1.4;
|
||||
//
|
||||
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
// Protection, Will not be true tot cross section = 0
|
||||
if ( GammaEnergy <= PairInvMassMin) { return; }
|
||||
|
||||
const G4double GammaEnergy2 = GammaEnergy*GammaEnergy;
|
||||
// Will not be true tot cross section = 0
|
||||
if ( GammaEnergy <= 2.0*ElectronMass) { return; }
|
||||
//
|
||||
const G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
const G4ParticleMomentum GammaDirection =
|
||||
aDynamicGamma->GetMomentumDirection();
|
||||
G4ThreeVector GammaPolarization = aDynamicGamma->GetPolarization();
|
||||
|
||||
// The protection polarization perpendicular to the direction vector,
|
||||
@@ -223,6 +349,7 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
// End of Protection
|
||||
//
|
||||
const G4double GammaPolarizationMag = GammaPolarization.mag();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// target element
|
||||
// select randomly one element constituting the material
|
||||
@@ -234,6 +361,10 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4double iZ13 = 1./anElement->GetIonisation()->GetZ3();
|
||||
const G4double targetMass = G4NucleiProperties::GetNuclearMass(A, Z);
|
||||
|
||||
const G4double NuThreshold = 2.0 * ( (LeptonMass2)/targetMass + LeptonMass);
|
||||
// No conversion possible below nuclear threshold
|
||||
if ( GammaEnergy <= NuThreshold) { return; }
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
// itriplet : true -- triplet, false -- nuclear.
|
||||
@@ -242,8 +373,8 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
itriplet = false;
|
||||
} else if (fConversionType == 2) {
|
||||
itriplet = true;
|
||||
if ( GammaEnergy <= 4.0*ElectronMass ) return;
|
||||
} else if ( GammaEnergy > 4.0*ElectronMass ) {
|
||||
if ( GammaEnergy <= TrThreshold ) return;
|
||||
} else if ( GammaEnergy > TrThreshold ) {
|
||||
// choose triplet or nuclear from a triplet/nuclear=1/Z
|
||||
// total cross section ratio.
|
||||
// approximate at low energies !
|
||||
@@ -251,6 +382,7 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
itriplet = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
const G4double RecoilMass = itriplet ? ElectronMass : targetMass;
|
||||
const G4double RecoilMass2 = RecoilMass*RecoilMass;
|
||||
@@ -269,27 +401,33 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
|
||||
// maximum value of pdf
|
||||
const G4double EffectiveZ = iraw ? 0.5 : Z;
|
||||
const G4double Threshold = itriplet ? 4.*ElectronMass : 2.*ElectronMass;
|
||||
const G4double Threshold = itriplet ? TrThreshold : NuThreshold;
|
||||
const G4double AvailableEnergy = GammaEnergy - Threshold;
|
||||
const G4double LogAvailableEnergy = G4Log(AvailableEnergy);
|
||||
//
|
||||
const G4double MaxDiffCross = itriplet
|
||||
? MaxDiffCrossSection(tr, EffectiveZ, AvailableEnergy, LogAvailableEnergy)
|
||||
: MaxDiffCrossSection(nu, EffectiveZ, AvailableEnergy, LogAvailableEnergy);
|
||||
? MaxDiffCrossSection(tr[fConvMode],
|
||||
EffectiveZ, AvailableEnergy, LogAvailableEnergy)
|
||||
: MaxDiffCrossSection(nu[fConvMode],
|
||||
EffectiveZ, AvailableEnergy, LogAvailableEnergy);
|
||||
//
|
||||
// 50% safety marging factor
|
||||
const G4double ymax = 1.5 * MaxDiffCross;
|
||||
// x1 bounds
|
||||
const G4double xu1 = (LogAvailableEnergy > para[2][0])
|
||||
? para[0][0] + para[1][0]*LogAvailableEnergy
|
||||
: para[0][0] + para[2][0]*para[1][0];
|
||||
const G4double xl1 = (LogAvailableEnergy > para[2][1])
|
||||
? para[0][1] + para[1][1]*LogAvailableEnergy
|
||||
: para[0][1] + para[2][1]*para[1][1];
|
||||
const G4double xu1 = (LogAvailableEnergy > para[fConvMode][2][0])
|
||||
? para[fConvMode][0][0] +
|
||||
para[fConvMode][1][0]*LogAvailableEnergy
|
||||
: para[fConvMode][0][0] +
|
||||
para[fConvMode][2][0]*para[fConvMode][1][0];
|
||||
const G4double xl1 = (LogAvailableEnergy > para[fConvMode][2][1])
|
||||
? para[fConvMode][0][1] +
|
||||
para[fConvMode][1][1]*LogAvailableEnergy
|
||||
: para[fConvMode][0][1] +
|
||||
para[fConvMode][2][1]*para[fConvMode][1][1];
|
||||
//
|
||||
G4LorentzVector Recoil;
|
||||
G4LorentzVector Positron;
|
||||
G4LorentzVector Electron;
|
||||
G4LorentzVector LeptonPlus;
|
||||
G4LorentzVector LeptonMinus;
|
||||
G4double pdf = 0.;
|
||||
|
||||
G4double rndmv6[6];
|
||||
@@ -356,30 +494,25 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
thePRecoil*cosTheta,
|
||||
RecEnergyCMS);
|
||||
|
||||
// const G4LorentzVector Pair(-Recoil.x(),
|
||||
// -Recoil.y(),
|
||||
// -Recoil.z(),
|
||||
// sqrts-RecEnergyCMS);
|
||||
|
||||
// in the pair frame
|
||||
const G4double thePLepton = std::sqrt( (LeptonEnergy2-ElectronMass)
|
||||
*(LeptonEnergy2+ElectronMass));
|
||||
const G4double thePLepton = std::sqrt( (LeptonEnergy2-LeptonMass)
|
||||
*(LeptonEnergy2+LeptonMass));
|
||||
|
||||
Positron.set(thePLepton*sinThetaLept*cosPhiLept,
|
||||
LeptonPlus.set(thePLepton*sinThetaLept*cosPhiLept,
|
||||
thePLepton*sinThetaLept*sinPhiLept,
|
||||
thePLepton*cosThetaLept,
|
||||
LeptonEnergy2);
|
||||
|
||||
Electron.set(-Positron.x(),
|
||||
-Positron.y(),
|
||||
-Positron.z(),
|
||||
LeptonMinus.set(-LeptonPlus.x(),
|
||||
-LeptonPlus.y(),
|
||||
-LeptonPlus.z(),
|
||||
LeptonEnergy2);
|
||||
|
||||
|
||||
// Normalisation of final state phase space:
|
||||
// Section 47 of Particle Data Group, Chin. Phys. C, 40, 100001 (2016)
|
||||
// const G4double Norme = Recoil1.vect().mag() * Positron2.vect().mag();
|
||||
const G4double Norme = Recoil.vect().mag() * Positron.vect().mag();
|
||||
// const G4double Norme = Recoil1.vect().mag() * LeptonPlus2.vect().mag();
|
||||
const G4double Norme = Recoil.vect().mag() * LeptonPlus.vect().mag();
|
||||
|
||||
// e+, e- to CMS frame from pair frame
|
||||
|
||||
@@ -388,50 +521,50 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
G4LorentzVector( -Recoil.x(), -Recoil.y(), -Recoil.z(),
|
||||
sqrts-RecEnergyCMS).boostVector();
|
||||
|
||||
Positron.boost(pair2cms);
|
||||
Electron.boost(pair2cms);
|
||||
LeptonPlus.boost(pair2cms);
|
||||
LeptonMinus.boost(pair2cms);
|
||||
|
||||
// back to the laboratory frame (make use of the CMS(0,0,Eg,Eg+RM)) form
|
||||
|
||||
Recoil.boostZ(betaCMS);
|
||||
Positron.boostZ(betaCMS);
|
||||
Electron.boostZ(betaCMS);
|
||||
LeptonPlus.boostZ(betaCMS);
|
||||
LeptonMinus.boostZ(betaCMS);
|
||||
|
||||
// Jacobian factors
|
||||
const G4double Jacob0 = x0*dum0*dum0;
|
||||
const G4double Jacob1 = 2.*X1*lnPairInvMassRange*PairInvMass;
|
||||
const G4double Jacob2 = std::abs(sinThetaLept);
|
||||
|
||||
const G4double EPlus = Positron.t();
|
||||
const G4double PPlus = Positron.vect().mag();
|
||||
const G4double sinThetaPlus = Positron.vect().perp()/PPlus;
|
||||
const G4double cosThetaPlus = Positron.vect().cosTheta();
|
||||
const G4double EPlus = LeptonPlus.t();
|
||||
const G4double PPlus = LeptonPlus.vect().mag();
|
||||
const G4double sinThetaPlus = LeptonPlus.vect().perp()/PPlus;
|
||||
const G4double cosThetaPlus = LeptonPlus.vect().cosTheta();
|
||||
|
||||
const G4double pPX = Positron.x();
|
||||
const G4double pPY = Positron.y();
|
||||
const G4double pPX = LeptonPlus.x();
|
||||
const G4double pPY = LeptonPlus.y();
|
||||
const G4double dum1 = 1./std::sqrt( pPX*pPX + pPY*pPY );
|
||||
const G4double cosPhiPlus = pPX*dum1;
|
||||
const G4double sinPhiPlus = pPY*dum1;
|
||||
|
||||
// denominators:
|
||||
// the two cancelling leading terms for forward emission at high energy, removed
|
||||
const G4double elMassCTP = ElectronMass*cosThetaPlus;
|
||||
const G4double elMassCTP = LeptonMass*cosThetaPlus;
|
||||
const G4double ePlusSTP = EPlus*sinThetaPlus;
|
||||
const G4double DPlus = (elMassCTP*elMassCTP + ePlusSTP*ePlusSTP)
|
||||
/(EPlus + PPlus*cosThetaPlus);
|
||||
|
||||
const G4double EMinus = Electron.t();
|
||||
const G4double PMinus = Electron.vect().mag();
|
||||
const G4double sinThetaMinus = Electron.vect().perp()/PMinus;
|
||||
const G4double cosThetaMinus = Electron.vect().cosTheta();
|
||||
const G4double EMinus = LeptonMinus.t();
|
||||
const G4double PMinus = LeptonMinus.vect().mag();
|
||||
const G4double sinThetaMinus = LeptonMinus.vect().perp()/PMinus;
|
||||
const G4double cosThetaMinus = LeptonMinus.vect().cosTheta();
|
||||
|
||||
const G4double ePX = Electron.x();
|
||||
const G4double ePY = Electron.y();
|
||||
const G4double ePX = LeptonMinus.x();
|
||||
const G4double ePY = LeptonMinus.y();
|
||||
const G4double dum2 = 1./std::sqrt( ePX*ePX + ePY*ePY );
|
||||
const G4double cosPhiMinus = ePX*dum2;
|
||||
const G4double sinPhiMinus = ePY*dum2;
|
||||
|
||||
const G4double elMassCTM = ElectronMass*cosThetaMinus;
|
||||
const G4double elMassCTM = LeptonMass*cosThetaMinus;
|
||||
const G4double eMinSTM = EMinus*sinThetaMinus;
|
||||
const G4double DMinus = (elMassCTM*elMassCTM + eMinSTM*eMinSTM)
|
||||
/(EMinus + PMinus*cosThetaMinus);
|
||||
@@ -440,7 +573,8 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4double cosdPhi = cosPhiPlus*cosPhiMinus + sinPhiPlus*sinPhiMinus;
|
||||
const G4double PRec = Recoil.vect().mag();
|
||||
const G4double q2 = PRec*PRec;
|
||||
const G4double BigPhi = -ElectronMass2 / (GammaEnergy*GammaEnergy2 * q2*q2);
|
||||
|
||||
const G4double BigPhi = -LeptonMass2 / (GammaEnergy*GammaEnergy2 * q2*q2);
|
||||
|
||||
G4double FormFactor = 1.;
|
||||
if (!iraw) {
|
||||
@@ -523,24 +657,22 @@ G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
G4RotationMatrix GtoW(GammaPolarization,yGrec,GammaDirection);
|
||||
|
||||
Recoil.transform(GtoW);
|
||||
Positron.transform(GtoW);
|
||||
Electron.transform(GtoW);
|
||||
LeptonPlus.transform(GtoW);
|
||||
LeptonMinus.transform(GtoW);
|
||||
|
||||
if ( fVerbose > 2 ) {
|
||||
G4cout << "BetheHeitler5DModel Recoil " << Recoil.x() << " " << Recoil.y() << " " << Recoil.z()
|
||||
<< " " << Recoil.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel Positron " << Positron.x() << " " << Positron.y() << " "
|
||||
<< Positron.z() << " " << Positron.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel Electron " << Electron.x() << " " << Electron.y() << " "
|
||||
<< Electron.z() << " " << Electron.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel LeptonPlus " << LeptonPlus.x() << " " << LeptonPlus.y() << " "
|
||||
<< LeptonPlus.z() << " " << LeptonPlus.t() << " " << G4endl;
|
||||
G4cout << "BetheHeitler5DModel LeptonMinus " << LeptonMinus.x() << " " << LeptonMinus.y() << " "
|
||||
<< LeptonMinus.z() << " " << LeptonMinus.t() << " " << G4endl;
|
||||
}
|
||||
|
||||
// Create secondaries
|
||||
G4DynamicParticle* aParticle1 = new G4DynamicParticle(fLepton1,LeptonMinus);
|
||||
G4DynamicParticle* aParticle2 = new G4DynamicParticle(fLepton2,LeptonPlus);
|
||||
|
||||
// electron
|
||||
G4DynamicParticle* aParticle1 = new G4DynamicParticle(fTheElectron,Electron);
|
||||
// positron
|
||||
G4DynamicParticle* aParticle2 = new G4DynamicParticle(fThePositron,Positron);
|
||||
// create G4DynamicParticle object for the particle3 ( recoil )
|
||||
G4ParticleDefinition* RecoilPart;
|
||||
if (itriplet) {
|
||||
|
||||
@@ -105,7 +105,7 @@ G4double G4ESTARStopping::GetElectronicDEDX(G4int i, G4double energy)
|
||||
|
||||
void G4ESTARStopping::Initialise()
|
||||
{
|
||||
dirPath = getenv("G4LEDATA");
|
||||
dirPath = std::getenv("G4LEDATA");
|
||||
if(!dirPath) {
|
||||
G4Exception("G4ESTARStopping()","em0006",FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
|
||||
@@ -253,7 +253,7 @@ void G4GSMottCorrection::InitMCDataPerMaterials() {
|
||||
// it's called only if data has not been loaded for this element yet
|
||||
void G4GSMottCorrection::LoadMCDataElement(const G4Element *elem) {
|
||||
// allocate memory
|
||||
G4int izet = G4lrint(elem->GetZ());
|
||||
G4int izet = elem->GetZasInt();
|
||||
if (izet>gMaxZet) {
|
||||
izet = gMaxZet;
|
||||
}
|
||||
@@ -262,7 +262,7 @@ void G4GSMottCorrection::LoadMCDataElement(const G4Element *elem) {
|
||||
fMCDataPerElement[izet] = perElem;
|
||||
//
|
||||
// load data from file
|
||||
char* tmppath = getenv("G4LEDATA");
|
||||
char* tmppath = std::getenv("G4LEDATA");
|
||||
if (!tmppath) {
|
||||
G4Exception("G4GSMottCorrection::LoadMCDataElement()","em0006",
|
||||
FatalException,
|
||||
|
||||
@@ -175,12 +175,12 @@ void G4GSPWACorrections::InitDataPerMaterials() {
|
||||
// it's called only if data has not been loaded for this element yet
|
||||
void G4GSPWACorrections::LoadDataElement(const G4Element *elem) {
|
||||
// allocate memory
|
||||
G4int izet = G4lrint(elem->GetZ());
|
||||
G4int izet = elem->GetZasInt();
|
||||
if (izet>gMaxZet) {
|
||||
izet = gMaxZet;
|
||||
}
|
||||
// load data from file
|
||||
char* tmppath = getenv("G4LEDATA");
|
||||
char* tmppath = std::getenv("G4LEDATA");
|
||||
if (!tmppath) {
|
||||
G4Exception("G4GSPWACorrection::LoadDataElement()","em0006",
|
||||
FatalException,
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "G4GammaConversion.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4BetheHeitlerModel.hh"
|
||||
#include "G4PairProductionRelModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
@@ -80,18 +79,10 @@ void G4GammaConversion::InitialiseProcess(const G4ParticleDefinition*)
|
||||
|
||||
SetMinKinEnergy(emin);
|
||||
|
||||
if(!EmModel(0)) { SetEmModel(new G4BetheHeitlerModel()); }
|
||||
if(!EmModel(0)) { SetEmModel(new G4PairProductionRelModel()); }
|
||||
EmModel(0)->SetLowEnergyLimit(emin);
|
||||
G4double energyLimit = std::min(EmModel(0)->HighEnergyLimit(), 80*GeV);
|
||||
EmModel(0)->SetHighEnergyLimit(energyLimit);
|
||||
EmModel(0)->SetHighEnergyLimit(emax);
|
||||
AddEmModel(1, EmModel(0));
|
||||
|
||||
if(emax > energyLimit) {
|
||||
if(!EmModel(1)) { SetEmModel(new G4PairProductionRelModel()); }
|
||||
EmModel(1)->SetLowEnergyLimit(energyLimit);
|
||||
EmModel(1)->SetHighEnergyLimit(emax);
|
||||
AddEmModel(1, EmModel(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,6 @@ G4GoudsmitSaundersonMscModel::G4GoudsmitSaundersonMscModel(const G4String& nam)
|
||||
charge = 0;
|
||||
currentMaterialIndex = -1;
|
||||
//
|
||||
lambdalimit = 1.*mm;
|
||||
fr = 0.1;
|
||||
rangeinit = 1.e+21;
|
||||
geombig = 1.e+50*mm;
|
||||
@@ -185,8 +184,6 @@ G4GoudsmitSaundersonMscModel::G4GoudsmitSaundersonMscModel(const G4String& nam)
|
||||
mass = electron_mass_c2;
|
||||
taulim = 1.e-6;
|
||||
//
|
||||
facsafety = 0.6;
|
||||
|
||||
currentCouple = nullptr;
|
||||
fParticleChange = nullptr;
|
||||
//
|
||||
@@ -253,6 +250,7 @@ G4GoudsmitSaundersonMscModel::~G4GoudsmitSaundersonMscModel() {
|
||||
|
||||
void G4GoudsmitSaundersonMscModel::Initialise(const G4ParticleDefinition* p, const G4DataVector&) {
|
||||
SetParticle(p);
|
||||
InitialiseParameters(p);
|
||||
// -create GoudsmitSaundersonTable and init its Mott-correction member if
|
||||
// Mott-correction was required
|
||||
if (IsMaster()) {
|
||||
@@ -314,14 +312,13 @@ G4double G4GoudsmitSaundersonMscModel::CrossSectionPerVolume(const G4Material* m
|
||||
G4double,
|
||||
G4double) {
|
||||
G4double xsecTr1 = 0.; // cross section per volume i.e. macroscopic 1st transport cross section
|
||||
G4double efEnergy = kineticEnergy;
|
||||
//
|
||||
fLambda0 = 0.0; // elastic mean free path
|
||||
fLambda1 = 0.0; // first transport mean free path
|
||||
fScrA = 0.0; // screening parameter
|
||||
fG1 = 0.0; // first transport coef.
|
||||
// use Moliere's screening (with Mott-corretion if it was requested)
|
||||
if (efEnergy<10.*CLHEP::eV) efEnergy = 10.*CLHEP::eV;
|
||||
G4double efEnergy = std::max(kineticEnergy, 10.*CLHEP::eV);
|
||||
// total mometum square
|
||||
G4double pt2 = efEnergy*(efEnergy+2.0*electron_mass_c2);
|
||||
// beta square
|
||||
|
||||
@@ -435,7 +435,7 @@ G4GoudsmitSaundersonTable::GSMSCAngularDtr* G4GoudsmitSaundersonTable::GetGSAngu
|
||||
|
||||
|
||||
void G4GoudsmitSaundersonTable::LoadMSCData() {
|
||||
char* path = getenv("G4LEDATA");
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4GoudsmitSaundersonTable::LoadMSCData()","em0006",
|
||||
FatalException,
|
||||
|
||||
@@ -94,10 +94,11 @@ void G4ICRU49NuclearStoppingModel::InitialiseArray()
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&G4ICRU49NuclearStoppingModel::ICRU49NuclearMutex);
|
||||
#endif
|
||||
if(0.0 == Z23[2]) {
|
||||
for(G4int i=1; i<100; ++i) {
|
||||
if(0.0 == Z23[1]) {
|
||||
for(G4int i=2; i<100; ++i) {
|
||||
Z23[i] = g4calc->powZ(i, 0.23);
|
||||
}
|
||||
Z23[1] = 1.0;
|
||||
}
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXUNLOCK(&G4ICRU49NuclearStoppingModel::ICRU49NuclearMutex);
|
||||
|
||||
@@ -117,6 +117,11 @@ G4PairProductionRelModel::G4PairProductionRelModel(const G4ParticleDefinition*,
|
||||
fTheElectron(G4Electron::Electron()), fThePositron(G4Positron::Positron()),
|
||||
fParticleChange(nullptr)
|
||||
{
|
||||
// gamma energy below which the parametrized atomic x-section is used (80 GeV)
|
||||
fParametrizedXSectionThreshold = 80.0*CLHEP::GeV;
|
||||
// gamma energy below the Coulomb correction is turned off (50 MeV)
|
||||
fCoulombCorrectionThreshold = 50.0*CLHEP::MeV;
|
||||
// set angular generator used in the final state kinematics computation
|
||||
SetAngularDistribution(new G4ModifiedTsai());
|
||||
}
|
||||
|
||||
@@ -174,7 +179,9 @@ G4double G4PairProductionRelModel::ComputeXSectionPerAtom(G4double gammaEnergy,
|
||||
// the way in which the Coulomb correction is applied i.e. avoid negative DCS)
|
||||
const G4int iz = std::min(gMaxZet, G4lrint(Z));
|
||||
const G4double eps0 = CLHEP::electron_mass_c2/gammaEnergy;
|
||||
const G4double dmax = gElementData[iz]->fDeltaMax;
|
||||
// Coulomb correction is always included in the DCS even below 50 MeV (note:
|
||||
// that this DCS is only used to get the integrated x-section)
|
||||
const G4double dmax = gElementData[iz]->fDeltaMaxHigh;
|
||||
const G4double dmin = 4.*eps0*gElementData[iz]->fDeltaFactor;
|
||||
const G4double eps1 = 0.5 - 0.5*std::sqrt(1.-dmin/dmax);
|
||||
const G4double epsMin = std::max(eps0, eps1);
|
||||
@@ -306,18 +313,26 @@ G4PairProductionRelModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*
|
||||
G4double crossSection = 0.0 ;
|
||||
// check kinematical limit
|
||||
if ( gammaEnergy <= 2.0*electron_mass_c2 ) { return crossSection; }
|
||||
// Computes the cross section with or without LPM suppression depending on
|
||||
// settings (by default with if the gamma energy is above a given threshold)
|
||||
// and using or not using complete sreening approximation (by default not).
|
||||
// Only the dependent part is computed in the numerical integration of the DCS
|
||||
// i.e. the result must be multiplied here with 4 \alpha r_0^2 Z(Z+\eta(Z))
|
||||
crossSection = ComputeXSectionPerAtom(gammaEnergy, Z);
|
||||
// apply the constant factors:
|
||||
// - eta(Z) is a correction to account interaction in the field of e-
|
||||
// - gXSecFactor = 4 \alpha r_0^2
|
||||
const G4int iz = std::min(gMaxZet, G4lrint(Z));
|
||||
const G4double eta = gElementData[iz]->fEtaValue;
|
||||
crossSection *= gXSecFactor*Z*(Z+eta);
|
||||
// compute the atomic cross section either by using x-section parametrization
|
||||
// or by numerically integrationg the DCS (with or without LPM)
|
||||
if ( gammaEnergy < fParametrizedXSectionThreshold) {
|
||||
// using the parametrized cross sections (max up to 80 GeV)
|
||||
crossSection = ComputeParametrizedXSectionPerAtom(gammaEnergy, Z);
|
||||
} else {
|
||||
// by numerical integration of the DCS:
|
||||
// Computes the cross section with or without LPM suppression depending on
|
||||
// settings (by default with if the gamma energy is above a given threshold)
|
||||
// and using or not using complete sreening approximation (by default not).
|
||||
// Only the dependent part is computed in the numerical integration of the DCS
|
||||
// i.e. the result must be multiplied here with 4 \alpha r_0^2 Z(Z+\eta(Z))
|
||||
crossSection = ComputeXSectionPerAtom(gammaEnergy, Z);
|
||||
// apply the constant factors:
|
||||
// - eta(Z) is a correction to account interaction in the field of e-
|
||||
// - gXSecFactor = 4 \alpha r_0^2
|
||||
const G4int iz = std::min(gMaxZet, G4lrint(Z));
|
||||
const G4double eta = gElementData[iz]->fEtaValue;
|
||||
crossSection *= gXSecFactor*Z*(Z+eta);
|
||||
}
|
||||
// final protection
|
||||
return std::max(crossSection, 0.);
|
||||
}
|
||||
@@ -363,76 +378,88 @@ G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
|
||||
// 'eps' is the total energy transferred to one of the e-/e+ pair in initial
|
||||
// gamma energy units Eg. Since the corresponding DCS is symmetric on eps=0.5,
|
||||
// the kinematical limits for eps0=mc^2/Eg <= eps <= 0.5
|
||||
//
|
||||
// The Coulomb factor for the target element (Z) (Eg>50 MeV is assumed)
|
||||
// F(Z) = 8*ln(Z)/3 + 8*fc(Z)
|
||||
//
|
||||
// The screening variable 'delta(eps)' = 136*Z^{-1/3}*eps0/[eps(1-eps)]
|
||||
// Due to the Coulomb correction, the DCS can go below zero even at
|
||||
// kinematicaly allowed eps > eps0 values. In order to exclude this eps
|
||||
// range with negative DCS, the minimum eps value will be set to eps_min =
|
||||
// max[eps0, epsp] with epsp is the solution of SF(delta(epsp)) - F(Z)/2 = 0
|
||||
// with SF being the screening function (SF1=SF2 at high value of delta).
|
||||
// The solution is epsp = 0.5 - 0.5*sqrt[ 1 - 4*136*Z^{-1/3}eps0/deltap]
|
||||
// with deltap = Exp[(42.038-F(Z))/8.29]-0.958. So the limits are:
|
||||
// - when eps=eps_max = 0.5 => delta_min = 136*Z^{-1/3}*eps0/4
|
||||
// - epsp = 0.5 - 0.5*sqrt[ 1 - delta_min/deltap]
|
||||
// - and eps_min = max[eps0, epsp]
|
||||
const G4int iZet = std::min(gMaxZet, anElement->GetZasInt());
|
||||
const G4double deltaFactor = gElementData[iZet]->fDeltaFactor*eps0;
|
||||
const G4double deltaMin = 4.*deltaFactor;
|
||||
const G4double deltaMax = gElementData[iZet]->fDeltaMax;
|
||||
// compute the limits of eps
|
||||
const G4double epsp = 0.5 - 0.5*std::sqrt(1. - deltaMin/deltaMax) ;
|
||||
const G4double epsMin = std::max(eps0,epsp);
|
||||
const G4double epsRange = 0.5 - epsMin;
|
||||
const G4double FZ = 8.*(gElementData[iZet]->fLogZ13 +
|
||||
gElementData[iZet]->fCoulomb);
|
||||
//
|
||||
// sample the energy rate (eps) of the created electron (or positron)
|
||||
G4double F10, F20;
|
||||
ScreenFunction12(deltaMin, F10, F20);
|
||||
F10 -= FZ;
|
||||
F20 -= FZ;
|
||||
const G4double NormF1 = std::max(F10 * epsRange * epsRange, 0.);
|
||||
const G4double NormF2 = std::max(1.5 * F20 , 0.);
|
||||
const G4double NormCond = NormF1/(NormF1 + NormF2);
|
||||
// check if LPM correction is active
|
||||
const G4bool isLPM = (fIsUseLPMCorrection && gammaEnergy>gEgLPMActivation);
|
||||
fLPMEnergy = mat->GetRadlen()*gLPMconstant;
|
||||
// we will need 3 uniform random number for each trial of sampling
|
||||
G4double rndmv[3];
|
||||
G4double greject = 0.;
|
||||
// 1. 'eps' is sampled uniformly on the [eps0, 0.5] inteval if Eg<Egsmall
|
||||
// 2. otherwise, on the [eps_min, 0.5] interval according to the DCS (case 2.)
|
||||
G4double eps;
|
||||
do {
|
||||
rndmEngine->flatArray(3, rndmv);
|
||||
if (NormCond > rndmv[0]) {
|
||||
eps = 0.5 - epsRange * fG4Calc->A13(rndmv[1]);
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*((2.*lpmPhiS+lpmGS)*phi1-lpmGS*phi2-lpmPhiS*FZ)/F10;
|
||||
} else {
|
||||
greject = (ScreenFunction1(delta)-FZ)/F10;
|
||||
}
|
||||
} else {
|
||||
eps = epsMin + epsRange*rndmv[1];
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*( (lpmPhiS+0.5*lpmGS)*phi1 + 0.5*lpmGS*phi2
|
||||
-0.5*(lpmGS+lpmPhiS)*FZ )/F20;
|
||||
} else {
|
||||
greject = (ScreenFunction2(delta)-FZ)/F20;
|
||||
}
|
||||
// case 1.
|
||||
static const G4double Egsmall = 2.*CLHEP::MeV;
|
||||
if (gammaEnergy < Egsmall) {
|
||||
eps = eps0 + (0.5-eps0)*rndmEngine->flat();
|
||||
} else {
|
||||
// case 2.
|
||||
// get the Coulomb factor for the target element (Z) and gamma energy (Eg)
|
||||
// F(Z) = 8*ln(Z)/3 if Eg <= 50 [MeV] => no Coulomb correction
|
||||
// F(Z) = 8*ln(Z)/3 + 8*fc(Z) if Eg > 50 [MeV] => fc(Z) is the Coulomb cor.
|
||||
//
|
||||
// The screening variable 'delta(eps)' = 136*Z^{-1/3}*eps0/[eps(1-eps)]
|
||||
// Due to the Coulomb correction, the DCS can go below zero even at
|
||||
// kinematicaly allowed eps > eps0 values. In order to exclude this eps
|
||||
// range with negative DCS, the minimum eps value will be set to eps_min =
|
||||
// max[eps0, epsp] with epsp is the solution of SF(delta(epsp)) - F(Z)/2 = 0
|
||||
// with SF being the screening function (SF1=SF2 at high value of delta).
|
||||
// The solution is epsp = 0.5 - 0.5*sqrt[ 1 - 4*136*Z^{-1/3}eps0/deltap]
|
||||
// with deltap = Exp[(42.038-F(Z))/8.29]-0.958. So the limits are:
|
||||
// - when eps=eps_max = 0.5 => delta_min = 136*Z^{-1/3}*eps0/4
|
||||
// - epsp = 0.5 - 0.5*sqrt[ 1 - delta_min/deltap]
|
||||
// - and eps_min = max[eps0, epsp]
|
||||
const G4int iZet = std::min(gMaxZet, anElement->GetZasInt());
|
||||
const G4double deltaFactor = gElementData[iZet]->fDeltaFactor*eps0;
|
||||
const G4double deltaMin = 4.*deltaFactor;
|
||||
G4double deltaMax = gElementData[iZet]->fDeltaMaxLow;
|
||||
G4double FZ = 8.*gElementData[iZet]->fLogZ13;
|
||||
if ( gammaEnergy > fCoulombCorrectionThreshold ) { // Eg > 50 MeV ?
|
||||
FZ += 8.*gElementData[iZet]->fCoulomb;
|
||||
deltaMax = gElementData[iZet]->fDeltaMaxHigh;
|
||||
}
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while (greject < rndmv[2]);
|
||||
// end of eps sampling
|
||||
// compute the limits of eps
|
||||
const G4double epsp = 0.5 - 0.5*std::sqrt(1. - deltaMin/deltaMax) ;
|
||||
const G4double epsMin = std::max(eps0,epsp);
|
||||
const G4double epsRange = 0.5 - epsMin;
|
||||
//
|
||||
// sample the energy rate (eps) of the created electron (or positron)
|
||||
G4double F10, F20;
|
||||
ScreenFunction12(deltaMin, F10, F20);
|
||||
F10 -= FZ;
|
||||
F20 -= FZ;
|
||||
const G4double NormF1 = std::max(F10 * epsRange * epsRange, 0.);
|
||||
const G4double NormF2 = std::max(1.5 * F20 , 0.);
|
||||
const G4double NormCond = NormF1/(NormF1 + NormF2);
|
||||
// check if LPM correction is active
|
||||
const G4bool isLPM = (fIsUseLPMCorrection && gammaEnergy>gEgLPMActivation);
|
||||
fLPMEnergy = mat->GetRadlen()*gLPMconstant;
|
||||
// we will need 3 uniform random number for each trial of sampling
|
||||
G4double rndmv[3];
|
||||
G4double greject = 0.;
|
||||
do {
|
||||
rndmEngine->flatArray(3, rndmv);
|
||||
if (NormCond > rndmv[0]) {
|
||||
eps = 0.5 - epsRange * fG4Calc->A13(rndmv[1]);
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*((2.*lpmPhiS+lpmGS)*phi1-lpmGS*phi2-lpmPhiS*FZ)/F10;
|
||||
} else {
|
||||
greject = (ScreenFunction1(delta)-FZ)/F10;
|
||||
}
|
||||
} else {
|
||||
eps = epsMin + epsRange*rndmv[1];
|
||||
const G4double delta = deltaFactor/(eps*(1.-eps));
|
||||
if (isLPM) {
|
||||
G4double lpmXiS, lpmGS, lpmPhiS, phi1, phi2;
|
||||
ComputePhi12(delta, phi1, phi2);
|
||||
ComputeLPMfunctions(lpmXiS, lpmGS, lpmPhiS, eps, gammaEnergy, iZet);
|
||||
greject = lpmXiS*( (lpmPhiS+0.5*lpmGS)*phi1 + 0.5*lpmGS*phi2
|
||||
-0.5*(lpmGS+lpmPhiS)*FZ )/F20;
|
||||
} else {
|
||||
greject = (ScreenFunction2(delta)-FZ)/F20;
|
||||
}
|
||||
}
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while (greject < rndmv[2]);
|
||||
// end of eps sampling
|
||||
}
|
||||
//
|
||||
// select charges randomly
|
||||
G4double eTotEnergy, pTotEnergy;
|
||||
@@ -452,8 +479,7 @@ G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
|
||||
G4ThreeVector eDirection, pDirection;
|
||||
//
|
||||
GetAngularDistribution()->SamplePairDirections(aDynamicGamma,
|
||||
eKinEnergy, pKinEnergy,
|
||||
eDirection, pDirection);
|
||||
eKinEnergy, pKinEnergy, eDirection, pDirection);
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle(
|
||||
fTheElectron,eDirection,eKinEnergy);
|
||||
@@ -486,7 +512,8 @@ void G4PairProductionRelModel::InitialiseElementData()
|
||||
const G4double logZ13 = elem->GetIonisation()->GetlogZ3();
|
||||
const G4double Z13 = elem->GetIonisation()->GetZ3();
|
||||
const G4double fc = elem->GetfCoulomb();
|
||||
const G4double FZ = 8.*(logZ13 + fc);
|
||||
const G4double FZLow = 8.*logZ13;
|
||||
const G4double FZHigh = 8.*(logZ13 + fc);
|
||||
G4double Fel;
|
||||
G4double Finel;
|
||||
if (iz<5) { // use data from Dirac-Fock atomic model
|
||||
@@ -501,7 +528,8 @@ void G4PairProductionRelModel::InitialiseElementData()
|
||||
elD->fCoulomb = fc;
|
||||
elD->fLradEl = Fel;
|
||||
elD->fDeltaFactor = 136./Z13;
|
||||
elD->fDeltaMax = G4Exp((42.038 - FZ)/8.29) - 0.958;
|
||||
elD->fDeltaMaxLow = G4Exp((42.038 - FZLow)/8.29) - 0.958;
|
||||
elD->fDeltaMaxHigh = G4Exp((42.038 - FZHigh)/8.29) - 0.958;
|
||||
elD->fEtaValue = Finel/(Fel-fc);
|
||||
elD->fLPMVarS1Cond = std::sqrt(2.)*Z13*Z13/(184.*184.);
|
||||
elD->fLPMILVarS1Cond = 1./G4Log(elD->fLPMVarS1Cond);
|
||||
@@ -611,3 +639,71 @@ void G4PairProductionRelModel::ComputeLPMfunctions(G4double &funcXiS,
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the microscopic cross section in GEANT4 internal units. Same as in
|
||||
// G4BetheHeitlerModel and should be used below 80 GeV since it start to deverge
|
||||
// from the cross section data above 80-90 GeV:
|
||||
// Parametrized formula (L. Urban) is used to estimate the atomic cross sections
|
||||
// given numerically in the table of [Hubbell, J. H., Heinz Albert Gimm, and I.
|
||||
// Overbo: "Pair, Triplet, and Total Atomic Cross Sections (and Mass Attenuation
|
||||
// Coefficients) for 1 MeV‐100 GeV Photons in Elements Z= 1 to 100." Journal of
|
||||
// physical and chemical reference data 9.4 (1980): 1023-1148.]
|
||||
//
|
||||
// The formula gives a good approximation of the data from 1.5 MeV to 100 GeV.
|
||||
// below 1.5 MeV: sigma=sigma(1.5MeV)*(GammaEnergy-2electronmass)
|
||||
// *(GammaEnergy-2electronmass)
|
||||
G4double
|
||||
G4PairProductionRelModel::ComputeParametrizedXSectionPerAtom(G4double gammaE,
|
||||
G4double Z)
|
||||
{
|
||||
G4double xSection = 0.0 ;
|
||||
// short versions
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
// zero cross section below the kinematical limit: Eg<2mc^2
|
||||
if (Z < 0.9 || gammaE <= 2.0*kMC2) { return xSection; }
|
||||
//
|
||||
static const G4double gammaEnergyLimit = 1.5*CLHEP::MeV;
|
||||
// set coefficients a, b c
|
||||
static const G4double a0 = 8.7842e+2*CLHEP::microbarn;
|
||||
static const G4double a1 = -1.9625e+3*CLHEP::microbarn;
|
||||
static const G4double a2 = 1.2949e+3*CLHEP::microbarn;
|
||||
static const G4double a3 = -2.0028e+2*CLHEP::microbarn;
|
||||
static const G4double a4 = 1.2575e+1*CLHEP::microbarn;
|
||||
static const G4double a5 = -2.8333e-1*CLHEP::microbarn;
|
||||
|
||||
static const G4double b0 = -1.0342e+1*CLHEP::microbarn;
|
||||
static const G4double b1 = 1.7692e+1*CLHEP::microbarn;
|
||||
static const G4double b2 = -8.2381 *CLHEP::microbarn;
|
||||
static const G4double b3 = 1.3063 *CLHEP::microbarn;
|
||||
static const G4double b4 = -9.0815e-2*CLHEP::microbarn;
|
||||
static const G4double b5 = 2.3586e-3*CLHEP::microbarn;
|
||||
|
||||
static const G4double c0 = -4.5263e+2*CLHEP::microbarn;
|
||||
static const G4double c1 = 1.1161e+3*CLHEP::microbarn;
|
||||
static const G4double c2 = -8.6749e+2*CLHEP::microbarn;
|
||||
static const G4double c3 = 2.1773e+2*CLHEP::microbarn;
|
||||
static const G4double c4 = -2.0467e+1*CLHEP::microbarn;
|
||||
static const G4double c5 = 6.5372e-1*CLHEP::microbarn;
|
||||
// check low energy limit of the approximation (1.5 MeV)
|
||||
G4double gammaEnergyOrg = gammaE;
|
||||
if (gammaE < gammaEnergyLimit) { gammaE = gammaEnergyLimit; }
|
||||
// compute gamma energy variables
|
||||
const G4double x = G4Log(gammaE/kMC2);
|
||||
const G4double x2 = x *x;
|
||||
const G4double x3 = x2*x;
|
||||
const G4double x4 = x3*x;
|
||||
const G4double x5 = x4*x;
|
||||
//
|
||||
const G4double F1 = a0 + a1*x + a2*x2 + a3*x3 + a4*x4 + a5*x5;
|
||||
const G4double F2 = b0 + b1*x + b2*x2 + b3*x3 + b4*x4 + b5*x5;
|
||||
const G4double F3 = c0 + c1*x + c2*x2 + c3*x3 + c4*x4 + c5*x5;
|
||||
// compute the approximated cross section
|
||||
xSection = (Z + 1.)*(F1*Z + F2*Z*Z + F3);
|
||||
// check if we are below the limit of the approximation and apply correction
|
||||
if (gammaEnergyOrg < gammaEnergyLimit) {
|
||||
const G4double dum = (gammaEnergyOrg-2.*kMC2)/(gammaEnergyLimit-2.*kMC2);
|
||||
xSection *= dum*dum;
|
||||
}
|
||||
return xSection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ void G4SBBremTable::InitSamplingTables() {
|
||||
|
||||
// should be called only from LoadSamplingTables(G4int) and once
|
||||
void G4SBBremTable::LoadSTGrid() {
|
||||
char* path = getenv("G4LEDATA");
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
|
||||
FatalException, "Environment variable G4LEDATA not defined");
|
||||
@@ -391,7 +391,7 @@ void G4SBBremTable::LoadSamplingTables(G4int iz) {
|
||||
}
|
||||
// load data for a given Z only once
|
||||
iz = std::max(std::min(fMaxZet, iz),1);
|
||||
char* path = getenv("G4LEDATA");
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4SBBremTable::LoadSamplingTables()","em0006",
|
||||
FatalException, "Environment variable G4LEDATA not defined");
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -40,11 +39,12 @@
|
||||
// Modifications:
|
||||
//
|
||||
// 24.07.2018 Introduced possibility to use sampling tables to sample the
|
||||
// emitted photon energy (instead of using rejectio) from the Seltzer-
|
||||
// Berger scalled DCS for bremsstrahlung photon emission. Using these
|
||||
// sampling tables option gives faster(30-70%) final state generation
|
||||
// than the original rejection but takes some extra memory (+ ~6MB in
|
||||
// the case of the full CMS detector). (M Novak)
|
||||
// emitted photon energy (instead of using rejectio) from the
|
||||
// Seltzer-Berger scalled DCS for bremsstrahlung photon emission.
|
||||
// Using these sampling tables option gives faster(30-70%) final
|
||||
// state generation than the original rejection but takes some
|
||||
// extra memory (+ ~6MB in the case of the full CMS detector).
|
||||
// (M Novak)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -61,21 +61,32 @@
|
||||
#include "G4ModifiedTsai.hh"
|
||||
//#include "G4DipBustGenerator.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
#include "G4Physics2DVector.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Log.hh"
|
||||
|
||||
#include "G4ios.hh"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
G4Physics2DVector* G4SeltzerBergerModel::gSBDCSData[] = { nullptr };
|
||||
G4SBBremTable* G4SeltzerBergerModel::gSBSamplingTable = nullptr;
|
||||
G4double G4SeltzerBergerModel::gYLimitData[] = { 0.0 };
|
||||
G4String G4SeltzerBergerModel::gDataDirectory = "";
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4SeltzerBergerModel::theSBMutex = G4MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
|
||||
G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
const G4String& nam)
|
||||
: G4eBremsstrahlungRelModel(p,nam), fIsUseBicubicInterpolation(false),
|
||||
fIsUseSamplingTables(true), fNumWarnings(0), fIndx(0), fIndy(0)
|
||||
{
|
||||
@@ -83,7 +94,6 @@ G4SeltzerBergerModel::G4SeltzerBergerModel(const G4ParticleDefinition* p,
|
||||
SetLowEnergyLimit(fLowestKinEnergy);
|
||||
SetLPMFlag(false);
|
||||
SetAngularDistribution(new G4ModifiedTsai());
|
||||
//SetAngularDistribution(new G4DipBustGenerator());
|
||||
}
|
||||
|
||||
G4SeltzerBergerModel::~G4SeltzerBergerModel()
|
||||
@@ -104,7 +114,7 @@ G4SeltzerBergerModel::~G4SeltzerBergerModel()
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector& cuts)
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
if (p) {
|
||||
SetParticle(p);
|
||||
@@ -112,17 +122,17 @@ void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
fIsUseSamplingTables = G4EmParameters::Instance()->EnableSamplingTable();
|
||||
// Access to elements
|
||||
if (IsMaster()) {
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
char* path = getenv("G4LEDATA");
|
||||
const G4ElementTable* theElemTable = G4Element::GetElementTable();
|
||||
size_t numOfElem = G4Element::GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int izet =
|
||||
std::max(1,std::min(((*theElemTable)[ie])->GetZasInt(), gMaxZet-1));
|
||||
// load SB-DCS data for this atomic number if it has not been loaded yet
|
||||
if (!gSBDCSData[izet]) {
|
||||
ReadData(izet, path);
|
||||
|
||||
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(size_t j=0; j<numOfCouples; ++j) {
|
||||
auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
|
||||
auto elmVec = mat->GetElementVector();
|
||||
size_t numOfElem = mat->GetNumberOfElements();
|
||||
for (size_t ie = 0; ie < numOfElem; ++ie) {
|
||||
G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), gMaxZet-1));
|
||||
// load SB-DCS data for this atomic number if it has not been loaded yet
|
||||
InitialiseForElement(nullptr, Z);
|
||||
}
|
||||
}
|
||||
// elem.selectr. only for master: base class init-local will set for workers
|
||||
@@ -146,26 +156,32 @@ void G4SeltzerBergerModel::Initialise(const G4ParticleDefinition* p,
|
||||
}
|
||||
}
|
||||
|
||||
G4String G4SeltzerBergerModel::DirectoryPath() const {
|
||||
return "/brem_SB/br";
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
// return if it has been already loaded
|
||||
if (gSBDCSData[izet]) {
|
||||
return;
|
||||
}
|
||||
const char* datadir = path;
|
||||
if (!datadir) {
|
||||
datadir = getenv("G4LEDATA");
|
||||
if (!datadir) {
|
||||
G4Exception("G4SeltzerBergerModel::ReadData()","em0006",FatalException,
|
||||
const G4String& G4SeltzerBergerModel::FindDirectoryPath()
|
||||
{
|
||||
// check environment variable
|
||||
// build the complete string identifying the file with the data set
|
||||
if(gDataDirectory.empty()) {
|
||||
const char* path = std::getenv("G4LEDATA");
|
||||
if (path) {
|
||||
std::ostringstream ost;
|
||||
ost << path << "/brem_SB/br";
|
||||
gDataDirectory = ost.str();
|
||||
} else {
|
||||
G4Exception("G4SeltzerBergerModel::FindDirectoryPath()","em0006",
|
||||
FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return gDataDirectory;
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::ReadData(G4int Z) {
|
||||
// return if it has been already loaded
|
||||
if (gSBDCSData[Z]) {
|
||||
return;
|
||||
}
|
||||
std::ostringstream ost;
|
||||
ost << datadir << DirectoryPath() << izet;
|
||||
ost << FindDirectoryPath() << Z;
|
||||
std::ifstream fin(ost.str().c_str());
|
||||
if (!fin.is_open()) {
|
||||
G4ExceptionDescription ed;
|
||||
@@ -180,9 +196,9 @@ void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
G4Physics2DVector* v = new G4Physics2DVector();
|
||||
if (v->Retrieve(fin)) {
|
||||
v->SetBicubicInterpolation(fIsUseBicubicInterpolation);
|
||||
gSBDCSData[izet] = v;
|
||||
static const G4double emaxlog = 4*G4Log(10.);
|
||||
gYLimitData[izet] = v->Value(0.97, emaxlog, fIndx, fIndy);
|
||||
gYLimitData[Z] = v->Value(0.97, emaxlog, fIndx, fIndy);
|
||||
gSBDCSData[Z] = v;
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Bremsstrahlung data file <" << ost.str().c_str()
|
||||
@@ -191,13 +207,10 @@ void G4SeltzerBergerModel::ReadData(G4int izet, const char* path) {
|
||||
ed,"G4LEDATA version should be G4EMLOW6.23 or later.");
|
||||
delete v;
|
||||
}
|
||||
// G4cout << dataSB[Z] << G4endl;
|
||||
}
|
||||
|
||||
G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
G4double dxsec = 0.0;
|
||||
if (gammaEnergy < 0.0 || fPrimaryKinEnergy <= 0.0) {
|
||||
return dxsec;
|
||||
@@ -212,14 +225,6 @@ G4double G4SeltzerBergerModel::ComputeDXSectionPerAtom(G4double gammaEnergy)
|
||||
if (!gSBDCSData[fCurrentIZ]) {
|
||||
InitialiseForElement(nullptr, fCurrentIZ);
|
||||
}
|
||||
/*
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Bremsstrahlung data for Z= " << Z
|
||||
<< " are not initialized!";
|
||||
G4Exception("G4SeltzerBergerModel::ComputeDXSectionPerAtom()","em0005",
|
||||
FatalException, ed,
|
||||
"G4LEDATA version should be G4EMLOW6.23 or later.");
|
||||
*/
|
||||
// NOTE: SetupForMaterial should have been called before!
|
||||
const G4double pt2 = fPrimaryKinEnergy*(fPrimaryKinEnergy+2.*kMC2);
|
||||
const G4double invb2 = fPrimaryTotalEnergy*fPrimaryTotalEnergy/pt2;
|
||||
@@ -251,7 +256,6 @@ G4SeltzerBergerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
const G4double kinEnergy = dp->GetKineticEnergy();
|
||||
const G4double logKinEnergy = dp->GetLogKineticEnergy();
|
||||
const G4double tmin = std::min(cutEnergy, kinEnergy);
|
||||
@@ -292,7 +296,8 @@ G4SeltzerBergerModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
vdp->push_back(gamma);
|
||||
//
|
||||
// compute post-interaction kinematics of the primary e-/e+
|
||||
G4ThreeVector dir = (totMomentum*dp->GetMomentumDirection()-gammaEnergy*gamDir).unit();
|
||||
G4ThreeVector dir =
|
||||
(totMomentum*dp->GetMomentumDirection()-gammaEnergy*gamDir).unit();
|
||||
const G4double finalE = kinEnergy - gammaEnergy;
|
||||
/*
|
||||
G4cout << "### G4SBModel: v= "
|
||||
@@ -323,8 +328,6 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
const G4double tmin,
|
||||
const G4double tmax)
|
||||
{
|
||||
static const G4double kMC2 = CLHEP::electron_mass_c2;
|
||||
static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
|
||||
// min max of the transformed variable: x(k) = ln(k^2+k_p^2) that is in
|
||||
// [ln(k_c^2+k_p^2), ln(E_k^2+k_p^2)]
|
||||
const G4double xmin = G4Log(tmin*tmin+fDensityCorr);
|
||||
@@ -333,24 +336,19 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
// majoranta
|
||||
const G4double x0 = tmin/kinEnergy;
|
||||
G4double vmax;
|
||||
if (fCurrentIZ < 93) {
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.02;
|
||||
} else {
|
||||
// reset cashed x and y indices
|
||||
fIndx = 0;
|
||||
fIndy = 0;
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.2;
|
||||
if (!gSBDCSData[fCurrentIZ]) {
|
||||
InitialiseForElement(nullptr, fCurrentIZ);
|
||||
}
|
||||
vmax = gSBDCSData[fCurrentIZ]->Value(x0, y, fIndx, fIndy)*1.02;
|
||||
//
|
||||
static const G4double kEPeakLim = 300.*CLHEP::MeV;
|
||||
static const G4double kELowLim = 20.*CLHEP::keV;
|
||||
// majoranta corrected for e-
|
||||
if (fIsElectron && x0 < 0.97 && ((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
|
||||
const G4double ylim = std::min(gYLimitData[fCurrentIZ],
|
||||
if (fIsElectron && x0 < 0.97 &&
|
||||
((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
|
||||
G4double ylim = std::min(gYLimitData[fCurrentIZ],
|
||||
1.1*gSBDCSData[fCurrentIZ]->Value(0.97,y,fIndx,fIndy));
|
||||
if (ylim > vmax) {
|
||||
vmax = ylim;
|
||||
}
|
||||
vmax = std::max(vmax, ylim);
|
||||
}
|
||||
if (x0 < 0.05) {
|
||||
vmax *= 1.2;
|
||||
@@ -363,7 +361,8 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
G4double gammaEnergy, v;
|
||||
for (G4int nn = 0; nn < kNCountMax; ++nn) {
|
||||
rndmEngine->flatArray(2, rndm);
|
||||
gammaEnergy = std::sqrt(std::max(G4Exp(xmin + rndm[0]*xrange)-fDensityCorr,0.));
|
||||
gammaEnergy =
|
||||
std::sqrt(std::max(G4Exp(xmin + rndm[0]*xrange)-fDensityCorr,0.));
|
||||
v = gSBDCSData[fCurrentIZ]->Value(gammaEnergy/kinEnergy, y, fIndx, fIndy);
|
||||
// e+ correction
|
||||
if (!fIsElectron) {
|
||||
@@ -401,21 +400,25 @@ G4SeltzerBergerModel::SampleEnergyTransfer(const G4double kinEnergy,
|
||||
return gammaEnergy;
|
||||
}
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex SeltzerBergerModel1Mutex = G4MUTEX_INITIALIZER; }
|
||||
void G4SeltzerBergerModel::InitialiseForElement(const G4ParticleDefinition*,
|
||||
G4int izet)
|
||||
G4int Z)
|
||||
{
|
||||
G4AutoLock l(&SeltzerBergerModel1Mutex);
|
||||
// G4cout << "G4SeltzerBergerModel::InitialiseForElement Z= " << Z << G4endl;
|
||||
if (!gSBDCSData[izet]) {
|
||||
ReadData(izet);
|
||||
}
|
||||
if (!gSBDCSData[Z]) {
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&theSBMutex);
|
||||
if (!gSBDCSData[Z]) {
|
||||
#endif
|
||||
ReadData(Z);
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&theSBMutex);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void G4SeltzerBergerModel::SetupForMaterial(const G4ParticleDefinition*,
|
||||
const G4Material* mat,
|
||||
G4double kineticEnergy)
|
||||
const G4Material* mat,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
fDensityFactor = gMigdalConstant*mat->GetElectronDensity();
|
||||
// calculate threshold for density effect: gamma*k_p = sqrt(fDensityCorr)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -123,16 +123,15 @@ void G4WentzelOKandVIxSection::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
// cosThetaMax is below 1.0 only when MSC is combined with SS
|
||||
if(isCombined) { cosThetaMax = cosThetaLim; }
|
||||
|
||||
G4double a = G4EmParameters::Instance()->FactorForAngleLimit()
|
||||
*CLHEP::hbarc/CLHEP::fermi;
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
G4double a = param->FactorForAngleLimit()*CLHEP::hbarc/CLHEP::fermi;
|
||||
factorA2 = 0.5*a*a;
|
||||
currentMaterial = nullptr;
|
||||
|
||||
fNucFormfactor = G4EmParameters::Instance()->NuclearFormfactorType();
|
||||
fNucFormfactor = param->NuclearFormfactorType();
|
||||
if(0.0 == ScreenRSquare[0]) { InitialiseA(); }
|
||||
|
||||
// Mott corrections
|
||||
// Mott corrections always added
|
||||
if((p == theElectron || p == thePositron) && !fMottXSection) {
|
||||
fMottXSection = new G4ScreeningMottCrossSection();
|
||||
fMottXSection->Initialise(p, 1.0);
|
||||
@@ -158,7 +157,7 @@ void G4WentzelOKandVIxSection::InitialiseA()
|
||||
G4double constn = 6.937e-6/(MeV*MeV);
|
||||
G4double fct = G4EmParameters::Instance()->ScreeningFactor();
|
||||
|
||||
G4double afact = fct*0.5*alpha2*a0*a0;
|
||||
G4double afact = 0.5*fct*alpha2*a0*a0;
|
||||
ScreenRSquare[0] = afact;
|
||||
ScreenRSquare[1] = afact;
|
||||
ScreenRSquareElec[1] = afact;
|
||||
@@ -388,14 +387,14 @@ G4WentzelOKandVIxSection::SampleSingleScattering(G4double cosTMin,
|
||||
}
|
||||
G4double grej;
|
||||
if(fMottXSection) {
|
||||
fMottXSection->SetupKinematic(tkin, (G4double)targetZ);
|
||||
fMottXSection->SetupKinematic(tkin, targetZ);
|
||||
grej = fMottXSection->RatioMottRutherfordCosT(std::sqrt(z1))*fm*fm;
|
||||
} else {
|
||||
grej = (1. - z1*factB + factB1*targetZ*sqrt(z1*factB)*(2. - z1))
|
||||
*fm*fm/(1.0 + z1*factD);
|
||||
}
|
||||
//G4cout << "SampleSingleScattering: E= " << tkin << " z1= "
|
||||
// << z1 << " grej= " << grej << G4endl;
|
||||
// G4cout << "SampleSingleScattering: E= " << tkin << " z1= "
|
||||
// << z1 << " grej= "<< grej << " mottFact= "<< fMottFactor<< G4endl;
|
||||
if(fMottFactor*rndmEngineMod->flat() <= grej ) {
|
||||
// exclude "false" scattering due to formfactor and spin effect
|
||||
G4double cost = 1.0 - z1;
|
||||
|
||||
@@ -124,6 +124,7 @@ void G4WentzelVIModel::Initialise(const G4ParticleDefinition* p,
|
||||
{
|
||||
// reset parameters
|
||||
SetupParticle(p);
|
||||
InitialiseParameters(p);
|
||||
currentRange = 0.0;
|
||||
|
||||
if(isCombined) {
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -94,13 +94,15 @@ G4eSingleCoulombScatteringModel::G4eSingleCoulombScatteringModel(const G4String&
|
||||
currentMaterialIndex = -1;
|
||||
|
||||
Mottcross = new G4ScreeningMottCrossSection();
|
||||
//G4cout <<"## G4eSingleCoulombScatteringModel: " << this << " " << Mottcross << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eSingleCoulombScatteringModel::~G4eSingleCoulombScatteringModel()
|
||||
{
|
||||
delete Mottcross;
|
||||
//G4cout <<"## G4eSingleCoulombScatteringModel: delete " << this << " " << Mottcross << G4endl;
|
||||
delete Mottcross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -168,7 +168,7 @@ G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& track,
|
||||
G4Track* t = new G4Track(dp, time, track.GetPosition());
|
||||
t->SetTouchableHandle(track.GetTouchableHandle());
|
||||
if (biasManager) {
|
||||
t->SetWeight(biasManager->GetWeight(i));
|
||||
t->SetWeight(weight * biasManager->GetWeight(i));
|
||||
} else {
|
||||
t->SetWeight(weight);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
@@ -58,8 +57,6 @@
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
Reference in New Issue
Block a user