Import Geant4 9.6.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 17:01:34 +02:00
parent b1eb5424d2
commit e2d2f9810a
10384 changed files with 698580 additions and 628834 deletions
@@ -17,6 +17,312 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
09 November 12: V.Ivant (emutils-V09-05-56)
08 November 12: V.Ivant (emutils-V09-05-55)
- G4VEnergyLossProcess - fixed non-reproducibility for ions
08 November 12: V.Ivant (emutils-V09-05-54)
- G4VMultipleScattering - improved logic of computation of PostStep
safety and true step length, added more accurate protection
against case when true length exceed physics step limit
06 November 12: V.Ivant (emutils-V09-05-53)
- G4VMultipleScattering - fixed non-reproducibility for ions, added
protection - do not sample scattering if range exceed true step
length less than minGeom parameter (1e-6 mm)
03 November 12: V.Ivant (emutils-V09-05-52)
- G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering - fixed
printout at initialisation
02 November 12: V.Ivant (emutils-V09-05-51)
- G4VMultipleScattering - ion multiple scattering is defined
in the class constructor
- G4VMscModel - build table for all particles except case when
multiple scattering process is shared with G4GenericIon
26 October 12: V.Ivant (emutils-V09-05-50)
- G4VMultipleScattering - return version 48
- G4VEmProcess - changed initialisation for ions
25 October 12: V.Ivant (emutils-V09-05-49)
- G4VMultipleScattering - moved relocation AlongStep and do not
call msc PostStep
21 October 12: V.Ivant (emutils-V09-05-48)
- G4EmBiasingManager - cleanup the code; do not modify ParticleChange
when apply RussianRoulette (monor CPU saving); moved
RussianRoulette method to inline; added range cut option
- G4VEmProcess, G4VEnergyLossProcess, G4EmProcessOption - add
corresponding modifiction needed for biasing interface
20 October 12: V.Ivant (emutils-V09-05-47)
- G4VMultipleScattering - fixed typo in previous tag;
compute true path length even is msc model is inactive
20 October 12: V.Ivant (emutils-V09-05-46)
- G4VMultipleScattering - critical fix for stopping particles
(ATLAS report on small steps of low-energy ions)
19 October 12: V.Ivant (emutils-V09-05-45)
- G4VEnergyLossProcess, G4VMultipleScattering - attempt to optimise
run time methods called at each step
- G4EmCalculator - added ComputeGammaAttenuationLength method
- added warning to obsolete methods and classes
18 October 12: V.Ivant (emutils-V09-05-44)
- G4VEnergyLossProcess - define flag isIon for all nucleus except
deuteron, triton and special DNA ions
- G4VEmProcess, G4EmModelManager - minor reduce of number of operations
at each step
- G4VMscModel - minor optimisation of inline methods
05 October 12: V.Ivant (emutils-V09-05-43)
- G4VMultipleScatteringProcess - check that true step length proposed
by msc model do not exceed physical true length
01 October 12: V.Ivant (emutils-V09-05-42)
- G4VAtomDeexcitation - updated initialisation for the case
when de-excitation is not used
27 September 12: V.Ivant (emutils-V09-05-41)
- G4VMscModel - added GetDEDX method
21 September 12: V.Ivant (emutils-V09-05-40)
- G4VAtomDeexcitation - removed forgotten debug printout
- G4VMultipleScatteringProcess - minor cleanup
20 September 12: V.Ivant (emutils-V09-05-39)
- G4VAtomDeexcitation - fixed logic of activation of de-excitation
per region and for all geometry
20 September 12: V.Ivant (emutils-V09-05-38)
- G4VAtomDeexcitation - added computation of sum of energies of
de-excitation gamma and electron produced AlongStep;
use logical OR instead of AND for de-exitation flags
- G4VEnergyLossProcess - fixed energy balance for the case of de-excitation
AlongStep
17 September 12: V.Ivant (emutils-V09-05-37)
- G4VAtomDeexcitation - fixed de-excitation AlongStep by substitution
which limited de-ecitation from ion ionisation
- G4VEnergyLossProcess - take into account modifications for
G4VAtomDeexcitation in order to keep energy balance
06 August 12: V.Ivant (emutils-V09-05-36)
- G4VMultipleScatteringProcess - added call to ReLocate PostStep
06 August 12: V.Ivant (emutils-V09-05-35)
- G4VMultipleScatteringProcess - change final position PostStep to
bypass bug in parallel transportation
28 August 12: V.Ivant (emutils-V09-05-34)
- G4VMultipleScatteringProcess - improved debug printout
24 August 12: V.Ivant (emutils-V09-05-33)
- G4VMultipleScatteringProcess, G4VMscModel - sampling scattering
is moved from PostStep to AlongStep
- G4VEmProcess - fixed minor memory leak at destruction
14 August 12: V.Ivant (emutils-V09-05-32)
- G4VEnergyLossProcess - fixed non-reproducibility by extention
of initialisation in StertTracking method for ions
- G4VEmProcess - removed over initialisation in StartTracking
- G4EmModelManager - improve printout on models
09 August 12: V.Ivant (emutils-V09-05-31)
- G4VMultipleScattering - allowed to change position and direction
AlongStep
01 August 12: V.Ivant (emutils-V09-05-30)
- G4EnergyLossMessenger - Allow to apply bising UI commands only
in G4_Idle state
30 July 12: V.Ivant (emutils-V09-05-29)
- G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering -
use the same list of particles for printout at initialisation
in the case of verboseLevel=1
20 July 12: V.Ivant (emutils-V09-05-28)
- G4VEnergyLossProcess - similar fix as for G4VEmProcess
- G4VEmAngularGenerator - cleanup comments, removed obsolete methods
19 July 12: V.Ivant (emutils-V09-05-27)
- G4VEmProcess - fixed problem introduced in previous tag making
possible infinite loop in DNA tracking of 6 eV electron
17 July 12: V.Ivant (emutils-V09-05-26)
- G4VEnergyLossProcess, G4VEmProcess - updated tracking parameters
and flags in PostStepGetPhysicalInteractionLength
- G4EmBiasingManager - fixed bug in bremsstrahlung splitting, which
practically forbid splitting
13 July 12: V.Ivant (emutils-V09-05-25)
- G4VEnergyLossProcess, G4LossTableManager - removed unused method
InitialiseMSC
13 July 12: V.Ivant (emutils-V09-05-24)
- G4EmBiasingManager - do not using dynamic weight for Russian roulette
12 July 12: V.Ivant (emutils-V09-05-23)
- G4VEnergyLossProcess, G4VMultipleScattering, G4VEmModel - added
implementation of new method StartTracking
- G4VMscModel - changed initialisation of the new track using
StartTracking method
- G4VEmAngularDistribution - add temporary dummy implementation of virtual
sampling methods - will be removed when all generators will migrated
to the new signature
10 July 12: G.Cosmo (emutils-V09-05-22)
- Explicitly use inclusion of headers for system of units and physical
constants, in plan to remove implicit inclusion from globals.hh.
05 July 12: V.Ivant (emutils-V09-05-21)
- G4EmCorrections, G4VEmModel, G4VMscModel - fixed shadowing
04 July 12: V.Ivant (emutils-V09-05-20)
- G4VMscModel - method Value() is moved to G4VEmModel
- G4VEmProcess - added extra option allowing to build two different tables
for low-energy and high-energy using different interpolation method,
for that added optinal extra energy limit and SetMinKinEnergyPrim(G4double)
method, improved initialisation of tables and initialisation printout
- G4EmTableType - added type fIsCrossSectionPrim
- G4EmModelManager - added possibility to build high energy table of
cross sections
- G4VEmAngularDistribution - cleanup user interface
08 June 12: D. Sawkey
- G4VEmProcess fix for first part of bug 1314. Force if step==1 (see 30May12)
08 June 12: V.Ivant (emutils-V09-05-19)
- Fixed shadowing
06 June 12: V.Ivant (emutils-V09-05-18)
- G4VMscModel - trying optimise inline methods
- G4VMultipleScattering - trying optimise initialisation and reduce
number of checks in run time
- G4LossTableManager - moved inline methods to the source
- G4EmBiasingmanager - add check on number of secondaries PostStep,
if it is not 1 then disable both spliting and Russian roulette,
this does not affect ordinary delta-electron and bremssrahlung
secondary biasing (splitting and Russian roulette);
Dynamic weight approach (weight is function of secondary energy)
is applied for Russian roulette if biasing limit energy is set
below 1 GeV, alternatively costant factor is used
05 June 12: V.Ivant (emutils-V09-05-17)
- G4VMscModel - allow build transport x-section table for d,t,He3,He4
01 June 12: D. Sawkey (emutils-V09-05-16)
- G4EnergyLossMessenger: Put back in guidance for high energy limit for
bremsplitting, russian roulette
31 May 12: D. Sawkey
G4EmBiasingManager:Put back in high energy limit for Russian roulette,
bremsplitting
31 May 12: V.Ivant (emutils-V09-05-15)
30 May 12: D. Sawkey
- G4VEnergyLossProcess bug 1314 fix: for forced biasing, now force if step==1
30 May 12: D. Sawkey
- G4VEmProcess, G4VEnergyLossProcess. for forced interaction, cross-
section biasing, set weight consistently
29 May 12: D. Sawkey
- G4EmBiasingManager, G4VEmProcess, G4VEnergyLossProcess,
G4EmProcessOptions, G4EnergyLossMessenger: Change brem splitting to
EGS-style with unique secondaries. Only brem split particles with
weight > 1/N (N=brem splitting factor), and only Russian Roulette
with weight < 1. Energy limit no longer used.
28 May 12: V.Ivant (emutils-V09-05-14)
- G4EmCalculator - fixed FindRegion
18 May 12: V.Ivant (emutils-V09-05-13)
- G4EmModelManager - improved printout of model energy limits
- G4VEmModel - added inline methods HighEnergyActivationLimit(),
LowEnergyActivationLimit(), ForceBuildTableFlag(), ForceBuildTable()
- G4VMscModel - updated GetRange() and GetEnergy() methods allowing to
use the same model class for many particles
09 May 12: V.Ivant (emutils-V09-05-12)
- G4ElectronIonPair - use inverse FanoFactor to simplify formula
09 May 12: V.Ivant (emutils-V09-05-11)
- G4VMultipleScatetring - improved printout at initialisation
- G4ElectronIonPair - cleanup implementation of sampling of number of ions
26 April 12: V.Ivant (emutils-V09-05-10)
- G4EmCalculator - fixed GetMeanFreePath for msc processes (bug introduced
in previous tags)
20 April 12: V.Ivant (emutils-V09-05-09)
- G4LossTableManager - added methods MinKinEnergy, MaxkinEnergy
- G4EmModelManager - extended printout if cross section table is built for
the model
- G4EmCalculator - improved model selection for msc processes
- G4VMultipleScatetring - removed transport cross section table,
simplified AlongStepGetPhysicalInteractionLength
method, added protection against zero
kinetic energy into PostStepDoIt,
general cleanup of the code
- G4VMscModel - added building of transport cross section table and new
method GetTransportCrossSection to be used in run time
- G4LossTableBuilder - added method BuildTableForModel
19 April 12: V.Ivant (emutils-V09-05-08)
- G4EmCorrections : A.Ribon fixed reproducibility violation due to the cashing
of IonHighOrderCorrections with a vector depending on the ion charge.
The correction depends not only on the ion charge but also on its
mass, therefore the cashing based on the ion charge only depends on
which isotope is encountered first, which depends on the history,
and violated the reproducibility. The fix consists of using a map
for cashing, with the key given by the PDG encoding of the ion,
which is unique for each isotope.
- G4VEmProcess - use ProposeWeight instead of ProposeParentWeight
to fix weights of secondary particle for gamma processes
- G4LossTableManager - minor correction of number of bins per decade
15 April 12: V.Ivant (emutils-V09-05-07)
- G4LossTableBuilder - added method BuildTableForModel allowing to build
G4PhysicsTable for a model
- G4VEmModel - added virtual method Value, by default computes cross section
- G4VMscModel - added method GetTransportMeanFreePath
19 March 12: V.Ivant (emutils-V09-05-06)
- G4EmCalculator - fixed compillation warning at gcc 4.6
15 March 12: V.Ivant (emutils-V09-05-05)
- G4LossTableManager - added a check and protection against double
registration of the same process; this addition allows to use
the same EM energy loss process for different particle types
- G4EmCalculator - modifed method to access a process taking into account
that the same process may used by different particle type;
added new methods ActiveForParticle, FindEnLossProcess,
FindDiscreteProcess, FindMscProcess
5 March 12: V.Ivant (emutils-V09-05-04)
- G4VEnergyLossProcess fixed crash due to apply G4hIonisation for ions;
- G4VEnergyLossProcess, G4VEmProcess, G4LossTableBuilder - delete old
G4PhysicsVectors if new vectors are built between runs
- G4VAtomDeexcitation - use safe method to extract integer Z
29 February 12: V.Ivant (emutils-V09-05-03)
- G4VEnergyLossProcess fixed computation of delta-electron cross section
for ions and very small cuts (about 1 um), reported by Sergio Ibarmia
21 February 12: V.Ivant (emutils-V09-05-02)
- G4VEmAngularDistribution added new method Initialise
21 February 12: V.Ivant (emutils-V09-05-01)
- G4VEmAngularDistribution added two new methods SampleCosinePolarAngle
and SampleDirection
7 February 12: V.Ivant (emutils-V09-05-00)
- G4VAtomDeexcitation - add activation of deexcitation for the world
if deexcitation is activated but G4Regions for deexcitation
are not defined
10 November 11: V.Ivant (emutils-V09-04-51)
- G4LossTableManager, G4EmModelManager - fixed defects reported by
Coverity - private assignment operator and copy constructor added
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4AtomicShell.hh,v 1.1 2009-07-24 17:22:32 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4DummyModel.hh,v 1.4 2009-04-07 18:39:47 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ElectronIonPair.hh,v 1.5 2010-10-25 17:23:01 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
#ifndef G4ElectronIonPair_h
@@ -125,7 +124,7 @@ private:
const G4Material* curMaterial;
G4double curMeanEnergy;
G4double FanoFactor;
G4double invFanoFactor;
G4int verbose;
G4int nMaterials;
@@ -147,16 +146,10 @@ G4ElectronIonPair::MeanNumberOfIonsAlongStep(const G4Step* step)
inline
G4int G4ElectronIonPair::SampleNumberOfIonsAlongStep(const G4Step* step)
{
// use gamma distribution with mean value n=meanion and
// dispersion D=meanion/invFanoFactor
G4double meanion = MeanNumberOfIonsAlongStep(step);
G4double lambda = 1./FanoFactor;
G4double a = meanion*lambda;
// old Gauss implementation
// G4double sig = FanoFactor*std::sqrt(meanion);
// G4int nion = G4int(G4RandGauss::shoot(meanion,sig) + 0.5);
G4int nion = G4int(CLHEP::RandGamma::shoot(a,lambda) + 0.5);
return nion;
return G4lrint(CLHEP::RandGamma::shoot(meanion*invFanoFactor,invFanoFactor));
}
inline
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmBiasingManager.hh,v 1.61 2010-08-17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -51,13 +50,19 @@
#include "globals.hh"
#include "G4ParticleDefinition.hh"
#include "G4DynamicParticle.hh"
#include "Randomize.hh"
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class G4Region;
class G4DynamicParticle;
class G4Track;
class G4VEnergyLossProcess;
class G4VEmModel;
class G4MaterialCutsCouple;
class G4ParticleChangeForLoss;
class G4ParticleChangeForGamma;
class G4EmBiasingManager
{
@@ -83,12 +88,32 @@ public:
// return weight of splitting or Russian roulette
// G4DynamicParticle may be deleted
G4double ApplySecondaryBiasing(std::vector<G4DynamicParticle*>&,
G4int coupleIdx);
// two functions are required because of the different ParticleChange
// ApplySecondaryBiasing() are wrappers
// Splitting or Russian roulette, G4Track may be deleted
void ApplySecondaryBiasing(std::vector<G4Track*>&, G4double primaryWeight,
G4int coupleIdx);
// for G4VEmProcess
G4double ApplySecondaryBiasing(std::vector<G4DynamicParticle*>&,
const G4Track& track,
G4VEmModel* currentModel,
G4ParticleChangeForGamma* pParticleChange,
G4double& eloss,
G4int coupleIdx,
G4double tcut,
G4double safety = 0.0);
// for G4VEnergyLossProcess
G4double ApplySecondaryBiasing(std::vector<G4DynamicParticle*>&,
const G4Track& track,
G4VEmModel* currentModel,
G4ParticleChangeForLoss* pParticleChange,
G4double& eloss,
G4int coupleIdx,
G4double tcut,
G4double safety = 0.0);
// for G4VEnergyLossProcess
G4double ApplySecondaryBiasing(std::vector<G4Track*>&,
G4int coupleIdx);
inline G4bool SecondaryBiasingRegion(G4int coupleIdx);
@@ -98,6 +123,20 @@ public:
private:
void ApplyRangeCut(std::vector<G4DynamicParticle*>& vd,
const G4Track& track,
G4double& eloss,
G4double safety);
G4double ApplySplitting(std::vector<G4DynamicParticle*>& vd,
const G4Track& track,
G4VEmModel* currentModel,
G4int index,
G4double tcut);
inline G4double ApplyRussianRoulette(std::vector<G4DynamicParticle*>& vd,
G4int index);
// copy constructor and hide assignment operator
G4EmBiasingManager(G4EmBiasingManager &);
G4EmBiasingManager & operator=(const G4EmBiasingManager &right);
@@ -114,6 +153,13 @@ private:
std::vector<G4int> idxForcedCouple;
std::vector<G4int> idxSecBiasedCouple;
std::vector<G4DynamicParticle*> tmpSecondaries;
G4VEnergyLossProcess* eIonisation;
const G4ParticleDefinition* theElectron;
G4double fSafetyMin;
G4double currentStepLimit;
G4bool startTracking;
};
@@ -144,4 +190,22 @@ inline void G4EmBiasingManager::ResetForcedInteraction()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4EmBiasingManager::ApplyRussianRoulette(std::vector<G4DynamicParticle*>& vd,
G4int index)
{
size_t n = vd.size();
G4double weight = secBiasedWeight[index];
for(size_t k=0; k<n; ++k) {
if(G4UniformRand()*weight > 1.0) {
const G4DynamicParticle* dp = vd[k];
delete dp;
vd[k] = 0;
}
}
return weight;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCalculator.hh,v 1.22 2011-01-03 19:34:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
// -------------------------------------------------------------------
@@ -69,6 +68,9 @@ class G4ParticleDefinition;
class G4PhysicsTable;
class G4VEmModel;
class G4VEnergyLossProcess;
class G4VEmProcess;
class G4VMultipleScattering;
class G4VProcess;
class G4ionEffectiveCharge;
class G4Region;
class G4Element;
@@ -83,17 +85,20 @@ public:
~G4EmCalculator();
//==================================================================================
//===========================================================================
// Methods to access precalculated dE/dx and cross sections
// Materials should exist in the list of the G4MaterialCutsCouple
//==================================================================================
//===========================================================================
G4double GetDEDX(G4double kinEnergy, const G4ParticleDefinition*, const G4Material*,
G4double GetDEDX(G4double kinEnergy, const G4ParticleDefinition*,
const G4Material*,
const G4Region* r = 0);
G4double GetDEDX(G4double kinEnergy, const G4String& part, const G4String& mat,
G4double GetDEDX(G4double kinEnergy, const G4String& part,
const G4String& mat,
const G4String& s = "world");
G4double GetRangeFromRestricteDEDX(G4double kinEnergy, const G4ParticleDefinition*,
G4double GetRangeFromRestricteDEDX(G4double kinEnergy,
const G4ParticleDefinition*,
const G4Material*,
const G4Region* r = 0);
G4double GetRangeFromRestricteDEDX(G4double kinEnergy, const G4String& part,
@@ -114,10 +119,12 @@ public:
const G4String& mat,
const G4String& s = "world");
G4double GetKinEnergy(G4double range, const G4ParticleDefinition*, const G4Material*,
const G4Region* r = 0);
G4double GetKinEnergy(G4double range, const G4String& part, const G4String& mat,
const G4String& s = "world");
G4double GetKinEnergy(G4double range, const G4ParticleDefinition*,
const G4Material*,
const G4Region* r = 0);
G4double GetKinEnergy(G4double range, const G4String& part,
const G4String& mat,
const G4String& s = "world");
G4double GetCrossSectionPerVolume(
G4double kinEnergy, const G4ParticleDefinition*,
@@ -135,7 +142,8 @@ public:
G4double GetMeanFreePath(G4double kinEnergy, const G4ParticleDefinition*,
const G4String& processName, const G4Material*,
const G4Region* r = 0);
G4double GetMeanFreePath(G4double kinEnergy, const G4String& part, const G4String& proc,
G4double GetMeanFreePath(G4double kinEnergy, const G4String& part,
const G4String& proc,
const G4String& mat, const G4String& s = "world");
void PrintDEDXTable(const G4ParticleDefinition*);
@@ -144,18 +152,20 @@ public:
void PrintInverseRangeTable(const G4ParticleDefinition*);
//==================================================================================
//===========================================================================
// Methods to calculate dE/dx and cross sections "on fly"
// Existing tables and G4MaterialCutsCouples are not used
//==================================================================================
//===========================================================================
G4double ComputeDEDX(G4double kinEnergy, const G4ParticleDefinition*,
const G4String& processName, const G4Material*,
G4double cut = DBL_MAX);
G4double ComputeDEDX(G4double kinEnergy, const G4String& part, const G4String& proc,
G4double ComputeDEDX(G4double kinEnergy, const G4String& part,
const G4String& proc,
const G4String& mat, G4double cut = DBL_MAX);
G4double ComputeElectronicDEDX(G4double kinEnergy, const G4ParticleDefinition*,
G4double ComputeElectronicDEDX(G4double kinEnergy,
const G4ParticleDefinition*,
const G4Material* mat, G4double cut = DBL_MAX);
G4double ComputeElectronicDEDX(G4double kinEnergy, const G4String& part,
const G4String& mat, G4double cut = DBL_MAX);
@@ -175,7 +185,8 @@ public:
const G4String& processName, const G4Material*,
G4double cut = 0.0);
G4double ComputeCrossSectionPerVolume(
G4double kinEnergy, const G4String& part, const G4String& proc,
G4double kinEnergy, const G4String& part,
const G4String& proc,
const G4String& mat, G4double cut = 0.0);
G4double ComputeCrossSectionPerAtom(
@@ -187,6 +198,9 @@ public:
const G4String& processName, const G4Element*,
G4double cut = 0.0);
G4double ComputeGammaAttenuationLength(G4double kinEnergy,
const G4Material*);
G4double ComputeShellIonisationCrossSectionPerAtom(
const G4String& part, G4int Z,
G4AtomicShellEnumerator shell,
@@ -208,9 +222,9 @@ public:
G4double range, const G4String&,
const G4String&);
//==================================================================================
//===========================================================================
// Methods to access particles, materials, regions
//==================================================================================
//===========================================================================
const G4ParticleDefinition* FindParticle(const G4String&);
@@ -220,13 +234,14 @@ public:
const G4Region* FindRegion(const G4String&);
const G4MaterialCutsCouple* FindCouple(const G4Material*, const G4Region* r = 0);
const G4MaterialCutsCouple* FindCouple(const G4Material*,
const G4Region* r = 0);
void SetVerbose(G4int val);
//==================================================================================
//===========================================================================
// Private methods
//==================================================================================
//===========================================================================
private:
@@ -234,7 +249,9 @@ private:
G4bool UpdateCouple(const G4Material*, G4double cut);
void FindLambdaTable(const G4ParticleDefinition*, const G4String& processName);
void FindLambdaTable(const G4ParticleDefinition*,
const G4String& processName,
G4double kinEnergy);
G4bool FindEmModel(const G4ParticleDefinition*,
const G4String& processName,
@@ -242,6 +259,18 @@ private:
G4VEnergyLossProcess* FindEnergyLossProcess(const G4ParticleDefinition*);
G4VEnergyLossProcess* FindEnLossProcess(const G4ParticleDefinition*,
const G4String& processName);
G4VEmProcess* FindDiscreteProcess(const G4ParticleDefinition*,
const G4String& processName);
G4VMultipleScattering* FindMscProcess(const G4ParticleDefinition*,
const G4String& processName);
G4bool ActiveForParticle(const G4ParticleDefinition* part,
G4VProcess* proc);
G4EmCalculator & operator=(const G4EmCalculator &right);
G4EmCalculator(const G4EmCalculator&);
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmConfigurator.hh,v 1.3 2010-04-12 11:44:40 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCorrections.hh,v 1.27 2010-11-15 19:18:34 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -42,6 +41,7 @@
// 13.05.2006 Add corrections for ion stopping (V.Ivanhcenko)
// 20.05.2008 Removed Finite Size correction (V.Ivanchenko)
// 12.09.2008 Added inlined interfaces to effective charge (V.Ivanchenko)
// 19.04.2012 Fix reproducibility problem (A.Ribon)
//
// Class Description:
//
@@ -54,6 +54,8 @@
#ifndef G4EmCorrections_h
#define G4EmCorrections_h 1
#include <CLHEP/Units/PhysicalConstants.h>
#include "globals.hh"
#include "G4ionEffectiveCharge.hh"
#include "G4Material.hh"
@@ -233,7 +235,7 @@ private:
G4LPhysicsFreeVector* ThetaL;
std::vector<const G4Material*> currmat;
std::vector<G4double> thcorr[100];
std::map< G4int, std::vector<G4double> > thcorr;
size_t ncouples;
const G4ParticleDefinition* particle;
@@ -309,11 +311,11 @@ inline G4double G4EmCorrections::Value2(G4double xv, G4double yv,
/ ((x2-x1)*(y2-y1));
}
inline
void G4EmCorrections::SetIonisationModels(G4VEmModel* m1, G4VEmModel* m2)
inline void
G4EmCorrections::SetIonisationModels(G4VEmModel* mod1, G4VEmModel* mod2)
{
if(m1) ionLEModel = m1;
if(m2) ionHEModel = m2;
if(mod1) { ionLEModel = mod1; }
if(mod2) { ionHEModel = mod2; }
}
inline G4int G4EmCorrections::GetNumberOfStoppingVectors()
@@ -351,9 +353,9 @@ inline void G4EmCorrections::SetupKinematics(const G4ParticleDefinition* p,
beta2 = bg2/(gamma*gamma);
beta = std::sqrt(beta2);
ba2 = beta2/alpha2;
G4double ratio = electron_mass_c2/mass;
tmax = 2.0*electron_mass_c2*bg2 /(1. + 2.0*gamma*ratio + ratio*ratio);
charge = p->GetPDGCharge()/eplus;
G4double ratio = CLHEP::electron_mass_c2/mass;
tmax = 2.0*CLHEP::electron_mass_c2*bg2 /(1. + 2.0*gamma*ratio + ratio*ratio);
charge = p->GetPDGCharge()/CLHEP::eplus;
//if(charge < 1.5) {q2 = charge*charge;}
//else {
// q2 = effCharge.EffectiveChargeSquareRatio(p,mat,kinEnergy);
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmElementSelector.hh,v 1.6 2009-09-29 11:31:37 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmModelManager.hh,v 1.34 2009-08-11 10:29:30 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmMultiModel.hh,v 1.7 2010-07-04 17:51:09 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmProcessOptions.hh,v 1.19 2010-11-23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
// -------------------------------------------------------------------
@@ -151,6 +150,9 @@ public:
void ActivateSecondaryBiasing(const G4String& name, const G4String& region,
G4double factor, G4double energyLimit);
void ActivateSecondaryBiasingForGamma(const G4String& name, const G4String& region,
G4double factor, G4double energyLimit);
private:
G4EmProcessOptions & operator=(const G4EmProcessOptions &right);
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmProcessSubType.hh,v 1.9 2008-12-18 13:01:42 gunter Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//---------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmSaturation.hh,v 1.8 2010-08-17 17:36:58 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
#ifndef G4EmSaturation_h
@@ -24,8 +24,7 @@
// ********************************************************************
//
//
// $Id: G4EmTableType.hh,v 1.4 2008-10-13 14:56:56 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//---------------------------------------------------------------
//
@@ -51,7 +50,8 @@ enum G4EmTableType
fRestricted,
fSubRestricted,
fIsIonisation,
fIsSubIonisation
fIsSubIonisation,
fIsCrossSectionPrim
};
#endif
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EnergyLossMessenger.hh,v 1.26 2010-11-23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -24,8 +24,7 @@
// ********************************************************************
//
//
// $Id: G4EnergyLossTables.hh,v 1.19 2006-06-29 19:54:35 gunter Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// $Id:
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LossTableBuilder.hh,v 1.8 2008-07-22 15:55:15 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
// -------------------------------------------------------------------
@@ -56,6 +55,9 @@
#include "globals.hh"
#include "G4PhysicsTable.hh"
class G4VEmModel;
class G4ParticleDefinition;
class G4LossTableBuilder
{
@@ -65,17 +67,32 @@ public:
virtual ~G4LossTableBuilder();
void BuildDEDXTable(G4PhysicsTable* dedxTable, const std::vector<G4PhysicsTable*>&);
// build sum of all energy loss processes
void BuildDEDXTable(G4PhysicsTable* dedxTable,
const std::vector<G4PhysicsTable*>&);
void BuildRangeTable(const G4PhysicsTable* dedxTable, G4PhysicsTable* rangeTable,
// build range
void BuildRangeTable(const G4PhysicsTable* dedxTable,
G4PhysicsTable* rangeTable,
G4bool isIonisation = false);
// build inverse range
void BuildInverseRangeTable(const G4PhysicsTable* rangeTable,
G4PhysicsTable* invRangeTable,
G4bool isIonisation = false);
// build a table requested by any model class
G4PhysicsTable* BuildTableForModel(G4PhysicsTable* table,
G4VEmModel* model,
const G4ParticleDefinition*,
G4double emin, G4double emax,
G4bool spline);
// initialise base materials
void InitialiseBaseMaterials(G4PhysicsTable* table);
// access methods
inline const std::vector<G4int>* GetCoupleIndexes();
inline const std::vector<G4double>* GetDensityFactors();
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LossTableManager.hh,v 1.61 2010-09-03 10:09:45 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
// -------------------------------------------------------------------
@@ -118,11 +117,15 @@ public:
void PreparePhysicsTable(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void PreparePhysicsTable(const G4ParticleDefinition* aParticle,
G4VEmProcess* p);
void PreparePhysicsTable(const G4ParticleDefinition* aParticle,
G4VMultipleScattering* p);
void BuildPhysicsTable(const G4ParticleDefinition* aParticle);
void BuildPhysicsTable(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
@@ -131,37 +134,37 @@ public:
// energy, and G4MaterialCutsCouple
//-------------------------------------------------
inline G4double GetDEDX(
G4double GetDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple);
inline G4double GetSubDEDX(
G4double GetSubDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple);
inline G4double GetRange(
G4double GetRange(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple);
inline G4double GetCSDARange(
G4double GetCSDARange(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple);
inline G4double GetRangeFromRestricteDEDX(
G4double GetRangeFromRestricteDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple);
inline G4double GetEnergy(
G4double GetEnergy(
const G4ParticleDefinition *aParticle,
G4double range,
const G4MaterialCutsCouple *couple);
inline G4double GetDEDXDispersion(
G4double GetDEDXDispersion(
const G4MaterialCutsCouple *couple,
const G4DynamicParticle* dp,
G4double& length);
@@ -254,13 +257,16 @@ public:
G4double FactorForAngleLimit() const;
G4double MinKinEnergy() const;
G4double MaxKinEnergy() const;
const std::vector<G4VEnergyLossProcess*>& GetEnergyLossProcessVector();
const std::vector<G4VEmProcess*>& GetEmProcessVector();
const std::vector<G4VMultipleScattering*>& GetMultipleScatteringVector();
inline
G4VEnergyLossProcess* GetEnergyLossProcess(const G4ParticleDefinition*);
G4EmCorrections* EmCorrections();
@@ -367,125 +373,6 @@ private:
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline G4VEnergyLossProcess* G4LossTableManager::GetEnergyLossProcess(
const G4ParticleDefinition *aParticle)
{
if(aParticle != currentParticle) {
currentParticle = aParticle;
std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
currentLoss = (*pos).second;
} else {
currentLoss = 0;
//ParticleHaveNoLoss(aParticle);
}
}
return currentLoss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4LossTableManager::GetDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { x = currentLoss->GetDEDX(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetDEDX(currentParticle,
kineticEnergy,couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline G4double G4LossTableManager::GetSubDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { x = currentLoss->GetDEDXForSubsec(kineticEnergy, couple); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline G4double G4LossTableManager::GetCSDARange(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = DBL_MAX;
if(currentLoss) { x = currentLoss->GetCSDARange(kineticEnergy, couple); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline G4double G4LossTableManager::GetRangeFromRestricteDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
if(currentLoss) { x = currentLoss->GetRangeForLoss(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetRange(currentParticle,kineticEnergy,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline G4double G4LossTableManager::GetRange(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
if(currentLoss) { x = currentLoss->GetRange(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetRange(currentParticle,kineticEnergy,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4LossTableManager::GetEnergy(
const G4ParticleDefinition *aParticle,
G4double range,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
if(currentLoss) { x = currentLoss->GetKineticEnergy(range, couple); }
else { x = G4EnergyLossTables::GetPreciseEnergyFromRange(currentParticle,range,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4LossTableManager::GetDEDXDispersion(
const G4MaterialCutsCouple *couple,
const G4DynamicParticle* dp,
G4double& length)
{
const G4ParticleDefinition* aParticle = dp->GetParticleDefinition();
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { currentLoss->GetDEDXDispersion(couple, dp, length); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -24,8 +24,7 @@
// ********************************************************************
//
//
// $Id: G4MscStepLimitType.hh,v 1.2 2007-06-11 14:56:51 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//---------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VAtomDeexcitation.hh,v 1.9 2011-01-03 19:34:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -82,10 +81,10 @@ public:
virtual void InitialiseForExtraAtom(G4int Z) = 0;
// Activation of deexcitation per detector region
void SetDeexcitationActiveRegion(const G4String& rname = "",
G4bool valDeexcitation = true,
G4bool valAuger = false,
G4bool valPIXE = true);
void SetDeexcitationActiveRegion(const G4String& rname,
G4bool valDeexcitation,
G4bool valAuger,
G4bool valPIXE);
// Activation of deexcitation
inline void SetFluo(G4bool);
@@ -220,7 +219,7 @@ inline void G4VAtomDeexcitation::SetPIXE(G4bool val)
inline G4bool G4VAtomDeexcitation::IsPIXEActive() const
{
return (flagPIXE && isActive);
return flagPIXE;
}
inline const G4String& G4VAtomDeexcitation::GetName() const
@@ -271,14 +270,14 @@ inline G4int G4VAtomDeexcitation::GetVerboseLevel() const
inline G4bool
G4VAtomDeexcitation::CheckDeexcitationActiveRegion(G4int coupleIndex)
{
return (isActive && activeDeexcitationMedia[coupleIndex]);
return (isActive || activeDeexcitationMedia[coupleIndex]);
}
inline G4bool
G4VAtomDeexcitation::CheckAugerActiveRegion(G4int coupleIndex)
{
return (flagAuger && activeAugerMedia[coupleIndex]);
return (flagAuger || activeAugerMedia[coupleIndex]);
}
inline void
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VBremAngularDistribution.hh,v 1.1 2010-10-14 16:34:04 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmAngularDistribution.hh,v 1.2 2010-11-04 12:55:09 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -52,6 +51,11 @@
#define G4VEmAngularDistribution_h 1
#include "globals.hh"
#include "Randomize.hh"
#include "G4ThreeVector.hh"
#include "G4DynamicParticle.hh"
class G4Material;
class G4VEmAngularDistribution
{
@@ -61,13 +65,20 @@ public:
virtual ~G4VEmAngularDistribution();
// method for bremsstrahlung
virtual G4double PolarAngle(const G4double initial_energy,
const G4double final_energy,
const G4int Z) = 0;
// Sample direction in global coordinate system,
// this means for zero scattering angle this direction is the same
// as the direction of primary
virtual G4ThreeVector& SampleDirection(const G4DynamicParticle* dp,
G4double finalTotalEnergy,
G4int Z,
const G4Material*) = 0;
inline const G4String& GetName() const;
protected:
G4ThreeVector fLocalDirection;
private:
// hide assignment operator
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmFluctuationModel.hh,v 1.12 2009-02-19 11:25:50 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmModel.hh,v 1.77 2010-10-14 16:27:35 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -159,6 +158,9 @@ public:
const G4Material*,
G4double kineticEnergy);
// Initialisation for a new track
virtual void StartTracking(G4Track*);
// add correction to energy loss and compute non-ionizing energy loss
virtual void CorrectionsAlongStep(const G4MaterialCutsCouple*,
const G4DynamicParticle*,
@@ -166,6 +168,15 @@ public:
G4double& niel,
G4double length);
// value which may be tabulated (by default cross section)
virtual G4double Value(const G4MaterialCutsCouple*,
const G4ParticleDefinition*,
G4double kineticEnergy);
// threshold for zero value
virtual G4double MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*);
// initilisation at run time for a given material
virtual void SetupForMaterial(const G4ParticleDefinition*,
const G4Material*,
@@ -246,6 +257,10 @@ public:
void SetParticleChange(G4VParticleChange*, G4VEmFluctuationModel* f=0);
void SetCrossSectionTable(G4PhysicsTable*);
inline G4PhysicsTable* GetCrossSectionTable();
inline G4VEmFluctuationModel* GetModelOfFluctuations();
inline G4VEmAngularDistribution* GetAngularDistribution();
@@ -256,6 +271,10 @@ public:
inline G4double LowEnergyLimit() const;
inline G4double HighEnergyActivationLimit() const;
inline G4double LowEnergyActivationLimit() const;
inline G4double PolarAngleLimit() const;
inline G4double SecondaryThreshold() const;
@@ -264,6 +283,8 @@ public:
inline G4bool DeexcitationFlag() const;
inline G4bool ForceBuildTableFlag() const;
inline void SetHighEnergyLimit(G4double);
inline void SetLowEnergyLimit(G4double);
@@ -282,6 +303,8 @@ public:
inline void SetDeexcitationFlag(G4bool val);
inline void ForceBuildTable(G4bool val);
inline G4double MaxSecondaryKinEnergy(const G4DynamicParticle* dynParticle);
inline const G4String& GetName() const;
@@ -317,13 +340,18 @@ private:
G4double polarAngleLimit;
G4double secondaryThreshold;
G4bool theLPMflag;
G4bool flagDeexcitation;
G4bool flagForceBuildTable;
G4int nSelectors;
std::vector<G4EmElementSelector*> elmSelectors;
protected:
G4VParticleChange* pParticleChange;
G4VParticleChange* pParticleChange;
G4PhysicsTable* xSectionTable;
const std::vector<G4double>* theDensityFactor;
const std::vector<G4int>* theDensityIdx;
// ======== Cashed values - may be state dependent ================
@@ -333,7 +361,6 @@ private:
const G4Element* fCurrentElement;
G4int nsec;
G4bool flagDeexcitation;
std::vector<G4double> xsec;
};
@@ -402,7 +429,7 @@ inline G4double G4VEmModel::CrossSection(const G4MaterialCutsCouple* c,
inline G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
G4double ekin,
const G4Material* material,
const G4Material* material,
G4double emin,
G4double emax)
{
@@ -428,12 +455,12 @@ inline G4double G4VEmModel::ComputeCrossSectionPerAtom(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline
const G4Element* G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
G4double kinEnergy,
G4double cutEnergy,
G4double maxEnergy)
inline const G4Element*
G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
G4double kinEnergy,
G4double cutEnergy,
G4double maxEnergy)
{
fCurrentCouple = couple;
if(nSelectors > 0) {
@@ -441,7 +468,7 @@ const G4Element* G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple
elmSelectors[couple->GetIndex()]->SelectRandomAtom(kinEnergy);
} else {
fCurrentElement = SelectRandomAtom(couple->GetMaterial(),p,kinEnergy,
cutEnergy,maxEnergy);
cutEnergy,maxEnergy);
}
return fCurrentElement;
}
@@ -506,6 +533,20 @@ inline G4double G4VEmModel::LowEnergyLimit() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4VEmModel::HighEnergyActivationLimit() const
{
return eMaxActive;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4VEmModel::LowEnergyActivationLimit() const
{
return eMinActive;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4VEmModel::PolarAngleLimit() const
{
return polarAngleLimit;
@@ -532,6 +573,13 @@ inline G4bool G4VEmModel::DeexcitationFlag() const
return flagDeexcitation;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4VEmModel::ForceBuildTableFlag() const
{
return flagForceBuildTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VEmModel::SetHighEnergyLimit(G4double val)
@@ -595,6 +643,13 @@ inline void G4VEmModel::SetDeexcitationFlag(G4bool val)
flagDeexcitation = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::ForceBuildTable(G4bool val)
{
flagForceBuildTable = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4String& G4VEmModel::GetName() const
@@ -602,6 +657,11 @@ inline const G4String& G4VEmModel::GetName() const
return name;
}
inline G4PhysicsTable* G4VEmModel::GetCrossSectionTable()
{
return xSectionTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmProcess.hh,v 1.61 2010-08-17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -67,6 +66,8 @@
#ifndef G4VEmProcess_h
#define G4VEmProcess_h 1
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4VDiscreteProcess.hh"
#include "globals.hh"
#include "G4Material.hh"
@@ -129,6 +130,9 @@ public:
void PrintInfoDefinition();
// Called before tracking of each new G4Track
void StartTracking(G4Track*);
// implementation of virtual method, specific for G4VEmProcess
G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
@@ -181,13 +185,16 @@ public:
inline G4int LambdaBinning() const;
// Min kinetic energy for tables
inline void SetMinKinEnergy(G4double e);
void SetMinKinEnergy(G4double e);
inline G4double MinKinEnergy() const;
// Max kinetic energy for tables
inline void SetMaxKinEnergy(G4double e);
void SetMaxKinEnergy(G4double e);
inline G4double MaxKinEnergy() const;
// Min kinetic energy for high energy table
inline void SetMinKinEnergyPrim(G4double e);
// Cross section table pointer
inline const G4PhysicsTable* LambdaTable() const;
@@ -215,12 +222,18 @@ public:
// model will be selected for a given energy interval
void AddEmModel(G4int, G4VEmModel*, const G4Region* region = 0);
// Assign a model to a process
// Assign a model to a process - obsolete will be removed
void SetModel(G4VEmModel*, G4int index = 1);
// return the assigned model
// return the assigned model - obsolete will be removed
G4VEmModel* Model(G4int index = 1);
// return the assigned model
G4VEmModel* EmModel(G4int index = 1);
// Assign a model to a process
void SetEmModel(G4VEmModel*, G4int index = 1);
// Define new energy range for the model identified by the name
void UpdateEmModel(const G4String&, G4double, G4double);
@@ -239,6 +252,10 @@ public:
const G4String& r = "",
G4bool flag = true);
void ActivateSecondaryBiasing(const G4String& region, G4double factor,
G4double energyLimit);
// Single scattering parameters
inline void SetPolarAngleLimit(G4double a);
inline G4double PolarAngleLimit() const;
@@ -281,6 +298,8 @@ protected:
inline void SetStartFromNullFlag(G4bool val);
inline void SetSplineFlag(G4bool val);
private:
void Clear();
@@ -289,14 +308,14 @@ private:
void FindLambdaMax();
inline void InitialiseStep(const G4Track&);
inline void DefineMaterial(const G4MaterialCutsCouple* couple);
inline void ComputeIntegralLambda(G4double kinEnergy);
inline G4double GetLambdaFromTable(G4double kinEnergy);
inline G4double GetLambdaFromTablePrim(G4double kinEnergy);
inline G4double GetCurrentLambda(G4double kinEnergy);
inline G4double ComputeCurrentLambda(G4double kinEnergy);
@@ -319,9 +338,11 @@ private:
// ======== Parameters of the class fixed at initialisation =======
std::vector<G4VEmModel*> emModels;
G4int numberOfModels;
// tables and vectors
G4PhysicsTable* theLambdaTable;
G4PhysicsTable* theLambdaTablePrim;
std::vector<G4double> theEnergyOfCrossSectionMax;
std::vector<G4double> theCrossSectionMax;
@@ -335,6 +356,7 @@ private:
G4int nLambdaBins;
G4double minKinEnergy;
G4double minKinEnergyPrim;
G4double maxKinEnergy;
G4double lambdaFactor;
G4double polarAngleLimit;
@@ -343,6 +365,7 @@ private:
G4bool integral;
G4bool applyCuts;
G4bool startFromNull;
G4bool splineFlag;
// ======== Cashed values - may be state dependent ================
@@ -372,6 +395,8 @@ private:
G4double fFactor;
G4bool biasFlag;
G4bool weightFlag;
G4int warn;
};
// ======== Run time inline methods ================
@@ -416,7 +441,9 @@ inline void G4VEmProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
inline
G4VEmModel* G4VEmProcess::SelectModel(G4double& kinEnergy, size_t index)
{
currentModel = modelManager->SelectModel(kinEnergy, index);
if(1 < numberOfModels) {
currentModel = modelManager->SelectModel(kinEnergy, index);
}
currentModel->SetCurrentCouple(currentCouple);
return currentModel;
}
@@ -432,39 +459,35 @@ G4VEmModel* G4VEmProcess::SelectModelForMaterial(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::InitialiseStep(const G4Track& track)
inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
{
currentParticle = track.GetParticleDefinition();
preStepKinEnergy = track.GetKineticEnergy();
DefineMaterial(track.GetMaterialCutsCouple());
SelectModel(preStepKinEnergy, currentCoupleIndex);
if (theNumberOfInteractionLengthLeft < 0.0) { mfpKinEnergy = DBL_MAX; }
return ((*theLambdaTable)[basedCoupleIndex])->Value(e);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
inline G4double G4VEmProcess::GetLambdaFromTablePrim(G4double e)
{
return fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e);
return ((*theLambdaTablePrim)[basedCoupleIndex])->Value(e)/e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::ComputeCurrentLambda(G4double e)
{
return fFactor *
(currentModel->CrossSectionPerVolume(baseMaterial,currentParticle,
e,(*theCuts)[currentCoupleIndex]));
return currentModel->CrossSectionPerVolume(baseMaterial,currentParticle,
e,(*theCuts)[currentCoupleIndex]);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetCurrentLambda(G4double e)
{
G4double x = 0.0;
if(theLambdaTable) { x = GetLambdaFromTable(e); }
else { x = ComputeCurrentLambda(e); }
return x;
G4double x;
if(e >= minKinEnergyPrim) { x = GetLambdaFromTablePrim(e); }
else if(theLambdaTable) { x = GetLambdaFromTable(e); }
else { x = ComputeCurrentLambda(e); }
return fFactor*x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -485,7 +508,7 @@ G4VEmProcess::RecalculateLambda(G4double e, const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
SelectModel(e, currentCoupleIndex);
return ComputeCurrentLambda(e);
return fFactor*ComputeCurrentLambda(e);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -527,13 +550,6 @@ inline G4int G4VEmProcess::LambdaBinning() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetMinKinEnergy(G4double e)
{
minKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::MinKinEnergy() const
{
return minKinEnergy;
@@ -541,16 +557,16 @@ inline G4double G4VEmProcess::MinKinEnergy() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetMaxKinEnergy(G4double e)
inline G4double G4VEmProcess::MaxKinEnergy() const
{
maxKinEnergy = e;
return maxKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::MaxKinEnergy() const
inline void G4VEmProcess::SetMinKinEnergyPrim(G4double e)
{
return maxKinEnergy;
minKinEnergyPrim = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -663,4 +679,11 @@ inline void G4VEmProcess::SetStartFromNullFlag(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetSplineFlag(G4bool val)
{
splineFlag = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -24,8 +24,7 @@
// ********************************************************************
//
//
// $Id: G4VEnergyLoss.hh,v 1.18 2006-06-29 19:54:47 gunter Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
//
// ------------------------------------------------------------
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEnergyLossProcess.hh,v 1.93 2010-10-14 16:27:35 vnivanch Exp $
// $Id$
// GEANT4 tag $Name:
//
// -------------------------------------------------------------------
@@ -174,6 +174,9 @@ public:
// summary printout after initialisation
void PrintInfoDefinition();
// Called before tracking of each new G4Track
void StartTracking(G4Track*);
// Step limit from AlongStep
G4double AlongStepGetPhysicalInteractionLength(const G4Track&,
G4double previousStepSize,
@@ -637,6 +640,8 @@ inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
{
//G4cout << "G4VEnergyLossProcess::GetDEDX: Idx= "
// << basedCoupleIndex << " E(MeV)= " << e << G4endl;
G4double x = fFactor*(*theDEDXTable)[basedCoupleIndex]->Value(e);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
@@ -674,6 +679,8 @@ G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
{
//G4cout << "G4VEnergyLossProcess::GetRange: Idx= "
// << basedCoupleIndex << " E(MeV)= " << e << G4endl;
G4double x = ((*theRangeTableForLoss)[basedCoupleIndex])->Value(e);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
@@ -699,6 +706,8 @@ G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(G4double e)
inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
{
//G4cout << "G4VEnergyLossProcess::GetEnergy: Idx= "
// << basedCoupleIndex << " R(mm)= " << r << G4endl;
G4PhysicsVector* v = (*theInverseRangeTable)[basedCoupleIndex];
G4double rmin = v->Energy(0);
G4double e = 0.0;
@@ -731,7 +740,7 @@ G4VEnergyLossProcess::GetDEDX(G4double& kineticEnergy,
inline G4double
G4VEnergyLossProcess::GetDEDXForSubsec(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
return GetSubDEDXForScaledEnergy(kineticEnergy*massRatio);
@@ -744,7 +753,7 @@ G4VEnergyLossProcess::GetRange(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x = fRange;
if(kineticEnergy != preStepKinEnergy || couple != currentCouple) {
if(couple != currentCouple || kineticEnergy != preStepKinEnergy) {
DefineMaterial(couple);
if(theCSDARangeTable) {
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
@@ -776,9 +785,9 @@ inline G4double
G4VEnergyLossProcess::GetRangeForLoss(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = DBL_MAX;
if(theRangeTableForLoss) {
G4double x = fRange;
if(couple != currentCouple || kineticEnergy != preStepKinEnergy) {
DefineMaterial(couple);
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
}
// G4cout << "Range from " << GetProcessName()
@@ -793,9 +802,7 @@ G4VEnergyLossProcess::GetKineticEnergy(G4double& range,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double r = range/reduceFactor;
G4double e = ScaledKinEnergyForLoss(r)/massRatio;
return e;
return ScaledKinEnergyForLoss(range/reduceFactor)/massRatio;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMscModel.hh,v 1.10 2010-09-07 16:05:33 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -39,6 +38,7 @@
//
// Modifications:
// 07.04.2009 V.Ivanchenko moved msc methods from G4VEmModel to G4VMscModel
// 26.03.2012 V.Ivanchenko added transport x-section pointer and Get?Set methods
//
// Class Description:
//
@@ -46,10 +46,11 @@
// -------------------------------------------------------------------
//
#ifndef G4VMscModel_h
#define G4VMscModel_h 1
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4VEmModel.hh"
#include "G4MscStepLimitType.hh"
#include "globals.hh"
@@ -57,6 +58,10 @@
#include "G4Track.hh"
#include "G4SafetyHelper.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4LossTableManager.hh"
#include "G4PhysicsTable.hh"
#include "G4ThreeVector.hh"
#include <vector>
class G4ParticleChangeForMSC;
@@ -70,17 +75,16 @@ public:
virtual ~G4VMscModel();
virtual G4double ComputeTruePathLengthLimit(const G4Track& track,
G4PhysicsTable*,
G4double currentMinimalStep);
G4double& stepLimit);
virtual G4double ComputeGeomPathLength(G4double truePathLength);
virtual G4double ComputeTrueStepLength(G4double geomPathLength);
virtual void SampleScattering(const G4DynamicParticle*,
G4double safety);
virtual G4ThreeVector& SampleScattering(const G4DynamicParticle*,
G4double safety);
// empty
// empty method
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
@@ -103,29 +107,42 @@ public:
inline void SetSampleZ(G4bool);
//================================================================
// Get/Set access to Physics Tables
//================================================================
inline G4VEnergyLossProcess* GetIonisation() const;
inline void SetIonisation(G4VEnergyLossProcess*);
inline void SetIonisation(G4VEnergyLossProcess*,
const G4ParticleDefinition* part);
//================================================================
// Run time methods
//================================================================
protected:
// initialisation of the ParticleChange for the model
// initialisation of interface with geometry and ionisation
G4ParticleChangeForMSC* GetParticleChangeForMSC();
G4ParticleChangeForMSC*
GetParticleChangeForMSC(const G4ParticleDefinition* p = 0);
// shift point of the track PostStep
void ComputeDisplacement(G4ParticleChangeForMSC*,
const G4ThreeVector& displDir,
G4double displacement,
G4double postsafety);
// convert true length to geometry length
inline G4double ConvertTrueToGeom(G4double& tLength, G4double& gLength);
public:
// compute safety
inline G4double ComputeSafety(const G4ThreeVector& position, G4double limit);
// compute linear distance to a geometry boundary
inline G4double ComputeGeomLimit(const G4Track& position, G4double& presafety,
inline G4double ComputeGeomLimit(const G4Track&, G4double& presafety,
G4double limit);
inline G4double GetDEDX(const G4ParticleDefinition* part,
G4double kineticEnergy,
const G4MaterialCutsCouple* couple);
inline G4double GetRange(const G4ParticleDefinition* part,
G4double kineticEnergy,
const G4MaterialCutsCouple* couple);
@@ -134,6 +151,11 @@ protected:
G4double range,
const G4MaterialCutsCouple* couple);
// G4MaterialCutsCouple should be defined before call to this method
inline
G4double GetTransportMeanFreePath(const G4ParticleDefinition* part,
G4double kinEnergy);
private:
// hide assignment operator
@@ -142,6 +164,8 @@ private:
G4SafetyHelper* safetyHelper;
G4VEnergyLossProcess* ionisation;
const G4ParticleDefinition* currentPart;
G4LossTableManager* man;
G4double dedx;
G4double localtkin;
@@ -158,6 +182,7 @@ protected:
G4double geomMin;
G4double geomMax;
G4ThreeVector fDisplacement;
G4MscStepLimitType steppingAlgorithm;
G4bool samplez;
@@ -218,6 +243,16 @@ inline G4double G4VMscModel::ComputeSafety(const G4ThreeVector& position,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4VMscModel::ConvertTrueToGeom(G4double& tlength,
G4double& glength)
{
glength = ComputeGeomPathLength(tlength);
// should return true length
return tlength;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4VMscModel::ComputeGeomLimit(const G4Track& track,
G4double& presafety,
G4double limit)
@@ -234,16 +269,31 @@ inline G4double G4VMscModel::ComputeGeomLimit(const G4Track& track,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetDEDX(const G4ParticleDefinition* part,
G4double kinEnergy, const G4MaterialCutsCouple* couple)
{
G4double x;
if(ionisation) { x = ionisation->GetDEDX(kinEnergy, couple); }
else {
G4double q = part->GetPDGCharge()/CLHEP::eplus;
x = dedx*q*q;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetRange(const G4ParticleDefinition* part,
G4double kinEnergy, const G4MaterialCutsCouple* couple)
{
localrange = DBL_MAX;
localtkin = kinEnergy;
if(ionisation) { localrange = ionisation->GetRangeForLoss(localtkin, couple); }
else {
G4double q = part->GetPDGCharge()/eplus;
if(ionisation) {
localrange = ionisation->GetRangeForLoss(kinEnergy, couple);
} else {
G4double q = part->GetPDGCharge()/CLHEP::eplus;
localrange = kinEnergy/(dedx*q*q*couple->GetMaterial()->GetDensity());
localtkin = kinEnergy;
}
return localrange;
}
@@ -254,15 +304,15 @@ inline G4double
G4VMscModel::GetEnergy(const G4ParticleDefinition* part,
G4double range, const G4MaterialCutsCouple* couple)
{
G4double e = localtkin;
G4double e;
if(ionisation) { e = ionisation->GetKineticEnergy(range, couple); }
else {
G4double q = part->GetPDGCharge()/eplus;
e = localtkin;
if(localrange > range) {
G4double q = part->GetPDGCharge()/CLHEP::eplus;
e -= (localrange - range)*dedx*q*q*couple->GetMaterial()->GetDensity();
}
}
}
if(e < 0.0) { e = 0.0; }
return e;
}
@@ -271,9 +321,29 @@ inline G4VEnergyLossProcess* G4VMscModel::GetIonisation() const
return ionisation;
}
inline void G4VMscModel::SetIonisation(G4VEnergyLossProcess* p)
inline void G4VMscModel::SetIonisation(G4VEnergyLossProcess* p,
const G4ParticleDefinition* part)
{
ionisation = p;
currentPart = part;
}
inline G4double
G4VMscModel::GetTransportMeanFreePath(const G4ParticleDefinition* part,
G4double ekin)
{
G4double x;
if(xSectionTable) {
G4int idx = CurrentCouple()->GetIndex();
x = (*xSectionTable)[(*theDensityIdx)[idx]]->Value(ekin)
*(*theDensityFactor)[idx]/(ekin*ekin);
} else {
x = CrossSectionPerVolume(CurrentCouple()->GetMaterial(), part, ekin,
0.0, DBL_MAX);
}
if(0.0 >= x) { x = DBL_MAX; }
else { x = 1.0/x; }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMultipleScattering.hh,v 1.63 2010-03-10 18:29:51 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -75,7 +74,6 @@
#include "G4VContinuousDiscreteProcess.hh"
#include "globals.hh"
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ParticleChangeForMSC.hh"
#include "G4Track.hh"
#include "G4Step.hh"
@@ -84,9 +82,9 @@
#include "G4MscStepLimitType.hh"
class G4ParticleDefinition;
class G4DataVector;
class G4PhysicsTable;
class G4PhysicsVector;
class G4VEnergyLossProcess;
class G4LossTableManager;
class G4SafetyHelper;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -141,6 +139,9 @@ public:
const G4String& directory,
G4bool ascii);
// This is called in the beginning of tracking for a new track
void StartTracking(G4Track*);
// The function overloads the corresponding function of the base
// class.It limits the step near to boundaries only
// and invokes the method GetMscContinuousStepLimit at every step.
@@ -170,52 +171,31 @@ public:
G4double currentMinimalStep,
G4double& currentSafety);
//------------------------------------------------------------------------
// Specific methods to build and access Physics Tables
//------------------------------------------------------------------------
// Build empty Physics Vector
G4PhysicsVector* PhysicsVector(const G4MaterialCutsCouple*);
inline void SetBinning(G4int nbins);
inline G4int Binning() const;
inline void SetMinKinEnergy(G4double e);
inline G4double MinKinEnergy() const;
inline void SetMaxKinEnergy(G4double e);
inline G4double MaxKinEnergy() const;
inline void SetBuildLambdaTable(G4bool val);
inline G4PhysicsTable* LambdaTable() const;
// access particle type
inline const G4ParticleDefinition* Particle() const;
//------------------------------------------------------------------------
// Specific methods to set, access, modify models
//------------------------------------------------------------------------
protected:
// Select model in run time
inline G4VEmModel* SelectModel(G4double kinEnergy);
inline G4VEmModel* SelectModel(G4double kinEnergy, size_t idx);
public:
// Select model in run time
inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy,
size_t& idxRegion) const;
// Add model for region, smaller value of order defines which
// model will be selected for a given energy interval
void AddEmModel(G4int order, G4VEmModel*, const G4Region* region = 0);
// Assign a model to a process
// Assign a model to a process - obsolete method will be removed
void SetModel(G4VMscModel*, G4int index = 1);
// return the assigned model
// return the assigned model - obsolete method will be removed
G4VMscModel* Model(G4int index = 1);
// Assign a model to a process
void SetEmModel(G4VMscModel*, G4int index = 1);
// return the assigned model
G4VMscModel* EmModel(G4int index = 1);
// Access to models by index
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
@@ -223,6 +203,8 @@ public:
// Get/Set parameters for simulation of multiple scattering
//------------------------------------------------------------------------
void SetIonisation(G4VEnergyLossProcess*);
inline G4bool LateralDisplasmentFlag() const;
inline void SetLateralDisplasmentFlag(G4bool val);
@@ -241,6 +223,8 @@ public:
inline G4MscStepLimitType StepLimitType() const;
inline void SetStepLimitType(G4MscStepLimitType val);
inline const G4ParticleDefinition* FirstParticle() const;
//------------------------------------------------------------------------
// Run time methods
//------------------------------------------------------------------------
@@ -258,15 +242,6 @@ protected:
G4double currentMinimalStep,
G4double& currentSafety);
// This method returns inversed transport cross section
inline G4double GetLambda(const G4ParticleDefinition* p,
G4double& kineticEnergy);
// defines current material in run time
inline void DefineMaterial(const G4MaterialCutsCouple* couple);
inline const G4MaterialCutsCouple* CurrentMaterialCutsCouple() const;
private:
// hide assignment operator
@@ -276,28 +251,26 @@ private:
// ======== Parameters of the class fixed at construction =========
G4EmModelManager* modelManager;
G4bool buildLambdaTable;
G4LossTableManager* emManager;
G4double geomMin;
// ======== Parameters of the class fixed at initialisation =======
G4SafetyHelper* safetyHelper;
std::vector<G4VMscModel*> mscModels;
G4int numberOfModels;
G4PhysicsTable* theLambdaTable;
const G4ParticleDefinition* firstParticle;
const std::vector<G4double>* theDensityFactor;
const std::vector<G4int>* theDensityIdx;
const G4ParticleDefinition* currParticle;
G4MscStepLimitType stepLimit;
G4double minKinEnergy;
G4double maxKinEnergy;
G4double skin;
G4double facrange;
G4double facgeom;
G4double polarAngleLimit;
G4int nBins;
G4double lowestKinEnergy;
G4bool latDisplasment;
G4bool isIon;
@@ -311,130 +284,29 @@ protected:
private:
G4VMscModel* currentModel;
// cache
const G4ParticleDefinition* currentParticle;
const G4MaterialCutsCouple* currentCouple;
size_t currentCoupleIndex;
size_t basedCoupleIndex;
G4VMscModel* currentModel;
G4VEnergyLossProcess* fIonisation;
G4double physStepLimit;
G4double tPathLength;
G4double gPathLength;
G4ThreeVector fNewPosition;
G4bool fPositionChanged;
G4bool isActive;
G4int warn;
};
// ======== Run time inline methods ================
inline const G4MaterialCutsCouple*
G4VMultipleScattering::CurrentMaterialCutsCouple() const
{
return currentCouple;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
void G4VMultipleScattering::DefineMaterial(const G4MaterialCutsCouple* couple)
inline G4VEmModel*
G4VMultipleScattering::SelectModel(G4double kinEnergy, size_t coupleIndex)
{
if(couple != currentCouple) {
currentCouple = couple;
currentCoupleIndex = couple->GetIndex();
basedCoupleIndex = (*theDensityIdx)[currentCoupleIndex];
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VMultipleScattering::GetLambda(const G4ParticleDefinition* p,
G4double& e)
{
G4double x;
if(theLambdaTable) {
x = (*theDensityFactor)[currentCoupleIndex]*
((*theLambdaTable)[basedCoupleIndex])->Value(e);
} else {
x = currentModel->CrossSection(currentCouple,p,e);
}
if(x > 0.0) { x = 1./x; }
else { x = DBL_MAX; }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmModel* G4VMultipleScattering::SelectModel(G4double kinEnergy)
{
return modelManager->SelectModel(kinEnergy, currentCoupleIndex);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmModel* G4VMultipleScattering::SelectModelForMaterial(
G4double kinEnergy, size_t& idxRegion) const
{
return modelManager->SelectModel(kinEnergy, idxRegion);
}
// ======== Get/Set inline methods used at initialisation ================
inline void G4VMultipleScattering::SetBinning(G4int nbins)
{
nBins = nbins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4int G4VMultipleScattering::Binning() const
{
return nBins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VMultipleScattering::SetMinKinEnergy(G4double e)
{
minKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VMultipleScattering::MinKinEnergy() const
{
return minKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VMultipleScattering::SetMaxKinEnergy(G4double e)
{
maxKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VMultipleScattering::MaxKinEnergy() const
{
return maxKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VMultipleScattering::SetBuildLambdaTable(G4bool val)
{
buildLambdaTable = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VMultipleScattering::LambdaTable() const
{
return theLambdaTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4ParticleDefinition* G4VMultipleScattering::Particle() const
{
return currentParticle;
return modelManager->SelectModel(kinEnergy, coupleIndex);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -527,4 +399,11 @@ inline void G4VMultipleScattering::SetStepLimitType(G4MscStepLimitType val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4ParticleDefinition* G4VMultipleScattering::FirstParticle() const
{
return firstParticle;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ionEffectiveCharge.hh,v 1.12 2008-09-20 19:39:34 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4DummyModel.cc,v 1.4 2009-04-07 18:39:47 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ElectronIonPair.cc,v 1.5 2010-10-25 17:23:01 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -45,6 +44,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4ElectronIonPair.hh"
#include "G4SystemOfUnits.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4StepPoint.hh"
@@ -61,7 +61,7 @@ G4ElectronIonPair::G4ElectronIonPair()
curMaterial = 0;
curMeanEnergy = 0.0;
nMaterials = 0;
FanoFactor = 0.2;
invFanoFactor = 1.0/0.2;
Initialise();
}
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmBiasingManager.cc,v 1.88 2010-08-17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -39,27 +38,37 @@
//
// Modifications:
//
// 31-05-12 D. Sawkey put back in high energy limit for brem, russian roulette
// 30-05-12 D. Sawkey brem split gammas are unique; do weight tests for
// brem, russian roulette
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmBiasingManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ProductionCutsTable.hh"
#include "G4ProductionCuts.hh"
#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "Randomize.hh"
#include "G4DynamicParticle.hh"
#include "G4Track.hh"
#include "G4Electron.hh"
#include "G4VEmModel.hh"
#include "G4LossTableManager.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4ParticleChangeForGamma.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmBiasingManager::G4EmBiasingManager()
: nForcedRegions(0),nSecBiasedRegions(0),
: nForcedRegions(0),nSecBiasedRegions(0),eIonisation(0),
currentStepLimit(0.0),startTracking(true)
{}
{
fSafetyMin = 1.e-6*mm;
theElectron = G4Electron::Electron();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -182,7 +191,6 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
//G4cout << "G4EmBiasingManager::ActivateSecondaryBiasing: "
// << rname << " F= " << factor << " E(MeV)= " << energyLimit/MeV
// << G4endl;
if(0.0 >= factor) { return; }
G4RegionStore* regionStore = G4RegionStore::GetInstance();
G4String name = rname;
if(name == "" || name == "world" || name == "World") {
@@ -196,15 +204,22 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
return;
}
// Range cut
G4int nsplit = 0;
G4double w = 1.0/factor;
G4double w = factor;
// splitting
if(factor >= 1.0) {
nsplit = G4int(factor + 0.5);
w = 1.0/G4double(nsplit);
nsplit = G4lrint(factor);
w = 1.0/G4double(nsplit);
// Russian roulette
} else if(0.0 < factor) {
nsplit = 1;
w = 1.0/factor;
}
// the region is in the list
// the region is in the list - overwrite parameters
if (0 < nSecBiasedRegions) {
for (G4int i=0; i<nSecBiasedRegions; ++i) {
if (reg == secBiasedRegions[i]) {
@@ -215,12 +230,11 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
}
}
}
if(1 == nsplit) {
G4cout << "### G4EmBiasingManager::ActivateSecondaryBiasing WARNING: "
<< nsplit << " = 1, so no activation for the G4Region <"
<< rname << ">" << G4endl;
return;
}
/*
G4cout << "### G4EmBiasingManager::ActivateSecondaryBiasing: "
<< " nsplit= " << nsplit << " for the G4Region <"
<< rname << ">" << G4endl;
*/
// new region
secBiasedRegions.push_back(reg);
@@ -255,35 +269,125 @@ G4double G4EmBiasingManager::GetStepLimit(G4int coupleIdx,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4DynamicParticle*>& vd,
G4EmBiasingManager::ApplySecondaryBiasing(
std::vector<G4DynamicParticle*>& vd,
const G4Track& track,
G4VEmModel* currentModel,
G4ParticleChangeForLoss* pPartChange,
G4double& eloss,
G4int coupleIdx,
G4double tcut,
G4double safety)
{
G4int index = idxSecBiasedCouple[coupleIdx];
G4double weight = 1.0;
if(0 <= index) {
size_t n = vd.size();
// the check cannot be applied per secondary particle
// because weight correction is common, so the first
// secondary is checked
if(0 < n && vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
G4int nsplit = nBremSplitting[index];
// Range cut
if(0 == nsplit) {
if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
// Russian Roulette
} if(1 == nsplit) {
weight = ApplyRussianRoulette(vd, index);
// Splitting
} else {
G4double tmpEnergy = pPartChange->GetProposedKineticEnergy();
G4ThreeVector tmpMomDir = pPartChange->GetProposedMomentumDirection();
weight = ApplySplitting(vd, track, currentModel, index, tcut);
pPartChange->SetProposedKineticEnergy(tmpEnergy);
pPartChange->ProposeMomentumDirection(tmpMomDir);
}
}
}
return weight;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4EmBiasingManager::ApplySecondaryBiasing(
std::vector<G4DynamicParticle*>& vd,
const G4Track& track,
G4VEmModel* currentModel,
G4ParticleChangeForGamma* pPartChange,
G4double& eloss,
G4int coupleIdx,
G4double tcut,
G4double safety)
{
G4int index = idxSecBiasedCouple[coupleIdx];
G4double weight = 1.0;
if(0 <= index) {
size_t n = vd.size();
// the check cannot be applied per secondary particle
// because weight correction is common, so the first
// secondary is checked
if(0 < n && vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
G4int nsplit = nBremSplitting[index];
// Range cut
if(0 == nsplit) {
if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
// Russian Roulette
} if(1 == nsplit) {
weight = ApplyRussianRoulette(vd, index);
// Splitting
} else {
G4double tmpEnergy = pPartChange->GetProposedKineticEnergy();
G4ThreeVector tmpMomDir = pPartChange->GetProposedMomentumDirection();
weight = ApplySplitting(vd, track, currentModel, index, tcut);
pPartChange->SetProposedKineticEnergy(tmpEnergy);
pPartChange->ProposeMomentumDirection(tmpMomDir);
}
}
}
return weight;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& track,
G4int coupleIdx)
{
G4int index = idxSecBiasedCouple[coupleIdx];
G4double weight = 1.0;
size_t n = vd.size();
G4int i = idxSecBiasedCouple[coupleIdx];
if(0 <= i && 0 < n) {
if(0 <= index) {
size_t n = track.size();
// apply biasing if first secondary has energy below the threshold
if(vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[i]) {
weight = secBiasedWeight[i];
G4int nsplit = nBremSplitting[i];
// the check cannot be applied per secondary particle
// because weight correction is common, so the first
// secondary is checked
if(0 < n && track[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
// splitting
if(1 < nsplit) {
G4int nsplit = nBremSplitting[index];
// Russian Roulette only
if(1 == nsplit) {
weight = secBiasedWeight[index];
for(size_t k=0; k<n; ++k) {
const G4DynamicParticle* dp = vd[k];
for(G4int j=1; j<nsplit; ++j) {
G4DynamicParticle* dpnew = new G4DynamicParticle(*dp);
vd.push_back(dpnew);
}
}
// Russian roulette
} else {
for(size_t k=0; k<n; ++k) {
const G4DynamicParticle* dp = vd[k];
if(G4UniformRand()*weight > 1.0) {
delete dp;
vd[k] = 0;
const G4Track* t = track[k];
delete t;
track[k] = 0;
}
}
}
@@ -295,38 +399,23 @@ G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4DynamicParticle*>& vd,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& tr,
G4double primaryWeight,
G4int coupleIdx)
G4EmBiasingManager::ApplyRangeCut(std::vector<G4DynamicParticle*>& vd,
const G4Track& track,
G4double& eloss, G4double safety)
{
G4double weight = primaryWeight;
size_t n = tr.size();
G4int i = idxSecBiasedCouple[coupleIdx];
if(0 <= i && 0 < n) {
weight *= secBiasedWeight[i];
G4int nsplit = nBremSplitting[i];
// splitting
if(1 < nsplit) {
for(size_t k=0; k<n; ++k) {
G4Track* t = tr[k];
t->SetWeight(weight);
for(G4int j=1; j<nsplit; ++j) {
G4Track* tnew = new G4Track(*t);
tnew->SetWeight(weight);
tr.push_back(tnew);
}
}
// Russian roulette
} else {
for(size_t k=0; k<n; ++k) {
G4Track* t = tr[k];
if(G4UniformRand()*secBiasedWeight[i] <= 1.0) {
t->SetWeight(weight);
} else {
delete t;
tr[k] = 0;
size_t n = vd.size();
if(!eIonisation) {
eIonisation = G4LossTableManager::Instance()->GetEnergyLossProcess(theElectron);
}
if(eIonisation) {
for(size_t k=0; k<n; ++k) {
const G4DynamicParticle* dp = vd[k];
if(dp->GetDefinition() == theElectron) {
G4double e = dp->GetKineticEnergy();
if(eIonisation->GetRangeForLoss(e, track.GetMaterialCutsCouple()) < safety) {
eloss += e;
delete dp;
vd[k] = 0;
}
}
}
@@ -334,3 +423,45 @@ G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& tr,
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4EmBiasingManager::ApplySplitting(std::vector<G4DynamicParticle*>& vd,
const G4Track& track,
G4VEmModel* currentModel,
G4int index,
G4double tcut)
{
// method is applied only if 1 secondary created PostStep
// in the case of many secodndaries there is a contrudition
G4double weight = 1.0;
size_t n = vd.size();
G4double w = secBiasedWeight[index];
if(1 != n || 1.0 <= w) { return weight; }
G4double trackWeight = track.GetWeight();
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
G4int nsplit = nBremSplitting[index];
// double splitting is supressed
if(1 < nsplit && trackWeight>w) {
weight = w;
// start from 1, because already one secondary created
if(nsplit > (G4int)tmpSecondaries.size()) {
tmpSecondaries.reserve(nsplit);
}
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
for(G4int k=1; k<nsplit; ++k) {
tmpSecondaries.clear();
currentModel->SampleSecondaries(&tmpSecondaries, couple, dynParticle, tcut);
for (size_t kk=0; kk<tmpSecondaries.size(); ++kk) {
vd.push_back(tmpSecondaries[kk]);
}
}
}
return weight;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCalculator.cc,v 1.59 2011-01-03 19:34:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -64,6 +63,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmCalculator.hh"
#include "G4SystemOfUnits.hh"
#include "G4LossTableManager.hh"
#include "G4VEmProcess.hh"
#include "G4VEnergyLossProcess.hh"
@@ -80,6 +80,8 @@
#include "G4Element.hh"
#include "G4EmCorrections.hh"
#include "G4GenericIon.hh"
#include "G4ProcessVector.hh"
#include "G4Gamma.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -314,22 +316,26 @@ G4double G4EmCalculator::GetCrossSectionPerVolume(G4double kinEnergy,
if(couple && UpdateParticle(p, kinEnergy)) {
G4int idx = couple->GetIndex();
FindLambdaTable(p, processName);
FindLambdaTable(p, processName, kinEnergy);
if(currentLambda) {
G4double e = kinEnergy*massRatio;
res = (((*currentLambda)[idx])->Value(e))*chargeSquare;
if(verbose>0) {
G4cout << "G4EmCalculator::GetXSPerVolume: E(MeV)= " << kinEnergy/MeV
<< " cross(cm-1)= " << res*cm
<< " " << p->GetParticleName()
<< " in " << mat->GetName();
if(verbose>1)
G4cout << " idx= " << idx << " Escaled((MeV)= " << e
<< " q2= " << chargeSquare;
G4cout << G4endl;
}
} else {
res = ComputeCrossSectionPerVolume(kinEnergy, p, processName, mat,
kinEnergy);
}
if(verbose>0) {
G4cout << "G4EmCalculator::GetXSPerVolume: E(MeV)= " << kinEnergy/MeV
<< " cross(cm-1)= " << res*cm
<< " " << p->GetParticleName()
<< " in " << mat->GetName();
if(verbose>1)
G4cout << " idx= " << idx << " Escaled((MeV)= "
<< kinEnergy*massRatio
<< " q2= " << chargeSquare;
G4cout << G4endl;
}
}
return res;
}
@@ -453,10 +459,10 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
}
} else {
res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
if(verbose > 1) G4cout << " no basePart E(MeV)= " << kinEnergy;
if(verbose > 1) { G4cout << " no basePart E(MeV)= " << kinEnergy << " "; }
}
if(verbose > 1) {
G4cout << " DEDX(MeV/mm)= " << res*mm/MeV
G4cout << currentModel->GetName() << ": DEDX(MeV/mm)= " << res*mm/MeV
<< " DEDX(MeV*cm^2/g)= "
<< res*gram/(MeV*cm2*mat->GetDensity())
<< G4endl;
@@ -538,14 +544,23 @@ G4double G4EmCalculator::ComputeElectronicDEDX(G4double kinEnergy,
currentMaterialName = mat->GetName();
G4double dedx = 0.0;
if(UpdateParticle(part, kinEnergy)) {
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
//G4cout << "ComputeElectronicDEDX for " << part->GetParticleName()
// << " n= " << n << G4endl;
for(G4int i=0; i<n; ++i) {
const G4ParticleDefinition* p = (vel[i])->Particle();
if((!isIon && p == part) || (isIon && p == theGenericIon)) {
dedx += ComputeDEDX(kinEnergy,part,(vel[i])->GetProcessName(),mat,cut);
if(vel[i]) {
G4VProcess* p = reinterpret_cast<G4VProcess*>(vel[i]);
if(ActiveForParticle(part, p)) {
//G4cout << "idx= " << i << " " << (vel[i])->GetProcessName()
// << " " << (vel[i])->Particle()->GetParticleName() << G4endl;
dedx += ComputeDEDX(kinEnergy,part,(vel[i])->GetProcessName(),mat,cut);
}
}
}
}
@@ -568,7 +583,7 @@ G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
G4double cut)
{
G4double dedx = ComputeElectronicDEDX(kinEnergy,part,mat,cut);
if(mass > 700.*MeV) dedx += ComputeNuclearDEDX(kinEnergy,part,mat);
if(mass > 700.*MeV) { dedx += ComputeNuclearDEDX(kinEnergy,part,mat); }
return dedx;
}
@@ -719,6 +734,22 @@ G4double G4EmCalculator::ComputeCrossSectionPerAtom(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4EmCalculator::ComputeGammaAttenuationLength(G4double kinEnergy,
const G4Material* mat)
{
G4double res = 0.0;
const G4ParticleDefinition* gamma = G4Gamma::Gamma();
res += ComputeCrossSectionPerVolume(kinEnergy, gamma, "conv", mat, 0.0);
res += ComputeCrossSectionPerVolume(kinEnergy, gamma, "compt", mat, 0.0);
res += ComputeCrossSectionPerVolume(kinEnergy, gamma, "phot", mat, 0.0);
res += ComputeCrossSectionPerVolume(kinEnergy, gamma, "Rayl", mat, 0.0);
if(res > 0.0) { res = 1.0/res; }
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCalculator::ComputeShellIonisationCrossSectionPerAtom(
const G4String& particle,
G4int Z,
@@ -746,7 +777,7 @@ G4double G4EmCalculator::ComputeMeanFreePath(G4double kinEnergy,
{
G4double mfp = DBL_MAX;
G4double x = ComputeCrossSectionPerVolume(kinEnergy, p, processName, mat, cut);
if(x > 0.0) mfp = 1.0/x;
if(x > 0.0) { mfp = 1.0/x; }
if(verbose>1) {
G4cout << "E(MeV)= " << kinEnergy/MeV
<< " MFP(mm)= " << mfp/mm
@@ -899,10 +930,11 @@ const G4Material* G4EmCalculator::FindMaterial(const G4String& name)
const G4Region* G4EmCalculator::FindRegion(const G4String& reg)
{
const G4Region* r = 0;
if(reg != "" || reg != "world")
if(reg != "" && reg != "world") {
r = G4RegionStore::GetInstance()->GetRegion(reg);
else
} else {
r = G4RegionStore::GetInstance()->GetRegion("DefaultRegionForTheWorld");
}
return r;
}
@@ -955,7 +987,8 @@ G4bool G4EmCalculator::UpdateCouple(const G4Material* material, G4double cut)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
const G4String& processName)
const G4String& processName,
G4double kinEnergy)
{
// Search for the process
if (!currentLambda || p != lambdaParticle || processName != lambdaName) {
@@ -963,66 +996,56 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
currentLambda = 0;
lambdaParticle = p;
G4String partname = p->GetParticleName();
const G4ParticleDefinition* part = p;
if(isIon) { part = theGenericIon; }
// energy loss process
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; ++i) {
if((vel[i])->GetProcessName() == lambdaName &&
(vel[i])->Particle() == part)
{
currentLambda = (vel[i])->LambdaTable();
isApplicable = true;
if(verbose>1) {
G4cout << "G4VEnergyLossProcess is found out: "
<< currentName << G4endl;
}
return;
// Search for energy loss process
currentName = processName;
currentModel = 0;
loweModel = 0;
G4VEnergyLossProcess* elproc = FindEnLossProcess(part, processName);
if(elproc) {
currentLambda = elproc->LambdaTable();
if(currentLambda) {
isApplicable = true;
if(verbose>1) {
G4cout << "G4VEnergyLossProcess is found out: " << currentName
<< G4endl;
}
}
// discrete process
if(!currentLambda) {
const std::vector<G4VEmProcess*> vem = lManager->GetEmProcessVector();
G4int n = vem.size();
for(G4int i=0; i<n; ++i) {
if((vem[i])->GetProcessName() == lambdaName &&
(vem[i])->Particle() == part)
{
currentLambda = (vem[i])->LambdaTable();
isApplicable = true;
if(verbose>1) {
G4cout << "G4VEmProcess is found out: "
<< currentName << G4endl;
}
return;
}
}
return;
}
// msc process
if(!currentLambda) {
const std::vector<G4VMultipleScattering*> vmsc =
lManager->GetMultipleScatteringVector();
G4int n = vmsc.size();
for(G4int i=0; i<n; ++i) {
if((vmsc[i])->GetProcessName() == lambdaName &&
(vmsc[i])->Particle() == part)
{
currentLambda = (vmsc[i])->LambdaTable();
// Search for discrete process
G4VEmProcess* proc = FindDiscreteProcess(part, processName);
if(proc) {
currentLambda = proc->LambdaTable();
if(currentLambda) {
isApplicable = true;
if(verbose>1) {
G4cout << "G4VEmProcess is found out: " << currentName << G4endl;
}
}
return;
}
// Search for msc process
G4VMultipleScattering* msc = FindMscProcess(part, processName);
if(msc) {
currentModel = msc->SelectModel(kinEnergy,0);
/*
if(currentModel) {
currentLambda = currentModel->GetCrossSectionTable();
if(currentLambda) {
isApplicable = true;
if(verbose>1) {
G4cout << "G4VMultipleScattering is found out: "
<< currentName << G4endl;
G4cout << "G4VMultipleScattering is found out: " << currentName
<< G4endl;
}
return;
}
}
}
*/
}
}
}
@@ -1045,11 +1068,11 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
if(isIon) { part = theGenericIon; }
if(verbose > 1) {
G4cout << "G4EmCalculator::FindEmModel for " << partname
G4cout << "## G4EmCalculator::FindEmModel for " << partname
<< " (type= " << p->GetParticleType()
<< ") and " << processName << " at E(MeV)= " << scaledEnergy;
if(p != part) G4cout << " GenericIon is the base particle";
G4cout << G4endl;
<< ") and " << processName << " at E(MeV)= " << scaledEnergy
<< G4endl;
if(p != part) { G4cout << " GenericIon is the base particle" << G4endl; }
}
// Search for energy loss process
@@ -1057,79 +1080,49 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
currentModel = 0;
loweModel = 0;
size_t idx = 0;
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
G4VEnergyLossProcess* elproc = 0;
for(G4int i=0; i<n; ++i) {
// G4cout << "i= " << i << " part= "
// << (vel[i])->Particle()->GetParticleName()
// << " proc= " << (vel[i])->GetProcessName() << G4endl;
if((vel[i])->GetProcessName() == currentName) {
if(baseParticle) {
if((vel[i])->Particle() == baseParticle) {
elproc = vel[i];
break;
}
} else {
if((vel[i])->Particle() == part) {
elproc = vel[i];
break;
}
}
}
}
G4VEnergyLossProcess* elproc = FindEnLossProcess(part, processName);
if(elproc) {
currentModel = elproc->SelectModelForMaterial(scaledEnergy, idx);
G4double eth = currentModel->LowEnergyLimit();
if(eth > 0.0) {
loweModel = elproc->SelectModelForMaterial(eth - CLHEP::eV, idx);
if(loweModel == currentModel) { loweModel = 0; }
}
}
// Search for discrete process
// Search for discrete process
if(!currentModel) {
const std::vector<G4VEmProcess*> vem = lManager->GetEmProcessVector();
G4int n = vem.size();
for(G4int i=0; i<n; ++i) {
if((vem[i])->GetProcessName() == currentName &&
(vem[i])->Particle() == part)
{
currentModel = (vem[i])->SelectModelForMaterial(kinEnergy, idx);
G4double eth = currentModel->LowEnergyLimit();
if(eth > 0.0) {
loweModel = (vem[i])->SelectModelForMaterial(eth - CLHEP::eV, idx);
}
break;
G4VEmProcess* proc = FindDiscreteProcess(part, processName);
if(proc) {
currentModel = proc->SelectModelForMaterial(kinEnergy, idx);
G4double eth = currentModel->LowEnergyLimit();
if(eth > 0.0) {
loweModel = proc->SelectModelForMaterial(eth - CLHEP::eV, idx);
if(loweModel == currentModel) { loweModel = 0; }
}
}
}
// Search for msc process
if(!currentModel) {
const std::vector<G4VMultipleScattering*> vmsc =
lManager->GetMultipleScatteringVector();
G4int n = vmsc.size();
for(G4int i=0; i<n; ++i) {
if((vmsc[i])->GetProcessName() == currentName &&
(vmsc[i])->Particle() == part)
{
currentModel = (vmsc[i])->SelectModelForMaterial(kinEnergy, idx);
G4double eth = currentModel->LowEnergyLimit();
if(eth > 0.0) {
loweModel = (vmsc[i])->SelectModelForMaterial(eth - CLHEP::eV, idx);
}
break;
}
G4VMultipleScattering* proc = FindMscProcess(part, processName);
if(proc) {
currentModel = proc->SelectModel(kinEnergy, idx);
loweModel = 0;
}
}
if(currentModel) {
if(loweModel == currentModel) { loweModel = 0; }
isApplicable = true;
if(verbose > 1) {
G4cout << "Model <" << currentModel->GetName()
<< "> Emin(MeV)= " << currentModel->LowEnergyLimit()/MeV;
G4cout << " Model <" << currentModel->GetName()
<< "> Emin(MeV)= " << currentModel->LowEnergyLimit()/MeV
<< " for " << part->GetParticleName();
if(elproc) {
G4cout << " and " << elproc->GetProcessName() << " " << elproc
<< G4endl;
}
if(loweModel) {
G4cout << " LowEnergy model <" << loweModel->GetName() << ">";
}
@@ -1155,18 +1148,93 @@ G4VEnergyLossProcess* G4EmCalculator::FindEnergyLossProcess(
&& currentParticleName != "helium"
&& currentParticleName != "hydrogen"
) { part = theGenericIon; }
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
elp = G4LossTableManager::Instance()->GetEnergyLossProcess(part);
return elp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEnergyLossProcess*
G4EmCalculator::FindEnLossProcess(const G4ParticleDefinition* part,
const G4String& processName)
{
G4VEnergyLossProcess* proc = 0;
const std::vector<G4VEnergyLossProcess*> v =
G4LossTableManager::Instance()->GetEnergyLossProcessVector();
G4int n = v.size();
for(G4int i=0; i<n; ++i) {
if( (vel[i])->Particle() == part ) {
elp = vel[i];
if((v[i])->GetProcessName() == processName) {
G4VProcess* p = reinterpret_cast<G4VProcess*>(v[i]);
if(ActiveForParticle(part, p)) {
proc = v[i];
break;
}
}
}
return proc;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmProcess*
G4EmCalculator::FindDiscreteProcess(const G4ParticleDefinition* part,
const G4String& processName)
{
G4VEmProcess* proc = 0;
const std::vector<G4VEmProcess*> v =
G4LossTableManager::Instance()->GetEmProcessVector();
G4int n = v.size();
for(G4int i=0; i<n; ++i) {
if((v[i])->GetProcessName() == processName) {
G4VProcess* p = reinterpret_cast<G4VProcess*>(v[i]);
if(ActiveForParticle(part, p)) {
proc = v[i];
break;
}
}
}
return proc;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMultipleScattering*
G4EmCalculator::FindMscProcess(const G4ParticleDefinition* part,
const G4String& processName)
{
G4VMultipleScattering* proc = 0;
const std::vector<G4VMultipleScattering*> v =
G4LossTableManager::Instance()->GetMultipleScatteringVector();
G4int n = v.size();
for(G4int i=0; i<n; ++i) {
if((v[i])->GetProcessName() == processName) {
G4VProcess* p = reinterpret_cast<G4VProcess*>(v[i]);
if(ActiveForParticle(part, p)) {
proc = v[i];
break;
}
}
}
return proc;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4EmCalculator::ActiveForParticle(const G4ParticleDefinition* part,
G4VProcess* proc)
{
G4ProcessManager* pm = part->GetProcessManager();
G4ProcessVector* pv = pm->GetProcessList();
G4int n = pv->size();
G4bool res = false;
for(G4int i=0; i<n; ++i) {
if((*pv)[i] == proc) {
if(pm->GetProcessActivation(i)) { res = true; }
break;
}
}
return elp;
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmConfigurator.cc,v 1.9 2010-07-29 11:13:28 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -48,6 +47,7 @@
//
#include "G4EmConfigurator.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ProcessManager.hh"
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCorrections.cc,v 1.64 2010-12-02 12:19:40 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -46,6 +45,7 @@
// 29.02.2008 V.Ivanchenko use expantions for log and power function
// 21.04.2008 Updated computations for ions (V.Ivanchenko)
// 20.05.2008 Removed Finite Size correction (V.Ivanchenko)
// 19.04.2012 Fix reproducibility problem (A.Ribon)
//
//
// Class Description:
@@ -58,6 +58,8 @@
#include "G4EmCorrections.hh"
#include "Randomize.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4VEmModel.hh"
@@ -213,18 +215,27 @@ G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
if(Z >= 100) Z = 99;
else if(Z < 1) Z = 1;
// fill vector
if(thcorr[Z].size() == 0) {
thcorr[Z].resize(ncouples);
G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
G4int ionPDG = p->GetPDGEncoding();
if(thcorr.find(ionPDG)==thcorr.end()) { // Not found: fill the map
std::vector<G4double> v;
for(size_t i=0; i<ncouples; ++i){
v.push_back(ethscaled*ComputeIonCorrections(p,currmat[i],ethscaled));
}
thcorr.insert(std::pair< G4int, std::vector<G4double> >(ionPDG,v));
}
for(size_t i=0; i<ncouples; ++i) {
(thcorr[Z])[i] = ethscaled*ComputeIonCorrections(p, currmat[i], ethscaled);
//G4cout << i << ". ethscaled= " << ethscaled
//<< " corr= " << (thcorr[Z])[i]/ethscaled << G4endl;
}
}
G4double rest = (thcorr[Z])[couple->GetIndex()];
//G4cout << " map size=" << thcorr.size() << G4endl;
//for(std::map< G4int, std::vector<G4double> >::iterator
// it = thcorr.begin(); it != thcorr.end(); ++it){
// G4cout << "\t map element: first (key)=" << it->first
// << "\t second (vector): vec size=" << (it->second).size() << G4endl;
// for(size_t i=0; i<(it->second).size(); ++i){
// G4cout << "\t \t vec element: [" << i << "]=" << (it->second)[i] << G4endl;
// }
//}
G4double rest = (thcorr.find(ionPDG)->second)[couple->GetIndex()];
sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e;
@@ -668,14 +679,14 @@ G4double G4EmCorrections::NuclearDEDX(const G4ParticleDefinition* p,
// Projectile nucleus
G4double z1 = std::fabs(particle->GetPDGCharge()/eplus);
G4double m1 = mass/amu_c2;
G4double mass1 = mass/amu_c2;
// loop for the elements in the material
for (G4int iel=0; iel<numberOfElements; iel++) {
const G4Element* element = (*theElementVector)[iel] ;
G4double z2 = element->GetZ();
G4double m2 = element->GetA()*mole/g ;
nloss += (NuclearStoppingPower(kinEnergy, z1, z2, m1, m2))
G4double mass2 = element->GetA()*mole/g ;
nloss += (NuclearStoppingPower(kinEnergy, z1, z2, mass1, mass2))
* atomDensity[iel] ;
}
nloss *= theZieglerFactor;
@@ -686,18 +697,18 @@ G4double G4EmCorrections::NuclearDEDX(const G4ParticleDefinition* p,
G4double G4EmCorrections::NuclearStoppingPower(G4double kineticEnergy,
G4double z1, G4double z2,
G4double m1, G4double m2)
G4double mass1, G4double mass2)
{
G4double energy = kineticEnergy/keV ; // energy in keV
G4double nloss = 0.0;
G4double rm;
if(z1 > 1.5) rm = (m1 + m2) * ( Z23[G4int(z1)] + Z23[G4int(z2)] ) ;
else rm = (m1 + m2) * nist->GetZ13(G4int(z2));
if(z1 > 1.5) rm = (mass1 + mass2) * ( Z23[G4int(z1)] + Z23[G4int(z2)] ) ;
else rm = (mass1 + mass2) * nist->GetZ13(G4int(z2));
G4double er = 32.536 * m2 * energy / ( z1 * z2 * rm ) ; // reduced energy
G4double er = 32.536 * mass2 * energy / ( z1 * z2 * rm ) ; // reduced energy
if (er >= ed[0]) nloss = a[0];
if (er >= ed[0]) { nloss = a[0]; }
else {
// the table is inverse in energy
for (G4int i=102; i>=0; i--)
@@ -712,14 +723,14 @@ G4double G4EmCorrections::NuclearStoppingPower(G4double kineticEnergy,
// Stragling
if(lossFlucFlag) {
// G4double sig = 4.0 * m1 * m2 / ((m1 + m2)*(m1 + m2)*
// (4.0 + 0.197*std::pow(er,-1.6991)+6.584*std::pow(er,-1.0494))) ;
G4double sig = 4.0 * m1 * m2 / ((m1 + m2)*(m1 + m2)*
// (4.0 + 0.197*std::pow(er,-1.6991)+6.584*std::pow(er,-1.0494))) ;
G4double sig = 4.0 * mass1 * mass2 / ((mass1 + mass2)*(mass1 + mass2)*
(4.0 + 0.197/(er*er) + 6.584/er));
nloss *= G4RandGauss::shoot(1.0,sig) ;
}
nloss *= 8.462 * z1 * z2 * m1 / rm ; // Return to [ev/(10^15 atoms/cm^2]
nloss *= 8.462 * z1 * z2 * mass1 / rm ; // Return to [ev/(10^15 atoms/cm^2]
if ( nloss < 0.0) nloss = 0.0 ;
@@ -884,9 +895,12 @@ void G4EmCorrections::InitialiseForNewRun()
ncouples = tb->GetTableSize();
if(currmat.size() != ncouples) {
currmat.resize(ncouples);
size_t i;
for(i=0; i<100; ++i) {thcorr[i].clear();}
for(i=0; i<ncouples; ++i) {
for(std::map< G4int, std::vector<G4double> >::iterator it =
thcorr.begin(); it != thcorr.end(); ++it){
(it->second).clear();
}
thcorr.clear();
for(size_t i=0; i<ncouples; ++i) {
currmat[i] = tb->GetMaterialCutsCouple(i)->GetMaterial();
G4String nam = currmat[i]->GetName();
for(G4int j=0; j<nIons; ++j) {
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmElementSelector.cc,v 1.12 2010-04-27 16:59:52 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmModelManager.cc,v 1.63 2010-10-15 10:22:13 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -77,6 +76,9 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmModelManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsVector.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -640,6 +642,7 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
}
G4double cross = mod->CrossSection(couple,particle,e,cut,tmax);
cross *= (1.0 + del/e);
if(fIsCrossSectionPrim == tType) { cross *= e; }
if(j==0 && startFromNull) { cross = 0.0; }
@@ -669,11 +672,30 @@ void G4EmModelManager::DumpModelList(G4int verb)
<< " ======" << G4endl;;
for(G4int j=0; j<n; ++j) {
G4VEmModel* model = models[r->ModelIndex(j)];
G4double emin =
std::max(r->LowEdgeEnergy(j),model->LowEnergyActivationLimit());
G4double emax =
std::min(r->LowEdgeEnergy(j+1),model->HighEnergyActivationLimit());
G4cout << std::setw(20);
G4cout << model->GetName() << " : Emin= "
<< std::setw(8) << G4BestUnit(r->LowEdgeEnergy(j),"Energy")
<< std::setw(8) << G4BestUnit(emin,"Energy")
<< " Emax= "
<< std::setw(8) << G4BestUnit(r->LowEdgeEnergy(j+1),"Energy");
<< std::setw(8) << G4BestUnit(emax,"Energy");
G4PhysicsTable* table = model->GetCrossSectionTable();
if(table) {
size_t kk = table->size();
for(size_t k=0; k<kk; ++k) {
G4PhysicsVector* v = (*table)[k];
if(v) {
G4int nn = v->GetVectorLength() - 1;
G4cout << " Table with " << nn << " bins Emin= "
<< std::setw(6) << G4BestUnit(v->Energy(0),"Energy")
<< " Emax= "
<< std::setw(6) << G4BestUnit(v->Energy(nn),"Energy");
break;
}
}
}
G4VEmAngularDistribution* an = model->GetAngularDistribution();
if(an) { G4cout << " " << an->GetName(); }
if(fluoFlag && model->DeexcitationFlag()) { G4cout << " FluoActive"; }
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmMultiModel.cc,v 1.8 2010-08-17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmProcessOptions.cc,v 1.30 2010-11-23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -44,6 +43,7 @@
// 10-05-06 Add command MscStepLimit to G4LossTableManager (V.Ivantchenko)
// 22-05-06 Add SetBremsstrahlungTh (V.Ivanchenko)
// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
// 30-05-12 Add biasing for G4VEmProcess (D. Sawkey)
//
// Class Description:
//
@@ -53,6 +53,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmProcessOptions.hh"
#include "G4SystemOfUnits.hh"
#include "G4LossTableManager.hh"
#include "G4VEmProcess.hh"
#include "G4VEnergyLossProcess.hh"
@@ -219,9 +220,9 @@ void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
G4VMultipleScattering* msc = *itm;
if(s) {
if (s->GetProcessName() == name) { s->SetVerboseLevel(val); }
if (msc->GetProcessName() == name) { msc->SetVerboseLevel(val); }
}
}
}
@@ -482,7 +483,7 @@ G4EmProcessOptions::ActivateSecondaryBiasing(const G4String& name,
G4double factor,
G4double energyLimit)
{
if(0.0 >= factor) { return; }
if(0.0 > factor) { return; }
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
@@ -498,3 +499,25 @@ G4EmProcessOptions::ActivateSecondaryBiasing(const G4String& name,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4EmProcessOptions::ActivateSecondaryBiasingForGamma(const G4String& name,
const G4String& region,
G4double factor,
G4double energyLimit)
{
if(0.0 > factor) { return; }
const std::vector<G4VEmProcess*>& v =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); ++itr) {
G4VEmProcess* p = *itr;
if(p) {
if (p->GetProcessName() == name) {
p->ActivateSecondaryBiasing(region, factor, energyLimit);
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmSaturation.cc,v 1.11 2010-10-25 17:23:01 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -45,6 +44,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmSaturation.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4LossTableManager.hh"
#include "G4NistManager.hh"
#include "G4Material.hh"
@@ -119,8 +120,8 @@ G4double G4EmSaturation::VisibleEnergyDeposition(
if(nloss > 0.0) {
if(!proton) { proton = G4Proton::Proton(); }
G4double escaled = nloss*curRatio;
G4double s = manager->GetRange(proton,escaled,couple)/curChargeSq;
nloss /= (1.0 + bfactor*nloss/s);
G4double range = manager->GetRange(proton,escaled,couple)/curChargeSq;
nloss /= (1.0 + bfactor*nloss/range);
}
evis = eloss + nloss;
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EnergyLossMessenger.cc,v 1.41 2011-01-03 19:34:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -312,7 +311,7 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
G4UIparameter* flagFact = new G4UIparameter("flagFact",'s',false);
bfCmd->SetParameter(flagFact);
bfCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
bfCmd->AvailableForStates(G4State_Idle);
fiCmd = new G4UIcommand("/process/em/setForcedInteraction",this);
fiCmd->SetGuidance("Set factor for the process cross section.");
@@ -336,7 +335,7 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
G4UIparameter* flagT = new G4UIparameter("tflag",'s',true);
fiCmd->SetParameter(flagT);
fiCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fiCmd->AvailableForStates(G4State_Idle);
brCmd = new G4UIcommand("/process/em/setSecBiasing",this);
brCmd->SetGuidance("Set bremsstrahlung or delta-electron splitting/Russian roullette per region.");
@@ -359,9 +358,9 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
G4UIparameter* bUnit = new G4UIparameter("bUnit",'s',true);
brCmd->SetParameter(bUnit);
brCmd->SetGuidance("unit of tlength");
brCmd->SetGuidance("unit of energy");
brCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
brCmd->AvailableForStates(G4State_Idle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -526,12 +525,13 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == bfCmd) {
G4double v1(1.0);
G4String s(""),s1("");
G4String s0(""),s1("");
std::istringstream is(newValue);
is >> s >> v1 >> s1;
is >> s0 >> v1 >> s1;
G4bool yes = false;
if(s1 == "true") { yes = true; }
opt->SetProcessBiasingFactor(s,v1,yes);
opt->SetProcessBiasingFactor(s0,v1,yes);
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == fiCmd) {
G4double v1(0.0);
G4String s1(""),s2(""),s3(""),unt("mm");
@@ -541,13 +541,17 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
if(s3 == "true") { yes = true; }
v1 *= G4UIcommand::ValueOf(unt);
opt->ActivateForcedInteraction(s1,v1,s2,yes);
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == brCmd) {
G4double fb(1.0),en(1.e+30);
G4String s1(""),s2(""),unt("MeV");
std::istringstream is(newValue);
is >> s1 >> s2 >> fb >> en >> unt;
en *= G4UIcommand::ValueOf(unt);
opt->ActivateSecondaryBiasing(s1,s2,fb,en);
if (s1=="phot"||s1=="compt"||s1=="conv")
opt->ActivateSecondaryBiasingForGamma(s1,s2,fb,en);
else opt->ActivateSecondaryBiasing(s1,s2,fb,en);
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
}
}
@@ -24,8 +24,7 @@
// ********************************************************************
//
//
// $Id: G4EnergyLossTables.cc,v 1.36 2010-12-23 17:04:54 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
// first version created by P.Urban , 06/04/1998
@@ -43,6 +42,7 @@
// -------------------------------------------------------------------
#include "G4EnergyLossTables.hh"
#include "G4SystemOfUnits.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4RegionStore.hh"
#include "G4LossTableManager.hh"
@@ -1029,11 +1029,12 @@ void G4EnergyLossTables::CPRWarning()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle,
const G4String& q)
void
G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition*,
const G4String& /*q*/)
{
G4String s = " " + q + " table not found for "
+ aParticle->GetParticleName() + " !";
//G4String s = " " + q + " table not found for "
// + aParticle->GetParticleName() + " !";
//G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01",
// FatalException, s);
}
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LossTableBuilder.cc,v 1.32 2009-08-11 17:24:53 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -56,6 +55,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4LossTableBuilder.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsTableHelper.hh"
@@ -63,6 +63,9 @@
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Material.hh"
#include "G4VEmModel.hh"
#include "G4ParticleDefinition.hh"
#include "G4LossTableManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -162,6 +165,8 @@ void G4LossTableBuilder::BuildRangeTable(const G4PhysicsTable* dedxTable,
// initialisation of a new vector
if(npoints < 2) { npoints = 2; }
delete (*rangeTable)[i];
G4PhysicsLogVector* v;
if(0 == bin0) { v = new G4PhysicsLogVector(*pv); }
else { v = new G4PhysicsLogVector(elow, ehigh, npoints-1); }
@@ -223,6 +228,7 @@ void G4LossTableBuilder::BuildInverseRangeTable(const G4PhysicsTable* rangeTable
G4double rlow = (*pv)[0];
G4double rhigh = (*pv)[npoints-1];
delete (*invRangeTable)[i];
G4LPhysicsFreeVector* v = new G4LPhysicsFreeVector(npoints,rlow,rhigh);
v->SetSpline(splineFlag);
@@ -246,10 +252,11 @@ G4LossTableBuilder::InitialiseBaseMaterials(G4PhysicsTable* table)
size_t nFlags = theFlag->size();
if(nCouples == nFlags && isInitialized) { return; }
isInitialized = true;
//G4cout << "%%%%%% Ncouples= " << nCouples << " FlagSize= " << nFlags
// << " IsInitialise= " << isInitialized << G4endl;
//G4cout << "%%%%%% G4LossTableBuilder::InitialiseBaseMaterials Ncouples= "
// << nCouples << " FlagSize= " << nFlags << G4endl;
// variable density check
const G4ProductionCutsTable* theCoupleTable=
@@ -312,10 +319,12 @@ G4LossTableBuilder::InitialiseBaseMaterials(G4PhysicsTable* table)
/*
for(size_t i=0; i<nCouples; ++i) {
G4cout << "CoupleIdx= " << i << " Flag= " << (*theFlag)[i]
<< " tableFlag= " << table->GetFlag(i) << " "
<< " TableFlag= " << table->GetFlag(i) << " "
<< theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial()->GetName()
<< G4endl;
}
G4cout << "%%%%%% G4LossTableBuilder::InitialiseBaseMaterials end"
<< G4endl;
*/
}
@@ -323,13 +332,14 @@ G4LossTableBuilder::InitialiseBaseMaterials(G4PhysicsTable* table)
void G4LossTableBuilder::InitialiseCouples()
{
//G4cout << "%%%%%% InitialiseCouples= " << G4endl;
isInitialized = true;
// variable density initialisation for the cas without tables
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t nCouples = theCoupleTable->GetTableSize();
//G4cout << "%%%%%% G4LossTableBuilder::InitialiseCouples() nCouples= "
// << nCouples << G4endl;
theDensityFactor->resize(nCouples, 1.0);
theDensityIdx->resize(nCouples, -1);
@@ -373,6 +383,100 @@ void G4LossTableBuilder::InitialiseCouples()
}
}
}
/*
for(size_t i=0; i<nCouples; ++i) {
G4cout << "CoupleIdx= " << i << " Flag= " << (*theFlag)[i] << " "
<< theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial()->GetName()
<< " DensityFactor= " << (*theDensityFactor)[i]
<< G4endl;
}
G4cout << "%%%%%% G4LossTableBuilder::InitialiseCouples() end" << G4endl;
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PhysicsTable*
G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
G4VEmModel* model,
const G4ParticleDefinition* part,
G4double emin, G4double emax,
G4bool spline)
{
// check input
G4PhysicsTable* table = G4PhysicsTableHelper::PreparePhysicsTable(aTable);
if(!table) { return table; }
if(emin >= emax) {
table->clearAndDestroy();
delete table;
table = 0;
return table;
}
InitialiseBaseMaterials(table);
G4int nbins = G4int(std::log10(emax/emin) + 0.5)
*G4LossTableManager::Instance()->GetNumberOfBinsPerDecade();
if(nbins < 3) { nbins = 3; }
// Access to materials
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
G4PhysicsLogVector* aVector = 0;
G4PhysicsLogVector* bVector = 0;
for(size_t i=0; i<numOfCouples; ++i) {
//G4cout<< "i= " << i << " Flag= " << GetFlag(i) << G4endl;
if (GetFlag(i)) {
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
delete (*table)[i];
// if start from zero then change the scale
const G4Material* mat = couple->GetMaterial();
G4double tmin = std::max(emin,model->MinPrimaryEnergy(mat,part));
if(0.0 >= tmin) { tmin = eV; }
G4int n = nbins + 1;
if(tmin >= emax) {
aVector = 0;
} else if(tmin > emin) {
G4int bin = nbins*G4int(std::log10(emax/tmin) + 0.5);
if(bin < 3) { bin = 3; }
n = bin + 1;
aVector = new G4PhysicsLogVector(tmin, emax, bin);
} else if(!bVector) {
aVector = new G4PhysicsLogVector(emin, emax, nbins);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
}
if(aVector) {
aVector->SetSpline(spline);
for(G4int j=0; j<n; ++j) {
aVector->PutValue(j, model->Value(couple, part, aVector->Energy(j)));
}
if(spline) { aVector->FillSecondDerivatives(); }
}
G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
}
}
/*
G4cout << "G4LossTableBuilder::BuildTableForModel done for "
<< part->GetParticleName() << " and "<< model->GetName()
<< " " << table << G4endl;
*/
return table;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LossTableManager.cc,v 1.105 2010-11-04 12:55:09 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -80,6 +79,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4LossTableManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4EnergyLossMessenger.hh"
#include "G4PhysicsTable.hh"
#include "G4ParticleDefinition.hh"
@@ -217,6 +217,14 @@ void G4LossTableManager::Clear()
void G4LossTableManager::Register(G4VEnergyLossProcess* p)
{
if(!p) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
<< p->GetProcessName() << " idx= " << n_loss << G4endl;
}
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(0);
@@ -234,15 +242,13 @@ void G4LossTableManager::Register(G4VEnergyLossProcess* p)
if(integralActive) { p->SetIntegral(integral); }
if(minEnergyActive) { p->SetMinKinEnergy(minKinEnergy); }
if(maxEnergyActive) { p->SetMaxKinEnergy(maxKinEnergy); }
if(verbose > 1)
G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
<< p->GetProcessName() << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
{
if(!p) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { loss_vector[i] = 0; }
}
@@ -252,17 +258,23 @@ void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
void G4LossTableManager::Register(G4VMultipleScattering* p)
{
msc_vector.push_back(p);
if(!p) { return; }
G4int n = msc_vector.size();
for (G4int i=0; i<n; ++i) {
if(msc_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
<< p->GetProcessName() << G4endl;
<< p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
}
msc_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
{
if(!p) { return; }
size_t msc = msc_vector.size();
for (size_t i=0; i<msc; ++i) {
if(msc_vector[i] == p) { msc_vector[i] = 0; }
@@ -273,17 +285,23 @@ void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
void G4LossTableManager::Register(G4VEmProcess* p)
{
emp_vector.push_back(p);
if(!p) { return; }
G4int n = emp_vector.size();
for (G4int i=0; i<n; ++i) {
if(emp_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VEmProcess : "
<< p->GetProcessName() << G4endl;
<< p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
}
emp_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VEmProcess* p)
{
if(!p) { return; }
size_t emp = emp_vector.size();
for (size_t i=0; i<emp; ++i) {
if(emp_vector[i] == p) { emp_vector[i] = 0; }
@@ -345,7 +363,16 @@ void G4LossTableManager::RegisterIon(const G4ParticleDefinition* ion,
void G4LossTableManager::RegisterExtraParticle(
const G4ParticleDefinition* part,
G4VEnergyLossProcess* p)
{
{
if(!p || !part) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::RegisterExtraParticle "
<< part->GetParticleName() << " G4VEnergyLossProcess : "
<< p->GetProcessName() << " idx= " << n_loss << G4endl;
}
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(part);
@@ -366,7 +393,8 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << " run= " << run << G4endl;
<< " and " << p->GetProcessName() << " run= " << run
<< " loss_vector " << loss_vector.size() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
@@ -443,8 +471,7 @@ void G4LossTableManager::BuildPhysicsTable(
if(1 < verbose) {
G4cout << "### G4LossTableManager::BuildDEDXTable() is requested for "
<< aParticle->GetParticleName()
<< " and process " << p->GetProcessName()
<< G4endl;
<< " and process " << p->GetProcessName() << G4endl;
}
// clear configurator
if(0 == run && startInitialisation) {
@@ -801,10 +828,6 @@ void G4LossTableManager::SetMinEnergy(G4double val)
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetMinKinEnergy(val); }
}
size_t msc = msc_vector.size();
for (size_t j=0; j<msc; ++j) {
if(msc_vector[j]) { msc_vector[j]->SetMinKinEnergy(val); }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetMinKinEnergy(val); }
@@ -820,10 +843,6 @@ void G4LossTableManager::SetMaxEnergy(G4double val)
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergy(val); }
}
size_t msc = msc_vector.size();
for (size_t j=0; j<msc; ++j) {
if(msc_vector[j]) { msc_vector[j]->SetMaxKinEnergy(val); }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetMaxKinEnergy(val); }
@@ -869,7 +888,7 @@ void G4LossTableManager::SetDEDXBinningForCSDARange(G4int val)
void G4LossTableManager::SetLambdaBinning(G4int val)
{
G4int n = val/G4int(std::log10(maxKinEnergy/minKinEnergy));
G4int n = val/G4int(std::log10(maxKinEnergy/minKinEnergy) + 0.5);
if(n < 5) {
G4cout << "G4LossTableManager::SetLambdaBinning WARNING "
<< "too small number of bins " << val << " ignored"
@@ -878,10 +897,6 @@ void G4LossTableManager::SetLambdaBinning(G4int val)
}
nbinsLambda = val;
nbinsPerDecade = n;
size_t msc = msc_vector.size();
for (size_t j=0; j<msc; ++j) {
if(msc_vector[j]) { msc_vector[j]->SetBinning(val); }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetLambdaBinning(val); }
@@ -1046,6 +1061,20 @@ G4double G4LossTableManager::FactorForAngleLimit() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossTableManager::MinKinEnergy() const
{
return minKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossTableManager::MaxKinEnergy() const
{
return maxKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmCorrections* G4LossTableManager::EmCorrections()
{
return emCorrections;
@@ -1093,4 +1122,116 @@ void G4LossTableManager::SetAtomDeexcitation(G4VAtomDeexcitation* p)
atomDeexcitation = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4VEnergyLossProcess*
G4LossTableManager::GetEnergyLossProcess(const G4ParticleDefinition *aParticle)
{
if(aParticle != currentParticle) {
currentParticle = aParticle;
std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
currentLoss = (*pos).second;
} else {
currentLoss = 0;
//ParticleHaveNoLoss(aParticle);
}
}
return currentLoss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossTableManager::GetDEDX(const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { x = currentLoss->GetDEDX(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetDEDX(currentParticle,
kineticEnergy,couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4LossTableManager::GetSubDEDX(const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { x = currentLoss->GetDEDXForSubsec(kineticEnergy, couple); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4LossTableManager::GetCSDARange(const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = DBL_MAX;
if(currentLoss) { x = currentLoss->GetCSDARange(kineticEnergy, couple); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double
G4LossTableManager::GetRangeFromRestricteDEDX(const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
if(currentLoss) { x = currentLoss->GetRangeForLoss(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetRange(currentParticle,kineticEnergy,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4LossTableManager::GetRange(const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
if(currentLoss) { x = currentLoss->GetRange(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetRange(currentParticle,kineticEnergy,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossTableManager::GetEnergy(const G4ParticleDefinition *aParticle,
G4double range,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
if(currentLoss) { x = currentLoss->GetKineticEnergy(range, couple); }
else { x = G4EnergyLossTables::GetPreciseEnergyFromRange(currentParticle,range,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossTableManager::GetDEDXDispersion(const G4MaterialCutsCouple *couple,
const G4DynamicParticle* dp,
G4double& length)
{
const G4ParticleDefinition* aParticle = dp->GetParticleDefinition();
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { currentLoss->GetDEDXDispersion(couple, dp, length); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VAtomDeexcitation.cc,v 1.8 2011-01-03 19:34:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -47,6 +46,7 @@
//
#include "G4VAtomDeexcitation.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleDefinition.hh"
#include "G4DynamicParticle.hh"
#include "G4Step.hh"
@@ -65,11 +65,10 @@
G4VAtomDeexcitation::G4VAtomDeexcitation(const G4String& modname,
const G4String& pname)
: lowestKinEnergy(keV), verbose(1), name(modname), namePIXE(pname),
nameElectronPIXE(""),isActive(false), flagAuger(false), flagPIXE(false)
nameElectronPIXE(""), isActive(false), flagAuger(false), flagPIXE(false)
{
vdyn.reserve(5);
theCoupleTable = 0;
SetDeexcitationActiveRegion("World");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -84,6 +83,10 @@ void G4VAtomDeexcitation::InitialiseAtomicDeexcitation()
// Define list of couples
theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
// needed for unit tests
if(0 == numOfCouples) { numOfCouples = 1; }
activeDeexcitationMedia.resize(numOfCouples, false);
activeAugerMedia.resize(numOfCouples, false);
activePIXEMedia.resize(numOfCouples, false);
@@ -93,15 +96,19 @@ void G4VAtomDeexcitation::InitialiseAtomicDeexcitation()
if( !isActive ) { return; }
// Define list of regions
size_t nRegions = activeRegions.size();
size_t nRegions = deRegions.size();
// There is no active regions
if(0 == nRegions) { return; }
if(0 == nRegions) {
SetDeexcitationActiveRegion("World",isActive,flagAuger,flagPIXE);
nRegions = 1;
}
if(0 < verbose) {
G4cout << G4endl;
G4cout << "### === Deexcitation model " << name
<< " is activated for regions:" << G4endl;
<< " is activated for " << nRegions;
if(1 == nRegions) { G4cout << " region:" << G4endl; }
else { G4cout << " regions:" << G4endl;}
}
// Identify active media
@@ -114,22 +121,22 @@ void G4VAtomDeexcitation::InitialiseAtomicDeexcitation()
}
for(size_t i=0; i<numOfCouples; ++i) {
if( !activeDeexcitationMedia[i] ) {
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
if (couple->GetProductionCuts() == rpcuts) {
activeDeexcitationMedia[i] = deRegions[j];
activeAugerMedia[i] = AugerRegions[j];
activePIXEMedia[i] = PIXERegions[j];
const G4Material* mat = couple->GetMaterial();
const G4ElementVector* theElementVector =
mat->GetElementVector();
G4int nelm = mat->GetNumberOfElements();
if(deRegions[j]) {
for(G4int k=0; k<nelm; ++k) {
G4int Z = (G4int)((*theElementVector)[k])->GetZ();
if(Z > 5 && Z < 93) { activeZ[Z] = true; }
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
if (couple->GetProductionCuts() == rpcuts) {
activeDeexcitationMedia[i] = deRegions[j];
activeAugerMedia[i] = AugerRegions[j];
activePIXEMedia[i] = PIXERegions[j];
const G4Material* mat = couple->GetMaterial();
const G4ElementVector* theElementVector =
mat->GetElementVector();
G4int nelm = mat->GetNumberOfElements();
if(deRegions[j]) {
for(G4int k=0; k<nelm; ++k) {
G4int Z = G4lrint(((*theElementVector)[k])->GetZ());
if(Z > 5 && Z < 93) {
activeZ[Z] = true;
//G4cout << "!!! Active de-excitation Z= " << Z << G4endl;
}
}
}
@@ -158,18 +165,19 @@ G4VAtomDeexcitation::SetDeexcitationActiveRegion(const G4String& rname,
G4bool valAuger,
G4bool valPIXE)
{
G4String s = rname;
//G4cout << "### G4VAtomDeexcitation::SetDeexcitationActiveRegion " << s
// << G4endl;
if(s == "world" || s == "World" || s == "WORLD") {
s = "DefaultRegionForTheWorld";
G4String ss = rname;
//G4cout << "### G4VAtomDeexcitation::SetDeexcitationActiveRegion " << ss
// << " " << valDeexcitation << " " << valAuger
// << " " << valPIXE << G4endl;
if(ss == "world" || ss == "World" || ss == "WORLD") {
ss = "DefaultRegionForTheWorld";
}
size_t n = activeRegions.size();
size_t n = deRegions.size();
if(n > 0) {
for(size_t i=0; i<n; ++i) {
// Region already exist
if(s == activeRegions[i]) {
if(ss == activeRegions[i]) {
deRegions[i] = valDeexcitation;
AugerRegions[i] = valAuger;
PIXERegions[i] = valPIXE;
@@ -178,7 +186,7 @@ G4VAtomDeexcitation::SetDeexcitationActiveRegion(const G4String& rname,
}
}
// New region
activeRegions.push_back(s);
activeRegions.push_back(ss);
deRegions.push_back(valDeexcitation);
AugerRegions.push_back(valAuger);
PIXERegions.push_back(valPIXE);
@@ -186,14 +194,15 @@ G4VAtomDeexcitation::SetDeexcitationActiveRegion(const G4String& rname,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
void
G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
const G4Step& step,
G4double& eLoss,
G4double& eLossMax,
G4int coupleIndex)
{
if(!flagPIXE || !isActive || !activeDeexcitationMedia[coupleIndex] ||
!activePIXEMedia[coupleIndex] || eLoss == 0.0) { return; }
G4double truelength = step.GetStepLength();
if(!flagPIXE && !activePIXEMedia[coupleIndex]) { return; }
if(eLossMax <= 0.0 || truelength <= 0.0) { return; }
// step parameters
const G4StepPoint* preStep = step.GetPreStepPoint();
@@ -201,18 +210,16 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
G4ThreeVector delta = step.GetPostStepPoint()->GetPosition() - prePos;
G4double preTime = preStep->GetGlobalTime();
G4double dt = step.GetPostStepPoint()->GetGlobalTime() - preTime;
G4double truelength = step.GetStepLength();
// particle parameters
const G4Track* track = step.GetTrack();
const G4ParticleDefinition* part = track->GetDefinition();
G4double ekin = preStep->GetKineticEnergy() - 0.5*eLoss;
if(ekin <= lowestKinEnergy) { return; }
G4double ekin = preStep->GetKineticEnergy();
// media parameters
G4double gCut = (*theCoupleTable->GetEnergyCutsVector(0))[coupleIndex];
G4double eCut = DBL_MAX;
if(flagAuger && activeAugerMedia[coupleIndex]) {
if(CheckAugerActiveRegion(coupleIndex)) {
eCut = (*theCoupleTable->GetEnergyCutsVector(1))[coupleIndex];
}
@@ -226,17 +233,19 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
// loop over deexcitations
for(G4int i=0; i<nelm; ++i) {
G4int Z = G4int((*theElementVector)[i]->GetZ());
if(Z >= 93) { continue; }
if(!activeZ[Z]) { continue; }
G4int nshells = std::min(9,(*theElementVector)[i]->GetNbOfAtomicShells());
G4double rho = truelength*theAtomNumDensityVector[i];
//G4cout << " Z " << Z <<" is active x(mm)= " << truelength/mm << G4endl;
if(rho > 0.0) {
G4int Z = G4lrint((*theElementVector)[i]->GetZ());
if(activeZ[Z] && Z < 93) {
G4int nshells = std::min(9,(*theElementVector)[i]->GetNbOfAtomicShells());
G4double rho = truelength*theAtomNumDensityVector[i];
//G4cout << " Z " << Z <<" is active x(mm)= " << truelength/mm << G4endl;
for(G4int ii=0; ii<nshells; ++ii) {
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(ii);
const G4AtomicShell* shell = GetAtomicShell(Z, as);
if(gCut < shell->BindingEnergy()) {
G4double bindingEnergy = shell->BindingEnergy();
if(gCut > bindingEnergy) { break; }
if(eLossMax > bindingEnergy) {
G4double sig = rho*
GetShellIonisationCrossSectionPerAtom(part, Z, as, ekin, material);
@@ -248,36 +257,35 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
// sample ionisation points
do {
stot -= mfp*std::log(G4UniformRand());
if( stot <= 1.0) {
if( stot > 1.0 || eLossMax < bindingEnergy) { break; }
// sample deexcitation
vdyn.clear();
GenerateParticles(&vdyn, shell, Z, gCut, eCut);
G4int nsec = vdyn.size();
if(nsec > 0) {
G4ThreeVector r = prePos + stot*delta;
G4double time = preTime + stot*dt;
for(G4int j=0; j<nsec; ++j) {
G4DynamicParticle* dp = vdyn[j];
G4double e = dp->GetKineticEnergy();
// sample deexcitation
vdyn.clear();
GenerateParticles(&vdyn, shell, Z, gCut, eCut);
G4int nsec = vdyn.size();
if(nsec > 0) {
G4ThreeVector r = prePos + stot*delta;
G4double time = preTime + stot*dt;
for(G4int j=0; j<nsec; ++j) {
G4DynamicParticle* dp = vdyn[j];
G4double e = dp->GetKineticEnergy();
// save new secondary if there is enough energy
if(e <= eLoss) {
G4Track* t = new G4Track(dp, time, r);
tracks.push_back(t);
eLoss -= e;
} else {
delete dp;
}
}
// save new secondary if there is enough energy
if(eLossMax >= e) {
eLossMax -= e;
G4Track* t = new G4Track(dp, time, r);
tracks.push_back(t);
} else {
delete dp;
}
}
}
} while ( stot < 1.0 && eLoss > 0.0);
} while (stot < 1.0);
}
}
}
}
}
return;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VBremAngularDistribution.cc,v 1.1 2010-10-14 16:34:04 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -59,7 +58,10 @@
G4VBremAngularDistribution::G4VBremAngularDistribution(const G4String& name)
: G4VEmAngularDistribution(name)
{}
{
G4cout << "### G4VBremAngularDistribution interface class is obsolete "
<< "and will be removed for the next release." << G4endl;
}
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmAngularDistribution.cc,v 1.1 2010-10-14 16:34:04 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -53,7 +52,9 @@
G4VEmAngularDistribution::G4VEmAngularDistribution(const G4String& name)
: fName(name)
{}
{
fLocalDirection.set(0.0,0.0,1.0);
}
G4VEmAngularDistribution::~G4VEmAngularDistribution()
{}
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmFluctuationModel.cc,v 1.4 2009-02-19 11:25:50 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmModel.cc,v 1.37 2010-10-14 16:27:35 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -61,11 +60,12 @@
G4VEmModel::G4VEmModel(const G4String& nam):
flucModel(0),anglModel(0), name(nam), lowLimit(0.1*CLHEP::keV),
highLimit(100.0*CLHEP::TeV),
eMinActive(0.0),eMaxActive(DBL_MAX),
polarAngleLimit(CLHEP::pi),secondaryThreshold(DBL_MAX),theLPMflag(false),
pParticleChange(0),fCurrentCouple(0),fCurrentElement(0),
nsec(5),flagDeexcitation(false)
highLimit(100.0*CLHEP::TeV),eMinActive(0.0),eMaxActive(DBL_MAX),
polarAngleLimit(CLHEP::pi),secondaryThreshold(DBL_MAX),
theLPMflag(false),flagDeexcitation(false),flagForceBuildTable(false),
pParticleChange(0),xSectionTable(0),theDensityFactor(0),theDensityIdx(0),
fCurrentCouple(0),fCurrentElement(0),
nsec(5)
{
xsec.resize(nsec);
nSelectors = 0;
@@ -84,6 +84,10 @@ G4VEmModel::~G4VEmModel()
}
}
delete anglModel;
if(xSectionTable) {
xSectionTable->clearAndDestroy();
delete xSectionTable;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -204,6 +208,11 @@ G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::StartTracking(G4Track*)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4Element* G4VEmModel::SelectRandomAtom(const G4Material* material,
const G4ParticleDefinition* pd,
G4double kinEnergy,
@@ -274,6 +283,23 @@ void G4VEmModel::CorrectionsAlongStep(const G4MaterialCutsCouple*,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::Value(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p, G4double e)
{
fCurrentCouple = couple;
return e*e*CrossSectionPerVolume(couple->GetMaterial(),p,e,0.0,DBL_MAX);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
G4double kineticEnergy)
{
@@ -296,3 +322,16 @@ G4VEmModel::SetParticleChange(G4VParticleChange* p, G4VEmFluctuationModel* f)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::SetCrossSectionTable(G4PhysicsTable* p)
{
if(p != xSectionTable) {
if(xSectionTable) {
xSectionTable->clearAndDestroy();
delete xSectionTable;
}
xSectionTable = p;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmProcess.cc,v 1.88 2010-08-17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -53,6 +52,7 @@
// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
// 24-06-09 Removed hidden bin in G4PhysicsVector (V.Ivanchenko)
// 17-02-10 Added pointer currentParticle (VI)
// 30-05-12 allow Russian roulette, brem splitting (D. Sawkey)
//
// Class Description:
//
@@ -63,6 +63,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4VEmProcess.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ProcessManager.hh"
#include "G4LossTableManager.hh"
#include "G4LossTableBuilder.hh"
@@ -80,6 +82,7 @@
#include "G4Positron.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4EmBiasingManager.hh"
#include "G4GenericIon.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -87,12 +90,15 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
G4VDiscreteProcess(name, type),
secondaryParticle(0),
buildLambdaTable(true),
numberOfModels(0),
theLambdaTable(0),
theLambdaTablePrim(0),
theDensityFactor(0),
theDensityIdx(0),
integral(false),
applyCuts(false),
startFromNull(false),
splineFlag(true),
currentModel(0),
particle(0),
currentParticle(0),
@@ -104,6 +110,7 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
minKinEnergy = 0.1*keV;
maxKinEnergy = 10.0*TeV;
nLambdaBins = 77;
minKinEnergyPrim = DBL_MAX;
// default lambda factor
lambdaFactor = 0.8;
@@ -128,6 +135,7 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
biasFlag = false;
weightFlag = false;
(G4LossTableManager::Instance())->Register(this);
warn = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -136,13 +144,17 @@ G4VEmProcess::~G4VEmProcess()
{
if(1 < verboseLevel) {
G4cout << "G4VEmProcess destruct " << GetProcessName()
<< G4endl;
<< " " << this << " " << theLambdaTable <<G4endl;
}
Clear();
if(theLambdaTable) {
theLambdaTable->clearAndDestroy();
delete theLambdaTable;
}
if(theLambdaTablePrim) {
theLambdaTablePrim->clearAndDestroy();
delete theLambdaTablePrim;
}
delete modelManager;
delete biasManager;
(G4LossTableManager::Instance())->DeRegister(this);
@@ -179,6 +191,12 @@ void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* p,
void G4VEmProcess::SetModel(G4VEmModel* p, G4int index)
{
++warn;
if(warn < 10) {
G4cout << "### G4VEmProcess::SetModel is obsolete method and will be "
<< "removed for the next release." << G4endl;
G4cout << " Please, use SetEmModel" << G4endl;
}
G4int n = emModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) {emModels.push_back(0);} }
emModels[index] = p;
@@ -187,6 +205,29 @@ void G4VEmProcess::SetModel(G4VEmModel* p, G4int index)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel* G4VEmProcess::Model(G4int index)
{
if(warn < 10) {
G4cout << "### G4VEmProcess::Model is obsolete method and will be "
<< "removed for the next release." << G4endl;
G4cout << " Please, use EmModel" << G4endl;
}
G4VEmModel* p = 0;
if(index >= 0 && index < G4int(emModels.size())) { p = emModels[index]; }
return p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetEmModel(G4VEmModel* p, G4int index)
{
G4int n = emModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) {emModels.push_back(0);} }
emModels[index] = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel* G4VEmProcess::EmModel(G4int index)
{
G4VEmModel* p = 0;
if(index >= 0 && index < G4int(emModels.size())) { p = emModels[index]; }
@@ -213,6 +254,20 @@ G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver)
void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if(!particle) { SetParticle(&part); }
if(part.GetParticleType() == "nucleus" &&
part.GetParticleSubType() == "generic") {
G4String pname = part.GetParticleName();
if(pname != "deuteron" && pname != "triton" &&
pname != "alpha" && pname != "He3" &&
pname != "alpha+" && pname != "helium" &&
pname != "hydrogen") {
particle = G4GenericIon::GenericIon();
}
}
if(1 < verboseLevel) {
G4cout << "G4VEmProcess::PreparePhysicsTable() for "
<< GetProcessName()
@@ -238,9 +293,10 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
theCrossSectionMax.resize(n, DBL_MAX);
// initialisation of models
G4int nmod = modelManager->NumberOfModels();
for(G4int i=0; i<nmod; ++i) {
numberOfModels = modelManager->NumberOfModels();
for(G4int i=0; i<numberOfModels; ++i) {
G4VEmModel* mod = modelManager->GetModel(i);
if(0 == i) { currentModel = mod; }
mod->SetPolarAngleLimit(polarAngleLimit);
if(mod->HighEnergyLimit() > maxKinEnergy) {
mod->SetHighEnergyLimit(maxKinEnergy);
@@ -259,6 +315,12 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
bld->InitialiseBaseMaterials(theLambdaTable);
}
// high energy table
if(minKinEnergyPrim < maxKinEnergy){
theLambdaTablePrim =
G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTablePrim);
bld->InitialiseBaseMaterials(theLambdaTablePrim);
}
// forced biasing
if(biasManager) {
biasManager->Initialise(part,GetProcessName(),verboseLevel);
@@ -273,35 +335,39 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
{
G4String partname = part.GetParticleName();
G4String num = part.GetParticleName();
if(1 < verboseLevel) {
G4cout << "G4VEmProcess::BuildPhysicsTable() for "
<< GetProcessName()
<< " and particle " << partname
<< " and particle " << num
<< " buildLambdaTable= " << buildLambdaTable
<< G4endl;
}
(G4LossTableManager::Instance())->BuildPhysicsTable(particle);
if(buildLambdaTable) {
if(buildLambdaTable || minKinEnergyPrim < maxKinEnergy) {
BuildLambdaTable();
FindLambdaMax();
}
// reduce printout for nuclear stopping
G4bool gproc = true;
G4int st = GetProcessSubType();
if((st == fCoulombScattering || st == fNuclearStopping) &&
part.GetParticleType() == "nucleus" &&
partname != "GenericIon" && partname != "alpha") { gproc = false; }
if(gproc && 0 < verboseLevel) { PrintInfoDefinition(); }
// explicitly defined printout by particle name
if(1 < verboseLevel ||
(0 < verboseLevel && (num == "gamma" || num == "e-" ||
num == "e+" || num == "mu+" ||
num == "mu-" || num == "proton"||
num == "pi+" || num == "pi-" ||
num == "kaon+" || num == "kaon-" ||
num == "alpha" || num == "anti_proton" ||
num == "GenericIon")))
{
particle = &part;
PrintInfoDefinition();
}
if(1 < verboseLevel) {
G4cout << "G4VEmProcess::BuildPhysicsTable() done for "
<< GetProcessName()
<< " and particle " << partname
<< " and particle " << num
<< G4endl;
}
}
@@ -313,7 +379,7 @@ void G4VEmProcess::BuildLambdaTable()
if(1 < verboseLevel) {
G4cout << "G4EmProcess::BuildLambdaTable() for process "
<< GetProcessName() << " and particle "
<< particle->GetParticleName()
<< particle->GetParticleName() << " " << this
<< G4endl;
}
@@ -323,47 +389,86 @@ void G4VEmProcess::BuildLambdaTable()
size_t numOfCouples = theCoupleTable->GetTableSize();
G4LossTableBuilder* bld = (G4LossTableManager::Instance())->GetTableBuilder();
G4bool splineFlag = (G4LossTableManager::Instance())->SplineFlag();
G4PhysicsLogVector* aVector = 0;
G4PhysicsLogVector* bVector = 0;
G4PhysicsLogVector* aVectorPrim = 0;
G4PhysicsLogVector* bVectorPrim = 0;
G4double scale = 0.0;
if(startFromNull) { scale = std::log(maxKinEnergy/minKinEnergy); }
G4double scale = 1.0;
G4double emax1 = maxKinEnergy;
if(startFromNull || minKinEnergyPrim < maxKinEnergy ) {
scale = std::log(maxKinEnergy/minKinEnergy);
if(minKinEnergyPrim < maxKinEnergy) { emax1 = minKinEnergyPrim; }
}
for(size_t i=0; i<numOfCouples; ++i) {
if (/*theLambdaTable->GetFlag(i)*/bld->GetFlag(i)) {
if (bld->GetFlag(i)) {
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
// if start from zero then change the scale
if(startFromNull) {
G4double emin = MinPrimaryEnergy(particle,couple->GetMaterial());
if(0.0 >= emin) { emin = eV; }
else if(maxKinEnergy <= emin) { emin = 0.5*maxKinEnergy; }
G4int bin =
G4int(nLambdaBins*std::log(maxKinEnergy/emin)/scale + 0.5);
if(bin < 3) { bin = 3; }
aVector = new G4PhysicsLogVector(emin, maxKinEnergy, bin);
// build main table
if(buildLambdaTable) {
delete (*theLambdaTable)[i];
G4bool startNull = startFromNull;
// if start from zero then change the scale
if(startFromNull || minKinEnergyPrim < maxKinEnergy) {
G4double emin = MinPrimaryEnergy(particle,couple->GetMaterial());
if(emin < minKinEnergy) {
emin = minKinEnergy;
startNull = false;
}
G4double emax = emax1;
if(emax <= emin) { emax = 2*emin; }
G4int bin =
G4lrint(nLambdaBins*std::log(emax/emin)/scale);
if(bin < 3) { bin = 3; }
aVector = new G4PhysicsLogVector(emin, emax, bin);
// start not from zero
} else if(!bVector) {
aVector =
new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
}
aVector->SetSpline(splineFlag);
modelManager->FillLambdaVector(aVector, couple, startNull);
if(splineFlag) { aVector->FillSecondDerivatives(); }
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
}
// build high energy table
if(minKinEnergyPrim < maxKinEnergy) {
delete (*theLambdaTablePrim)[i];
// start not from zero
} else if(!bVector) {
aVector =
new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
if(!bVectorPrim) {
G4int bin =
G4lrint(nLambdaBins*std::log(maxKinEnergy/minKinEnergyPrim)/scale);
if(bin < 3) { bin = 3; }
aVectorPrim =
new G4PhysicsLogVector(minKinEnergyPrim, maxKinEnergy, bin);
bVectorPrim = aVectorPrim;
} else {
aVectorPrim = new G4PhysicsLogVector(*bVectorPrim);
}
// always use spline
aVectorPrim->SetSpline(true);
modelManager->FillLambdaVector(aVectorPrim, couple, false,
fIsCrossSectionPrim);
aVectorPrim->FillSecondDerivatives();
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTablePrim, i, aVectorPrim);
}
aVector->SetSpline(splineFlag);
modelManager->FillLambdaVector(aVector, couple, startFromNull);
if(splineFlag) { aVector->FillSecondDerivatives(); }
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
}
}
if(buildLambdaTable) { FindLambdaMax(); }
if(1 < verboseLevel) {
G4cout << "Lambda table is built for "
<< particle->GetParticleName()
@@ -384,13 +489,37 @@ void G4VEmProcess::PrintInfoDefinition()
if(biasFactor != 1.0) { G4cout << " BiasingFactor= " << biasFactor; }
G4cout << G4endl;
if(buildLambdaTable) {
G4cout << " Lambda tables from "
<< G4BestUnit(minKinEnergy,"Energy")
<< " to "
<< G4BestUnit(maxKinEnergy,"Energy")
<< " in " << nLambdaBins << " bins, spline: "
<< (G4LossTableManager::Instance())->SplineFlag()
<< G4endl;
size_t length = theLambdaTable->length();
for(size_t i=0; i<length; ++i) {
G4PhysicsVector* v = (*theLambdaTable)[i];
if(v) {
G4cout << " Lambda table from "
<< G4BestUnit(minKinEnergy,"Energy")
<< " to "
<< G4BestUnit(v->GetMaxEnergy(),"Energy")
<< " in " << v->GetVectorLength()-1
<< " bins, spline: "
<< splineFlag
<< G4endl;
break;
}
}
}
if(minKinEnergyPrim < maxKinEnergy) {
size_t length = theLambdaTablePrim->length();
for(size_t i=0; i<length; ++i) {
G4PhysicsVector* v = (*theLambdaTablePrim)[i];
if(v) {
G4cout << " LambdaPrime table from "
<< G4BestUnit(minKinEnergyPrim,"Energy")
<< " to "
<< G4BestUnit(maxKinEnergy,"Energy")
<< " in " << v->GetVectorLength()-1
<< " bins "
<< G4endl;
break;
}
}
}
PrintInfo();
modelManager->DumpModelList(verboseLevel);
@@ -404,25 +533,44 @@ void G4VEmProcess::PrintInfoDefinition()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::StartTracking(G4Track* track)
{
// reset parameters for the new track
currentParticle = track->GetParticleDefinition();
theNumberOfInteractionLengthLeft = -1.0;
//currentInteractionLength = -1.0;
// theInitialNumberOfInteractionLength=-1.0;
mfpKinEnergy = DBL_MAX;
// forced biasing only for primary particles
if(biasManager) {
if(0 == track->GetParentID()) {
// primary particle
biasFlag = true;
biasManager->ResetForcedInteraction();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
// condition is set to "Not Forced"
*condition = NotForced;
G4double x = DBL_MAX;
if(previousStepSize <= 0.0) { theNumberOfInteractionLengthLeft = -1.0; }
InitialiseStep(track);
preStepKinEnergy = track.GetKineticEnergy();
DefineMaterial(track.GetMaterialCutsCouple());
SelectModel(preStepKinEnergy, currentCoupleIndex);
if(!currentModel->IsActive(preStepKinEnergy)) { return x; }
// forced biasing only for primary particles
if(biasManager) {
if(0 == track.GetParentID()) {
if(0 == track.GetCurrentStepNumber()) {
biasFlag = true;
biasManager->ResetForcedInteraction();
}
if(biasFlag && biasManager->ForcedInteractionRegion(currentCoupleIndex)) {
return biasManager->GetStepLimit(currentCoupleIndex, previousStepSize);
}
@@ -433,22 +581,34 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
if(preStepKinEnergy < mfpKinEnergy) {
if (integral) { ComputeIntegralLambda(preStepKinEnergy); }
else { preStepLambda = GetCurrentLambda(preStepKinEnergy); }
if(preStepLambda <= 0.0) { mfpKinEnergy = 0.0; }
// zero cross section
if(preStepLambda <= 0.0) {
theNumberOfInteractionLengthLeft = -1.0;
currentInteractionLength = DBL_MAX;
}
}
// non-zero cross sect}ion
// non-zero cross section
if(preStepLambda > 0.0) {
if (theNumberOfInteractionLengthLeft < 0.0) {
// beggining of tracking (or just after DoIt of this process)
ResetNumberOfInteractionLengthLeft();
} else if(currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft
SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.)
theNumberOfInteractionLengthLeft = perMillion;
// subtract NumberOfInteractionLengthLeft using previous step
theNumberOfInteractionLengthLeft -= previousStepSize/currentInteractionLength;
//SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.) {
theNumberOfInteractionLengthLeft = 0.0;
//theNumberOfInteractionLengthLeft = perMillion;
}
}
// get mean free path and step limit
// new mean free path and step limit for the next step
currentInteractionLength = 1.0/preStepLambda;
x = theNumberOfInteractionLengthLeft * currentInteractionLength;
#ifdef G4VERBOSE
@@ -459,22 +619,10 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
<< " in Material " << currentMaterial->GetName()
<< " Ekin(MeV)= " << preStepKinEnergy/MeV
<<G4endl;
G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]"
<< "InteractionLength= " << x/cm <<"[cm] " <<G4endl;
G4cout << " MeanFreePath = " << currentInteractionLength/cm << "[cm]"
<< " InteractionLength= " << x/cm <<"[cm] " <<G4endl;
}
#endif
// zero cross section case
} else {
if(theNumberOfInteractionLengthLeft > DBL_MIN &&
currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft
SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.)
theNumberOfInteractionLengthLeft = perMillion;
}
currentInteractionLength = DBL_MAX;
}
return x;
}
@@ -482,8 +630,12 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
const G4Step&)
const G4Step& step)
{
// In all cases clear number of interaction lengths
theNumberOfInteractionLengthLeft = -1.0;
mfpKinEnergy = DBL_MAX;
fParticleChange.InitializeForPostStep(track);
// Do not make anything if particle is stopped, the annihilation then
@@ -503,7 +655,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
if (integral) {
G4double lx = GetLambda(finalT, currentCouple);
if(preStepLambda<lx && 1 < verboseLevel) {
G4cout << "WARING: for " << currentParticle->GetParticleName()
G4cout << "WARNING: for " << currentParticle->GetParticleName()
<< " and " << GetProcessName()
<< " E(MeV)= " << finalT/MeV
<< " preLambda= " << preStepLambda << " < "
@@ -521,10 +673,12 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
if(!currentModel->IsActive(finalT)) { return &fParticleChange; }
// define new weight for primary and secondaries
if(weightFlag) {
G4double weight = fParticleChange.GetParentWeight()/biasFactor;
fParticleChange.ProposeParentWeight(weight);
G4double weight = fParticleChange.GetParentWeight();
if(weightFlag) {
weight /= biasFactor;
fParticleChange.ProposeWeight(weight);
}
/*
if(0 < verboseLevel) {
G4cout << "G4VEmProcess::PostStepDoIt: Sample secondary; E= "
@@ -542,6 +696,23 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
track.GetDynamicParticle(),
(*theCuts)[currentCoupleIndex]);
// bremsstrahlung splitting or Russian roulette
if(biasManager) {
if(biasManager->SecondaryBiasingRegion(currentCoupleIndex)) {
G4double eloss = 0.0;
weight *= biasManager->ApplySecondaryBiasing(secParticles,
track, currentModel,
&fParticleChange,
eloss, currentCoupleIndex,
(*theCuts)[currentCoupleIndex],
step.GetPostStepPoint()->GetSafety());
if(eloss > 0.0) {
eloss += fParticleChange.GetLocalEnergyDeposit();
fParticleChange.ProposeLocalEnergyDeposit(eloss);
}
}
}
// save secondaries
G4int num = secParticles.size();
if(num > 0) {
@@ -550,31 +721,40 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
G4double edep = fParticleChange.GetLocalEnergyDeposit();
for (G4int i=0; i<num; ++i) {
G4DynamicParticle* dp = secParticles[i];
const G4ParticleDefinition* p = dp->GetParticleDefinition();
G4double e = dp->GetKineticEnergy();
G4bool good = true;
if(applyCuts) {
if (p == theGamma) {
if (e < (*theCutsGamma)[currentCoupleIndex]) good = false;
if (secParticles[i]) {
G4DynamicParticle* dp = secParticles[i];
const G4ParticleDefinition* p = dp->GetParticleDefinition();
G4double e = dp->GetKineticEnergy();
G4bool good = true;
if(applyCuts) {
if (p == theGamma) {
if (e < (*theCutsGamma)[currentCoupleIndex]) { good = false; }
} else if (p == theElectron) {
if (e < (*theCutsElectron)[currentCoupleIndex]) good = false;
} else if (p == theElectron) {
if (e < (*theCutsElectron)[currentCoupleIndex]) { good = false; }
} else if (p == thePositron) {
if (electron_mass_c2 < (*theCutsGamma)[currentCoupleIndex] &&
e < (*theCutsPositron)[currentCoupleIndex]) {
good = false;
e += 2.0*electron_mass_c2;
} else if (p == thePositron) {
if (electron_mass_c2 < (*theCutsGamma)[currentCoupleIndex] &&
e < (*theCutsPositron)[currentCoupleIndex]) {
good = false;
e += 2.0*electron_mass_c2;
}
}
}
if(!good) {
// added secondary if it is good
}
if (good) {
G4Track* t = new G4Track(dp, track.GetGlobalTime(), track.GetPosition());
t->SetTouchableHandle(track.GetTouchableHandle());
t->SetWeight(weight);
pParticleChange->AddSecondary(t);
//G4cout << "Secondary(post step) has weight " << t->GetWeight()
// << ", Ekin= " << t->GetKineticEnergy()/MeV << " MeV" <<G4endl;
} else {
delete dp;
edep += e;
}
}
if (good) { fParticleChange.AddSecondary(dp); }
}
}
}
fParticleChange.ProposeLocalEnergyDeposit(edep);
}
@@ -585,7 +765,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
else { fParticleChange.ProposeTrackStatus(fStopAndKill); }
}
ClearNumberOfInteractionLengthLeft();
// ClearNumberOfInteractionLengthLeft();
return &fParticleChange;
}
@@ -603,12 +783,30 @@ G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
yes = theLambdaTable->StorePhysicsTable(name,ascii);
if ( yes ) {
G4cout << "Physics tables are stored for " << particle->GetParticleName()
G4cout << "Physics table is stored for " << particle->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
} else {
G4cout << "Fail to store Physics Tables for "
G4cout << "Fail to store Physics Table for "
<< particle->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
}
}
if ( theLambdaTablePrim && part == particle) {
const G4String name =
GetPhysicsTableFileName(part,directory,"LambdaPrim",ascii);
yes = theLambdaTablePrim->StorePhysicsTable(name,ascii);
if ( yes ) {
G4cout << "Physics table prim is stored for " << particle->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
} else {
G4cout << "Fail to store Physics Table Prim for "
<< particle->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
@@ -631,34 +829,64 @@ G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
}
G4bool yes = true;
if(!buildLambdaTable || particle != part) return yes;
if((!buildLambdaTable && minKinEnergyPrim > maxKinEnergy)
|| particle != part) { return yes; }
const G4String particleName = part->GetParticleName();
G4String filename;
filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTable,
filename,ascii);
if ( yes ) {
if (0 < verboseLevel) {
G4cout << "Lambda table for " << particleName
<< " is Retrieved from <"
<< filename << ">"
<< G4endl;
}
if((G4LossTableManager::Instance())->SplineFlag()) {
size_t n = theLambdaTable->length();
for(size_t i=0; i<n; ++i) {
if((* theLambdaTable)[i]) {
(* theLambdaTable)[i]->SetSpline(true);
if(buildLambdaTable) {
filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTable,
filename,ascii);
if ( yes ) {
if (0 < verboseLevel) {
G4cout << "Lambda table for " << particleName
<< " is Retrieved from <"
<< filename << ">"
<< G4endl;
}
if((G4LossTableManager::Instance())->SplineFlag()) {
size_t n = theLambdaTable->length();
for(size_t i=0; i<n; ++i) {
if((* theLambdaTable)[i]) {
(* theLambdaTable)[i]->SetSpline(true);
}
}
}
} else {
if (1 < verboseLevel) {
G4cout << "Lambda table for " << particleName << " in file <"
<< filename << "> is not exist"
<< G4endl;
}
}
} else {
if (1 < verboseLevel) {
G4cout << "Lambda table for " << particleName << " in file <"
<< filename << "> is not exist"
<< G4endl;
}
if(minKinEnergyPrim < maxKinEnergy) {
filename = GetPhysicsTableFileName(part,directory,"LambdaPrim",ascii);
yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTablePrim,
filename,ascii);
if ( yes ) {
if (0 < verboseLevel) {
G4cout << "Lambda table prim for " << particleName
<< " is Retrieved from <"
<< filename << ">"
<< G4endl;
}
if((G4LossTableManager::Instance())->SplineFlag()) {
size_t n = theLambdaTablePrim->length();
for(size_t i=0; i<n; ++i) {
if((* theLambdaTablePrim)[i]) {
(* theLambdaTablePrim)[i]->SetSpline(true);
}
}
}
} else {
if (1 < verboseLevel) {
G4cout << "Lambda table prim for " << particleName << " in file <"
<< filename << "> is not exist"
<< G4endl;
}
}
}
@@ -734,7 +962,7 @@ void G4VEmProcess::FindLambdaMax()
}
size_t n = theLambdaTable->length();
G4PhysicsVector* pv;
G4double e, s, emax, smax;
G4double e, ss, emax, smax;
size_t i;
@@ -748,9 +976,9 @@ void G4VEmProcess::FindLambdaMax()
if(nb > 0) {
for (size_t j=0; j<nb; ++j) {
e = pv->Energy(j);
s = (*pv)(j);
if(s > smax) {
smax = s;
ss = (*pv)(j);
if(ss > smax) {
smax = ss;
emax = e;
}
}
@@ -765,7 +993,7 @@ void G4VEmProcess::FindLambdaMax()
}
}
// second loop using base materials
for (size_t i=0; i<n; ++i) {
for (i=0; i<n; ++i) {
pv = (*theLambdaTable)[i];
if(!pv){
G4int j = (*theDensityIdx)[i];
@@ -833,3 +1061,47 @@ G4VEmProcess::ActivateForcedInteraction(G4double length, const G4String& r,
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4VEmProcess::ActivateSecondaryBiasing(const G4String& region,
G4double factor,
G4double energyLimit)
{
if (0.0 <= factor) {
// Range cut can be applied only for e-
if(0.0 == factor && secondaryParticle != G4Electron::Electron())
{ return; }
if(!biasManager) { biasManager = new G4EmBiasingManager(); }
biasManager->ActivateSecondaryBiasing(region, factor, energyLimit);
if(1 < verboseLevel) {
G4cout << "### ActivateSecondaryBiasing: for "
<< " process " << GetProcessName()
<< " factor= " << factor
<< " in G4Region <" << region
<< "> energyLimit(MeV)= " << energyLimit/MeV
<< G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetMinKinEnergy(G4double e)
{
nLambdaBins = G4lrint(nLambdaBins*std::log(maxKinEnergy/e)
/std::log(maxKinEnergy/minKinEnergy));
minKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetMaxKinEnergy(G4double e)
{
nLambdaBins = G4lrint(nLambdaBins*std::log(e/minKinEnergy)
/std::log(maxKinEnergy/minKinEnergy));
maxKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -24,8 +24,7 @@
// ********************************************************************
//
//
// $Id: G4VEnergyLoss.cc,v 1.46 2006-06-29 19:55:21 gunter Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// --------------------------------------------------------------
@@ -52,6 +51,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4VEnergyLoss.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4EnergyLossMessenger.hh"
#include "G4ProductionCutsTable.hh"
@@ -83,7 +84,11 @@ G4VEnergyLoss::G4VEnergyLoss(const G4String& aName , G4ProcessType aType)
nmaxCont1(4),
nmaxCont2(16)
{
if(!ELossMessenger) { ELossMessenger = new G4EnergyLossMessenger(); }
if(!ELossMessenger) {
G4cout << "### G4VEnergyLoss class is obsolete "
<< "and will be removed for the next release." << G4endl;
ELossMessenger = new G4EnergyLossMessenger();
}
imat = 0;
f1Fluct = f2Fluct = e1Fluct = e2Fluct = rateFluct = ipotFluct = e1LogFluct
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEnergyLossProcess.cc,v 1.174 2010-12-27 17:42:21 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -108,6 +107,8 @@
// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
// 24-06-09 Removed hidden bin in G4PhysicsVector (V.Ivanchenko)
// 15-10-10 Fixed 4-momentum balance if deexcitation is active (L.Pandola)
// 30-05-12 Call new ApplySecondaryBiasing so 2ries may be unique (D. Sawkey)
// 30-05-12 Fix bug in forced biasing: now called on first step (D. Sawkey)
//
// Class Description:
//
@@ -122,6 +123,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4VEnergyLossProcess.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ProcessManager.hh"
#include "G4LossTableManager.hh"
#include "G4LossTableBuilder.hh"
@@ -241,15 +244,15 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name,
G4VEnergyLossProcess::~G4VEnergyLossProcess()
{
if(1 < verboseLevel)
G4cout << "G4VEnergyLossProcess destruct " << GetProcessName()
<< G4endl;
//delete vstrag;
if(1 < verboseLevel) {
G4cout << "G4VEnergyLossProcess destruct " << GetProcessName()
<< " " << this << " " << baseParticle << G4endl;
}
Clean();
if ( !baseParticle ) {
if(theDEDXTable && theRangeTableForLoss) {
if(theIonisationTable == theDEDXTable) theIonisationTable = 0;
if(theDEDXTable) {
if(theIonisationTable == theDEDXTable) { theIonisationTable = 0; }
theDEDXTable->clearAndDestroy();
delete theDEDXTable;
if(theDEDXSubTable) {
@@ -380,9 +383,8 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if(1 < verboseLevel) {
G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
<< GetProcessName()
<< " for " << part.GetParticleName()
<< G4endl;
<< GetProcessName() << " for " << part.GetParticleName()
<< " " << this << G4endl;
}
currentCouple = 0;
@@ -398,21 +400,23 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
G4LossTableManager* lManager = G4LossTableManager::Instance();
// Are particle defined?
if( !particle ) {
particle = &part;
if(GetProcessName() == "ionIoni") {
G4String pname = particle->GetParticleName();
if(pname != "GenericIon" && pname != "alpha" && pname != "He3") {
lManager->RegisterIon(&part, this);
theGenericIon = G4GenericIon::GenericIon();
particle = theGenericIon;
return;
}
if( !particle ) { particle = &part; }
if(part.GetParticleType() == "nucleus") {
G4String pname = part.GetParticleName();
if(pname != "deuteron" && pname != "triton" &&
pname != "alpha+" && pname != "helium" &&
pname != "hydrogen") {
theGenericIon = G4GenericIon::GenericIon();
isIon = true;
// process is shared between all ions inheriting G4GenericIon
// for all excluding He3 and alpha
if(pname != "He3" && pname != "alpha") { particle = theGenericIon; }
}
}
if(part.GetParticleType() == "nucleus") { isIon = true; }
if( particle != &part ) {
if(isIon) {
lManager->RegisterIon(&part, this);
@@ -421,7 +425,9 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
}
if(1 < verboseLevel) {
G4cout << "### G4VEnergyLossProcess::PreparePhysicsTable() interrupted for "
<< part.GetParticleName() << G4endl;
<< part.GetParticleName() << " isIon= " << isIon
<< " particle " << particle << " GenericIon " << theGenericIon
<< G4endl;
}
return;
}
@@ -453,27 +459,23 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
G4PhysicsTableHelper::PreparePhysicsTable(theDEDXunRestrictedTable);
theCSDARangeTable =
G4PhysicsTableHelper::PreparePhysicsTable(theCSDARangeTable);
bld->InitialiseBaseMaterials(theDEDXunRestrictedTable);
bld->InitialiseBaseMaterials(theCSDARangeTable);
}
theRangeTableForLoss =
G4PhysicsTableHelper::PreparePhysicsTable(theRangeTableForLoss);
theInverseRangeTable =
G4PhysicsTableHelper::PreparePhysicsTable(theInverseRangeTable);
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
bld->InitialiseBaseMaterials(theRangeTableForLoss);
bld->InitialiseBaseMaterials(theInverseRangeTable);
bld->InitialiseBaseMaterials(theLambdaTable);
if(isIonisation) {
theRangeTableForLoss =
G4PhysicsTableHelper::PreparePhysicsTable(theRangeTableForLoss);
theInverseRangeTable =
G4PhysicsTableHelper::PreparePhysicsTable(theInverseRangeTable);
}
if (nSCoffRegions) {
theDEDXSubTable =
G4PhysicsTableHelper::PreparePhysicsTable(theDEDXSubTable);
theSubLambdaTable =
G4PhysicsTableHelper::PreparePhysicsTable(theSubLambdaTable);
bld->InitialiseBaseMaterials(theDEDXSubTable);
bld->InitialiseBaseMaterials(theSubLambdaTable);
}
}
@@ -490,9 +492,6 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
G4double initialMass = particle->GetPDGMass();
if (baseParticle) {
if(baseParticle->GetParticleName() == "GenericIon") {
theGenericIon = G4GenericIon::GenericIon();
}
massRatio = (baseParticle->GetPDGMass())/initialMass;
G4double q = initialCharge/baseParticle->GetPDGCharge();
chargeSqRatio = q*q;
@@ -532,11 +531,12 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
}
}
if (1 < verboseLevel) {
if(1 < verboseLevel) {
G4cout << "G4VEnergyLossProcess::Initialise() is done "
<< " for local " << particle->GetParticleName()
<< " isIon= " << isIon
<< " chargeSqRatio= " << chargeSqRatio
<< " isIon= " << isIon;
if(baseParticle) { G4cout << "; base: " << baseParticle->GetParticleName(); }
G4cout << " chargeSqRatio= " << chargeSqRatio
<< " massRatio= " << massRatio
<< " reduceFactor= " << reduceFactor << G4endl;
if (nSCoffRegions) {
@@ -558,8 +558,9 @@ void G4VEnergyLossProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< "; local: " << particle->GetParticleName();
if(baseParticle) G4cout << "; base: " << baseParticle->GetParticleName();
G4cout << G4endl;
if(baseParticle) { G4cout << "; base: " << baseParticle->GetParticleName(); }
G4cout << " TablesAreBuilt= " << tablesAreBuilt
<< " isIon= " << isIon << " " << this << G4endl;
}
if(&part == particle) {
@@ -567,12 +568,25 @@ void G4VEnergyLossProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
G4LossTableManager::Instance()->BuildPhysicsTable(particle, this);
}
if(!baseParticle) {
if(0 < verboseLevel) { PrintInfoDefinition(); }
// needs to be done only once
safetyHelper->InitialiseHelper();
}
}
// explicitly defined printout by particle name
G4String num = part.GetParticleName();
if(1 < verboseLevel ||
(0 < verboseLevel && (num == "e-" ||
num == "e+" || num == "mu+" ||
num == "mu-" || num == "proton"||
num == "pi+" || num == "pi-" ||
num == "kaon+" || num == "kaon-" ||
num == "alpha" || num == "anti_proton" ||
num == "GenericIon")))
{
particle = &part;
PrintInfoDefinition();
}
// Added tracking cut to avoid tracking artifacts
// identify deexcitation flag
@@ -635,7 +649,7 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildDEDXTable(G4EmTableType tType)
<< " maxKinEnergy= " << emax
<< " nbin= " << bin
<< " EmTableType= " << tType
<< " table= " << table
<< " table= " << table << " " << this
<< G4endl;
}
if(!table) return table;
@@ -651,12 +665,12 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildDEDXTable(G4EmTableType tType)
G4cout << "G4VEnergyLossProcess::BuildDEDXVector flagTable= "
<< table->GetFlag(i) << " Flag= " << bld->GetFlag(i) << G4endl;
}
if (/*table->GetFlag(i)*/bld->GetFlag(i)) {
if(bld->GetFlag(i)) {
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
//bVector = static_cast<G4PhysicsLogVector*>((*table)[i]);
delete (*table)[i];
if(!bVector) {
aVector = new G4PhysicsLogVector(minKinEnergy, emax, bin);
bVector = aVector;
@@ -722,12 +736,12 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildLambdaTable(G4EmTableType tType)
for(size_t i=0; i<numOfCouples; ++i) {
if (/*table->GetFlag(i)*/bld->GetFlag(i)) {
// if (table->GetFlag(i)) {
if (bld->GetFlag(i)) {
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
delete (*table)[i];
G4double emin = MinPrimaryEnergy(particle,couple->GetMaterial(),(*theCuts)[i]);
if(0.0 >= emin) { emin = eV; }
else if(maxKinEnergy <= emin) { emin = 0.5*maxKinEnergy; }
@@ -857,6 +871,35 @@ void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::StartTracking(G4Track* track)
{
// reset parameters for the new track
theNumberOfInteractionLengthLeft = -1.0;
mfpKinEnergy = DBL_MAX;
// reset ion
if(isIon) {
chargeSqRatio = 0.5;
G4double newmass = track->GetDefinition()->GetPDGMass();
if(baseParticle) {
massRatio = baseParticle->GetPDGMass()/newmass;
} else {
massRatio = proton_mass_c2/newmass;
}
}
// forced biasing only for primary particles
if(biasManager) {
if(0 == track->GetParentID()) {
// primary particle
biasFlag = true;
biasManager->ResetForcedInteraction();
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEnergyLossProcess::AlongStepGetPhysicalInteractionLength(
const G4Track&,G4double,G4double,G4double&,
G4GPILSelection* selection)
@@ -874,6 +917,7 @@ G4double G4VEnergyLossProcess::AlongStepGetPhysicalInteractionLength(
}
if(x > finR) { x = y + finR*(1.0 - dRoverRange)*(2.0 - finR/fRange); }
/*
if(particle->GetPDGMass() > 0.9*GeV)
G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
<<" range= "<<fRange << " idx= " << basedCoupleIndex
<< " y= " << y << " finR= " << finR
@@ -896,10 +940,6 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
G4double x = DBL_MAX;
// initialisation of material, mass, charge, model at the beginning of the step
const G4ParticleDefinition* currPart = track.GetParticleDefinition();
if(theGenericIon == particle) {
massRatio = proton_mass_c2/currPart->GetPDGMass();
}
/*
if(!theDensityFactor || !theDensityIdx) {
G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength 1: "
@@ -915,6 +955,7 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
preStepKinEnergy = track.GetKineticEnergy();
preStepScaledEnergy = preStepKinEnergy*massRatio;
SelectModel(preStepScaledEnergy);
if(!currentModel->IsActive(preStepScaledEnergy)) { return x; }
// change effective charge of an ion on fly
@@ -926,18 +967,15 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
reduceFactor = 1.0/(fFactor*massRatio);
}
}
// if(particle->GetPDGMass() > 0.9*GeV)
//G4cout << "q2= " << chargeSqRatio << " massRatio= " << massRatio << G4endl;
// initialisation for sampling of the interaction length
if(previousStepSize <= 0.0) { theNumberOfInteractionLengthLeft = -1.0; }
if(theNumberOfInteractionLengthLeft < 0.0) { mfpKinEnergy = DBL_MAX; }
//if(previousStepSize <= 0.0) { theNumberOfInteractionLengthLeft = -1.0; }
//if(theNumberOfInteractionLengthLeft < 0.0) { mfpKinEnergy = DBL_MAX; }
// forced biasing only for primary particles
if(biasManager) {
if(0 == track.GetParentID()) {
if(0 == track.GetCurrentStepNumber()) {
biasFlag = true;
biasManager->ResetForcedInteraction();
}
if(biasFlag && biasManager->ForcedInteractionRegion(currentCoupleIndex)) {
return biasManager->GetStepLimit(currentCoupleIndex, previousStepSize);
}
@@ -948,31 +986,42 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
if(preStepScaledEnergy < mfpKinEnergy) {
if (integral) { ComputeLambdaForScaledEnergy(preStepScaledEnergy); }
else { preStepLambda = GetLambdaForScaledEnergy(preStepScaledEnergy); }
if(preStepLambda <= 0.0) { mfpKinEnergy = 0.0; }
// zero cross section
if(preStepLambda <= 0.0) {
theNumberOfInteractionLengthLeft = -1.0;
currentInteractionLength = DBL_MAX;
}
}
// non-zero cross section
if(preStepLambda > 0.0) {
if (theNumberOfInteractionLengthLeft < 0.0) {
// beggining of tracking (or just after DoIt of this process)
ResetNumberOfInteractionLengthLeft();
} else if(currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft
SubtractNumberOfInteractionLengthLeft(previousStepSize);
// subtract NumberOfInteractionLengthLeft using previous step
theNumberOfInteractionLengthLeft -= previousStepSize/currentInteractionLength;
// SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.) {
theNumberOfInteractionLengthLeft = perMillion;
theNumberOfInteractionLengthLeft = 0.0;
//theNumberOfInteractionLengthLeft = perMillion;
}
}
// get mean free path and step limit
// new mean free path and step limit
currentInteractionLength = 1.0/preStepLambda;
x = theNumberOfInteractionLengthLeft * currentInteractionLength;
#ifdef G4VERBOSE
if (verboseLevel>2){
// if(particle->GetPDGMass() > 0.9*GeV){
G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength ";
G4cout << "[ " << GetProcessName() << "]" << G4endl;
G4cout << " for " << currPart->GetParticleName()
G4cout << " for " << track.GetDefinition()->GetParticleName()
<< " in Material " << currentMaterial->GetName()
<< " Ekin(MeV)= " << preStepKinEnergy/MeV
<<G4endl;
@@ -980,17 +1029,6 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
<< "InteractionLength= " << x/cm <<"[cm] " <<G4endl;
}
#endif
// zero cross section case
} else {
if(theNumberOfInteractionLengthLeft > DBL_MIN &&
currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft
SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.) {
theNumberOfInteractionLengthLeft = perMillion;
}
}
currentInteractionLength = DBL_MAX;
}
return x;
}
@@ -1034,7 +1072,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
G4double weight = fParticleChange.GetParentWeight();
if(weightFlag) {
weight /= biasFactor;
fParticleChange.ProposeParentWeight(weight);
fParticleChange.ProposeWeight(weight);
}
// stopping
@@ -1043,7 +1081,8 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
if (useDeexcitation) {
atomDeexcitation->AlongStepDeexcitation(scTracks, step,
eloss, currentCoupleIndex);
FillSecondariesAlongStep(eloss, weight);
if(scTracks.size() > 0) { FillSecondariesAlongStep(eloss, weight); }
if(eloss < 0.0) { eloss = 0.0; }
}
fParticleChange.SetProposedKineticEnergy(0.0);
fParticleChange.ProposeLocalEnergyDeposit(eloss);
@@ -1056,8 +1095,9 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
// Long step
if(eloss > preStepKinEnergy*linLossLimit) {
G4double x = GetScaledRangeForScaledEnergy(preStepScaledEnergy)
- length/reduceFactor;
//G4double x = GetScaledRangeForScaledEnergy(preStepScaledEnergy)
// - length/reduceFactor;
G4double x = (fRange - length)/reduceFactor;
eloss = preStepKinEnergy - ScaledKinEnergyForLoss(x)/massRatio;
/*
@@ -1178,11 +1218,40 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
// deexcitation
if (useDeexcitation) {
G4double eloss_before = eloss;
G4double esecfluo = preStepKinEnergy - esec;
G4double de = esecfluo;
//G4double eloss0 = eloss;
/*
G4cout << "### 1: E(keV)= " << preStepKinEnergy/keV
<< " Efluomax(keV)= " << de/keV
<< " Eloss(keV)= " << eloss/keV << G4endl;
*/
atomDeexcitation->AlongStepDeexcitation(scTracks, step,
eloss, currentCoupleIndex);
esec += eloss_before - eloss;
de, currentCoupleIndex);
// sum of de-excitation energies
esecfluo -= de;
// subtracted from energy loss
if(eloss >= esecfluo) {
esec += esecfluo;
eloss -= esecfluo;
} else {
esec += esecfluo;
eloss = 0.0;
}
/*
if(esecfluo > 0.0) {
G4cout << "### 2: E(keV)= " << preStepKinEnergy/keV
<< " Esec(keV)= " << esec/keV
<< " Esecf(kV)= " << esecfluo/keV
<< " Eloss0(kV)= " << eloss0/keV
<< " Eloss(keV)= " << eloss/keV
<< G4endl;
}
*/
}
if(scTracks.size() > 0) { FillSecondariesAlongStep(eloss, weight); }
// Energy balanse
G4double finalT = preStepKinEnergy - eloss - esec;
@@ -1195,49 +1264,49 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
currentMaterial,finalT));
}
FillSecondariesAlongStep(eloss, weight);
if(eloss < 0.0) { eloss = 0.0; }
fParticleChange.SetProposedKineticEnergy(finalT);
fParticleChange.ProposeLocalEnergyDeposit(eloss);
/*
if(-1 < verboseLevel) {
if(1 < verboseLevel) {
G4double del = finalT + eloss + esec - preStepKinEnergy;
G4cout << "Final value eloss(MeV)= " << eloss/MeV
<< " preStepKinEnergy= " << preStepKinEnergy
<< " postStepKinEnergy= " << finalT
<< " de(keV)= " << del/keV
<< " lossFlag= " << lossFluctuationFlag
<< " status= " << track.GetTrackStatus()
<< G4endl;
}
*/
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4VEnergyLossProcess::FillSecondariesAlongStep(G4double& eloss, G4double& weight)
G4VEnergyLossProcess::FillSecondariesAlongStep(G4double&, G4double& weight)
{
if(eloss < 0.0) { eloss = 0.0; }
G4int n = scTracks.size();
if(0 == n) { return; }
// weight may be changed by biasing manager
G4bool weightNotChanged = true;
if(biasManager) {
if(biasManager->SecondaryBiasingRegion(currentCoupleIndex)) {
biasManager->ApplySecondaryBiasing(scTracks,weight,currentCoupleIndex);
weightNotChanged = false;
weight *=
biasManager->ApplySecondaryBiasing(scTracks, currentCoupleIndex);
}
}
}
// fill secondaries
G4int n = scTracks.size();
fParticleChange.SetNumberOfSecondaries(n);
for(G4int i=0; i<n; ++i) {
G4Track* t = scTracks[i];
if(t) {
if(weightNotChanged) { t->SetWeight(weight); }
//esec += t->GetKineticEnergy();
t->SetWeight(weight);
pParticleChange->AddSecondary(t);
//G4cout << "Secondary(along step) has weight " << t->GetWeight()
//<< ", kenergy " << t->GetKineticEnergy()/MeV << " MeV" <<G4endl;
}
}
scTracks.clear();
@@ -1339,10 +1408,11 @@ G4VEnergyLossProcess::SampleSubCutSecondaries(std::vector<G4Track*>& tracks,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
const G4Step&)
const G4Step& step)
{
// In all cases clear number of interaction lengths
theNumberOfInteractionLengthLeft = -1.0;
mfpKinEnergy = DBL_MAX;
fParticleChange.InitializeForPostStep(track);
G4double finalT = track.GetKineticEnergy();
@@ -1393,7 +1463,7 @@ G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
G4double weight = fParticleChange.GetParentWeight();
if(weightFlag) {
weight /= biasFactor;
fParticleChange.ProposeParentWeight(weight);
fParticleChange.ProposeWeight(weight);
}
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
@@ -1401,26 +1471,39 @@ G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
// sample secondaries
secParticles.clear();
//G4cout << "Energy of primary: " << dynParticle->GetKineticEnergy()/MeV<<G4endl;
currentModel->SampleSecondaries(&secParticles, currentCouple, dynParticle, tcut);
// bremsstrahlung splitting or Russian roulette
if(biasManager) {
if(biasManager->SecondaryBiasingRegion(currentCoupleIndex)) {
weight *= biasManager->ApplySecondaryBiasing(secParticles,currentCoupleIndex);
G4double eloss = 0.0;
weight *= biasManager->ApplySecondaryBiasing(secParticles,
track, currentModel,
&fParticleChange, eloss,
currentCoupleIndex, tcut,
step.GetPostStepPoint()->GetSafety());
if(eloss > 0.0) {
eloss += fParticleChange.GetLocalEnergyDeposit();
fParticleChange.ProposeLocalEnergyDeposit(eloss);
}
}
}
// save secondaries
G4int num = secParticles.size();
if(num > 0) {
fParticleChange.SetNumberOfSecondaries(num);
for (G4int i=0; i<num; ++i) {
fParticleChange.SetNumberOfSecondaries(num);
for (G4int i=0; i<num; ++i) {
if(secParticles[i]) {
G4Track* t = new G4Track(secParticles[i], track.GetGlobalTime(),
track.GetPosition());
t->SetTouchableHandle(track.GetTouchableHandle());
t->SetWeight(weight);
//G4cout << "Secondary(post step) has weight " << t->GetWeight()
//<< ", kenergy " << t->GetKineticEnergy()/MeV << " MeV" <<G4endl;
pParticleChange->AddSecondary(t);
}
}
@@ -1887,7 +1970,7 @@ void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
if(theLambdaTable) {
size_t n = theLambdaTable->length();
G4PhysicsVector* pv = (*theLambdaTable)[0];
G4double e, s, smax, emax;
G4double e, ss, smax, emax;
size_t i;
@@ -1901,9 +1984,9 @@ void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
if(nb > 0) {
for (size_t j=0; j<nb; ++j) {
e = pv->Energy(j);
s = (*pv)(j);
if(s > smax) {
smax = s;
ss = (*pv)(j);
if(ss > smax) {
smax = ss;
emax = e;
}
}
@@ -1918,7 +2001,7 @@ void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
}
}
// second loop using base materials
for (size_t i=0; i<n; ++i) {
for (i=0; i<n; ++i) {
pv = (*theLambdaTable)[i];
if(!pv){
G4int j = (*theDensityIdx)[i];
@@ -1996,7 +2079,12 @@ G4VEnergyLossProcess::ActivateSecondaryBiasing(const G4String& region,
G4double factor,
G4double energyLimit)
{
if (0.0 < factor) {
if (0.0 <= factor) {
// Range cut can be applied only for e-
if(0.0 == factor && secondaryParticle != G4Electron::Electron())
{ return; }
if(!biasManager) { biasManager = new G4EmBiasingManager(); }
biasManager->ActivateSecondaryBiasing(region, factor, energyLimit);
if(1 < verboseLevel) {
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMscModel.cc,v 1.18 2010-09-07 16:05:33 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -48,8 +47,10 @@
//
#include "G4VMscModel.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleChangeForMSC.hh"
#include "G4TransportationManager.hh"
#include "G4LossTableBuilder.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -73,6 +74,8 @@ G4VMscModel::G4VMscModel(const G4String& nam):
dedx = 2.0*CLHEP::MeV*CLHEP::cm2/CLHEP::g;
localrange = DBL_MAX;
localtkin = 0.0;
man = G4LossTableManager::Instance();
currentPart = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -82,7 +85,8 @@ G4VMscModel::~G4VMscModel()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ParticleChangeForMSC* G4VMscModel::GetParticleChangeForMSC()
G4ParticleChangeForMSC*
G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition* p)
{
if(!safetyHelper) {
safetyHelper = G4TransportationManager::GetTransportationManager()
@@ -95,54 +99,43 @@ G4ParticleChangeForMSC* G4VMscModel::GetParticleChangeForMSC()
} else {
change = new G4ParticleChangeForMSC();
}
if(p) {
// table is never built for GenericIon
if(p->GetParticleName() == "GenericIon") {
if(xSectionTable) {
xSectionTable->clearAndDestroy();
delete xSectionTable;
xSectionTable = 0;
}
// table is always built for low mass particles
} else if(p->GetPDGMass() < 4.5*GeV || ForceBuildTableFlag()) {
G4double emin = std::max(LowEnergyLimit(), LowEnergyActivationLimit());
G4double emax = std::min(HighEnergyLimit(), HighEnergyActivationLimit());
emin = std::max(emin, man->MinKinEnergy());
emax = std::min(emax, man->MaxKinEnergy());
G4LossTableBuilder* builder = man->GetTableBuilder();
xSectionTable = builder->BuildTableForModel(xSectionTable, this, p,
emin, emax, true);
theDensityFactor = builder->GetDensityFactors();
theDensityIdx = builder->GetCoupleIndexes();
}
}
return change;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VMscModel::ComputeDisplacement(G4ParticleChangeForMSC* fParticleChange,
const G4ThreeVector& dir,
G4double displacement,
G4double postsafety)
G4ThreeVector&
G4VMscModel::SampleScattering(const G4DynamicParticle*, G4double)
{
if(displacement <= geomMin) { return; }
const G4ThreeVector* pos = fParticleChange->GetProposedPosition();
// displaced point is definitely within the volume
if(displacement < postsafety) {
// compute new endpoint of the Step
G4ThreeVector newPosition = *pos + displacement*dir;
safetyHelper->ReLocateWithinVolume(newPosition);
fParticleChange->ProposePosition(newPosition);
return;
}
// displaced point may be outside the volume
G4double newsafety = safetyHelper->ComputeSafety(*pos);
// add a factor which ensure numerical stability
G4double r = std::min(displacement, newsafety*0.99);
if(r > geomMin) {
// compute new endpoint of the Step
G4ThreeVector newPosition = *pos + r*dir;
safetyHelper->ReLocateWithinVolume(newPosition);
fParticleChange->ProposePosition(newPosition);
}
return fDisplacement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VMscModel::SampleScattering(const G4DynamicParticle*, G4double)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VMscModel::ComputeTruePathLengthLimit(const G4Track&,
G4PhysicsTable*,
G4double)
G4double G4VMscModel::ComputeTruePathLengthLimit(const G4Track&, G4double&)
{
return DBL_MAX;
}
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMultipleScattering.cc,v 1.86 2010-10-26 11:30:46 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -68,59 +67,57 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4VMultipleScattering.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4LossTableManager.hh"
#include "G4LossTableBuilder.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4VEmFluctuationModel.hh"
#include "G4DataVector.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsVector.hh"
#include "G4PhysicsLogVector.hh"
#include "G4UnitsTable.hh"
#include "G4ProductionCutsTable.hh"
#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4GenericIon.hh"
#include "G4Electron.hh"
#include "G4EmConfigurator.hh"
#include "G4GenericIon.hh"
#include "G4TransportationManager.hh"
#include "G4SafetyHelper.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMultipleScattering::G4VMultipleScattering(const G4String& name,
G4ProcessType type):
G4VContinuousDiscreteProcess(name, type),
buildLambdaTable(true),
theLambdaTable(0),
G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType):
G4VContinuousDiscreteProcess("msc", fElectromagnetic),
numberOfModels(0),
firstParticle(0),
theDensityFactor(0),
theDensityIdx(0),
currParticle(0),
stepLimit(fUseSafety),
skin(1.0),
facrange(0.04),
facgeom(2.5),
latDisplasment(true),
isIon(false),
currentParticle(0),
currentCouple(0)
isIon(false)
{
SetVerboseLevel(1);
SetProcessSubType(fMultipleScattering);
if("ionmsc" == name) { firstParticle = G4GenericIon::GenericIon(); }
// Size of tables assuming spline
minKinEnergy = 0.1*keV;
maxKinEnergy = 10.0*TeV;
nBins = 77;
geomMin = 1.e-6*CLHEP::mm;
lowestKinEnergy = 1*eV;
// default limit on polar angle
polarAngleLimit = 0.0;
physStepLimit = gPathLength = tPathLength = 0.0;
fIonisation = 0;
pParticleChange = &fParticleChange;
safetyHelper = 0;
fPositionChanged = false;
isActive = false;
modelManager = new G4EmModelManager();
(G4LossTableManager::Instance())->Register(this);
emManager = G4LossTableManager::Instance();
emManager->Register(this);
warn = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -132,11 +129,7 @@ G4VMultipleScattering::~G4VMultipleScattering()
<< G4endl;
}
delete modelManager;
if (theLambdaTable) {
theLambdaTable->clearAndDestroy();
delete theLambdaTable;
}
(G4LossTableManager::Instance())->DeRegister(this);
emManager->DeRegister(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -148,10 +141,17 @@ void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p,
modelManager->AddEmModel(order, p, fm, region);
if(p) { p->SetParticleChange(pParticleChange); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::SetModel(G4VMscModel* p, G4int index)
{
++warn;
if(warn < 10) {
G4cout << "### G4VMultipleScattering::SetModel is obsolete method "
<< "and will be removed for the next release." << G4endl;
G4cout << " Please, use SetEmModel" << G4endl;
}
G4int n = mscModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) {mscModels.push_back(0);} }
mscModels[index] = p;
@@ -160,6 +160,30 @@ void G4VMultipleScattering::SetModel(G4VMscModel* p, G4int index)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMscModel* G4VMultipleScattering::Model(G4int index)
{
++warn;
if(warn < 10) {
G4cout << "### G4VMultipleScattering::Model is obsolete method "
<< "and will be removed for the next release." << G4endl;
G4cout << " Please, use EmModel" << G4endl;
}
G4VMscModel* p = 0;
if(index >= 0 && index < G4int(mscModels.size())) { p = mscModels[index]; }
return p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::SetEmModel(G4VMscModel* p, G4int index)
{
G4int n = mscModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) { mscModels.push_back(0); } }
mscModels[index] = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMscModel* G4VMultipleScattering::EmModel(G4int index)
{
G4VMscModel* p = 0;
if(index >= 0 && index < G4int(mscModels.size())) { p = mscModels[index]; }
@@ -176,36 +200,27 @@ G4VMultipleScattering::GetModelByIndex(G4int idx, G4bool ver) const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
void
G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if (!firstParticle) {
currentCouple = 0;
if(part.GetParticleType() == "nucleus" &&
part.GetParticleSubType() == "generic") {
firstParticle = G4GenericIon::GenericIon();
isIon = true;
} else {
firstParticle = &part;
if(part.GetParticleType() == "nucleus" ||
part.GetPDGMass() > GeV) {isIon = true;}
}
// limitations for ions
if(isIon) {
SetStepLimitType(fMinimal);
SetLateralDisplasmentFlag(false);
SetBuildLambdaTable(false);
}
currentParticle = &part;
if(!firstParticle) { firstParticle = &part; }
if(part.GetParticleType() == "nucleus") {
SetStepLimitType(fMinimal);
SetLateralDisplasmentFlag(false);
SetRangeFactor(0.2);
if(&part == G4GenericIon::GenericIon()) { firstParticle = &part; }
isIon = true;
}
G4LossTableManager* man = G4LossTableManager::Instance();
man->PreparePhysicsTable(&part, this);
emManager->PreparePhysicsTable(&part, this);
currParticle = 0;
if(1 < verboseLevel) {
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< " local particle " << firstParticle->GetParticleName()
<< " isIon= " << isIon
<< G4endl;
}
@@ -213,11 +228,12 @@ void G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part
InitialiseProcess(firstParticle);
// initialisation of models
G4int nmod = modelManager->NumberOfModels();
for(G4int i=0; i<nmod; ++i) {
numberOfModels = modelManager->NumberOfModels();
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
msc->SetIonisation(0, firstParticle);
if(0 == i) { currentModel = msc; }
if(isIon) {
msc->SetStepLimitType(fMinimal);
msc->SetLateralDisplasmentFlag(false);
@@ -230,22 +246,19 @@ void G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part
msc->SetGeomFactor(GeomFactor());
}
msc->SetPolarAngleLimit(polarAngleLimit);
if(msc->HighEnergyLimit() > maxKinEnergy) {
msc->SetHighEnergyLimit(maxKinEnergy);
}
G4double emax =
std::min(msc->HighEnergyLimit(),emManager->MaxKinEnergy());
msc->SetHighEnergyLimit(emax);
}
modelManager->Initialise(firstParticle, G4Electron::Electron(),
10.0, verboseLevel);
// prepare tables
G4LossTableBuilder* bld = man->GetTableBuilder();
if(buildLambdaTable) {
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
bld->InitialiseBaseMaterials(theLambdaTable);
if(!safetyHelper) {
safetyHelper = G4TransportationManager::GetTransportationManager()
->GetSafetyHelper();
safetyHelper->InitialiseHelper();
}
theDensityFactor = bld->GetDensityFactors();
theDensityIdx = bld->GetCoupleIndexes();
}
}
@@ -261,53 +274,26 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
<< G4endl;
}
(G4LossTableManager::Instance())->BuildPhysicsTable(firstParticle);
emManager->BuildPhysicsTable(firstParticle);
if (buildLambdaTable && firstParticle == &part) {
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
//G4LossTableBuilder* bld = (G4LossTableManager::Instance())->GetTableBuilder();
G4bool splineFlag = (G4LossTableManager::Instance())->SplineFlag();
G4PhysicsLogVector* aVector = 0;
G4PhysicsLogVector* bVector = 0;
for (size_t i=0; i<numOfCouples; ++i) {
if (theLambdaTable->GetFlag(i)/*bld->GetFlag(i)*/) {
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
if(!bVector) {
aVector = static_cast<G4PhysicsLogVector*>(PhysicsVector(couple));
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
}
aVector->SetSpline(splineFlag);
modelManager->FillLambdaVector(aVector, couple, false);
if(splineFlag) { aVector->FillSecondDerivatives(); }
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
}
// explicitly defined printout by particle name
if(1 < verboseLevel ||
(0 < verboseLevel && (num == "e-" ||
num == "e+" || num == "mu+" ||
num == "mu-" || num == "proton"||
num == "pi+" || num == "pi-" ||
num == "kaon+" || num == "kaon-" ||
num == "alpha" || num == "anti_proton" ||
num == "GenericIon")))
{
G4cout << G4endl << GetProcessName()
<< ": for " << num
<< " SubType= " << GetProcessSubType()
<< G4endl;
PrintInfo();
modelManager->DumpModelList(verboseLevel);
}
if(1 < verboseLevel) {
G4cout << "Lambda table is built for "
<< num
<< G4endl;
}
}
if(verboseLevel>0 && ( num == "e-" || num == "mu+" ||
num == "proton" || num == "pi-" ||
num == "kaon+" || num == "GenericIon")) {
PrintInfoDefinition();
if(2 < verboseLevel && theLambdaTable)
{ G4cout << *theLambdaTable << G4endl; }
}
if(1 < verboseLevel) {
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() done for "
<< GetProcessName()
@@ -325,20 +311,32 @@ void G4VMultipleScattering::PrintInfoDefinition()
<< ": for " << firstParticle->GetParticleName()
<< " SubType= " << GetProcessSubType()
<< G4endl;
if (theLambdaTable) {
G4cout << " Lambda tables from "
<< G4BestUnit(MinKinEnergy(),"Energy")
<< " to "
<< G4BestUnit(MaxKinEnergy(),"Energy")
<< " in " << nBins << " bins, spline: "
<< (G4LossTableManager::Instance())->SplineFlag()
<< G4endl;
}
PrintInfo();
modelManager->DumpModelList(verboseLevel);
if (2 < verboseLevel) {
G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
if(theLambdaTable) { G4cout << (*theLambdaTable) << G4endl; }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::StartTracking(G4Track* track)
{
G4VEnergyLossProcess* eloss = 0;
if(track->GetParticleDefinition() != currParticle) {
currParticle = track->GetParticleDefinition();
fIonisation = emManager->GetEnergyLossProcess(currParticle);
eloss = fIonisation;
}
// one model
if(1 == numberOfModels) {
currentModel->StartTracking(track);
if(eloss) { currentModel->SetIonisation(fIonisation, currParticle); }
// many models
} else {
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
msc->StartTracking(track);
if(eloss) { msc->SetIonisation(fIonisation, currParticle); }
}
}
}
@@ -354,28 +352,38 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
{
// get Step limit proposed by the process
*selection = NotCandidateForSelection;
G4double x = currentMinimalStep;
DefineMaterial(track.GetMaterialCutsCouple());
physStepLimit = gPathLength = tPathLength = currentMinimalStep;
G4double ekin = track.GetKineticEnergy();
if(isIon) { ekin *= proton_mass_c2/track.GetParticleDefinition()->GetPDGMass(); }
currentModel = static_cast<G4VMscModel*>(SelectModel(ekin));
// define ionisation process
if(!currentModel->GetIonisation()) {
currentModel->SetIonisation(G4LossTableManager::Instance()
->GetEnergyLossProcess(track.GetParticleDefinition()));
}
if(x > 0.0 && ekin > 0.0 && currentModel->IsActive(ekin)) {
G4double tPathLength =
currentModel->ComputeTruePathLengthLimit(track, theLambdaTable, x);
if (tPathLength < x) { *selection = CandidateForSelection; }
x = currentModel->ComputeGeomPathLength(tPathLength);
// G4cout << "tPathLength= " << tPathLength
// << " stepLimit= " << x
// << " currentMinimalStep= " << currentMinimalStep<< G4endl;
// isIon flag is used only to select a model
if(isIon) {
ekin *= proton_mass_c2/track.GetParticleDefinition()->GetPDGMass();
}
return x;
// select new model
if(1 < numberOfModels) {
currentModel = static_cast<G4VMscModel*>(
SelectModel(ekin,track.GetMaterialCutsCouple()->GetIndex()));
}
// step limit
if(currentModel->IsActive(ekin) && gPathLength >= geomMin
&& ekin >= lowestKinEnergy) {
isActive = true;
tPathLength = currentModel->ComputeTruePathLengthLimit(track, gPathLength);
if (tPathLength < physStepLimit) {
*selection = CandidateForSelection;
}
} else { isActive = false; }
/*
if(currParticle->GetPDGMass() > GeV)
G4cout << "MSC::AlongStepGPIL: Ekin= " << ekin
<< " gPathLength= " << gPathLength
<< " tPathLength= " << tPathLength
<< " currentMinimalStep= " << currentMinimalStep
<< " isActive " << isActive << G4endl;
*/
return gPathLength;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -385,6 +393,7 @@ G4VMultipleScattering::PostStepGetPhysicalInteractionLength(
const G4Track&, G4double, G4ForceCondition* condition)
{
*condition = Forced;
//*condition = NotForced;
return DBL_MAX;
}
@@ -393,23 +402,94 @@ G4VMultipleScattering::PostStepGetPhysicalInteractionLength(
G4VParticleChange*
G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step)
{
if(currentModel->IsActive(track.GetKineticEnergy())) {
fParticleChange.ProposeTrueStepLength(currentModel->ComputeTrueStepLength(step.GetStepLength()));
fParticleChange.ProposeMomentumDirection(step.GetPostStepPoint()->GetMomentumDirection());
fNewPosition = step.GetPostStepPoint()->GetPosition();
fParticleChange.ProposePosition(fNewPosition);
fPositionChanged = false;
G4double geomLength = step.GetStepLength();
// very small step - no msc
if(!isActive) {
tPathLength = geomLength;
// sample msc
} else {
fParticleChange.ProposeTrueStepLength(step.GetStepLength());
G4double range =
currentModel->GetRange(currParticle,track.GetKineticEnergy(),
track.GetMaterialCutsCouple());
G4double trueLength = currentModel->ComputeTrueStepLength(geomLength);
// protection against wrong t->g->t conversion
// if(trueLength > tPathLength)
/*
if(currParticle->GetPDGMass() > GeV)
G4cout << "G4VMsc::AlongStepDoIt: GeomLength= "
<< geomLength
<< " trueLenght= " << trueLength
<< " tPathLength= " << tPathLength
<< " dr= " << range - trueLength
<< " ekin= " << track.GetKineticEnergy() << G4endl;
*/
if (trueLength <= physStepLimit) {
tPathLength = trueLength;
} else {
tPathLength = physStepLimit - 0.5*geomMin;
}
// do not sample scattering at the last or at a small step
if(tPathLength + geomMin < range && tPathLength > geomMin) {
G4double preSafety = step.GetPreStepPoint()->GetSafety();
G4double postSafety= preSafety - geomLength;
G4bool safetyRecomputed = false;
if( postSafety < geomMin ) {
safetyRecomputed = true;
postSafety = currentModel->ComputeSafety(fNewPosition,0.0);
}
G4ThreeVector displacement =
currentModel->SampleScattering(track.GetDynamicParticle(),postSafety);
G4double r2 = displacement.mag2();
//G4cout << "R= " << sqrt(r2) << " postSafety= " << postSafety << G4endl;
// make correction for displacement
if(r2 > 0.0) {
fPositionChanged = true;
G4double fac = 1.0;
// displaced point is definitely within the volume
if(r2 > postSafety*postSafety) {
if(!safetyRecomputed) {
postSafety = currentModel->ComputeSafety(fNewPosition, 0.0);
}
// add a factor which ensure numerical stability
if(r2 > postSafety*postSafety) { fac = 0.99*postSafety/std::sqrt(r2); }
}
// compute new endpoint of the Step
fNewPosition += fac*displacement;
//safetyHelper->ReLocateWithinVolume(fNewPosition);
}
}
}
fParticleChange.ProposeTrueStepLength(tPathLength);
//fParticleChange.ProposePosition(fNewPosition);
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange*
G4VMultipleScattering::PostStepDoIt(const G4Track& track, const G4Step& step)
G4VMultipleScattering::PostStepDoIt(const G4Track& track, const G4Step&)
{
fParticleChange.Initialize(track);
if(currentModel->IsActive(track.GetKineticEnergy())) {
currentModel->SampleScattering(track.GetDynamicParticle(),
step.GetPostStepPoint()->GetSafety());
fParticleChange.Initialize(track);
if(fPositionChanged) {
safetyHelper->ReLocateWithinVolume(fNewPosition);
fParticleChange.ProposePosition(fNewPosition);
}
return &fParticleChange;
}
@@ -450,41 +530,39 @@ G4double G4VMultipleScattering::GetMeanFreePath(
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PhysicsVector*
G4VMultipleScattering::PhysicsVector(const G4MaterialCutsCouple* couple)
{
G4int nbins = 3;
if( couple->IsUsed() ) { nbins = nBins; }
G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nbins);
v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
return v;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part,
const G4String& directory,
G4bool ascii)
G4bool
G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part,
const G4String& directory,
G4bool ascii)
{
G4bool yes = true;
if ( theLambdaTable && part == firstParticle) {
const G4String name = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
G4bool yes = theLambdaTable->StorePhysicsTable(name,ascii);
if(part != firstParticle) { return yes; }
G4int nmod = modelManager->NumberOfModels();
const G4String ss[4] = {"1","2","3","4"};
for(G4int i=0; i<nmod; ++i) {
G4VEmModel* msc = modelManager->GetModel(i);
yes = true;
G4PhysicsTable* table = msc->GetCrossSectionTable();
if (table) {
G4int j = std::min(i,3);
G4String name =
GetPhysicsTableFileName(part,directory,"LambdaMod"+ss[j],ascii);
yes = table->StorePhysicsTable(name,ascii);
if ( yes ) {
if ( verboseLevel>0 ) {
G4cout << "Physics table are stored for " << part->GetParticleName()
<< " and process " << GetProcessName()
if ( yes ) {
if ( verboseLevel>0 ) {
G4cout << "Physics table are stored for " << part->GetParticleName()
<< " and process " << GetProcessName()
<< " with a name <" << name << "> " << G4endl;
}
} else {
G4cout << "Fail to store Physics Table for " << part->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
}
} else {
G4cout << "Fail to store Physics Table for " << part->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
}
}
return yes;
@@ -493,48 +571,21 @@ G4bool G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool
G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition* part,
const G4String& directory,
G4bool ascii)
G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition*,
const G4String&,
G4bool)
{
if(0 < verboseLevel) {
G4cout << "G4VMultipleScattering::RetrievePhysicsTable() for "
<< part->GetParticleName() << " and process "
<< GetProcessName() << G4endl;
}
G4bool yes = true;
if(!buildLambdaTable || firstParticle != part) return yes;
const G4String particleName = part->GetParticleName();
G4String filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
yes =
G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTable,filename,ascii);
if ( yes ) {
if (0 < verboseLevel) {
G4cout << "Lambda table for " << part->GetParticleName()
<< " is retrieved from <"
<< filename << ">"
<< G4endl;
}
if((G4LossTableManager::Instance())->SplineFlag()) {
size_t n = theLambdaTable->length();
for(size_t i=0; i<n; ++i) {
if((* theLambdaTable)[i]) {
(* theLambdaTable)[i]->SetSpline(true);
}
}
}
} else {
if (1 < verboseLevel) {
G4cout << "Lambda table for " << part->GetParticleName()
<< " in file <"
<< filename << "> is not exist"
<< G4endl;
}
}
return yes;
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::SetIonisation(G4VEnergyLossProcess* p)
{
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
msc->SetIonisation(p, firstParticle);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ionEffectiveCharge.cc,v 1.25 2009-10-29 16:57:39 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
// $Id$
//
// -------------------------------------------------------------------
//
@@ -52,6 +51,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4ionEffectiveCharge.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"