Import Geant4 10.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 11:51:14 +02:00
parent e2d2f9810a
commit 286caacf06
12421 changed files with 730077 additions and 502383 deletions
@@ -7,7 +7,7 @@
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt,v 1.1 2010-09-29 18:53:25 bmorgan Exp $
# $Id: CMakeLists.txt 66892 2013-01-17 10:57:59Z gunter $
#
#------------------------------------------------------------------------------
@@ -1,4 +1,4 @@
# $Id: GNUmakefile,v 1.6 2004-11-22 03:28:15 vnivanch Exp $
# $Id: GNUmakefile 66892 2013-01-17 10:57:59Z gunter $
# --------------------------------------------------------------------
# GNUmakefile for electromagnetic sub-library. John Allison, 25/6/98.
# --------------------------------------------------------------------
+132 -1
View File
@@ -1,4 +1,4 @@
$Id: History,v 1.138 2010-11-04 12:40:29 vnivanch Exp $
$Id: History 75168 2013-10-29 09:20:52Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,137 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
28 October 13: V.Ivanchenko (emmuons-V09-06-24)
- G4EnergyLossForExtrapolator - substitute G4eBremsstrahlungModel
by G4SeltzerBergerModel
- G4MuBremsstrahlungModel - lowest energy is set to 1 GeV
14 October 2013: V.Ivant (emmuons-V09-06-23)
- G4MuPairProductionModel - fixed problem with the end of the spectra
by cleanup initialisation of sampling table
02 October 2013: V.Ivant (emmuons-V09-06-22)
- G4EnergyLossForExtrapolator - use G4Log
19 September 2013: V.Ivant (emmuons-V09-06-21)
- G4MuPairProductionModel - minor cleanup
18 September 2013: V.Ivant (emmuons-V09-06-20)
- G4MuPairProductionModel - fixed trivial Coverity report; merge
SetElement() and MaxSecondaryEnergy() methods into one
MaxSecondaryEnergyForElement() - this is more performant
and more safe for reproducibility; use G4Log and G4Exp
- G4MuBremsstrahlungModel and G4MuBetheBlochModel - use G4Log and
G4Exp
12 September 2013: V.Ivant (emmuons-V09-06-19)
- G4MuPairProductionModel - fixed bug in sampling when cut value is
high; perform common initialisation of internal variables for
all threads - fix of non-reproducibility
29 August 2013: V.Ivant (emmuons-V09-06-18)
- G4MuBremsstrahlungModel - do not repeat initialisation of elelment
selectors if model is shared between particle and anti-particle
- G4MuPairProductionModel - fixed bug in energy sampling which couse
FPE and other problems
09 August 2013: V.Ivant (emmuons-V09-06-17)
- G4MuPairProduction - improved initialisation printout
- G4MuPairProductionModel - fixed bining to 1000 for internal
sampling table
09 August 2013: V.Ivant (emmuons-V09-06-16)
- G4MuBremsstrahlungModel - minThreshold is reduced from 1 keV to
0.9 keV in order to avoid extra warning printout
- G4MuBremsstrahlung - removed unused headers;
- G4MuPairProduction - removed unused headers; lowestEnergy limit
should not be lower than 8*mass because the model is not
applicable
- G4MuPairProductionModel - sampling table is re-implemented as
G4ElementData with 2D-tables per atomic number; sampling
algorithm is rewritten, data fully shared between threads
09 July 2013: V.Ivant (emmuons-V09-06-15)
- G4MuPairProductionModel - fixed non-reproducibity due to currentZ
member of the class definition; changed signature of the method
MinPrimaryEnergy(..) - added "G4double cut"; substitute
SetCurrentElement(G4double) by SetElement(G4int); use more G4Pow
- G4MuBremsstrahlung - changed signature of the method
MinPrimaryEnergy(..) - added "G4double cut"
17 June 2013: V.Ivant (emmuons-V09-06-14)
- G4MuPairProductionModel, G4MuBremsstrahlungModel - added
MinPrimaryEnergy method implementation (all cross section tables
will start from the reaction threshold)
17 June 2013: V.Ivant (emmuons-V09-06-13)
- G4MuPairProductionModel - added protection and warning message
if p1=p2 in the SampleSecodaries method
04 June 2013: V.Ivant (emmuons-V09-06-12)
- G4EnergyLossForExtrapolator - use cut DBL_MAX to avoid creation
of G4EmSelectors in lazy initialisation
- G4MuPairProductionModel,G4MuBremsstrahlungModel - fixed usage of
element selectors
31 May 2013: V.Ivant (emmuons-V09-06-11)
- G4MuPairProductionModel - provides different
initialisation for master and worker threads sharing element
selectors
- G4MuBremsstrahlungModel - removed partialSubSigma data structure,
use instead G4ElementSelectors; provides different
initialisation for master and worker threads sharing element
selectors
29 May 2013: V.Ivant (emmuons-V09-06-10)
- G4MuPairProductionModel, G4MuBremsstrahlungModel - fixed rare bug
in cross section computation - division by zero (bug report #1471)
22 May 2013: V.Ivant (emmuons-V09-06-09)
- G4MuPairProductionModel, G4MuBremsstrahlungModel - fixed rare bug
in dEdx computation - division by zero (bug report #1471)
08 May 2013: V.Ivant (emmuons-V09-06-08)
- G4MuPairProductionModel - A.Bogdanov provides improved algorithm
for sampling of final state
22 March 2013: V.Ivant (emmuons-V09-06-07)
- G4MuPairProductionModel, G4MuBremsstrahlungModel - correctly use
"static const G4double" for const parameters
19 February 2013: V.Ivant (emmuons-V09-06-06)
- G4MuPairProductionModel - number of bins for virtual gamma returned
to be 1000
19 February 2013: V.Ivant (emmuons-V09-06-05)
- G4MuMultipleScattering - G4UrbanMscModel become default
- G4MuPairProductionModel - number of bins for virtual gamma returned
to be 2000
19 February 2013: V.Ivant (emmuons-V09-06-04)
- G4MuPairProductionModel - number of bins for virtual gamma reduced
from 2000 to 1600
- G4MuBetheBlochModel - removed G4ThreadLocal declaration
18 February 2013: V.Ivant (emmuons-V09-06-02)
- G4MuPairProductionModel - add check on max energy to reduce number
of bins in muon energy; number of bins for virtual gamma reduced
from 4000 to 2000.
02 February 2013: V.Ivant (emmuons-V09-06-01)
- G4MuPairProductionModel - make main table of differential cross
section private and not static, because G4hPairProductionModel
inherit of this class and muons cannot share the same tables with
hadrons; two new inline access methods are added GetSecondaryEnergy
and GetDifferentialCrossSection.
01 February 2013: V.Ivant (emmuons-V09-06-00)
- G4MuPairProductionModel - (A.Bogdanov) - extended grid of differential
cross section tables (from 8 to 40 points in muon energy, from 1000 to
4000 points in energy of e+e- pair); use more fast binary search of
index in the table; make table static - common for all threads
06 November 2012: V.Ivant (emmuons-V09-05-06)
- G4MuBremsstrahlungModel, G4MuPairProductionModel - reduce number of
computations of log of the same argument, no change in results
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EnergyLossForExtrapolator.hh 74310 2013-10-03 06:44:36Z gcosmo $
//
//---------------------------------------------------------------------------
//
@@ -55,6 +55,8 @@
#include "globals.hh"
#include "G4PhysicsTable.hh"
#include "G4DataVector.hh"
#include "G4Log.hh"
class G4ParticleDefinition;
class G4Material;
@@ -66,6 +68,7 @@ class G4ProductionCuts;
class G4EnergyLossForExtrapolator
{
public:
G4EnergyLossForExtrapolator(G4int verb = 1);
~G4EnergyLossForExtrapolator();
@@ -99,7 +102,8 @@ public:
const G4Material*,
const G4String& particleName);
inline G4double ComputeTrueStep(const G4Material*, const G4ParticleDefinition* part,
inline G4double ComputeTrueStep(const G4Material*,
const G4ParticleDefinition* part,
G4double kinEnergy, G4double stepLength);
inline G4double EnergyDispersion(G4double kinEnergy, G4double step,
@@ -127,13 +131,17 @@ private:
const G4ParticleDefinition* FindParticle(const G4String& name);
void ComputeElectronDEDX(const G4ParticleDefinition* part, G4PhysicsTable* table);
void ComputeElectronDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table);
void ComputeMuonDEDX(const G4ParticleDefinition* part, G4PhysicsTable* table);
void ComputeMuonDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table);
void ComputeProtonDEDX(const G4ParticleDefinition* part, G4PhysicsTable* table);
void ComputeProtonDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table);
void ComputeTrasportXS(const G4ParticleDefinition* part, G4PhysicsTable* table);
void ComputeTrasportXS(const G4ParticleDefinition* part,
G4PhysicsTable* table);
inline G4double ComputeValue(G4double x, const G4PhysicsTable* table);
@@ -148,7 +156,9 @@ private:
const G4ParticleDefinition* muonMinus;
const G4ParticleDefinition* proton;
G4ProductionCuts* cuts;
G4DataVector cuts;
G4ProductionCuts* pcuts;
std::vector<const G4MaterialCutsCouple*> couples;
G4String currentParticleName;
@@ -192,30 +202,33 @@ private:
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4EnergyLossForExtrapolator::EnergyAfterStep(G4double kinEnergy,
G4double step,
const G4Material* mat,
const G4String& name)
inline G4double
G4EnergyLossForExtrapolator::EnergyAfterStep(G4double kinEnergy,
G4double step,
const G4Material* mat,
const G4String& name)
{
return EnergyAfterStep(kinEnergy,step,mat,FindParticle(name));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4EnergyLossForExtrapolator::EnergyBeforeStep(G4double kinEnergy,
G4double step,
const G4Material* mat,
const G4String& name)
inline G4double
G4EnergyLossForExtrapolator::EnergyBeforeStep(G4double kinEnergy,
G4double step,
const G4Material* mat,
const G4String& name)
{
return EnergyBeforeStep(kinEnergy,step,mat,FindParticle(name));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4EnergyLossForExtrapolator::AverageScatteringAngle(G4double kinEnergy,
G4double step,
const G4Material* mat,
const G4String& name)
inline G4double
G4EnergyLossForExtrapolator::AverageScatteringAngle(G4double kinEnergy,
G4double step,
const G4Material* mat,
const G4String& name)
{
return AverageScatteringAngle(kinEnergy,step,mat,FindParticle(name));
}
@@ -243,7 +256,8 @@ G4EnergyLossForExtrapolator::AverageScatteringAngle(G4double kinEnergy,
if(SetupKinematics(part, mat, kinEnergy)) {
G4double t = stepLength/radLength;
G4double y = std::max(0.001, t);
theta = 19.23*CLHEP::MeV*std::sqrt(charge2*t)*(1.0 + 0.038*std::log(y))/(beta2*gam*mass);
theta = 19.23*CLHEP::MeV*std::sqrt(charge2*t)*(1.0 + 0.038*G4Log(y))
/(beta2*gam*mass);
}
return theta;
}
@@ -262,11 +276,11 @@ G4EnergyLossForExtrapolator::ComputeTrueStep(const G4Material* mat,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4EnergyLossForExtrapolator::EnergyDispersion(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
inline G4double
G4EnergyLossForExtrapolator::EnergyDispersion(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
{
G4double sig2 = 0.0;
if(SetupKinematics(part, mat, kinEnergy)) {
@@ -278,8 +292,9 @@ G4double G4EnergyLossForExtrapolator::EnergyDispersion(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4EnergyLossForExtrapolator::ComputeValue(G4double x,
const G4PhysicsTable* table)
inline G4double
G4EnergyLossForExtrapolator::ComputeValue(G4double x,
const G4PhysicsTable* table)
{
G4double res = 0.0;
G4bool b;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuBetheBlochModel.hh 68035 2013-03-13 14:12:34Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuBremsstrahlung.hh 72942 2013-08-14 13:37:37Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -90,9 +90,10 @@ public:
const G4Material*,
G4double cut);
// Print out of the class parameters
virtual void PrintInfo();
inline void SetLowestKineticEnergy(G4double e);
protected:
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*,
@@ -103,8 +104,7 @@ private:
G4MuBremsstrahlung & operator=(const G4MuBremsstrahlung &right);
G4MuBremsstrahlung(const G4MuBremsstrahlung&);
const G4ParticleDefinition* theParticle;
const G4ParticleDefinition* theBaseParticle;
protected:
G4double lowestKinEnergy;
G4bool isInitialised;
@@ -113,4 +113,11 @@ private:
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4MuBremsstrahlung::SetLowestKineticEnergy(G4double e)
{
lowestKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuBremsstrahlungModel.hh 72114 2013-07-10 09:37:26Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -47,6 +47,7 @@
// 11-10-07 Add ignoreCut flag (V.Ivanchenko)
// 28-02-08 Reorganized protected methods and members (V.Ivanchenko)
// 06-03-08 Remove obsolete methods and members (V.Ivanchenko)
// 31-05-13 Use element selectors instead of local data (V.Ivanchenko)
//
//
@@ -80,6 +81,9 @@ public:
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&);
virtual void InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel* masterModel);
virtual G4double MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*);
@@ -103,6 +107,9 @@ public:
inline void SetLowestKineticEnergy(G4double e);
virtual G4double MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*, G4double);
protected:
G4double ComputMuBremLoss(G4double Z, G4double tkin, G4double cut);
@@ -119,11 +126,6 @@ protected:
private:
G4DataVector* ComputePartialSumSigma(const G4Material* material,
G4double tkin, G4double cut);
const G4Element* SelectRandomAtom(const G4MaterialCutsCouple* couple) const;
// hide assignment operator
G4MuBremsstrahlungModel & operator=(const G4MuBremsstrahlungModel &right);
G4MuBremsstrahlungModel(const G4MuBremsstrahlungModel&);
@@ -150,9 +152,10 @@ private:
G4double lowestKinEnergy;
G4double minThreshold;
G4double fDN[93];
static const G4double xgi[6];
static const G4double wgi[6];
std::vector<G4DataVector*> partialSumSigma;
static G4double fDN[93];
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuIonisation.hh 68035 2013-03-13 14:12:34Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuMultipleScattering.hh 68035 2013-03-13 14:12:34Z gcosmo $
//
// -----------------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuPairProduction.hh 72942 2013-08-14 13:37:37Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -70,7 +70,6 @@
#include "globals.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4VEmModel.hh"
class G4MuPairProduction : public G4VEnergyLossProcess
{
@@ -85,9 +84,10 @@ public:
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition* p,
const G4Material*, G4double cut);
// Print out of the class parameters
virtual void PrintInfo();
inline void SetLowestKineticEnergy(G4double e);
protected:
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*,
@@ -98,8 +98,9 @@ private:
G4MuPairProduction & operator=(const G4MuPairProduction &right);
G4MuPairProduction(const G4MuPairProduction&);
protected:
const G4ParticleDefinition* theParticle;
const G4ParticleDefinition* theBaseParticle;
G4double lowestKinEnergy;
G4bool isInitialised;
@@ -107,4 +108,11 @@ private:
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4MuPairProduction::SetLowestKineticEnergy(G4double e)
{
lowestKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuPairProductionModel.hh 74544 2013-10-14 12:40:29Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -62,6 +62,8 @@
#include "G4VEmModel.hh"
#include "G4NistManager.hh"
#include "G4ElementData.hh"
#include "G4Physics2DVector.hh"
#include <vector>
class G4Element;
@@ -78,6 +80,9 @@ public:
virtual ~G4MuPairProductionModel();
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&);
virtual void InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel* masterModel);
virtual G4double ComputeCrossSectionPerAtom(
const G4ParticleDefinition*,
@@ -97,8 +102,9 @@ public:
G4double tmin,
G4double maxEnergy);
virtual G4double MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*);
virtual G4double MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*,
G4double);
inline void SetLowestKineticEnergy(G4double e);
@@ -117,24 +123,17 @@ protected:
G4double Z,
G4double pairEnergy);
virtual G4double MaxSecondaryEnergy(const G4ParticleDefinition*,
G4double kineticEnergy);
inline void SetCurrentElement(G4double Z);
inline G4double MaxSecondaryEnergyForElement(G4double kineticEnergy,
G4double Z);
private:
const G4Element* SelectRandomAtom(G4double kinEnergy,
G4double dt,
G4int it,
const G4MaterialCutsCouple* couple,
G4double tmin);
void MakeSamplingTables();
inline G4double InterpolatedIntegralCrossSection(
G4double dt, G4double dz, G4int iz,
G4int it, G4int iy, G4double z);
void DataCorrupted(G4int Z, G4double logTkin);
inline G4double FindScaledEnergy(G4int Z, G4double rand, G4double logTkin,
G4double yymin, G4double yymax);
// hide assignment operator
G4MuPairProductionModel & operator=(const G4MuPairProductionModel &right);
@@ -148,12 +147,12 @@ protected:
G4double factorForCross;
G4double sqrte;
G4double particleMass;
G4double currentZ;
G4double z13;
G4double z23;
G4double lnZ;
G4int currentZ;
static G4double xgi[8],wgi[8];
static const G4double xgi[8],wgi[8];
private:
@@ -164,20 +163,19 @@ private:
G4double minPairEnergy;
G4double lowestKinEnergy;
// tables for sampling
G4int nzdat;
G4int ntdat;
G4int nbiny;
size_t nmaxElements;
static G4double zdat[5], adat[5], tdat[8];
G4double ya[1001], proba[5][8][1001];
// gamma energy bins
G4int nYBinPerDecade;
size_t nbiny;
size_t nbine;
G4double ymin;
G4double ymax;
G4double dy;
G4double emin;
G4double emax;
G4bool samplingTablesAreFilled;
std::vector<G4double> partialSum;
static const G4int zdat[5];
static const G4double adat[5];
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -200,30 +198,39 @@ void G4MuPairProductionModel::SetParticle(const G4ParticleDefinition* p)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4MuPairProductionModel::SetCurrentElement(G4double Z)
inline G4double
G4MuPairProductionModel::MaxSecondaryEnergyForElement(G4double kineticEnergy,
G4double ZZ)
{
G4int Z = G4lrint(ZZ);
if(Z != currentZ) {
currentZ = Z;
G4int iz = G4int(Z);
z13 = nist->GetZ13(iz);
z13 = nist->GetZ13(Z);
z23 = z13*z13;
lnZ = nist->GetLOGZ(iz);
lnZ = nist->GetLOGZ(Z);
}
return kineticEnergy + particleMass*(1.0 - 0.75*sqrte*z13);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4MuPairProductionModel::InterpolatedIntegralCrossSection(
G4double dt, G4double dz,
G4int iz, G4int it, G4int iy, G4double z)
inline G4double
G4MuPairProductionModel::FindScaledEnergy(G4int Z, G4double rand,
G4double logTkin,
G4double yymin, G4double yymax)
{
G4double fac = 1./(zdat[iz] *(zdat[iz] +1.));
G4double fac1 = 1./(zdat[iz-1]*(zdat[iz-1]+1.));
G4double f0 = fac1*proba[iz-1][it-1][iy] +
(fac*proba[iz][it-1][iy]-fac1*proba[iz-1][it-1][iy])*dz;
G4double f1 = fac1*proba[iz-1][it ][iy] +
(fac*proba[iz][it ][iy]-fac1*proba[iz-1][it ][iy])*dz;
return (f0 + (f1-f0)*dt)*z*(z+1.);
G4double res = yymin;
G4Physics2DVector* pv = fElementData->GetElement2DData(Z);
if(!pv) {
DataCorrupted(Z, logTkin);
} else {
G4double pmin = pv->Value(yymin, logTkin);
G4double pmax = pv->Value(yymax, logTkin);
G4double p0 = pv->Value(0.0, logTkin);
if(p0 <= 0.0) { DataCorrupted(Z, logTkin); }
else { res = pv->FindLinearX((pmin + rand*(pmax - pmin))/p0, logTkin); }
}
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -11,7 +11,7 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake,v 1.1 2010-09-29 18:53:33 bmorgan Exp $
# $Id: sources.cmake 66892 2013-01-17 10:57:59Z gunter $
#
#------------------------------------------------------------------------------
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EnergyLossForExtrapolator.cc 75168 2013-10-29 09:20:52Z gcosmo $
//
//---------------------------------------------------------------------------
//
@@ -63,7 +63,7 @@
#include "G4LossTableBuilder.hh"
#include "G4MollerBhabhaModel.hh"
#include "G4BetheBlochModel.hh"
#include "G4eBremsstrahlungModel.hh"
#include "G4eBremsstrahlungRelModel.hh"
#include "G4MuPairProductionModel.hh"
#include "G4MuBremsstrahlungModel.hh"
#include "G4ProductionCuts.hh"
@@ -84,7 +84,7 @@ G4EnergyLossForExtrapolator::G4EnergyLossForExtrapolator(G4int verb)
nbins = 70;
nmat = index = 0;
cuts = 0;
pcuts = 0;
mass = charge2 = electronDensity = radLength = bg2 = beta2
= kineticEnergy = tmax = 0;
@@ -93,7 +93,7 @@ G4EnergyLossForExtrapolator::G4EnergyLossForExtrapolator(G4int verb)
dedxElectron = dedxPositron = dedxProton = rangeElectron
= rangePositron = rangeProton = invRangeElectron = invRangePositron
= invRangeProton = mscElectron = dedxMuon = rangeMuon = invRangeMuon = 0;
cuts = 0;
electron = positron = proton = muonPlus = muonMinus = 0;
}
@@ -115,15 +115,16 @@ G4EnergyLossForExtrapolator:: ~G4EnergyLossForExtrapolator()
delete invRangeProton;
delete invRangeMuon;
delete mscElectron;
delete cuts;
delete pcuts;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EnergyLossForExtrapolator::EnergyAfterStep(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
G4double
G4EnergyLossForExtrapolator::EnergyAfterStep(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
{
if(!isInitialised) Initialisation();
G4double kinEnergyFinal = kinEnergy;
@@ -144,12 +145,13 @@ G4double G4EnergyLossForExtrapolator::EnergyAfterStep(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EnergyLossForExtrapolator::EnergyBeforeStep(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
G4double
G4EnergyLossForExtrapolator::EnergyBeforeStep(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
{
if(!isInitialised) Initialisation();
if(!isInitialised) { Initialisation(); }
G4double kinEnergyFinal = kinEnergy;
if(SetupKinematics(part, mat, kinEnergy)) {
@@ -168,19 +170,20 @@ G4double G4EnergyLossForExtrapolator::EnergyBeforeStep(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EnergyLossForExtrapolator::TrueStepLength(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
G4double
G4EnergyLossForExtrapolator::TrueStepLength(G4double kinEnergy,
G4double stepLength,
const G4Material* mat,
const G4ParticleDefinition* part)
{
G4double res = stepLength;
if(!isInitialised) Initialisation();
if(SetupKinematics(part, mat, kinEnergy)) {
if(part == electron || part == positron) {
G4double x = stepLength*ComputeValue(kinEnergy, mscElectron);
if(x < 0.2) res *= (1.0 + 0.5*x + x*x/3.0);
else if(x < 0.9999) res = -std::log(1.0 - x)*stepLength/x;
else res = ComputeRange(kinEnergy,part);
if(x < 0.2) { res *= (1.0 + 0.5*x + x*x/3.0); }
else if(x < 0.9999) { res = -G4Log(1.0 - x)*stepLength/x; }
else { res = ComputeRange(kinEnergy,part); }
} else {
res = ComputeTrueStep(mat,part,kinEnergy,stepLength);
@@ -191,9 +194,10 @@ G4double G4EnergyLossForExtrapolator::TrueStepLength(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4EnergyLossForExtrapolator::SetupKinematics(const G4ParticleDefinition* part,
const G4Material* mat,
G4double kinEnergy)
G4bool
G4EnergyLossForExtrapolator::SetupKinematics(const G4ParticleDefinition* part,
const G4Material* mat,
G4double kinEnergy)
{
if(!part || !mat || kinEnergy < keV) return false;
if(!isInitialised) Initialisation();
@@ -258,12 +262,13 @@ void G4EnergyLossForExtrapolator::Initialisation()
nmat = G4Material::GetNumberOfMaterials();
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
cuts = new G4ProductionCuts();
pcuts = new G4ProductionCuts();
couples.resize(nmat,0);
cuts.resize(nmat,DBL_MAX);
const G4MaterialCutsCouple* couple;
for(G4int i=0; i<nmat; i++) {
couple = new G4MaterialCutsCouple((*mtable)[i],cuts);
couples.push_back(couple);
couples[i] = new G4MaterialCutsCouple((*mtable)[i],pcuts);
}
dedxElectron = PrepareTable();
@@ -282,30 +287,33 @@ void G4EnergyLossForExtrapolator::Initialisation()
G4LossTableBuilder builder;
if(verbose>1)
G4cout << "### G4EnergyLossForExtrapolator Builds electron tables" << G4endl;
if(verbose>1) {
G4cout << "### G4EnergyLossForExtrapolator Builds electron tables"
<< G4endl;
}
ComputeElectronDEDX(electron, dedxElectron);
builder.BuildRangeTable(dedxElectron,rangeElectron);
builder.BuildInverseRangeTable(rangeElectron, invRangeElectron);
if(verbose>1)
G4cout << "### G4EnergyLossForExtrapolator Builds positron tables" << G4endl;
if(verbose>1) {
G4cout << "### G4EnergyLossForExtrapolator Builds positron tables"
<< G4endl;
}
ComputeElectronDEDX(positron, dedxPositron);
builder.BuildRangeTable(dedxPositron, rangePositron);
builder.BuildInverseRangeTable(rangePositron, invRangePositron);
if(verbose>1)
if(verbose>1) {
G4cout << "### G4EnergyLossForExtrapolator Builds muon tables" << G4endl;
}
ComputeMuonDEDX(muonPlus, dedxMuon);
builder.BuildRangeTable(dedxMuon, rangeMuon);
builder.BuildInverseRangeTable(rangeMuon, invRangeMuon);
if(verbose>1)
G4cout << "### G4EnergyLossForExtrapolator Builds proton tables" << G4endl;
if(verbose>1) {
G4cout << "### G4EnergyLossForExtrapolator Builds proton tables"
<< G4endl;
}
ComputeProtonDEDX(proton, dedxProton);
builder.BuildRangeTable(dedxProton, rangeProton);
builder.BuildInverseRangeTable(rangeProton, invRangeProton);
@@ -330,7 +338,8 @@ G4PhysicsTable* G4EnergyLossForExtrapolator::PrepareTable()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4ParticleDefinition* G4EnergyLossForExtrapolator::FindParticle(const G4String& name)
const G4ParticleDefinition*
G4EnergyLossForExtrapolator::FindParticle(const G4String& name)
{
const G4ParticleDefinition* p = 0;
if(name != currentParticleName) {
@@ -347,8 +356,9 @@ const G4ParticleDefinition* G4EnergyLossForExtrapolator::FindParticle(const G4St
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EnergyLossForExtrapolator::ComputeDEDX(G4double kinEnergy,
const G4ParticleDefinition* part)
G4double
G4EnergyLossForExtrapolator::ComputeDEDX(G4double kinEnergy,
const G4ParticleDefinition* part)
{
G4double x = 0.0;
if(part == electron) x = ComputeValue(kinEnergy, dedxElectron);
@@ -364,8 +374,9 @@ G4double G4EnergyLossForExtrapolator::ComputeDEDX(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EnergyLossForExtrapolator::ComputeRange(G4double kinEnergy,
const G4ParticleDefinition* part)
G4double
G4EnergyLossForExtrapolator::ComputeRange(G4double kinEnergy,
const G4ParticleDefinition* part)
{
G4double x = 0.0;
if(part == electron) x = ComputeValue(kinEnergy, rangeElectron);
@@ -382,8 +393,9 @@ G4double G4EnergyLossForExtrapolator::ComputeRange(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EnergyLossForExtrapolator::ComputeEnergy(G4double range,
const G4ParticleDefinition* part)
G4double
G4EnergyLossForExtrapolator::ComputeEnergy(G4double range,
const G4ParticleDefinition* part)
{
G4double x = 0.0;
if(part == electron) x = ComputeValue(range, invRangeElectron);
@@ -400,14 +412,14 @@ G4double G4EnergyLossForExtrapolator::ComputeEnergy(G4double range,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EnergyLossForExtrapolator::ComputeElectronDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table)
void G4EnergyLossForExtrapolator::ComputeElectronDEDX(
const G4ParticleDefinition* part,
G4PhysicsTable* table)
{
G4DataVector v;
G4MollerBhabhaModel* ioni = new G4MollerBhabhaModel();
G4eBremsstrahlungModel* brem = new G4eBremsstrahlungModel();
ioni->Initialise(part, v);
brem->Initialise(part, v);
G4eBremsstrahlungRelModel* brem = new G4eBremsstrahlungRelModel();
ioni->Initialise(part, cuts);
brem->Initialise(part, cuts);
mass = electron_mass_c2;
charge2 = 1.0;
@@ -430,12 +442,15 @@ void G4EnergyLossForExtrapolator::ComputeElectronDEDX(const G4ParticleDefinition
for(G4int j=0; j<=nbins; j++) {
G4double e = aVector->Energy(j);
G4double dedx = ioni->ComputeDEDX(couple,part,e,e) + brem->ComputeDEDX(couple,part,e,e);
G4double dedx = ioni->ComputeDEDX(couple,part,e,e)
+ brem->ComputeDEDX(couple,part,e,e);
if(1<verbose) {
G4cout << "j= " << j
<< " e(MeV)= " << e/MeV
<< " dedx(Mev/cm)= " << dedx*cm/MeV
<< " dedx(Mev.cm2/g)= " << dedx/((MeV*mat->GetDensity())/(g/cm2)) << G4endl;
<< " dedx(Mev.cm2/g)= "
<< dedx/((MeV*mat->GetDensity())/(g/cm2))
<< G4endl;
}
aVector->PutValue(j,dedx);
}
@@ -446,16 +461,16 @@ void G4EnergyLossForExtrapolator::ComputeElectronDEDX(const G4ParticleDefinition
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EnergyLossForExtrapolator::ComputeMuonDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table)
void
G4EnergyLossForExtrapolator::ComputeMuonDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table)
{
G4DataVector v;
G4BetheBlochModel* ioni = new G4BetheBlochModel();
G4MuPairProductionModel* pair = new G4MuPairProductionModel();
G4MuBremsstrahlungModel* brem = new G4MuBremsstrahlungModel();
ioni->Initialise(part, v);
pair->Initialise(part, v);
brem->Initialise(part, v);
ioni->Initialise(part, cuts);
pair->Initialise(part, cuts);
brem->Initialise(part, cuts);
mass = part->GetPDGMass();
charge2 = 1.0;
@@ -464,15 +479,17 @@ void G4EnergyLossForExtrapolator::ComputeMuonDEDX(const G4ParticleDefinition* pa
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
if(0<verbose) {
G4cout << "G4EnergyLossForExtrapolator::ComputeMuonDEDX for " << part->GetParticleName()
G4cout << "G4EnergyLossForExtrapolator::ComputeMuonDEDX for "
<< part->GetParticleName()
<< G4endl;
}
for(G4int i=0; i<nmat; i++) {
const G4Material* mat = (*mtable)[i];
if(1<verbose)
if(1<verbose) {
G4cout << "i= " << i << " mat= " << mat->GetName() << G4endl;
}
const G4MaterialCutsCouple* couple = couples[i];
G4PhysicsVector* aVector = (*table)[i];
for(G4int j=0; j<=nbins; j++) {
@@ -486,7 +503,8 @@ void G4EnergyLossForExtrapolator::ComputeMuonDEDX(const G4ParticleDefinition* pa
G4cout << "j= " << j
<< " e(MeV)= " << e/MeV
<< " dedx(Mev/cm)= " << dedx*cm/MeV
<< " dedx(Mev/(g/cm2)= " << dedx/((MeV*mat->GetDensity())/(g/cm2)) << G4endl;
<< " dedx(Mev/(g/cm2)= " << dedx/((MeV*mat->GetDensity())/(g/cm2))
<< G4endl;
}
}
}
@@ -495,12 +513,12 @@ void G4EnergyLossForExtrapolator::ComputeMuonDEDX(const G4ParticleDefinition* pa
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EnergyLossForExtrapolator::ComputeProtonDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table)
void
G4EnergyLossForExtrapolator::ComputeProtonDEDX(const G4ParticleDefinition* part,
G4PhysicsTable* table)
{
G4DataVector v;
G4BetheBlochModel* ioni = new G4BetheBlochModel();
ioni->Initialise(part, v);
ioni->Initialise(part, cuts);
mass = part->GetPDGMass();
charge2 = 1.0;
@@ -509,7 +527,8 @@ void G4EnergyLossForExtrapolator::ComputeProtonDEDX(const G4ParticleDefinition*
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
if(0<verbose) {
G4cout << "G4EnergyLossForExtrapolator::ComputeProtonDEDX for " << part->GetParticleName()
G4cout << "G4EnergyLossForExtrapolator::ComputeProtonDEDX for "
<< part->GetParticleName()
<< G4endl;
}
@@ -529,7 +548,8 @@ void G4EnergyLossForExtrapolator::ComputeProtonDEDX(const G4ParticleDefinition*
G4cout << "j= " << j
<< " e(MeV)= " << e/MeV
<< " dedx(Mev/cm)= " << dedx*cm/MeV
<< " dedx(Mev.cm2/g)= " << dedx/((mat->GetDensity())/(g/cm2)) << G4endl;
<< " dedx(Mev.cm2/g)= " << dedx/((mat->GetDensity())/(g/cm2))
<< G4endl;
}
}
}
@@ -538,13 +558,13 @@ void G4EnergyLossForExtrapolator::ComputeProtonDEDX(const G4ParticleDefinition*
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EnergyLossForExtrapolator::ComputeTrasportXS(const G4ParticleDefinition* part,
G4PhysicsTable* table)
void
G4EnergyLossForExtrapolator::ComputeTrasportXS(const G4ParticleDefinition* part,
G4PhysicsTable* table)
{
G4DataVector v;
G4WentzelVIModel* msc = new G4WentzelVIModel();
msc->SetPolarAngleLimit(CLHEP::pi);
msc->Initialise(part, v);
msc->Initialise(part, cuts);
mass = part->GetPDGMass();
charge2 = 1.0;
@@ -553,7 +573,8 @@ void G4EnergyLossForExtrapolator::ComputeTrasportXS(const G4ParticleDefinition*
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
if(0<verbose) {
G4cout << "G4EnergyLossForExtrapolator::ComputeProtonDEDX for " << part->GetParticleName()
G4cout << "G4EnergyLossForExtrapolator::ComputeProtonDEDX for "
<< part->GetParticleName()
<< G4endl;
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuBetheBlochModel.cc 74019 2013-09-19 13:35:34Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -52,7 +52,6 @@
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -64,6 +63,8 @@
#include "G4LossTableManager.hh"
#include "G4EmCorrections.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
G4double G4MuBetheBlochModel::xgi[]={ 0.0199, 0.1017, 0.2372, 0.4083, 0.5917,
0.7628, 0.8983, 0.9801 };
@@ -80,8 +81,8 @@ G4MuBetheBlochModel::G4MuBetheBlochModel(const G4ParticleDefinition* p,
: G4VEmModel(nam),
particle(0),
limitKinEnergy(100.*keV),
logLimitKinEnergy(log(limitKinEnergy)),
twoln10(2.0*log(10.0)),
logLimitKinEnergy(G4Log(limitKinEnergy)),
twoln10(2.0*G4Log(10.0)),
bg2lim(0.0169),
taulim(8.4146e-3),
alphaprime(fine_structure_const/twopi)
@@ -147,22 +148,22 @@ G4double G4MuBetheBlochModel::ComputeCrossSectionPerElectron(
G4double energy2 = totEnergy*totEnergy;
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
cross = 1.0/cutEnergy - 1.0/maxEnergy - beta2*log(maxEnergy/cutEnergy)/tmax
cross = 1.0/cutEnergy - 1.0/maxEnergy - beta2*G4Log(maxEnergy/cutEnergy)/tmax
+ 0.5*(maxEnergy - cutEnergy)/energy2;
// radiative corrections of R. Kokoulin
if (maxEnergy > limitKinEnergy) {
G4double logtmax = log(maxEnergy);
G4double logtmin = log(max(cutEnergy,limitKinEnergy));
G4double logtmax = G4Log(maxEnergy);
G4double logtmin = G4Log(max(cutEnergy,limitKinEnergy));
G4double logstep = logtmax - logtmin;
G4double dcross = 0.0;
for (G4int ll=0; ll<8; ll++)
{
G4double ep = exp(logtmin + xgi[ll]*logstep);
G4double a1 = log(1.0 + 2.0*ep/electron_mass_c2);
G4double a3 = log(4.0*totEnergy*(totEnergy - ep)/massSquare);
G4double ep = G4Exp(logtmin + xgi[ll]*logstep);
G4double a1 = G4Log(1.0 + 2.0*ep/electron_mass_c2);
G4double a3 = G4Log(4.0*totEnergy*(totEnergy - ep)/massSquare);
dcross += wgi[ll]*(1.0/ep - beta2/tmax + 0.5*ep/energy2)*a1*(a3 - a1);
}
@@ -232,7 +233,7 @@ G4double G4MuBetheBlochModel::ComputeDEDXPerVolume(const G4Material* material,
G4double eDensity = material->GetElectronDensity();
G4double dedx = log(2.0*electron_mass_c2*bg2*cutEnergy/eexc2)
G4double dedx = G4Log(2.0*electron_mass_c2*bg2*cutEnergy/eexc2)
-(1.0 + cutEnergy/tmax)*beta2;
G4double totEnergy = kineticEnergy + mass;
@@ -240,7 +241,7 @@ G4double G4MuBetheBlochModel::ComputeDEDXPerVolume(const G4Material* material,
dedx += del*del;
// density correction
G4double x = log(bg2)/twoln10;
G4double x = G4Log(bg2)/twoln10;
//if ( x >= x0den ) {
// dedx -= twoln10*x - cden ;
// if ( x < x1den ) dedx -= aden*pow((x1den-x),mden) ;
@@ -257,16 +258,16 @@ G4double G4MuBetheBlochModel::ComputeDEDXPerVolume(const G4Material* material,
// radiative corrections of R. Kokoulin
if (cutEnergy > limitKinEnergy) {
G4double logtmax = log(cutEnergy);
G4double logtmax = G4Log(cutEnergy);
G4double logstep = logtmax - logLimitKinEnergy;
G4double dloss = 0.0;
G4double ftot2= 0.5/(totEnergy*totEnergy);
for (G4int ll=0; ll<8; ll++)
{
G4double ep = exp(logLimitKinEnergy + xgi[ll]*logstep);
G4double a1 = log(1.0 + 2.0*ep/electron_mass_c2);
G4double a3 = log(4.0*totEnergy*(totEnergy - ep)/massSquare);
G4double ep = G4Exp(logLimitKinEnergy + xgi[ll]*logstep);
G4double a1 = G4Log(1.0 + 2.0*ep/electron_mass_c2);
G4double a3 = G4Log(4.0*totEnergy*(totEnergy - ep)/massSquare);
dloss += wgi[ll]*(1.0 - beta2*ep/tmax + ep*ep*ftot2)*a1*(a3 - a1);
}
dedx += dloss*logstep*alphaprime;
@@ -299,7 +300,7 @@ void G4MuBetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
G4double grej = 1.;
if(tmax > limitKinEnergy) {
G4double a0 = log(2.*totEnergy/mass);
G4double a0 = G4Log(2.*totEnergy/mass);
grej += alphaprime*a0*a0;
}
@@ -316,8 +317,8 @@ void G4MuBetheBlochModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
+ 0.5*deltaKinEnergy*deltaKinEnergy/etot2;
if(deltaKinEnergy > limitKinEnergy) {
G4double a1 = log(1.0 + 2.0*deltaKinEnergy/electron_mass_c2);
G4double a3 = log(4.0*totEnergy*(totEnergy - deltaKinEnergy)/massSquare);
G4double a1 = G4Log(1.0 + 2.0*deltaKinEnergy/electron_mass_c2);
G4double a3 = G4Log(4.0*totEnergy*(totEnergy - deltaKinEnergy)/massSquare);
f *= (1. + alphaprime*a1*(a3 - a1));
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuBremsstrahlung.cc 72942 2013-08-14 13:37:37Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -66,10 +66,7 @@
#include "G4MuBremsstrahlung.hh"
#include "G4SystemOfUnits.hh"
#include "G4Gamma.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
#include "G4MuBremsstrahlungModel.hh"
#include "G4UniversalFluctuation.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -77,8 +74,6 @@ using namespace std;
G4MuBremsstrahlung::G4MuBremsstrahlung(const G4String& name)
: G4VEnergyLossProcess(name),
theParticle(0),
theBaseParticle(0),
lowestKinEnergy(1.*GeV),
isInitialised(false)
{
@@ -111,15 +106,13 @@ G4double G4MuBremsstrahlung::MinPrimaryEnergy(const G4ParticleDefinition*,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuBremsstrahlung::InitialiseEnergyLossProcess(
const G4ParticleDefinition* part,
const G4ParticleDefinition*,
const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
theParticle = part;
if (!EmModel()) { SetEmModel(new G4MuBremsstrahlungModel()); }
G4VEmFluctuationModel* fm = 0;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuBremsstrahlungModel.cc 75168 2013-10-29 09:20:52Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -50,6 +50,7 @@
// 21-03-06 Fix problem of initialisation in case when cuts are not defined (VI)
// 07-11-07 Improve sampling of final state (A.Bogdanov)
// 28-02-08 Use precomputed Z^1/3 and Log(A) (V.Ivanchenko)
// 31-05-13 Use element selectors instead of local data structure (V.Ivanchenko)
//
//
@@ -73,36 +74,48 @@
#include "G4ElementVector.hh"
#include "G4ProductionCutsTable.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4LossTableManager.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
const G4double G4MuBremsstrahlungModel::xgi[] =
{0.03377,0.16940,0.38069,0.61931,0.83060,0.96623};
const G4double G4MuBremsstrahlungModel::wgi[] =
{0.08566,0.18038,0.23396,0.23396,0.18038,0.08566};
G4double G4MuBremsstrahlungModel::fDN[] = {0.0};
G4MuBremsstrahlungModel::G4MuBremsstrahlungModel(const G4ParticleDefinition* p,
const G4String& nam)
: G4VEmModel(nam),
particle(0),
sqrte(sqrt(exp(1.))),
sqrte(sqrt(G4Exp(1.))),
bh(202.4),
bh1(446.),
btf(183.),
btf1(1429.),
fParticleChange(0),
lowestKinEnergy(1.0*GeV),
minThreshold(1.0*keV)
minThreshold(0.9*keV)
{
theGamma = G4Gamma::Gamma();
nist = G4NistManager::Instance();
lowestKinEnergy = 1.*GeV;
mass = rmass = cc = coeff = 1.0;
fDN[0] = 0.0;
for(G4int i=1; i<93; ++i) {
G4double dn = 1.54*nist->GetA27(i);
fDN[i] = dn;
if(1 < i) {
fDN[i] /= std::pow(dn, 1./G4double(i));
if(0.0 == fDN[1]) {
for(G4int i=1; i<93; ++i) {
G4double dn = 1.54*nist->GetA27(i);
fDN[i] = dn;
if(1 < i) {
fDN[i] /= std::pow(dn, 1./G4double(i));
}
}
}
@@ -112,73 +125,48 @@ G4MuBremsstrahlungModel::G4MuBremsstrahlungModel(const G4ParticleDefinition* p,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4MuBremsstrahlungModel::~G4MuBremsstrahlungModel()
{
size_t n = partialSumSigma.size();
if(n > 0) {
for(size_t i=0; i<n; i++) {
delete partialSumSigma[i];
}
}
}
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuBremsstrahlungModel::MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*)
const G4MaterialCutsCouple*)
{
return minThreshold;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuBremsstrahlungModel::MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*,
G4double cut)
{
return std::max(lowestKinEnergy,cut);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MuBremsstrahlungModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if(p) { SetParticle(p); }
// partial cross section is computed for fixed energy
G4double fixedEnergy = 0.5*HighEnergyLimit();
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
if(theCoupleTable) {
G4int numOfCouples = theCoupleTable->GetTableSize();
G4int nn = partialSumSigma.size();
G4int nc = cuts.size();
// do we need to perform initialisation?
if(nn == numOfCouples) { return; }
// clear old data
if(nn > 0) {
for (G4int ii=0; ii<nn; ii++){
G4DataVector* a = partialSumSigma[ii];
if ( a ) { delete a; }
}
partialSumSigma.clear();
}
// fill new data
if (numOfCouples>0) {
for (G4int i=0; i<numOfCouples; i++) {
G4double cute = DBL_MAX;
// protection for usage with extrapolator
if(i < nc) { cute = cuts[i]; }
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
const G4Material* material = couple->GetMaterial();
G4DataVector* dv = ComputePartialSumSigma(material,fixedEnergy,cute);
partialSumSigma.push_back(dv);
}
}
}
if(IsMaster() && p == particle) { InitialiseElementSelectors(p, cuts); }
// define pointer to G4ParticleChange
if(!fParticleChange) { fParticleChange = GetParticleChangeForLoss(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuBremsstrahlungModel::InitialiseLocal(const G4ParticleDefinition* p,
G4VEmModel* masterModel)
{
if(p == particle) {
SetElementSelectors(masterModel->GetElementSelectors());
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuBremsstrahlungModel::ComputeDEDXPerVolume(
@@ -188,11 +176,11 @@ G4double G4MuBremsstrahlungModel::ComputeDEDXPerVolume(
G4double cutEnergy)
{
G4double dedx = 0.0;
if (kineticEnergy <= lowestKinEnergy) return dedx;
if (kineticEnergy <= lowestKinEnergy) { return dedx; }
G4double tmax = kineticEnergy;
G4double cut = std::min(cutEnergy,tmax);
if(cut < minThreshold) cut = minThreshold;
if(cut < minThreshold) { cut = minThreshold; }
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomicNumDensityVector =
@@ -217,10 +205,8 @@ G4double G4MuBremsstrahlungModel::ComputMuBremLoss(G4double Z,
G4double tkin, G4double cut)
{
G4double totalEnergy = mass + tkin;
G4double ak1 = 0.05;
G4int k2=5;
G4double xgi[]={0.03377,0.16940,0.38069,0.61931,0.83060,0.96623};
G4double wgi[]={0.08566,0.18038,0.23396,0.23396,0.18038,0.08566};
static const G4double ak1 = 0.05;
static const G4int k2=5;
G4double loss = 0.;
G4double vcut = cut/totalEnergy;
@@ -228,9 +214,11 @@ G4double G4MuBremsstrahlungModel::ComputMuBremLoss(G4double Z,
G4double aaa = 0.;
G4double bbb = vcut;
if(vcut>vmax) bbb=vmax ;
G4int kkk = (G4int)((bbb-aaa)/ak1)+k2 ;
G4double hhh=(bbb-aaa)/float(kkk) ;
if(vcut>vmax) { bbb = vmax; }
G4int kkk = (G4int)((bbb-aaa)/ak1)+k2;
if(kkk < 1) { kkk = 1; }
G4double hhh=(bbb-aaa)/G4double(kkk);
G4double aa = aaa;
for(G4int l=0; l<kkk; l++)
@@ -256,10 +244,8 @@ G4double G4MuBremsstrahlungModel::ComputeMicroscopicCrossSection(
G4double cut)
{
G4double totalEnergy = tkin + mass;
G4double ak1 = 2.3;
G4int k2 = 4;
G4double xgi[]={0.03377,0.16940,0.38069,0.61931,0.83060,0.96623};
G4double wgi[]={0.08566,0.18038,0.23396,0.23396,0.18038,0.08566};
static const G4double ak1 = 2.3;
static const G4int k2 = 4;
G4double cross = 0.;
if(cut >= tkin) return cross;
@@ -267,9 +253,11 @@ G4double G4MuBremsstrahlungModel::ComputeMicroscopicCrossSection(
G4double vcut = cut/totalEnergy;
G4double vmax = tkin/totalEnergy;
G4double aaa = log(vcut);
G4double bbb = log(vmax);
G4double aaa = G4Log(vcut);
G4double bbb = G4Log(vmax);
G4int kkk = (G4int)((bbb-aaa)/ak1)+k2 ;
if(kkk < 1) { kkk = 1; }
G4double hhh = (bbb-aaa)/G4double(kkk);
G4double aa = aaa;
@@ -278,7 +266,7 @@ G4double G4MuBremsstrahlungModel::ComputeMicroscopicCrossSection(
{
for(G4int i=0; i<6; i++)
{
G4double ep = exp(aa + xgi[i]*hhh)*totalEnergy;
G4double ep = G4Exp(aa + xgi[i]*hhh)*totalEnergy;
cross += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, ep);
}
aa += hhh;
@@ -301,16 +289,16 @@ G4double G4MuBremsstrahlungModel::ComputeDMicroscopicCrossSection(
{
G4double dxsection = 0.;
if( gammaEnergy > tkin) return dxsection ;
if(gammaEnergy > tkin) { return dxsection; }
G4double E = tkin + mass ;
G4double v = gammaEnergy/E ;
G4double delta = 0.5*mass*mass*v/(E-gammaEnergy) ;
G4double rab0=delta*sqrte ;
G4double rab0 = delta*sqrte ;
G4int iz = G4int(Z);
if(iz < 1) iz = 1;
else if(iz > 92) iz = 92;
G4int iz = G4lrint(Z);
if(iz < 1) { iz = 1; }
else if(iz > 92) { iz = 92; }
G4double z13 = 1.0/nist->GetZ13(iz);
G4double dnstar = fDN[iz];
@@ -327,18 +315,18 @@ G4double G4MuBremsstrahlungModel::ComputeDMicroscopicCrossSection(
// nucleus contribution logarithm
G4double rab1=b*z13;
G4double fn=log(rab1/(dnstar*(electron_mass_c2+rab0*rab1))*
G4double fn=G4Log(rab1/(dnstar*(electron_mass_c2+rab0*rab1))*
(mass+delta*(dnstar*sqrte-2.))) ;
if(fn <0.) fn = 0. ;
if(fn <0.) { fn = 0.; }
// electron contribution logarithm
G4double epmax1=E/(1.+0.5*mass*rmass/E) ;
G4double fe=0.;
if(gammaEnergy<epmax1)
{
G4double rab2=b1*z13*z13 ;
fe=log(rab2*mass/((1.+delta*rmass/(electron_mass_c2*sqrte))*
fe=G4Log(rab2*mass/((1.+delta*rmass/(electron_mass_c2*sqrte))*
(electron_mass_c2+rab0*rab2))) ;
if(fe<0.) fe=0. ;
if(fe<0.) { fe=0.; }
}
dxsection = coeff*(1.-v*(1. - 0.75*v))*Z*(fn*Z + fe)/gammaEnergy;
@@ -371,35 +359,6 @@ G4double G4MuBremsstrahlungModel::ComputeCrossSectionPerAtom(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4DataVector* G4MuBremsstrahlungModel::ComputePartialSumSigma(
const G4Material* material,
G4double kineticEnergy,
G4double cut)
// Build the table of cross section per element.
// The table is built for material
// This table is used to select randomly an element in the material.
{
G4int nElements = material->GetNumberOfElements();
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector =
material->GetAtomicNumDensityVector();
G4DataVector* dv = new G4DataVector();
G4double cross = 0.0;
for (G4int i=0; i<nElements; i++ ) {
cross += theAtomNumDensityVector[i]
* ComputeMicroscopicCrossSection(kineticEnergy,
(*theElementVector)[i]->GetZ(), cut);
dv->push_back(cross);
}
return dv;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MuBremsstrahlungModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
@@ -419,7 +378,7 @@ void G4MuBremsstrahlungModel::SampleSecondaries(
G4ParticleMomentum partDirection = dp->GetMomentumDirection();
// select randomly one element constituing the material
const G4Element* anElement = SelectRandomAtom(couple);
const G4Element* anElement = SelectRandomAtom(couple,particle,kineticEnergy);
G4double Z = anElement->GetZ();
G4double totalEnergy = kineticEnergy + mass;
@@ -431,12 +390,12 @@ void G4MuBremsstrahlungModel::SampleSecondaries(
G4double lnepksi, epksi;
G4double func2;
G4double xmin = log(tmin/MeV);
G4double xmax = log(kineticEnergy/tmin);
G4double xmin = G4Log(tmin/MeV);
G4double xmax = G4Log(kineticEnergy/tmin);
do {
lnepksi = xmin + G4UniformRand()*xmax;
epksi = MeV*exp(lnepksi);
epksi = MeV*G4Exp(lnepksi);
func2 = epksi*ComputeDMicroscopicCrossSection(kineticEnergy,Z,epksi);
} while(func2 < func1*G4UniformRand());
@@ -474,24 +433,3 @@ void G4MuBremsstrahlungModel::SampleSecondaries(
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4Element* G4MuBremsstrahlungModel::SelectRandomAtom(
const G4MaterialCutsCouple* couple) const
{
// select randomly 1 element within the material
const G4Material* material = couple->GetMaterial();
G4int nElements = material->GetNumberOfElements();
const G4ElementVector* theElementVector = material->GetElementVector();
if(1 == nElements) { return (*theElementVector)[0]; }
else if(1 > nElements) { return 0; }
G4DataVector* dv = partialSumSigma[couple->GetIndex()];
G4double rval = G4UniformRand()*((*dv)[nElements-1]);
for (G4int i=0; i<nElements; i++) {
if (rval <= (*dv)[i]) { return (*theElementVector)[i]; }
}
return (*theElementVector)[nElements-1];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuIonisation.cc 68035 2013-03-13 14:12:34Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuMultipleScattering.cc 68035 2013-03-13 14:12:34Z gcosmo $
//
// -----------------------------------------------------------------------------
//
@@ -47,7 +47,7 @@
#include "G4MuMultipleScattering.hh"
#include "G4SystemOfUnits.hh"
#include "G4WentzelVIModel.hh"
#include "G4UrbanMscModel95.hh"
#include "G4UrbanMscModel.hh"
#include "G4MscStepLimitType.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -79,7 +79,7 @@ void G4MuMultipleScattering::InitialiseProcess(const G4ParticleDefinition*)
{
// Modification of parameters between runs
if(isInitialized) { return; }
if(!EmModel(1)) { SetEmModel(new G4UrbanMscModel95(), 1); }
if(!EmModel(1)) { SetEmModel(new G4UrbanMscModel(), 1); }
AddEmModel(1, EmModel(1));
isInitialized = true;
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuPairProduction.cc 72942 2013-08-14 13:37:37Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -71,12 +71,10 @@
#include "G4MuPairProduction.hh"
#include "G4SystemOfUnits.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
#include "G4VEmModel.hh"
#include "G4MuPairProductionModel.hh"
#include "G4UniversalFluctuation.hh"
#include "G4ElementData.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -85,7 +83,6 @@ using namespace std;
G4MuPairProduction::G4MuPairProduction(const G4String& name)
: G4VEnergyLossProcess(name),
theParticle(0),
theBaseParticle(0),
lowestKinEnergy(1.*GeV),
isInitialised(false)
{
@@ -126,7 +123,10 @@ void G4MuPairProduction::InitialiseEnergyLossProcess(
theParticle = part;
if (!EmModel()) { SetEmModel(new G4MuPairProductionModel()); }
if (!EmModel()) { SetEmModel(new G4MuPairProductionModel(part)); }
G4double limit = part->GetPDGMass()*8;
if(limit > lowestKinEnergy) { lowestKinEnergy = limit; }
G4VEmFluctuationModel* fm = 0;
EmModel()->SetLowEnergyLimit(MinKinEnergy());
@@ -138,7 +138,22 @@ void G4MuPairProduction::InitialiseEnergyLossProcess(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuPairProduction::PrintInfo()
{}
{
G4ElementData* ed = EmModel()->GetElementData();
if(ed) {
for(G4int Z=1; Z<93; ++Z) {
G4Physics2DVector* pv = ed->GetElement2DData(Z);
if(pv) {
G4cout << " Sampling table " << pv->GetLengthY()
<< "x" << pv->GetLengthX() << "; from "
<< exp(pv->GetY(0))/GeV << " GeV to "
<< exp(pv->GetY(pv->GetLengthY()-1))/TeV
<< " TeV " << G4endl;
break;
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4MuPairProductionModel.cc 74544 2013-10-14 12:40:29Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -83,19 +83,19 @@
#include "G4ProductionCutsTable.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// static members
//
G4double G4MuPairProductionModel::zdat[]={1., 4., 13., 29., 92.};
G4double G4MuPairProductionModel::adat[]={1.01, 9.01, 26.98, 63.55, 238.03};
G4double G4MuPairProductionModel::tdat[]={1.e3, 1.e4, 1.e5, 1.e6, 1.e7, 1.e8,
1.e9, 1.e10};
G4double G4MuPairProductionModel::xgi[]={ 0.0199, 0.1017, 0.2372, 0.4083,
0.5917, 0.7628, 0.8983, 0.9801 };
G4double G4MuPairProductionModel::wgi[]={ 0.0506, 0.1112, 0.1569, 0.1813,
0.1813, 0.1569, 0.1112, 0.0506 };
const G4int G4MuPairProductionModel::zdat[]={1, 4, 13, 29, 92};
const G4double G4MuPairProductionModel::adat[]={1.01, 9.01,26.98, 63.55, 238.03};
const G4double G4MuPairProductionModel::xgi[]={ 0.0199, 0.1017, 0.2372, 0.4083,
0.5917, 0.7628, 0.8983, 0.9801 };
const G4double G4MuPairProductionModel::wgi[]={ 0.0506, 0.1112, 0.1569, 0.1813,
0.1813, 0.1569, 0.1112, 0.0506 };
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -107,21 +107,18 @@ G4MuPairProductionModel::G4MuPairProductionModel(const G4ParticleDefinition* p,
particle(0),
factorForCross(4.*fine_structure_const*fine_structure_const
*classic_electr_radius*classic_electr_radius/(3.*pi)),
sqrte(sqrt(exp(1.))),
sqrte(sqrt(G4Exp(1.))),
currentZ(0),
fParticleChange(0),
minPairEnergy(4.*electron_mass_c2),
lowestKinEnergy(GeV),
lowestKinEnergy(1.0*GeV),
nzdat(5),
ntdat(8),
nYBinPerDecade(4),
nbiny(1000),
nmaxElements(0),
nbine(0),
ymin(-5.),
ymax(0.),
dy((ymax-ymin)/nbiny),
samplingTablesAreFilled(false)
dy(0.005)
{
SetLowEnergyLimit(minPairEnergy);
nist = G4NistManager::Instance();
theElectron = G4Electron::Electron();
@@ -129,9 +126,14 @@ G4MuPairProductionModel::G4MuPairProductionModel(const G4ParticleDefinition* p,
particleMass = lnZ = z13 = z23 = 0;
for(size_t i=0; i<1001; ++i) { ya[i] = 0.0; }
if(p) { SetParticle(p); }
// setup lowest limit dependent on particle mass
if(p) {
SetParticle(p);
G4double limit = p->GetPDGMass()*8;
if(limit > lowestKinEnergy) { lowestKinEnergy = limit; }
}
emin = lowestKinEnergy;
emax = 10*TeV;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -141,33 +143,54 @@ G4MuPairProductionModel::~G4MuPairProductionModel()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuPairProductionModel::MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple* )
G4double G4MuPairProductionModel::MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*,
G4double cut)
{
return minPairEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuPairProductionModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
G4double kineticEnergy)
{
G4double maxPairEnergy = kineticEnergy + particleMass*(1.0 - 0.75*sqrte*z13);
return maxPairEnergy;
return std::max(lowestKinEnergy,cut);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MuPairProductionModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector&)
const G4DataVector& cuts)
{
if (!samplingTablesAreFilled) {
if(p) { SetParticle(p); }
MakeSamplingTables();
SetParticle(p);
// define scale of internal table for each thread only once
if(0 == nbine) {
emax = HighEnergyLimit();
emin = std::max(lowestKinEnergy, LowEnergyLimit());
nbine = size_t(nYBinPerDecade*std::log10(emax/emin));
if(nbine < 3) { nbine = 3; }
ymin = G4Log(minPairEnergy/emin);
dy = -ymin/G4double(nbiny);
}
if(IsMaster() && p == particle) {
if(!fElementData) {
fElementData = new G4ElementData();
MakeSamplingTables();
}
InitialiseElementSelectors(p, cuts);
}
if(!fParticleChange) { fParticleChange = GetParticleChangeForLoss(); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuPairProductionModel::InitialiseLocal(const G4ParticleDefinition* p,
G4VEmModel* masterModel)
{
if(p == particle) {
SetElementSelectors(masterModel->GetElementSelectors());
fElementData = masterModel->GetElementData();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuPairProductionModel::ComputeDEDXPerVolume(
@@ -187,8 +210,7 @@ G4double G4MuPairProductionModel::ComputeDEDXPerVolume(
// loop for elements in the material
for (size_t i=0; i<material->GetNumberOfElements(); ++i) {
G4double Z = (*theElementVector)[i]->GetZ();
SetCurrentElement(Z);
G4double tmax = MaxSecondaryEnergy(particle, kineticEnergy);
G4double tmax = MaxSecondaryEnergyForElement(kineticEnergy, Z);
G4double loss = ComputMuPairLoss(Z, kineticEnergy, cutEnergy, tmax);
dedx += loss*theAtomicNumDensityVector[i];
}
@@ -203,7 +225,6 @@ G4double G4MuPairProductionModel::ComputMuPairLoss(G4double Z,
G4double cutEnergy,
G4double tmax)
{
SetCurrentElement(Z);
G4double loss = 0.0;
G4double cut = std::min(cutEnergy,tmax);
@@ -213,10 +234,13 @@ G4double G4MuPairProductionModel::ComputMuPairLoss(G4double Z,
// numerical integration in log(PairEnergy)
G4double ak1=6.9;
G4double ak2=1.0;
G4double aaa = log(minPairEnergy);
G4double bbb = log(cut);
G4double aaa = G4Log(minPairEnergy);
G4double bbb = G4Log(cut);
G4int kkk = (G4int)((bbb-aaa)/ak1+ak2);
if (kkk > 8) kkk = 8;
if (kkk > 8) { kkk = 8; }
else if (kkk < 1) { kkk = 1; }
G4double hhh = (bbb-aaa)/(G4double)kkk;
G4double x = aaa;
@@ -225,7 +249,7 @@ G4double G4MuPairProductionModel::ComputMuPairLoss(G4double Z,
for (G4int ll=0; ll<8; ll++)
{
G4double ep = exp(x+xgi[ll]*hhh);
G4double ep = G4Exp(x+xgi[ll]*hhh);
loss += wgi[ll]*ep*ep*ComputeDMicroscopicCrossSection(tkin, Z, ep);
}
x += hhh;
@@ -240,19 +264,21 @@ G4double G4MuPairProductionModel::ComputMuPairLoss(G4double Z,
G4double G4MuPairProductionModel::ComputeMicroscopicCrossSection(
G4double tkin,
G4double Z,
G4double cut)
G4double cutEnergy)
{
G4double cross = 0.;
SetCurrentElement(Z);
G4double tmax = MaxSecondaryEnergy(particle, tkin);
G4double tmax = MaxSecondaryEnergyForElement(tkin, Z);
G4double cut = std::max(cutEnergy, minPairEnergy);
if (tmax <= cut) { return cross; }
G4double ak1=6.9 ;
G4double ak2=1.0 ;
G4double aaa = log(cut);
G4double bbb = log(tmax);
G4double aaa = G4Log(cut);
G4double bbb = G4Log(tmax);
G4int kkk = (G4int)((bbb-aaa)/ak1 + ak2);
if(kkk > 8) { kkk = 8; }
else if (kkk < 1) { kkk = 1; }
G4double hhh = (bbb-aaa)/G4double(kkk);
G4double x = aaa;
@@ -260,7 +286,7 @@ G4double G4MuPairProductionModel::ComputeMicroscopicCrossSection(
{
for(G4int i=0; i<8; ++i)
{
G4double ep = exp(x + xgi[i]*hhh);
G4double ep = G4Exp(x + xgi[i]*hhh);
cross += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, ep);
}
x += hhh;
@@ -271,6 +297,8 @@ G4double G4MuPairProductionModel::ComputeMicroscopicCrossSection(
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
G4double tkin,
G4double Z,
@@ -279,12 +307,12 @@ G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
// using the cross section formula of R.P. Kokoulin (18/01/98)
// Code modified by R.P. Kokoulin, V.N. Ivanchenko (27/01/04)
{
G4double bbbtf= 183. ;
G4double bbbh = 202.4 ;
G4double g1tf = 1.95e-5 ;
G4double g2tf = 5.3e-5 ;
G4double g1h = 4.4e-5 ;
G4double g2h = 4.8e-5 ;
static const G4double bbbtf= 183. ;
static const G4double bbbh = 202.4 ;
static const G4double g1tf = 1.95e-5 ;
static const G4double g2tf = 5.3e-5 ;
static const G4double g1h = 4.4e-5 ;
static const G4double g2h = 4.8e-5 ;
G4double totalEnergy = tkin + particleMass;
G4double residEnergy = totalEnergy - pairEnergy;
@@ -292,12 +320,10 @@ G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
G4double massratio2 = massratio*massratio ;
G4double cross = 0.;
SetCurrentElement(Z);
G4double c3 = 0.75*sqrte*particleMass;
if (residEnergy <= c3*z13) { return cross; }
G4double c7 = 4.*electron_mass_c2;
G4double c7 = 4.*CLHEP::electron_mass_c2;
G4double c8 = 6.*particleMass*particleMass;
G4double alf = c7/pairEnergy;
G4double a3 = 1. - alf;
@@ -309,10 +335,12 @@ G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
else { bbb = bbbtf; g1 = g1tf; g2 = g2tf; }
G4double zeta = 0;
G4double zeta1 = 0.073*log(totalEnergy/(particleMass+g1*z23*totalEnergy))-0.26;
G4double zeta1 =
0.073*G4Log(totalEnergy/(particleMass+g1*z23*totalEnergy))-0.26;
if ( zeta1 > 0.)
{
G4double zeta2 = 0.058*log(totalEnergy/(particleMass+g2*z13*totalEnergy))-0.14;
G4double zeta2 =
0.058*G4Log(totalEnergy/(particleMass+g2*z13*totalEnergy))-0.14;
zeta = zeta1/zeta2 ;
}
@@ -326,15 +354,15 @@ G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
G4double rta3 = sqrt(a3);
G4double tmnexp = alf/(1. + rta3) + del*rta3;
if(tmnexp >= 1.0) return cross;
if(tmnexp >= 1.0) { return cross; }
G4double tmn = log(tmnexp);
G4double tmn = G4Log(tmnexp);
G4double sum = 0.;
// Gaussian integration in ln(1-ro) ( with 8 points)
for (G4int i=0; i<8; ++i)
{
G4double a4 = exp(tmn*xgi[i]); // a4 = (1.-asymmetry)
G4double a4 = G4Exp(tmn*xgi[i]); // a4 = (1.-asymmetry)
G4double a5 = a4*(2.-a4) ;
G4double a6 = 1.-a5 ;
G4double a7 = 1.+a6 ;
@@ -344,39 +372,41 @@ G4double G4MuPairProductionModel::ComputeDMicroscopicCrossSection(
G4double xi1 = 1.+xi ;
G4double screen = screen0*xi1/a5 ;
G4double yeu = 5.-a6+4.*bet*a7 ;
G4double yed = 2.*(1.+3.*bet)*log(3.+xii)-a6-a1*(2.-a6) ;
G4double yed = 2.*(1.+3.*bet)*G4Log(3.+xii)-a6-a1*(2.-a6) ;
G4double ye1 = 1.+yeu/yed ;
G4double ale=log(bbb/z13*sqrt(xi1*ye1)/(1.+screen*ye1)) ;
G4double cre = 0.5*log(1.+2.25*z23*xi1*ye1/massratio2) ;
G4double ale = G4Log(bbb/z13*sqrt(xi1*ye1)/(1.+screen*ye1)) ;
G4double cre = 0.5*G4Log(1.+2.25*z23*xi1*ye1/massratio2) ;
G4double be;
if (xi <= 1.e3) be = ((2.+a6)*(1.+bet)+xi*a9)*log(1.+xii)+(a5-bet)/xi1-a9;
else be = (3.-a6+a1*a7)/(2.*xi);
if (xi <= 1.e3) {
be = ((2.+a6)*(1.+bet)+xi*a9)*G4Log(1.+xii)+(a5-bet)/xi1-a9;
} else {
be = (3.-a6+a1*a7)/(2.*xi);
}
G4double fe = (ale-cre)*be;
if ( fe < 0.) fe = 0. ;
G4double ymu = 4.+a6 +3.*bet*a7 ;
G4double ymd = a7*(1.5+a1)*log(3.+xi)+1.-1.5*a6 ;
G4double ymd = a7*(1.5+a1)*G4Log(3.+xi)+1.-1.5*a6 ;
G4double ym1 = 1.+ymu/ymd ;
G4double alm_crm = log(bbb*massratio/(1.5*z23*(1.+screen*ym1)));
G4double alm_crm = G4Log(bbb*massratio/(1.5*z23*(1.+screen*ym1)));
G4double a10,bm;
if ( xi >= 1.e-3)
{
a10 = (1.+a1)*a5 ;
bm = (a7*(1.+1.5*bet)-a10*xii)*log(xi1)+xi*(a5-bet)/xi1+a10;
bm = (a7*(1.+1.5*bet)-a10*xii)*G4Log(xi1)+xi*(a5-bet)/xi1+a10;
} else {
bm = (5.-a6+bet*a9)*(xi/2.);
}
G4double fm = alm_crm*bm;
if ( fm < 0.) fm = 0. ;
if ( fm < 0.) { fm = 0.; }
sum += wgi[i]*a4*(fe+fm/massratio2);
}
cross = -tmn*sum*factorForCross*z2*residEnergy/(totalEnergy*pairEnergy);
if(cross < 0.0) { cross = 0.0; }
return cross;
}
@@ -392,14 +422,12 @@ G4double G4MuPairProductionModel::ComputeCrossSectionPerAtom(
G4double cross = 0.0;
if (kineticEnergy <= lowestKinEnergy) { return cross; }
SetCurrentElement(Z);
G4double maxPairEnergy = MaxSecondaryEnergy(particle,kineticEnergy);
G4double maxPairEnergy = MaxSecondaryEnergyForElement(kineticEnergy, Z);
G4double tmax = std::min(maxEnergy, maxPairEnergy);
G4double cut = std::max(cutEnergy, minPairEnergy);
if (cut >= tmax) return cross;
if (cut >= tmax) { return cross; }
cross = ComputeMicroscopicCrossSection (kineticEnergy, Z, cut);
cross = ComputeMicroscopicCrossSection(kineticEnergy, Z, cut);
if(tmax < kineticEnergy) {
cross -= ComputeMicroscopicCrossSection(kineticEnergy, Z, tmax);
}
@@ -410,138 +438,156 @@ G4double G4MuPairProductionModel::ComputeCrossSectionPerAtom(
void G4MuPairProductionModel::MakeSamplingTables()
{
for (G4int iz=0; iz<nzdat; ++iz)
{
G4double factore = G4Exp(G4Log(emax/emin)/G4double(nbine));
for (G4int iz=0; iz<nzdat; ++iz) {
G4double Z = zdat[iz];
SetCurrentElement(Z);
G4Physics2DVector* pv = new G4Physics2DVector(nbiny+1,nbine+1);
G4double kinEnergy = emin;
for (G4int it=0; it<ntdat; ++it) {
for (size_t it=0; it<=nbine; ++it) {
G4double kineticEnergy = tdat[it];
G4double maxPairEnergy = MaxSecondaryEnergy(particle,kineticEnergy);
// G4cout << "Z= " << currentZ << " z13= " << z13
//<< " mE= " << maxPairEnergy << G4endl;
G4double xSec = 0.0 ;
pv->PutY(it, G4Log(kinEnergy/MeV));
G4double maxPairEnergy = MaxSecondaryEnergyForElement(kinEnergy, Z);
/*
G4cout << "it= " << it << " E= " << kinEnergy
<< " " << particle->GetParticleName()
<< " maxE= " << maxPairEnergy << " minE= " << minPairEnergy
<< " ymin= " << ymin << G4endl;
*/
G4double coef = G4Log(minPairEnergy/kinEnergy)/ymin;
G4double ymax = G4Log(maxPairEnergy/kinEnergy)/coef;
G4double fac = (ymax - ymin)/dy;
size_t imax = (size_t)fac;
fac -= (G4double)imax;
G4double xSec = 0.0;
G4double x = ymin;
/*
G4cout << "Z= " << currentZ << " z13= " << z13
<< " mE= " << maxPairEnergy << " ymin= " << ymin
<< " dy= " << dy << " c= " << coef << G4endl;
*/
// start from zero
pv->PutValue(0, it, 0.0);
if(0 == it) { pv->PutX(nbiny, 0.0); }
if(maxPairEnergy > minPairEnergy) {
for (size_t i=0; i<nbiny; ++i) {
G4double y = ymin - 0.5*dy ;
G4double yy = ymin - dy ;
G4double x = exp(y);
G4double fac = exp(dy);
G4double dx = exp(yy)*(fac - 1.0);
if(0 == it) { pv->PutX(i, x); }
G4double c = log(maxPairEnergy/minPairEnergy);
if(i < imax) {
G4double ep = kinEnergy*G4Exp(coef*(x + dy*0.5));
for (G4int i=0 ; i<nbiny; ++i) {
y += dy ;
if(c > 0.0) {
x *= fac;
dx*= fac;
G4double ep = minPairEnergy*exp(c*x) ;
xSec +=
ep*dx*ComputeDMicroscopicCrossSection(kineticEnergy, Z, ep);
}
ya[i] = y;
proba[iz][it][i] = xSec;
// not multiplied by interval, because table
// will be used only for sampling
//G4cout << "i= " << i << " x= " << x << "E= " << kinEnergy
// << " Egamma= " << ep << G4endl;
xSec += ep*ComputeDMicroscopicCrossSection(kinEnergy, Z, ep);
// last bin before the kinematic limit
} else if(i == imax) {
G4double ep = kinEnergy*G4Exp(coef*(x + fac*dy*0.5));
xSec += ep*fac*ComputeDMicroscopicCrossSection(kinEnergy, Z, ep);
}
} else {
for (G4int i=0 ; i<nbiny; ++i) {
proba[iz][it][i] = xSec;
}
}
ya[nbiny]=ymax;
proba[iz][it][nbiny] = xSec;
pv->PutValue(i + 1, it, xSec);
x += dy;
}
kinEnergy *= factore;
// to avoid precision lost
if(it+1 == nbine) { kinEnergy = emax; }
}
fElementData->InitialiseForElement(zdat[iz], pv);
}
samplingTablesAreFilled = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4MuPairProductionModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* aDynamicParticle,
G4double tmin,
G4double tmax)
void G4MuPairProductionModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* aDynamicParticle,
G4double tmin,
G4double tmax)
{
G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
//G4cout << "------- G4MuPairProductionModel::SampleSecondaries E(MeV)= "
// << kineticEnergy << " "
// << aDynamicParticle->GetDefinition()->GetParticleName() << G4endl;
G4double totalEnergy = kineticEnergy + particleMass;
G4double totalMomentum =
sqrt(kineticEnergy*(kineticEnergy + 2.0*particleMass));
G4ThreeVector partDirection = aDynamicParticle->GetMomentumDirection();
G4int it;
for(it=1; it<ntdat; ++it) { if(kineticEnergy <= tdat[it]) { break; } }
if(it == ntdat) { --it; }
G4double dt = log(kineticEnergy/tdat[it-1])/log(tdat[it]/tdat[it-1]);
// select randomly one element constituing the material
const G4Element* anElement =
SelectRandomAtom(kineticEnergy, dt, it, couple, tmin);
SetCurrentElement(anElement->GetZ());
const G4Element* anElement = SelectRandomAtom(couple,particle,kineticEnergy);
// define interval of enegry transfer
G4double maxPairEnergy = MaxSecondaryEnergy(particle,kineticEnergy);
// define interval of energy transfer
G4double maxPairEnergy = MaxSecondaryEnergyForElement(kineticEnergy,
anElement->GetZ());
G4double maxEnergy = std::min(tmax, maxPairEnergy);
G4double minEnergy = std::max(tmin, minPairEnergy);
if(minEnergy >= maxEnergy) { return; }
//G4cout << "emin= " << minEnergy << " emax= " << maxEnergy
// << " minPair= " << minPairEnergy << " maxpair= " << maxPairEnergy
// << " ymin= " << ymin << " dy= " << dy << G4endl;
// << " minPair= " << minPairEnergy << " maxpair= " << maxPairEnergy
// << " ymin= " << ymin << " dy= " << dy << G4endl;
G4double logmaxmin = log(maxPairEnergy/minPairEnergy);
G4double coeff = G4Log(minPairEnergy/kineticEnergy)/ymin;
// select bins
G4int iymin = 0;
G4int iymax = nbiny-1;
if( minEnergy > minPairEnergy)
{
G4double xc = log(minEnergy/minPairEnergy)/logmaxmin;
iymin = (G4int)((log(xc) - ymin)/dy);
if(iymin >= nbiny) iymin = nbiny-1;
else if(iymin < 0) iymin = 0;
xc = log(maxEnergy/minPairEnergy)/logmaxmin;
iymax = (G4int)((log(xc) - ymin)/dy) + 1;
if(iymax >= nbiny) iymax = nbiny-1;
else if(iymax < 0) iymax = 0;
}
// compute limits
G4double yymin = G4Log(minEnergy/kineticEnergy)/coeff;
G4double yymax = G4Log(maxEnergy/kineticEnergy)/coeff;
//G4cout << "yymin= " << yymin << " yymax= " << yymax << G4endl;
// units should not be used, bacause table was built without
G4double logTkin = G4Log(kineticEnergy/MeV);
// sample e-e+ energy, pair energy first
G4int iz, iy;
for(iz=1; iz<nzdat; ++iz) { if(currentZ <= zdat[iz]) { break; } }
if(iz == nzdat) { --iz; }
G4double dz = log(currentZ/zdat[iz-1])/log(zdat[iz]/zdat[iz-1]);
G4double pmin = InterpolatedIntegralCrossSection(dt,dz,iz,it,iymin,currentZ);
G4double pmax = InterpolatedIntegralCrossSection(dt,dz,iz,it,iymax,currentZ);
G4double p = pmin+G4UniformRand()*(pmax - pmin);
// interpolate sampling vector;
G4double p1 = pmin;
G4double p2 = pmin;
for(iy=iymin+1; iy<=iymax; ++iy) {
p1 = p2;
p2 = InterpolatedIntegralCrossSection(dt, dz, iz, it, iy, currentZ);
if(p <= p2) { break; }
// select sample table via Z
G4int iz1(0), iz2(0);
for(G4int iz=0; iz<nzdat; ++iz) {
if(currentZ == zdat[iz]) {
iz1 = iz2 = currentZ;
break;
} else if(currentZ < zdat[iz]) {
iz2 = zdat[iz];
if(iz > 0) { iz1 = zdat[iz-1]; }
else { iz1 = iz2; }
break;
}
}
// G4cout << "iy= " << iy << " iymin= " << iymin << " iymax= "
// << iymax << " Z= " << currentZ << G4endl;
G4double y = ya[iy-1] + dy*(p - p1)/(p2 - p1);
if(0 == iz1) { iz1 = iz2 = zdat[nzdat-1]; }
G4double PairEnergy = minPairEnergy*exp( exp(y)*logmaxmin );
if(PairEnergy < minEnergy) { PairEnergy = minEnergy; }
if(PairEnergy > maxEnergy) { PairEnergy = maxEnergy; }
G4double PairEnergy = 0.0;
G4int count = 0;
//G4cout << "start loop Z1= " << iz1 << " Z2= " << iz2 << G4endl;
do {
++count;
// sampling using only one random number
G4double rand = G4UniformRand();
G4double x = FindScaledEnergy(iz1, rand, logTkin, yymin, yymax);
if(iz1 != iz2) {
G4double x2 = FindScaledEnergy(iz2, rand, logTkin, yymin, yymax);
G4double lz1= nist->GetLOGZ(iz1);
G4double lz2= nist->GetLOGZ(iz2);
//G4cout << count << ". x= " << x << " x2= " << x2
// << " Z1= " << iz1 << " Z2= " << iz2 << G4endl;
x += (x2 - x)*(lnZ - lz1)/(lz2 - lz1);
}
//G4cout << "x= " << x << " coeff= " << coeff << G4endl;
PairEnergy = kineticEnergy*G4Exp(x*coeff);
} while((PairEnergy < minEnergy || PairEnergy > maxEnergy) && 10 > count);
//G4cout << "## PairEnergy(GeV)= " << PairEnergy/GeV
// << " Etot(GeV)= " << totalEnergy/GeV << G4endl;
// sample r=(E+-E-)/PairEnergy ( uniformly .....)
G4double rmax =
@@ -593,73 +639,20 @@ G4MuPairProductionModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
// add secondary
vdp->push_back(aParticle1);
vdp->push_back(aParticle2);
//G4cout << "-- G4MuPairProductionModel::SampleSecondaries done" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4Element* G4MuPairProductionModel::SelectRandomAtom(
G4double kinEnergy, G4double dt, G4int it,
const G4MaterialCutsCouple* couple, G4double tmin)
void G4MuPairProductionModel::DataCorrupted(G4int Z, G4double logTkin)
{
// select randomly 1 element within the material
const G4Material* material = couple->GetMaterial();
size_t nElements = material->GetNumberOfElements();
const G4ElementVector* theElementVector = material->GetElementVector();
if (nElements == 1) { return (*theElementVector)[0]; }
if(nElements > nmaxElements) {
nmaxElements = nElements;
partialSum.resize(nmaxElements);
}
const G4double* theAtomNumDensityVector=material->GetAtomicNumDensityVector();
G4double sum = 0.0;
G4double dl;
size_t i;
for (i=0; i<nElements; ++i) {
G4double Z = ((*theElementVector)[i])->GetZ();
SetCurrentElement(Z);
G4double maxPairEnergy = MaxSecondaryEnergy(particle,kinEnergy);
G4double minEnergy = std::max(tmin, minPairEnergy);
dl = 0.0;
if(minEnergy < maxPairEnergy) {
G4int iz;
for(iz=1; iz<nzdat; ++iz) {if(Z <= zdat[iz]) { break; } }
if(iz == nzdat) { --iz; }
G4double dz = log(Z/zdat[iz-1])/log(zdat[iz]/zdat[iz-1]);
G4double sigcut;
if(minEnergy <= minPairEnergy)
sigcut = 0.;
else
{
G4double xc = log(minEnergy/minPairEnergy)/log(maxPairEnergy/minPairEnergy);
G4int iy = (G4int)((log(xc) - ymin)/dy);
if(iy < 0) { iy = 0; }
if(iy >= nbiny) { iy = nbiny-1; }
sigcut = InterpolatedIntegralCrossSection(dt,dz,iz,it,iy, Z);
}
G4double sigtot = InterpolatedIntegralCrossSection(dt,dz,iz,it,nbiny,Z);
dl = (sigtot - sigcut)*theAtomNumDensityVector[i];
}
// protection
if(dl < 0.0) { dl = 0.0; }
sum += dl;
partialSum[i] = sum;
}
G4double rval = G4UniformRand()*sum;
for (i=0; i<nElements; ++i) {
if(rval<=partialSum[i]) { return (*theElementVector)[i]; }
}
return (*theElementVector)[nElements - 1];
G4ExceptionDescription ed;
ed << "G4ElementData is not properly initialized Z= " << Z
<< " Ekin(MeV)= " << G4Exp(logTkin)
<< " IsMasterThread= " << IsMaster()
<< " Model " << GetName();
G4Exception("G4MuPairProductionModel::()","em0033",FatalException,
ed,"");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......