Import Geant4 9.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 16:25:56 +02:00
parent 74cad5e589
commit 89a9605df1
4440 changed files with 379508 additions and 189225 deletions
@@ -0,0 +1,18 @@
#------------------------------------------------------------------------------
# CMakeLists.txt
# Module : G4emutils
# Package: Geant4.src.G4processes.G4electromagnetic.G4emutils
#
# CMakeLists.txt for building a single granular library.
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt,v 1.1 2010/09/29 18:54:13 bmorgan Exp $
#
#------------------------------------------------------------------------------
if(GEANT4_BUILD_GRANULAR_LIBS)
include(Geant4MacroLibraryTargets)
GEANT4_GRANULAR_LIBRARY_TARGET(COMPONENT sources.cmake)
endif()
+138 -1
View File
@@ -1,4 +1,4 @@
$Id: History,v 1.400 2009/11/22 19:48:30 vnivanch Exp $
$Id: History,v 1.446 2010/12/02 12:21:22 vnivanch Exp $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,143 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
2 December 10: V.Ivant (emutils-V09-03-30)
- G4EmCorrections - fixed minor memory leak at initialisation
23 November 10: V.Ivant (emutils-V09-03-29)
- G4EmProcessOptions, G4EnergyLossMessenger - added forgotten option
22 November 10: V.Ivant (emutils-V09-03-28)
- G4VAtomDeexcitation - added lowestKinEnergy (fixed FPE report)
21 November 10: V.Ivant (emutils-V09-03-27)
- G4VAtomDeexcitation, G4EmProcessOptions - fixed initialisation
- G4EmCalculator - improved cross section calculation
18 November 10: V.Ivant (emutils-V09-03-26)
- G4VAtomDeexcitation, G4VEnergyLossProcess improved printout at
initialisation
16 November 10: V.Ivant (emutils-V09-03-25)
- G4EmCorrections - used G4PhysicsVector for approximation of the
Barkas correction; cleanup comments
13 November 10: V.Ivant (emutils-V09-03-24)
- G4EmCorrections - fixed computation of shell corrections according
to prescriptions of original papers; added Bichsel approximation
for Barkas corrections for the large Z > 47
04 November 10: V.Ivant (emutils-V09-03-23)
- Fixed part of problems reported by the Coverity tool
(mainly initialisation)
25 October 10: V.Ivant (emutils-V09-03-22)
- Fixed problems reported by the Coverity tool (mainly initialisation)
15 October 10: V.Ivant (emutils-V09-03-21)
- G4VEmAngularDistribution - new general interface
- G4VBremAngularDistribution moved from lowenergy
- G4VEmModel - G4VEmAngularDistribution added and Get/Set methods
- G4VEnergyLossProcess - fixed bug #1141 (L.Pandola)
07 September 10: V.Ivant (emutils-V09-03-20)
- G4VMscModel - in computation of the displacement added
a protection limited displacement to be incide current
volume (address bug #1128)
- G4LossTableManager - a little cleanup of interfaces
- G4ElectronIonPair - added method SampleNumberOfIonsAlongStep
- G4EmCalculator - return back tag 18
23 August 10: V.Ivant (emutils-V09-03-19)
G4VEnergyLossProcess - minor optimisation of PostStepDoIt (in some cases
one call to the log of random number less)
17 August 10: V.Ivant (emutils-V09-03-18)
G4VEmProcess, G4VEnergyLossProcess, G4VMultipleScattering, G4VEmModel,
G4EmMultiModel - substituted obsolete method GetDefinition() of the class
G4DynamicParticle by the new one GetParticleDefinition()
29 July 10: V.Ivant (emutils-V09-03-17)
G4EmMultiModel - fixed and cleaned up
G4VMultipleScattering - added more detailed printout for kaon+
G4LossTableManager - added pointer and access method to G4ElectronIonPair
4 June 10: V.Ivant (emutils-V09-03-16)
Previous tag was set from wrong directory
4 June 10: V.Ivant (emutils-V09-03-15)
G4EmConfigurator - fixed case of more than one model is added per a process
4 June 10: V.Ivant (emutils-V09-03-14)
G4EmCorrections - moved G4AtomicShell header into source
26 May 10: V.Ivant (emutils-V09-03-13)
G4VEmModel - added method ChargeSquareRatio to access current charge of an ion
G4VEnergyLossProcess - use this new method
10 May 10: V.Ivant (emutils-V09-03-12)
G4VEmProcess - cleanup printout at initialisation for scattering process
28 April 10: V.Ivant (emutils-V09-03-11)
G4VEmProcess, G4VEnergyLossProcess, G4VEmModel - provided GetCurrentElement method
(addressed bug report #1115 and HyperNews request)
27 April 10: V.Ivant (emutils-V09-03-10)
G4LossTableManager - added class member and a method GetNumberOfBinsPerDecade
G4VEmModel - use GetNumberOfBinsPerDecade and spline flag to initialise
G4EmElementSelector (addressed bug report #1115)
G4EmElementSelector - use spline flag to construct vectors probabilities
G4EmProcessOptions - removed double implementation of initialisation code,
which already exist in G4LossTableManager
G4VEnergyLossProcess - call CorrectionsAlongStep only for ions (minor CPU saving)
23 April 10: V.Ivant (emutils-V09-03-09)
G4VEnergyLossProcess - removed unused variable
12 April 10: V.Ivant (emutils-V09-03-08)
G4EmModelManager - do not use min energy cut defined by models allowing
decreasing of cuts in limit to zero
G4EmCalculator - fixed GetCrossSection method
12 April 10: V.Ivant (emutils-V09-03-07)
G4LossTableManager - added methods PreparePhsyicsTables, BuildPhysicsTables,
and changed initialisation of models via G4EmConfigurator
G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering - added
calls of new G4LossTableManager methods
PreparePhsyicsTables, BuildPhysicsTables
G4EmConfigarator - upgraded and fixed old problem
06 April 10: V.Ivant (emutils-V09-03-06)
G4VEnergyLossProcess - use the same method to build cross section table
as DEDX table (use copy constructors to reduce
number of calls to std::exp)
G4EmModelManager - cleanup comments
22 March 10: V.Ivant (emutils-V09-03-05)
G4EmCorrections - added protection against large Barkas and Bloch
corrections in the case of large negatively charged
particle (100*e-) - fixed problem reported by ATLAS
G4EmCalculator - cleanup
10 March 10: V.Ivant (emutils-V09-03-04)
G4VEmModel, G4VEmProcess, G4VEnergyLossProcess, G4VMultipleScattering,
G4LossTableManager - reorder inline methods and add comments
05 March 10: V.Ivant (emutils-V09-03-03)
G4VMscModel, G4VMultipleScattering - set skin=1.0 as a default
24 February 10: V.Ivant (emutils-V09-03-02)
G4VEmProcess - move SetBuildTableFlag method from protected to public
17 February 10: V.Ivant (emutils-V09-03-01)
G4VEmProcess - fixed problem for ion processes by adding pointer to
currentParticle which may be different from GenericIon
22 January 10: V.Ivant (emutils-V09-03-00)
G4VEmProcess - added protection against negative cross section
G4VEnergyLossProcess - added protection against negative cross section;
- improved logic in RetrieveTable method
23 November 09: V.Ivant (emutils-V09-02-24)
G4EmConfigurator - fixed bug in selection of models
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ElectronIonPair.hh,v 1.2 2008/10/17 14:46:16 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4ElectronIonPair.hh,v 1.5 2010/10/25 17:23:01 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
#ifndef G4ElectronIonPair_h
@@ -61,7 +61,6 @@
#include "G4Step.hh"
#include "G4ParticleDefinition.hh"
#include "G4ThreeVector.hh"
#include "G4TrackVector.hh"
#include "G4VProcess.hh"
#include <vector>
@@ -85,13 +84,10 @@ public:
inline G4double MeanNumberOfIonsAlongStep(const G4Step*);
inline G4int SampleNumberOfIonsAlongStep(const G4Step*);
// returns pointer to the new vector of positions of
// ionisation points in the World coordinate system
std::vector<G4ThreeVector>*
SampleIonsAlongStep(const G4ThreeVector& prePosition,
const G4ThreeVector& postPosition,
G4double numberOfIonisations);
std::vector<G4ThreeVector>* SampleIonsAlongStep(const G4Step*);
// compute number of holes in the atom after PostStep interaction
@@ -114,53 +110,53 @@ public:
private:
void Initialise();
G4double FindMeanEnergyPerIonPair(const G4Material*);
// hide assignment operator
G4ElectronIonPair & operator=(const G4ElectronIonPair &right);
G4ElectronIonPair(const G4ElectronIonPair&);
G4double FindMeanEnergyPerIonPair(const G4Material*);
void Initialise();
const G4ParticleDefinition* gamma;
// cash
const G4Material* curMaterial;
G4double curMeanEnergy;
const G4Material* curMaterial;
G4double curMeanEnergy;
G4double FanoFactor;
G4int verbose;
G4int nMaterials;
// list of G4 NIST materials with mean energy per ion defined
std::vector<G4double> g4MatData;
std::vector<G4String> g4MatNames;
std::vector<G4double> g4MatData;
std::vector<G4String> g4MatNames;
};
inline G4double
G4ElectronIonPair::MeanNumberOfIonsAlongStep(const G4Step* step)
{
return MeanNumberOfIonsAlongStep(step->GetTrack()->GetDefinition(),
return MeanNumberOfIonsAlongStep(step->GetTrack()->GetParticleDefinition(),
step->GetPreStepPoint()->GetMaterial(),
step->GetTotalEnergyDeposit(),
step->GetNonIonizingEnergyDeposit());
}
inline std::vector<G4ThreeVector>*
G4ElectronIonPair::SampleIonsAlongStep(const G4Step* step)
inline
G4int G4ElectronIonPair::SampleNumberOfIonsAlongStep(const G4Step* step)
{
return SampleIonsAlongStep(step->GetPreStepPoint()->GetPosition(),
step->GetPostStepPoint()->GetPosition(),
MeanNumberOfIonsAlongStep(step));
}
G4double meanion = MeanNumberOfIonsAlongStep(step);
G4double sig = FanoFactor*std::sqrt(meanion);
G4int nion = G4int(G4RandGauss::shoot(meanion,sig) + 0.5);
return nion;
}
inline
G4int G4ElectronIonPair::ResidualeChargePostStep(const G4Step* step)
{
G4int subtype = -1;
const G4VProcess* proc = step->GetPostStepPoint()->GetProcessDefinedStep();
if(proc) subtype = proc->GetProcessSubType();
return ResidualeChargePostStep(step->GetTrack()->GetDefinition(),
if(proc) { subtype = proc->GetProcessSubType(); }
return ResidualeChargePostStep(step->GetTrack()->GetParticleDefinition(),
step->GetSecondary(),
subtype);
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCalculator.hh,v 1.19 2009/11/11 23:59:48 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmCalculator.hh,v 1.21 2010/11/21 16:45:11 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// -------------------------------------------------------------------
@@ -60,6 +60,7 @@
#include "globals.hh"
#include "G4DataVector.hh"
#include "G4DynamicParticle.hh"
#include "G4VAtomDeexcitation.hh"
class G4LossTableManager;
class G4Material;
@@ -126,6 +127,11 @@ public:
G4double kinEnergy, const G4String& part, const G4String& proc,
const G4String& mat, const G4String& s = "world");
G4double GetShellIonisationCrossSectionPerAtom(
const G4String& part, G4int Z,
G4AtomicShellEnumerator shell,
G4double kinEnergy);
G4double GetMeanFreePath(G4double kinEnergy, const G4ParticleDefinition*,
const G4String& processName, const G4Material*,
const G4Region* r = 0);
@@ -181,6 +187,11 @@ public:
const G4String& processName, const G4Element*,
G4double cut = 0.0);
G4double ComputeShellIonisationCrossSectionPerAtom(
const G4String& part, G4int Z,
G4AtomicShellEnumerator shell,
G4double kinEnergy);
G4double ComputeMeanFreePath(
G4double kinEnergy, const G4ParticleDefinition*,
const G4String& processName, const G4Material*,
@@ -248,6 +259,7 @@ private:
const G4MaterialCutsCouple* currentCouple;
const G4Material* currentMaterial;
const G4ParticleDefinition* currentParticle;
const G4ParticleDefinition* lambdaParticle;
const G4ParticleDefinition* baseParticle;
const G4PhysicsTable* currentLambda;
G4VEmModel* currentModel;
@@ -259,6 +271,7 @@ private:
G4DynamicParticle dynParticle;
G4String currentName;
G4String lambdaName;
G4double currentCut;
G4double chargeSquare;
G4double massRatio;
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmConfigurator.hh,v 1.2 2008/11/21 12:30:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4EmConfigurator.hh,v 1.3 2010/04/12 11:44:40 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04-beta-01 $
//
// -------------------------------------------------------------------
//
@@ -57,35 +57,21 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4VEnergyLossProcess;
class G4VEmProcess;
class G4VMultipleScattering;
class G4EmConfigurator
{
public:
G4EmConfigurator();
G4EmConfigurator(G4int verboseLevel = 1);
~G4EmConfigurator();
// Add EM model to the list of extra models potentially to be
// declared for the G4Region and energy interval
//
void AddExtraEmModel(const G4String& particleName,
G4VEmModel*, G4VEmFluctuationModel* fm = 0);
// Declare EM model for particle type and process to
// be active for the G4Region and energy interval
// The model should be previously added to the configurator
// or be "dummy"
//
void AddModelForRegion(const G4String& particleName,
const G4String& processName,
const G4String& modelName,
const G4String& regionName = "",
G4double emin = 0.0,
G4double emax = DBL_MAX,
const G4String& flucModelName = "");
// Set EM model for particle type and process to
// be active for the G4Region and energy interval
// The model will be added to the list
//
void SetExtraEmModel(const G4String& particleName,
const G4String& processName,
@@ -96,39 +82,63 @@ public:
G4VEmFluctuationModel* fm = 0);
// Add all previously declared models to corresponding processes
// Can be called in ConstructPhysics
//
void AddModels();
// These methods called by G4LossTableManager
//
void PrepareModels(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void PrepareModels(const G4ParticleDefinition* aParticle,
G4VEmProcess* p);
void PrepareModels(const G4ParticleDefinition* aParticle,
G4VMultipleScattering* p);
void Clear();
inline void SetVerbose(G4int value);
private:
void SetModelForRegion(const G4String& particleName,
G4Region* FindRegion(const G4String&);
void SetModelForRegion(G4VEmModel* model,
G4VEmFluctuationModel* fm,
G4Region* reg,
const G4String& particleName,
const G4String& processName,
const G4String& modelName,
const G4String& regionName,
const G4String& flucModelName,
G4double emin,
G4double emax);
G4bool UpdateModelEnergyRange(G4VEmModel* mod,
G4double emin, G4double emax);
// hide assignment operator
G4EmConfigurator & operator=(const G4EmConfigurator &right);
G4EmConfigurator(const G4EmConfigurator&);
std::vector<G4VEmModel*> models;
std::vector<G4VEmFluctuationModel*> flucModels;
std::vector<G4String> particles;
std::vector<G4String> processes;
std::vector<G4String> models;
std::vector<G4String> regions;
std::vector<G4String> flucModels;
std::vector<G4double> lowEnergy;
std::vector<G4double> highEnergy;
std::vector<G4String> particleList;
std::vector<G4VEmModel*> modelList;
std::vector<G4VEmFluctuationModel*> flucModelList;
G4int index;
G4int verbose;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4EmConfigurator::SetVerbose(G4int value)
{
verbose = value;
}
#endif
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCorrections.hh,v 1.24 2008/09/12 14:44:48 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4EmCorrections.hh,v 1.27 2010/11/15 19:18:34 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -55,7 +55,6 @@
#define G4EmCorrections_h 1
#include "globals.hh"
#include "G4AtomicShells.hh"
#include "G4ionEffectiveCharge.hh"
#include "G4Material.hh"
#include "G4ParticleDefinition.hh"
@@ -65,6 +64,7 @@ class G4VEmModel;
class G4PhysicsVector;
class G4IonTable;
class G4MaterialCutsCouple;
class G4LPhysicsFreeVector;
class G4EmCorrections
{
@@ -191,8 +191,6 @@ private:
G4EmCorrections & operator=(const G4EmCorrections &right);
G4EmCorrections(const G4EmCorrections&);
G4double engBarkas[47];
G4double corBarkas[47];
G4double ed[104];
G4double a[104];
G4double theZieglerFactor;
@@ -228,10 +226,12 @@ private:
G4double CL[26][28];
G4double HM[53];
G4double HN[31];
G4double MSH[93];
G4double TAU[93];
G4double Z23[100];
G4LPhysicsFreeVector* BarkasCorr;
G4LPhysicsFreeVector* ThetaK;
G4LPhysicsFreeVector* ThetaL;
std::vector<const G4Material*> currmat;
std::vector<G4double> thcorr[100];
size_t ncouples;
@@ -262,7 +262,6 @@ private:
G4double eCorrMax;
G4int nbinCorr;
G4AtomicShells shells;
G4ionEffectiveCharge effCharge;
G4NistManager* nist;
@@ -355,11 +354,13 @@ inline void G4EmCorrections::SetupKinematics(const G4ParticleDefinition* p,
G4double ratio = electron_mass_c2/mass;
tmax = 2.0*electron_mass_c2*bg2 /(1. + 2.0*gamma*ratio + ratio*ratio);
charge = p->GetPDGCharge()/eplus;
if(charge < 1.5) {q2 = charge*charge;}
else {
q2 = effCharge.EffectiveChargeSquareRatio(p,mat,kinEnergy);
charge = std::sqrt(q2);
}
//if(charge < 1.5) {q2 = charge*charge;}
//else {
// q2 = effCharge.EffectiveChargeSquareRatio(p,mat,kinEnergy);
// charge = std::sqrt(q2);
//}
if(charge > 1.5) { charge = effCharge.EffectiveCharge(p,mat,kinEnergy); }
q2 = charge*charge;
}
if(mat != material) {
material = mat;
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmMultiModel.hh,v 1.6 2007/05/22 17:31:57 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4EmMultiModel.hh,v 1.7 2010/07/04 17:51:09 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -39,10 +39,11 @@
//
// Modifications:
// 15-04-05 optimize internal interface (V.Ivanchenko)
// 04-07-10 updated interfaces according to g4 9.4 (V.Ivanchenko)
//
// Class Description:
//
// Energy loss model using several G4VEmModels
// EM model using several G4VEmModels for the same energy interval
// -------------------------------------------------------------------
//
@@ -54,8 +55,6 @@
#include "G4VEmModel.hh"
#include <vector>
class G4Region;
class G4PhysicsTable;
class G4DynamicParticle;
class G4EmMultiModel : public G4VEmModel
@@ -67,37 +66,30 @@ public:
virtual ~G4EmMultiModel();
void Initialise(const G4ParticleDefinition*, const G4DataVector&);
void AddModel(G4VEmModel*);
G4double MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*);
virtual void Initialise(const G4ParticleDefinition*,
const G4DataVector&);
virtual G4double ComputeDEDX(const G4MaterialCutsCouple*,
const G4ParticleDefinition*,
G4double kineticEnergy,
G4double cutEnergy);
G4double ComputeDEDX(const G4MaterialCutsCouple*,
const G4ParticleDefinition*,
G4double kineticEnergy,
G4double cutEnergy);
// main method to compute cross section per atom
virtual
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
G4double kinEnergy,
G4double Z,
G4double A = 0., /* amu */
G4double cutEnergy = 0.0,
G4double maxEnergy = DBL_MAX);
G4double CrossSection(const G4MaterialCutsCouple*,
const G4ParticleDefinition*,
G4double kineticEnergy,
G4double cutEnergy,
G4double maxEnergy);
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double tmax);
void DefineForRegion(const G4Region*);
void AddModel(G4VEmModel*, G4double tmin, G4double tmax);
protected:
G4double MaxSecondaryEnergy(const G4ParticleDefinition*,
G4double kineticEnergy);
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double tmax);
private:
@@ -107,8 +99,7 @@ private:
G4int nModels;
std::vector<G4VEmModel*> model;
G4DataVector tsecmin;
G4DataVector cross_section;
std::vector<G4double> cross_section;
};
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmProcessOptions.hh,v 1.16 2009/10/29 19:25:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmProcessOptions.hh,v 1.19 2010/11/23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// -------------------------------------------------------------------
@@ -106,9 +106,23 @@ public:
void SetLinearLossLimit(G4double val);
// obsolete will be removed
void ActivateDeexcitation(const G4String& proc, G4bool val,
const G4String& reg = "");
void SetDeexcitationActive(G4bool val);
void SetDeexcitationActiveRegion(const G4String& rname = "",
G4bool valDeexcitation = true,
G4bool valAuger = true,
G4bool valPIXE = true);
void SetAugerActive(G4bool val);
void SetPIXEActive(G4bool val);
void SetPIXECrossSectionModel(const G4String& val);
void SetMscStepLimitation(G4MscStepLimitType val);
void SetMscLateralDisplacement(G4bool val);
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmSaturation.hh,v 1.7 2009/09/25 09:16:40 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmSaturation.hh,v 1.8 2010/08/17 17:36:58 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
#ifndef G4EmSaturation_h
@@ -139,7 +139,7 @@ inline G4double G4EmSaturation::VisibleEnergyDeposition(
const G4Step* step)
{
G4Track* track = step->GetTrack();
return VisibleEnergyDeposition(track->GetDefinition(),
return VisibleEnergyDeposition(track->GetParticleDefinition(),
track->GetMaterialCutsCouple(),
step->GetStepLength(),
step->GetTotalEnergyDeposit(),
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4EnergyLossMessenger.hh,v 1.24 2009/10/29 19:25:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EnergyLossMessenger.hh,v 1.26 2010/11/23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -116,6 +116,10 @@ private:
G4UIcmdWithABool* latCmd;
G4UIcmdWithABool* splCmd;
G4UIcmdWithABool* aplCmd;
G4UIcmdWithABool* deCmd;
G4UIcmdWithABool* auCmd;
G4UIcmdWithABool* pixeCmd;
G4UIcmdWithAString* pixeXsCmd;
G4UIcmdWithAnInteger* verCmd;
G4UIcmdWithAnInteger* ver1Cmd;
G4UIcmdWithAnInteger* dedxCmd;
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LossTableManager.hh,v 1.55 2009/10/29 19:25:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4LossTableManager.hh,v 1.61 2010/09/03 10:09:45 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
//
// -------------------------------------------------------------------
@@ -60,6 +60,7 @@
// 22-05-06 Add methods Set/Get bremsTh (VI)
// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
// 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
// 12-04-10 Added PreparePhsyicsTables and BuildPhysicsTables entries (V.Ivanchenko)
//
// Class Description:
//
@@ -91,7 +92,10 @@ class G4VEmProcess;
class G4EmCorrections;
class G4EmSaturation;
class G4EmConfigurator;
class G4ElectronIonPair;
class G4LossTableBuilder;
class G4VAtomDeexcitation;
class G4Region;
class G4LossTableManager
{
@@ -102,9 +106,31 @@ public:
~G4LossTableManager();
//-------------------------------------------------
// called from destructor
//-------------------------------------------------
void Clear();
// get the DEDX or the range for a given particle/energy/material
//-------------------------------------------------
// initialisation before a new run
//-------------------------------------------------
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);
//-------------------------------------------------
// Run time access to DEDX, range, energy for a given particle,
// energy, and G4MaterialCutsCouple
//-------------------------------------------------
inline G4double GetDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
@@ -140,7 +166,10 @@ public:
const G4DynamicParticle* dp,
G4double& length);
// to be called only by energy loss processes
//-------------------------------------------------
// Methods to be called only at initialisation
//-------------------------------------------------
void Register(G4VEnergyLossProcess* p);
void DeRegister(G4VEnergyLossProcess* p);
@@ -161,21 +190,15 @@ public:
void DeRegister(G4VEmFluctuationModel* p);
void EnergyLossProcessIsInitialised(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void RegisterIon(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void RegisterExtraParticle(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void BuildPhysicsTable(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void SetLossFluctuations(G4bool val);
void SetSubCutoff(G4bool val);
void SetSubCutoff(G4bool val, const G4Region* r=0);
void SetIntegral(G4bool val);
@@ -197,6 +220,8 @@ public:
void SetLambdaBinning(G4int val);
G4int GetNumberOfBinsPerDecade() const;
void SetStepFunction(G4double v1, G4double v2);
void SetBuildCSDARange(G4bool val);
@@ -213,6 +238,10 @@ public:
void SetVerbose(G4int val);
//-------------------------------------------------
// Access methods
//-------------------------------------------------
G4EnergyLossMessenger* GetMessenger();
G4bool BuildCSDARange() const;
@@ -231,7 +260,8 @@ public:
const std::vector<G4VMultipleScattering*>& GetMultipleScatteringVector();
inline G4VEnergyLossProcess* GetEnergyLossProcess(const G4ParticleDefinition*);
inline
G4VEnergyLossProcess* GetEnergyLossProcess(const G4ParticleDefinition*);
G4EmCorrections* EmCorrections();
@@ -239,8 +269,18 @@ public:
G4EmConfigurator* EmConfigurator();
G4ElectronIonPair* ElectronIonPair();
G4VAtomDeexcitation* AtomDeexcitation();
void SetAtomDeexcitation(G4VAtomDeexcitation*);
private:
//-------------------------------------------------
// Private methods and members
//-------------------------------------------------
G4LossTableManager();
G4VEnergyLossProcess* BuildTables(const G4ParticleDefinition* aParticle);
@@ -250,15 +290,15 @@ private:
void ParticleHaveNoLoss(const G4ParticleDefinition* aParticle);
void SetParameters(G4VEnergyLossProcess*);
void SetParameters(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess*);
void CopyDEDXTables();
private:
static G4LossTableManager* theInstance;
typedef const G4ParticleDefinition* PD;
std::map<PD,G4VEnergyLossProcess*,std::less<PD> > loss_map;
std::vector<G4VEnergyLossProcess*> loss_vector;
@@ -278,18 +318,19 @@ private:
G4VEnergyLossProcess* currentLoss;
PD currentParticle;
PD theElectron;
PD firstParticle;
G4int n_loss;
G4int run;
G4bool all_tables_are_built;
// G4bool first_entry;
G4bool startInitialisation;
G4bool lossFluctuationFlag;
G4bool subCutoffFlag;
G4bool rndmStepFlag;
G4bool integral;
G4bool integralActive;
G4bool all_tables_are_stored;
G4bool buildCSDARange;
G4bool minEnergyActive;
G4bool maxEnergyActive;
@@ -312,8 +353,11 @@ private:
G4EmCorrections* emCorrections;
G4EmSaturation* emSaturation;
G4EmConfigurator* emConfigurator;
G4ElectronIonPair* emElectronIonPair;
G4VAtomDeexcitation* atomDeexcitation;
const G4ParticleDefinition* firstParticle;
G4int nbinsLambda;
G4int nbinsPerDecade;
G4int verbose;
};
@@ -321,112 +365,6 @@ private:
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline G4double G4LossTableManager::GetDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) GetEnergyLossProcess(aParticle);
G4double x;
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->GetDefinition();
if(aParticle != currentParticle) {
std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
currentParticle = aParticle;
currentLoss = (*pos).second;
} else {
ParticleHaveNoLoss(aParticle);
}
}
return currentLoss->GetDEDXDispersion(couple, dp, length);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4VEnergyLossProcess* G4LossTableManager::GetEnergyLossProcess(
const G4ParticleDefinition *aParticle)
{
@@ -445,5 +383,111 @@ inline G4VEnergyLossProcess* G4LossTableManager::GetEnergyLossProcess(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4LossTableManager::GetDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
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) {
std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
currentParticle = aParticle;
currentLoss = (*pos).second;
} else {
ParticleHaveNoLoss(aParticle);
}
}
return currentLoss->GetDEDXDispersion(couple, dp, length);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VAtomDeexcitation.hh,v 1.1 2009/07/09 11:42:52 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VAtomDeexcitation.hh,v 1.8 2010/11/22 18:18:08 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -50,69 +50,124 @@
#define G4VAtomDeexcitation_h 1
#include "globals.hh"
#include "G4AtomicShell.hh"
#include "G4ProductionCutsTable.hh"
#include "G4Track.hh"
#include <vector>
class G4AtomicShell;
class G4ParticleDefinition;
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4VParticleChange;
enum G4AtomicShellEnumerator
{
fKShell = 0,
fL1Shell,
fL2Shell,
fL3Shell,
fM1Shell,
fM2Shell,
fM3Shell,
fM4Shell,
fM5Shell
};
class G4VAtomDeexcitation {
public:
G4VAtomDeexcitation(const G4String& pname = "");
G4VAtomDeexcitation(const G4String& modname = "Deexcitation",
const G4String& pixename = "");
virtual ~G4VAtomDeexcitation();
//initialization
virtual void PreparePhysicsTable(const G4ParticleDefinition&);
virtual void BuildPhysicsTable(const G4ParticleDefinition&);
//========== initialization ==========
// Get atomic shell by shell index, used by discrete processes
// (for example, photoelectric), when shell vacancy sampled by the model
virtual const G4AtomicChell* GetAtomicShell(G4int Z, G4int ShellIndex);
// Overall initialisation before new run
void InitialiseAtomicDeexcitation();
// selection of random shell for ionisation process
virtual const G4AtomicShell* SelectRandomShell(const G4DynamicParticle*,
G4int Z);
// Initialisation of deexcitation at the beginning of run
virtual void InitialiseForNewRun() = 0;
// generation of deexcitation for given atom and shell vacancy
virtual void GenerateParticles(std::vector<G4DynamicParticle*>*,
const G4AtomicChell*, G4int Z);
// Initialisation for a concrete atom
// May be called at run time
virtual void InitialiseForExtraAtom(G4int Z) = 0;
// access or compute PIXE cross section
virtual G4double GetPIXECrossSection (const G4ParticleDefinition*,
G4int Z, G4double kinE);
// Activation of deexcitation
inline void SetActive(G4bool);
// calculate PIXE cross section from the models
virtual G4double CalculatePIXECrossSection(const G4ParticleDefinition*,
G4int Z, G4double kinE);
// Activation of deexcitation per detector region
void SetDeexcitationActiveRegion(const G4String& rname = "",
G4bool valDeexcitation = true,
G4bool valAuger = false,
G4bool valPIXE = true);
// Sampling of PIXE for ionisation processes
virtual void
AlongStepDeexcitation(std::vector<G4DynamicParticle*>* secVect,
const G4DynamicParticle* icidentParticle,
const G4MaterialCutsCouple*,
G4double trueStepLenght,
G4double eLoss);
// Activation of Auger electron production
inline void SetAugerActive(G4bool);
inline G4bool IsAugerActive() const;
// Check if deexcitation is active for a given geometry volume
G4bool CheckActiveRegion(G4int coupleIndex);
// Activation of PIXE simulation
inline void SetPIXEActive(G4bool);
inline G4bool IsPIXEActive() const;
// Access flags defined in the CheckActiveVolume method
inline G4bool IsFluorescenceActive() const;
inline G4bool IsPIXECrossSectionActive() const;
// Deexcitation model name
inline const G4String& GetName() const;
// PIXE model name
inline void SetPIXECrossSectionModel(const G4String&);
inline const G4String& PIXECrossSectionModel() const;
// Activation of deexcitation per detector region
void SetFluorescenceActiveRegion(const G4Region* region = 0);
void SetAugerActiveRegion(const G4Region* region = 0);
void SetPIXECrossSectionActiveRegion(const G4Region* region = 0);
// Access to the list of atoms active for deexcitation
inline const std::vector<G4bool>& GetListOfActiveAtoms() const;
void SetFluorescenceActiveRegion(const G4String& rname = "");
void SetAugerActiveRegion(const G4String& rname = "");
void SetPIXECrossSectionActiveRegion(const G4String& rname = "");
// Verbosity level
inline void SetVerboseLevel(G4int);
inline G4int GetVerboseLevel() const;
//========== Run time methods ==========
// Check if deexcitation is active for a given geometry volume
inline G4bool CheckDeexcitationActiveRegion(G4int coupleIndex);
inline G4bool CheckAugerActiveRegion(G4int coupleIndex);
// Get atomic shell by shell index, used by discrete processes
// (for example, photoelectric), when shell vacancy sampled by the model
virtual
const G4AtomicShell* GetAtomicShell(G4int Z,
G4AtomicShellEnumerator shell) = 0;
// generation of deexcitation for given atom and shell vacancy
inline void GenerateParticles(std::vector<G4DynamicParticle*>* secVect,
const G4AtomicShell*,
G4int Z,
G4int coupleIndex);
// generation of deexcitation for given atom and shell vacancy
virtual void GenerateParticles(std::vector<G4DynamicParticle*>* secVect,
const G4AtomicShell*,
G4int Z,
G4double gammaCut,
G4double eCut) = 0;
// access or compute PIXE cross section
virtual G4double
GetShellIonisationCrossSectionPerAtom(const G4ParticleDefinition*,
G4int Z,
G4AtomicShellEnumerator shell,
G4double kinE) = 0;
// access or compute PIXE cross section
virtual G4double
ComputeShellIonisationCrossSectionPerAtom(const G4ParticleDefinition*,
G4int Z,
G4AtomicShellEnumerator shell,
G4double kinE) = 0;
// Sampling of PIXE for ionisation processes
void AlongStepDeexcitation(G4VParticleChange* pParticleChange,
const G4Step& step,
G4double& eLoss,
G4int coupleIndex);
private:
@@ -120,20 +175,54 @@ private:
G4VAtomDeexcitation(G4VAtomDeexcitation &);
G4VAtomDeexcitation & operator=(const G4VAtomDeexcitation &right);
G4ProductionCutsTable* theCoupleTable;
G4double lowestKinEnergy;
G4int verbose;
G4String name;
G4String namePIXE;
G4bool isFluoActive;
G4bool isPIXEActive;
G4bool isActive;
G4bool flagAuger;
G4bool flagPIXE;
std::vector<G4bool> activeZ;
std::vector<G4bool> activeDeexcitationMedia;
std::vector<G4bool> activeAugerMedia;
std::vector<G4bool> activePIXEMedia;
std::vector<G4String> activeRegions;
std::vector<G4bool> deRegions;
std::vector<G4bool> AugerRegions;
std::vector<G4bool> PIXERegions;
std::vector<G4DynamicParticle*> vdyn;
std::vector<G4Track*> secVect;
};
inline G4bool IsFluorescenceActive() const
inline void G4VAtomDeexcitation::SetActive(G4bool val)
{
return isFluoActive;
isActive = val;
}
inline G4bool IsPIXECrossSectionActive() const
inline void G4VAtomDeexcitation::SetAugerActive(G4bool val)
{
return isPIXEActive;
flagAuger = val;
}
inline G4bool G4VAtomDeexcitation::IsAugerActive() const
{
return (flagAuger && isActive);
}
inline void G4VAtomDeexcitation::SetPIXEActive(G4bool val)
{
flagPIXE = val;
}
inline G4bool G4VAtomDeexcitation::IsPIXEActive() const
{
return (flagPIXE && isActive);
}
inline const G4String& G4VAtomDeexcitation::GetName() const
{
return name;
}
inline
@@ -148,5 +237,51 @@ const G4String& G4VAtomDeexcitation::PIXECrossSectionModel() const
return namePIXE;
}
inline const std::vector<G4bool>&
G4VAtomDeexcitation::GetListOfActiveAtoms() const
{
return activeZ;
}
inline void G4VAtomDeexcitation::SetVerboseLevel(G4int val)
{
verbose = val;
}
inline G4int G4VAtomDeexcitation::GetVerboseLevel() const
{
return verbose;
}
inline G4bool
G4VAtomDeexcitation::CheckDeexcitationActiveRegion(G4int coupleIndex)
{
return (isActive && activeDeexcitationMedia[coupleIndex]);
}
inline G4bool
G4VAtomDeexcitation::CheckAugerActiveRegion(G4int coupleIndex)
{
return (flagAuger && activeAugerMedia[coupleIndex]);
}
inline void
G4VAtomDeexcitation::GenerateParticles(std::vector<G4DynamicParticle*>* v,
const G4AtomicShell* as,
G4int Z,
G4int idx)
{
if(CheckDeexcitationActiveRegion(idx)) {
G4double gCut = (*(theCoupleTable->GetEnergyCutsVector(0)))[idx];
if(gCut < as->BindingEnergy()) {
G4double eCut = DBL_MAX;
if(flagAuger && CheckAugerActiveRegion(idx)) {
eCut = (*(theCoupleTable->GetEnergyCutsVector(1)))[idx];
}
GenerateParticles(v, as, Z, gCut, eCut);
}
}
}
#endif
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * 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: geant4-09-04 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VBremAngularDistribution
//
// Author: Pedro Rodrigues (psilva@lip.pt)
// Andreia Trindade (andreia@lip.pt)
// Luis Peralta (luis@lip.pt)
// Design from Maria Grazia Pia (MariaGrazia.Pia@ge.infn.it)
//
//
// Creation date: 21 March 2003
//
// Modifications:
// 21 Mar 2003 A.Trindade First implementation acording with new design
// 13 Oct 2010 V.Ivanchenko Moved to utils
//
// Class Description:
//
// Abstract class for Bremsstrahlung Angular Distribution Generation
// -------------------------------------------------------------------
//
#ifndef G4VBremAngularDistribution_h
#define G4VBremAngularDistribution_h 1
#include "globals.hh"
#include "G4VEmAngularDistribution.hh"
class G4VBremAngularDistribution : public G4VEmAngularDistribution
{
public:
G4VBremAngularDistribution(const G4String& name);
virtual ~G4VBremAngularDistribution();
virtual G4double PolarAngle(const G4double initial_energy,
const G4double final_energy,
const G4int Z) = 0;
virtual void PrintGeneratorInformation() const;
private:
// hide assignment operator
G4VBremAngularDistribution & operator=(const G4VBremAngularDistribution &right);
G4VBremAngularDistribution(const G4VBremAngularDistribution&);
};
#endif
@@ -0,0 +1,86 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * 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: geant4-09-04 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
// File name: G4VEmAngularDistribution
//
// Author: V. Ivanchenko using design of existing
// interface G4VBremAngularDistribution
//
// Creation date: 13 October 2010
//
// Modifications:
//
// Class Description:
//
// Abstract base class for polar angle sampling
//
// Class Description: End
// -------------------------------------------------------------------
//
#ifndef G4VEmAngularDistribution_h
#define G4VEmAngularDistribution_h 1
#include "globals.hh"
class G4VEmAngularDistribution
{
public:
G4VEmAngularDistribution(const G4String& name);
virtual ~G4VEmAngularDistribution();
// method for bremsstrahlung
virtual G4double PolarAngle(const G4double initial_energy,
const G4double final_energy,
const G4int Z) = 0;
inline const G4String& GetName() const;
private:
// hide assignment operator
G4VEmAngularDistribution & operator=(const G4VEmAngularDistribution &right);
G4VEmAngularDistribution(const G4VEmAngularDistribution&);
G4String fName;
};
inline const G4String& G4VEmAngularDistribution::GetName() const
{
return fName;
}
#endif
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmModel.hh,v 1.72 2009/09/23 14:42:47 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VEmModel.hh,v 1.77 2010/10/14 16:27:35 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -66,6 +66,7 @@
// CorrectionsAlongStep, ActivateNuclearStopping (VI)
// 16-02-09 Moved implementations of virtual methods to source (VI)
// 07-04-09 Moved msc methods from G4VEmModel to G4VMscModel (VI)
// 13-10-10 Added G4VEmAngularDistribution (VI)
//
// Class Description:
//
@@ -86,6 +87,7 @@
#include "G4ElementVector.hh"
#include "G4DataVector.hh"
#include "G4VEmFluctuationModel.hh"
#include "G4VEmAngularDistribution.hh"
#include "G4EmElementSelector.hh"
#include "Randomize.hh"
#include <vector>
@@ -145,9 +147,13 @@ public:
G4double maxEnergy = DBL_MAX);
// min cut in kinetic energy allowed by the model
// obsolete method will be removed
virtual G4double MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*);
// Compute effective ion charge square
virtual G4double ChargeSquareRatio(const G4Track&);
// Compute effective ion charge square
virtual G4double GetChargeSquareRatio(const G4ParticleDefinition*,
const G4Material*,
@@ -227,6 +233,9 @@ public:
G4double cutEnergy = 0.0,
G4double maxEnergy = DBL_MAX);
// select isotope in order to have precise mass of the nucleus
inline G4int SelectIsotopeNumber(const G4Element*);
// atom can be selected effitiantly if element selectors are initialised
inline const G4Element* SelectRandomAtom(const G4MaterialCutsCouple*,
const G4ParticleDefinition*,
@@ -235,21 +244,24 @@ public:
G4double maxEnergy = DBL_MAX);
// to select atom cross section per volume is recomputed for each element
inline const G4Element* SelectRandomAtom(const G4Material*,
const G4ParticleDefinition*,
G4double kineticEnergy,
G4double cutEnergy = 0.0,
G4double maxEnergy = DBL_MAX);
// select isotope in order to have precise mass of the nucleus
inline G4int SelectIsotopeNumber(const G4Element*);
const G4Element* SelectRandomAtom(const G4Material*,
const G4ParticleDefinition*,
G4double kineticEnergy,
G4double cutEnergy = 0.0,
G4double maxEnergy = DBL_MAX);
//------------------------------------------------------------------------
// Get/Set methods
//------------------------------------------------------------------------
void SetParticleChange(G4VParticleChange*, G4VEmFluctuationModel* f=0);
inline G4VEmFluctuationModel* GetModelOfFluctuations();
inline G4VEmAngularDistribution* GetAngularDistribution();
inline void SetAngularDistribution(G4VEmAngularDistribution*);
inline G4double HighEnergyLimit() const;
inline G4double LowEnergyLimit() const;
@@ -280,24 +292,20 @@ public:
inline void SetDeexcitationFlag(G4bool val);
inline void ActivateNuclearStopping(G4bool);
inline G4double MaxSecondaryKinEnergy(const G4DynamicParticle* dynParticle);
inline const G4String& GetName() const;
inline void SetParticleChange(G4VParticleChange*, G4VEmFluctuationModel*);
inline void SetCurrentCouple(const G4MaterialCutsCouple*);
inline const G4Element* GetCurrentElement() const;
protected:
inline const G4MaterialCutsCouple* CurrentCouple() const;
inline void SetCurrentElement(const G4Element*);
inline const G4Element* GetCurrentElement() const;
private:
// hide assignment operator
@@ -306,7 +314,8 @@ private:
// ======== Parameters of the class fixed at construction =========
G4VEmFluctuationModel* fluc;
G4VEmFluctuationModel* flucModel;
G4VEmAngularDistribution* anglModel;
const G4String name;
// ======== Parameters of the class fixed at initialisation =======
@@ -325,7 +334,7 @@ private:
protected:
G4VParticleChange* pParticleChange;
G4bool nuclearStopping;
// G4bool nuclearStopping;
// ======== Cashed values - may be state dependent ================
@@ -340,7 +349,43 @@ private:
};
// ======== Run time inline methods ================
inline void G4VEmModel::SetCurrentCouple(const G4MaterialCutsCouple* p)
{
currentCouple = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4MaterialCutsCouple* G4VEmModel::CurrentCouple() const
{
return currentCouple;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VEmModel::SetCurrentElement(const G4Element* elm)
{
currentElement = elm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4Element* G4VEmModel::GetCurrentElement() const
{
return currentElement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline
G4double G4VEmModel::MaxSecondaryKinEnergy(const G4DynamicParticle* dynPart)
{
return MaxSecondaryEnergy(dynPart->GetParticleDefinition(),
dynPart->GetKineticEnergy());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double G4VEmModel::ComputeDEDX(const G4MaterialCutsCouple* c,
@@ -374,7 +419,7 @@ inline G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
{
G4double mfp = DBL_MAX;
G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax);
if (cross > DBL_MIN) mfp = 1./cross;
if (cross > DBL_MIN) { mfp = 1./cross; }
return mfp;
}
@@ -414,31 +459,6 @@ const G4Element* G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline
const G4Element* G4VEmModel::SelectRandomAtom(const G4Material* material,
const G4ParticleDefinition* pd,
G4double kinEnergy,
G4double tcut,
G4double tmax)
{
const G4ElementVector* theElementVector = material->GetElementVector();
G4int n = material->GetNumberOfElements() - 1;
currentElement = (*theElementVector)[n];
if (n > 0) {
G4double x = G4UniformRand()*
G4VEmModel::CrossSectionPerVolume(material,pd,kinEnergy,tcut,tmax);
for(G4int i=0; i<n; i++) {
if (x <= xsec[i]) {
currentElement = (*theElementVector)[i];
break;
}
}
}
return currentElement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4int G4VEmModel::SelectIsotopeNumber(const G4Element* elm)
{
currentElement = elm;
@@ -449,22 +469,36 @@ inline G4int G4VEmModel::SelectIsotopeNumber(const G4Element* elm)
if(ni > 1) {
G4double* ab = elm->GetRelativeAbundanceVector();
G4double x = G4UniformRand();
for(; idx<ni; idx++) {
for(; idx<ni; ++idx) {
x -= ab[idx];
if (x <= 0.0) break;
if (x <= 0.0) { break; }
}
if(idx >= ni) idx = ni - 1;
if(idx >= ni) { idx = ni - 1; }
}
N = elm->GetIsotope(idx)->GetN();
}
return N;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// ======== Get/Set inline methods used at initialisation ================
inline G4VEmFluctuationModel* G4VEmModel::GetModelOfFluctuations()
{
return fluc;
return flucModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4VEmAngularDistribution* G4VEmModel::GetAngularDistribution()
{
return anglModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VEmModel::SetAngularDistribution(G4VEmAngularDistribution* p)
{
anglModel = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -572,22 +606,6 @@ inline void G4VEmModel::SetDeexcitationFlag(G4bool val)
flagDeexcitation = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::ActivateNuclearStopping(G4bool val)
{
nuclearStopping = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline
G4double G4VEmModel::MaxSecondaryKinEnergy(const G4DynamicParticle* dynPart)
{
return MaxSecondaryEnergy(dynPart->GetDefinition(),
dynPart->GetKineticEnergy());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4String& G4VEmModel::GetName() const
@@ -597,42 +615,5 @@ inline const G4String& G4VEmModel::GetName() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VEmModel::SetParticleChange(G4VParticleChange* p,
G4VEmFluctuationModel* f = 0)
{
if(p && pParticleChange != p) pParticleChange = p;
fluc = f;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VEmModel::SetCurrentCouple(const G4MaterialCutsCouple* p)
{
currentCouple = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4MaterialCutsCouple* G4VEmModel::CurrentCouple() const
{
return currentCouple;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VEmModel::SetCurrentElement(const G4Element* elm)
{
currentElement = elm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4Element* G4VEmModel::GetCurrentElement() const
{
return currentElement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmProcess.hh,v 1.55 2009/09/23 14:42:47 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VEmProcess.hh,v 1.61 2010/08/17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -55,6 +55,7 @@
// PostStepGetPhysicalInteractionLength (V.Ivanchenko)
// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
// 15-07-08 Reorder class members for further multi-thread development (VI)
// 17-02-10 Added pointer currentParticle (VI)
//
// Class Description:
//
@@ -157,11 +158,11 @@ public:
const G4MaterialCutsCouple* couple);
// It returns the cross section of the process per atom
inline G4double ComputeCrossSectionPerAtom(G4double kineticEnergy,
G4double Z, G4double A=0.,
G4double cut=0.0);
G4double ComputeCrossSectionPerAtom(G4double kineticEnergy,
G4double Z, G4double A=0.,
G4double cut=0.0);
inline G4double MeanFreePath(const G4Track& track);
G4double MeanFreePath(const G4Track& track);
// It returns cross section per volume
inline G4double GetLambda(G4double& kinEnergy,
@@ -224,6 +225,9 @@ public:
// Access to models
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false);
// access atom on which interaction happens
const G4Element* GetCurrentElement() const;
inline void SetLambdaFactor(G4double val);
inline void SetIntegral(G4bool val);
@@ -231,6 +235,8 @@ public:
inline void SetApplyCuts(G4bool val);
inline void SetBuildTableFlag(G4bool val);
//------------------------------------------------------------------------
// Other generic methods
//------------------------------------------------------------------------
@@ -244,7 +250,7 @@ protected:
G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*);
inline G4double RecalculateLambda(G4double kinEnergy,
const G4MaterialCutsCouple* couple);
const G4MaterialCutsCouple* couple);
inline G4ParticleChangeForGamma* GetParticleChange();
@@ -258,8 +264,6 @@ protected:
inline G4double GetElectronEnergyCut();
inline void SetBuildTableFlag(G4bool val);
inline void SetStartFromNullFlag(G4bool val);
private:
@@ -339,6 +343,7 @@ private:
G4VEmModel* currentModel;
const G4ParticleDefinition* particle;
const G4ParticleDefinition* currentParticle;
// cash
const G4Material* currentMaterial;
@@ -351,29 +356,92 @@ private:
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// ======== Run time inline methods ================
inline G4double G4VEmProcess::ComputeCrossSectionPerAtom(
G4double kineticEnergy, G4double Z, G4double A, G4double cut)
inline size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
{
SelectModel(kineticEnergy, currentCoupleIndex);
G4double x = 0.0;
if(currentModel) {
x = currentModel->ComputeCrossSectionPerAtom(particle,kineticEnergy,
Z,A,cut);
}
return x;
return currentCoupleIndex;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::MeanFreePath(const G4Track& track)
inline G4double G4VEmProcess::GetGammaEnergyCut()
{
return (*theCutsGamma)[currentCoupleIndex];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetElectronEnergyCut()
{
return (*theCutsElectron)[currentCoupleIndex];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
{
if(couple != currentCouple) {
currentCouple = couple;
currentMaterial = couple->GetMaterial();
currentCoupleIndex = couple->GetIndex();
mfpKinEnergy = DBL_MAX;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4VEmModel* G4VEmProcess::SelectModel(G4double& kinEnergy, size_t index)
{
currentModel = modelManager->SelectModel(kinEnergy, index);
currentModel->SetCurrentCouple(currentCouple);
return currentModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4VEmModel* G4VEmProcess::SelectModelForMaterial(G4double kinEnergy,
size_t& idxRegion) const
{
return modelManager->SelectModel(kinEnergy, idxRegion);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::InitialiseStep(const G4Track& track)
{
currentParticle = track.GetParticleDefinition();
preStepKinEnergy = track.GetKineticEnergy();
DefineMaterial(track.GetMaterialCutsCouple());
preStepLambda = GetCurrentLambda(track.GetKineticEnergy());
G4double x = DBL_MAX;
if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
SelectModel(preStepKinEnergy, currentCoupleIndex);
if (theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
{
return (((*theLambdaTable)[currentCoupleIndex])->Value(e));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::ComputeCurrentLambda(G4double e)
{
SelectModel(e, currentCoupleIndex);
return currentModel->CrossSectionPerVolume(currentMaterial,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;
}
@@ -388,6 +456,38 @@ inline G4double G4VEmProcess::GetLambda(G4double& kineticEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::RecalculateLambda(G4double e,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
return ComputeCurrentLambda(e);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::ComputeIntegralLambda(G4double e)
{
mfpKinEnergy = theEnergyOfCrossSectionMax[currentCoupleIndex];
if (e <= mfpKinEnergy) {
preStepLambda = GetLambdaFromTable(e);
} else {
G4double e1 = e*lambdaFactor;
if(e1 > mfpKinEnergy) {
preStepLambda = GetLambdaFromTable(e);
G4double preStepLambda1 = GetLambdaFromTable(e1);
if(preStepLambda1 > preStepLambda) {
mfpKinEnergy = e1;
preStepLambda = preStepLambda1;
}
} else {
preStepLambda = theCrossSectionMax[currentCoupleIndex];
}
}
}
// ======== Get/Set inline methods used at initialisation ================
inline void G4VEmProcess::SetLambdaBinning(G4int nbins)
{
nLambdaBins = nbins;
@@ -467,36 +567,17 @@ inline const G4ParticleDefinition* G4VEmProcess::SecondaryParticle() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4VEmModel* G4VEmProcess::SelectModel(G4double& kinEnergy, size_t index)
{
currentModel = modelManager->SelectModel(kinEnergy, index);
currentModel->SetCurrentCouple(currentCouple);
return currentModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4VEmModel* G4VEmProcess::SelectModelForMaterial(G4double kinEnergy,
size_t& idxRegion) const
{
return modelManager->SelectModel(kinEnergy, idxRegion);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetLambdaFactor(G4double val)
{
if(val > 0.0 && val <= 1.0) lambdaFactor = val;
if(val > 0.0 && val <= 1.0) { lambdaFactor = val; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetIntegral(G4bool val)
{
if(particle && particle != theGamma) integral = val;
if(integral) buildLambdaTable = true;
if(particle && particle != theGamma) { integral = val; }
if(integral) { buildLambdaTable = true; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -515,11 +596,10 @@ inline void G4VEmProcess::SetApplyCuts(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::RecalculateLambda(G4double e,
const G4MaterialCutsCouple* couple)
inline void G4VEmProcess::SetBuildTableFlag(G4bool val)
{
DefineMaterial(couple);
return ComputeCurrentLambda(e);
buildLambdaTable = val;
if(!val) { integral = false; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -534,6 +614,7 @@ inline G4ParticleChangeForGamma* G4VEmProcess::GetParticleChange()
inline void G4VEmProcess::SetParticle(const G4ParticleDefinition* p)
{
particle = p;
currentParticle = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -545,35 +626,6 @@ inline void G4VEmProcess::SetSecondaryParticle(const G4ParticleDefinition* p)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
{
return currentCoupleIndex;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetGammaEnergyCut()
{
return (*theCutsGamma)[currentCoupleIndex];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetElectronEnergyCut()
{
return (*theCutsElectron)[currentCoupleIndex];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetBuildTableFlag(G4bool val)
{
buildLambdaTable = val;
if(!val) integral = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::SetStartFromNullFlag(G4bool val)
{
startFromNull = val;
@@ -581,75 +633,4 @@ inline void G4VEmProcess::SetStartFromNullFlag(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::InitialiseStep(const G4Track& track)
{
preStepKinEnergy = track.GetKineticEnergy();
DefineMaterial(track.GetMaterialCutsCouple());
SelectModel(preStepKinEnergy, currentCoupleIndex);
if (theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
{
if(couple != currentCouple) {
currentCouple = couple;
currentMaterial = couple->GetMaterial();
currentCoupleIndex = couple->GetIndex();
mfpKinEnergy = DBL_MAX;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmProcess::ComputeIntegralLambda(G4double e)
{
mfpKinEnergy = theEnergyOfCrossSectionMax[currentCoupleIndex];
if (e <= mfpKinEnergy) {
preStepLambda = GetLambdaFromTable(e);
} else {
G4double e1 = e*lambdaFactor;
if(e1 > mfpKinEnergy) {
preStepLambda = GetLambdaFromTable(e);
G4double preStepLambda1 = GetLambdaFromTable(e1);
if(preStepLambda1 > preStepLambda) {
mfpKinEnergy = e1;
preStepLambda = preStepLambda1;
}
} else {
preStepLambda = theCrossSectionMax[currentCoupleIndex];
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
{
return (((*theLambdaTable)[currentCoupleIndex])->Value(e));
}
//....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;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::ComputeCurrentLambda(G4double e)
{
SelectModel(e, currentCoupleIndex);
return currentModel->CrossSectionPerVolume(currentMaterial,particle,
e,(*theCuts)[currentCoupleIndex]);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEnergyLossProcess.hh,v 1.89 2009/07/03 14:39:17 vnivanch Exp $
// $Id: G4VEnergyLossProcess.hh,v 1.93 2010/10/14 16:27:35 vnivanch Exp $
// GEANT4 tag $Name:
//
// -------------------------------------------------------------------
@@ -113,6 +113,7 @@ class G4VEmFluctuationModel;
class G4DataVector;
class G4Region;
class G4SafetyHelper;
class G4VAtomDeexcitation;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -195,8 +196,7 @@ public:
// Sampling of secondaries in vicinity of geometrical boundary
void SampleSubCutSecondaries(std::vector<G4Track*>&, const G4Step&,
G4VEmModel* model, G4int matIdx,
G4double& extraEdep);
G4VEmModel* model, G4int matIdx);
// PostStep sampling of secondaries
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
@@ -418,6 +418,9 @@ public:
// Run time method for simulation of ionisation
//------------------------------------------------------------------------
// access atom on which interaction happens
const G4Element* GetCurrentElement() const;
// sample range at the end of a step
inline G4double SampleRange();
@@ -463,6 +466,7 @@ private:
std::vector<G4VEmModel*> emModels;
G4VEmFluctuationModel* fluctModel;
G4VAtomDeexcitation* atomDeexcitation;
std::vector<const G4Region*> scoffRegions;
std::vector<const G4Region*> deRegions;
G4int nSCoffRegions;
@@ -552,8 +556,7 @@ private:
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// ======== Run time inline methods ================
inline size_t G4VEnergyLossProcess::CurrentMaterialCutsCoupleIndex() const
{
@@ -585,6 +588,245 @@ inline G4VEmModel* G4VEnergyLossProcess::SelectModelForMaterial(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void
G4VEnergyLossProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
{
if(couple != currentCouple) {
currentCouple = couple;
currentMaterial = couple->GetMaterial();
currentMaterialIndex = couple->GetIndex();
mfpKinEnergy = DBL_MAX;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
G4double charge2ratio)
{
massRatio = massratio;
chargeSqRatio = charge2ratio;
reduceFactor = 1.0/(chargeSqRatio*massRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
{
G4double x = ((*theDEDXTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e)
{
G4double x = ((*theDEDXSubTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
{
//G4double x = 0.0;
// if(theIonisationTable) {
G4double x = ((*theIonisationTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
//}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
{
// G4double x = 0.0;
//if(theIonisationSubTable) {
G4double x = ((*theIonisationSubTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
//}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
{
G4double x = ((*theRangeTableForLoss)[currentMaterialIndex])->Value(e);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(G4double e)
{
G4double x;
if (e < maxKinEnergyCSDA) {
x = ((*theCSDARangeTable)[currentMaterialIndex])->Value(e);
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
} else {
x = theRangeAtMaxEnergy[currentMaterialIndex] +
(e - maxKinEnergyCSDA)/theDEDXAtMaxEnergy[currentMaterialIndex];
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
{
G4PhysicsVector* v = (*theInverseRangeTable)[currentMaterialIndex];
G4double rmin = v->Energy(0);
G4double e = 0.0;
if(r >= rmin) { e = v->Value(r); }
else if(r > 0.0) {
G4double x = r/rmin;
e = minKinEnergy*x*x;
}
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e)
{
return chargeSqRatio*(((*theLambdaTable)[currentMaterialIndex])->Value(e));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetDEDX(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
return GetDEDXForScaledEnergy(kineticEnergy*massRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetDEDXForSubsec(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
return GetSubDEDXForScaledEnergy(kineticEnergy*massRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetRange(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x = fRange;
if(kineticEnergy != preStepKinEnergy || couple != currentCouple) {
DefineMaterial(couple);
if(theCSDARangeTable)
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
* reduceFactor;
else if(theRangeTableForLoss)
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetCSDARange(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = DBL_MAX;
if(theCSDARangeTable)
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
* reduceFactor;
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetRangeForLoss(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = DBL_MAX;
if(theRangeTableForLoss)
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
// G4cout << "Range from " << GetProcessName()
// << " e= " << kineticEnergy << " r= " << x << G4endl;
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetKineticEnergy(G4double& range,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double r = range/reduceFactor;
G4double e = ScaledKinEnergyForLoss(r)/massRatio;
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4VEnergyLossProcess::GetLambda(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = 0.0;
if(theLambdaTable) { x = GetLambdaForScaledEnergy(kineticEnergy*massRatio); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e)
{
mfpKinEnergy = theEnergyOfCrossSectionMax[currentMaterialIndex];
if (e <= mfpKinEnergy) {
preStepLambda = GetLambdaForScaledEnergy(e);
} else {
G4double e1 = e*lambdaFactor;
if(e1 > mfpKinEnergy) {
preStepLambda = GetLambdaForScaledEnergy(e);
G4double preStepLambda1 = GetLambdaForScaledEnergy(e1);
if(preStepLambda1 > preStepLambda) {
mfpKinEnergy = e1;
preStepLambda = preStepLambda1;
}
} else {
preStepLambda = chargeSqRatio*theCrossSectionMax[currentMaterialIndex];
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::SampleRange()
{
G4double e = amu_c2*preStepKinEnergy/particle->GetPDGMass();
G4double s = fRange*std::pow(10.,vstrag->Value(e));
G4double x = fRange + G4RandGauss::shoot(0.0,s);
if(x > 0.0) { fRange = x; }
return fRange;
}
// ======== Get/Set inline methods used at initialisation ================
inline void G4VEnergyLossProcess::SetFluctModel(G4VEmFluctuationModel* p)
{
fluctModel = p;
@@ -672,8 +914,8 @@ inline G4bool G4VEnergyLossProcess::IsIntegral() const
inline void G4VEnergyLossProcess::SetIonisation(G4bool val)
{
isIonisation = val;
if(val) aGPILSelection = CandidateForSelection;
else aGPILSelection = NotCandidateForSelection;
if(val) { aGPILSelection = CandidateForSelection; }
else { aGPILSelection = NotCandidateForSelection; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -701,7 +943,7 @@ inline void G4VEnergyLossProcess::SetMinSubRange(G4double val)
inline void G4VEnergyLossProcess::SetLambdaFactor(G4double val)
{
if(val > 0.0 && val <= 1.0) lambdaFactor = val;
if(val > 0.0 && val <= 1.0) { lambdaFactor = val; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -710,7 +952,7 @@ void G4VEnergyLossProcess::SetStepFunction(G4double v1, G4double v2)
{
dRoverRange = v1;
finalRange = v2;
if (dRoverRange > 0.999) dRoverRange = 1.0;
if (dRoverRange > 0.999) { dRoverRange = 1.0; }
currentCouple = 0;
mfpKinEnergy = DBL_MAX;
}
@@ -776,7 +1018,7 @@ inline G4double G4VEnergyLossProcess::MinKinEnergy() const
inline void G4VEnergyLossProcess::SetMaxKinEnergy(G4double e)
{
maxKinEnergy = e;
if(e < maxKinEnergyCSDA) maxKinEnergyCSDA = e;
if(e < maxKinEnergyCSDA) { maxKinEnergyCSDA = e; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -793,91 +1035,6 @@ inline void G4VEnergyLossProcess::SetMaxKinEnergyForCSDARange(G4double e)
maxKinEnergyCSDA = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetDEDX(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
return GetDEDXForScaledEnergy(kineticEnergy*massRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetDEDXForSubsec(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
return GetSubDEDXForScaledEnergy(kineticEnergy*massRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetRange(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x = fRange;
if(kineticEnergy != preStepKinEnergy || couple != currentCouple) {
DefineMaterial(couple);
if(theCSDARangeTable)
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
* reduceFactor;
else if(theRangeTableForLoss)
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetCSDARange(
G4double& kineticEnergy, const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = DBL_MAX;
if(theCSDARangeTable)
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
* reduceFactor;
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetRangeForLoss(
G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = DBL_MAX;
if(theRangeTableForLoss)
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
// G4cout << "Range from " << GetProcessName()
// << " e= " << kineticEnergy << " r= " << x << G4endl;
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetKineticEnergy(
G4double& range,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double r = range/reduceFactor;
G4double e = ScaledKinEnergyForLoss(r)/massRatio;
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetLambda(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4double x = 0.0;
if(theLambdaTable) x = GetLambdaForScaledEnergy(kineticEnergy*massRatio);
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -912,7 +1069,7 @@ inline G4PhysicsTable* G4VEnergyLossProcess::DEDXunRestrictedTable() const
inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const
{
G4PhysicsTable* t = theDEDXTable;
if(theIonisationTable) t = theIonisationTable;
if(theIonisationTable) { t = theIonisationTable; }
return t;
}
@@ -921,7 +1078,7 @@ inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const
inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTableForSubsec() const
{
G4PhysicsTable* t = theDEDXSubTable;
if(theIonisationSubTable) t = theIonisationSubTable;
if(theIonisationSubTable) { t = theIonisationSubTable; }
return t;
}
@@ -962,152 +1119,4 @@ inline G4PhysicsTable* G4VEnergyLossProcess::SubLambdaTable()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::SampleRange()
{
G4double e = amu_c2*preStepKinEnergy/particle->GetPDGMass();
G4double s = fRange*std::pow(10.,vstrag->Value(e));
G4double x = fRange + G4RandGauss::shoot(0.0,s);
if(x > 0.0) fRange = x;
return fRange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
G4double charge2ratio)
{
massRatio = massratio;
chargeSqRatio = charge2ratio;
reduceFactor = 1.0/(chargeSqRatio*massRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEnergyLossProcess::DefineMaterial(
const G4MaterialCutsCouple* couple)
{
if(couple != currentCouple) {
currentCouple = couple;
currentMaterial = couple->GetMaterial();
currentMaterialIndex = couple->GetIndex();
mfpKinEnergy = DBL_MAX;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
{
G4double x = ((*theDEDXTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e)
{
G4double x = ((*theDEDXSubTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
{
//G4double x = 0.0;
// if(theIonisationTable) {
G4double x = ((*theIonisationTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
//}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
{
// G4double x = 0.0;
//if(theIonisationSubTable) {
G4double x = ((*theIonisationSubTable)[currentMaterialIndex]->Value(e))*chargeSqRatio;
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
//}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
{
G4double x = ((*theRangeTableForLoss)[currentMaterialIndex])->Value(e);
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(
G4double e)
{
G4double x;
if (e < maxKinEnergyCSDA) {
x = ((*theCSDARangeTable)[currentMaterialIndex])->Value(e);
if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
} else {
x = theRangeAtMaxEnergy[currentMaterialIndex] +
(e - maxKinEnergyCSDA)/theDEDXAtMaxEnergy[currentMaterialIndex];
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
{
G4PhysicsVector* v = (*theInverseRangeTable)[currentMaterialIndex];
G4double rmin = v->Energy(0);
G4double e = 0.0;
if(r >= rmin) { e = v->Value(r); }
else if(r > 0.0) {
G4double x = r/rmin;
e = minKinEnergy*x*x;
}
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e)
{
return chargeSqRatio*(((*theLambdaTable)[currentMaterialIndex])->Value(e));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e)
{
mfpKinEnergy = theEnergyOfCrossSectionMax[currentMaterialIndex];
if (e <= mfpKinEnergy) {
preStepLambda = GetLambdaForScaledEnergy(e);
} else {
G4double e1 = e*lambdaFactor;
if(e1 > mfpKinEnergy) {
preStepLambda = GetLambdaForScaledEnergy(e);
G4double preStepLambda1 = GetLambdaForScaledEnergy(e1);
if(preStepLambda1 > preStepLambda) {
mfpKinEnergy = e1;
preStepLambda = preStepLambda1;
}
} else {
preStepLambda = chargeSqRatio*theCrossSectionMax[currentMaterialIndex];
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMscModel.hh,v 1.9 2009/04/07 18:39:47 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VMscModel.hh,v 1.10 2010/09/07 16:05:33 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -139,7 +139,8 @@ protected:
G4double skin;
G4double dtrl;
G4double lambdalimit;
G4double geommax;
G4double geomMin;
G4double geomMax;
G4MscStepLimitType steppingAlgorithm;
@@ -205,7 +206,7 @@ inline G4double G4VMscModel::ComputeGeomLimit(const G4Track& track,
G4double& presafety,
G4double limit)
{
G4double res = geommax;
G4double res = geomMax;
if(track.GetVolume() != safetyHelper->GetWorldVolume()) {
res = safetyHelper->CheckNextStep(
track.GetStep()->GetPreStepPoint()->GetPosition(),
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMultipleScattering.hh,v 1.62 2009/10/29 17:56:04 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VMultipleScattering.hh,v 1.63 2010/03/10 18:29:51 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04-beta-01 $
//
// -------------------------------------------------------------------
//
@@ -153,22 +153,22 @@ public:
// The function overloads the corresponding function of the base
// class.
inline G4double PostStepGetPhysicalInteractionLength(
G4double PostStepGetPhysicalInteractionLength(
const G4Track&,
G4double previousStepSize,
G4ForceCondition* condition);
// Along step actions
inline G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&);
G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&);
// Post step actions
inline G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
// This method does not used for tracking, it is intended only for tests
inline G4double ContinuousStepLimit(const G4Track& track,
G4double previousStepSize,
G4double currentMinimalStep,
G4double& currentSafety);
G4double ContinuousStepLimit(const G4Track& track,
G4double previousStepSize,
G4double currentMinimalStep,
G4double& currentSafety);
//------------------------------------------------------------------------
// Specific methods to build and access Physics Tables
@@ -317,21 +317,59 @@ private:
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// ======== Run time inline methods ================
inline const G4MaterialCutsCouple*
G4VMultipleScattering::CurrentMaterialCutsCouple() const
{
return currentCouple;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VMultipleScattering::ContinuousStepLimit(
const G4Track& track,
G4double previousStepSize,
G4double currentMinimalStep,
G4double& currentSafety)
inline
void G4VMultipleScattering::DefineMaterial(const G4MaterialCutsCouple* couple)
{
return GetContinuousStepLimit(track,previousStepSize,currentMinimalStep,
currentSafety);
if(couple != currentCouple) {
currentCouple = couple;
currentMaterialIndex = couple->GetIndex();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VMultipleScattering::GetLambda(const G4ParticleDefinition* p,
G4double& e)
{
G4double x;
if(theLambdaTable) {
x = ((*theLambdaTable)[currentMaterialIndex])->Value(e);
} else {
x = currentModel->CrossSection(currentCouple,p,e);
}
if(x > DBL_MIN) { x = 1./x; }
else { x = DBL_MAX; }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmModel* G4VMultipleScattering::SelectModel(G4double kinEnergy)
{
return modelManager->SelectModel(kinEnergy, currentMaterialIndex);
}
//....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;
@@ -395,21 +433,6 @@ inline const G4ParticleDefinition* G4VMultipleScattering::Particle() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmModel* G4VMultipleScattering::SelectModel(G4double kinEnergy)
{
return modelManager->SelectModel(kinEnergy, currentMaterialIndex);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmModel* G4VMultipleScattering::SelectModelForMaterial(
G4double kinEnergy, size_t& idxRegion) const
{
return modelManager->SelectModel(kinEnergy, idxRegion);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4VMultipleScattering::LateralDisplasmentFlag() const
{
return latDisplasment;
@@ -433,8 +456,8 @@ inline G4double G4VMultipleScattering::Skin() const
inline void G4VMultipleScattering::SetSkin(G4double val)
{
if(val < 1.0) skin = 0.0;
else skin = val;
if(val < 1.0) { skin = 0.0; }
else { skin = val; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -476,9 +499,9 @@ inline G4double G4VMultipleScattering::PolarAngleLimit() const
inline void G4VMultipleScattering::SetPolarAngleLimit(G4double val)
{
if(val < 0.0) polarAngleLimit = 0.0;
else if(val > pi) polarAngleLimit = pi;
else polarAngleLimit = val;
if(val < 0.0) { polarAngleLimit = 0.0; }
else if(val > CLHEP::pi) { polarAngleLimit = CLHEP::pi; }
else { polarAngleLimit = val; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -493,81 +516,7 @@ inline G4MscStepLimitType G4VMultipleScattering::StepLimitType() const
inline void G4VMultipleScattering::SetStepLimitType(G4MscStepLimitType val)
{
stepLimit = val;
if(val == fMinimal) facrange = 0.2;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VMultipleScattering::GetLambda(const G4ParticleDefinition* p,
G4double& e)
{
G4double x;
if(theLambdaTable) {
x = ((*theLambdaTable)[currentMaterialIndex])->Value(e);
} else {
x = currentModel->CrossSection(currentCouple,p,e);
}
if(x > DBL_MIN) x = 1./x;
else x = DBL_MAX;
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
void G4VMultipleScattering::DefineMaterial(const G4MaterialCutsCouple* couple)
{
if(couple != currentCouple) {
currentCouple = couple;
currentMaterialIndex = couple->GetIndex();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4MaterialCutsCouple*
G4VMultipleScattering::CurrentMaterialCutsCouple() const
{
return currentCouple;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Follwoing methods are virtual, they are inlined because they applied at
// each simulation step and some compilers may inline these methods
inline G4double
G4VMultipleScattering::PostStepGetPhysicalInteractionLength(
const G4Track&, G4double, G4ForceCondition* condition)
{
*condition = Forced;
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VParticleChange*
G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step)
{
if(currentModel->IsActive(track.GetKineticEnergy())) {
fParticleChange.ProposeTrueStepLength(currentModel->ComputeTrueStepLength(step.GetStepLength()));
}
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VParticleChange*
G4VMultipleScattering::PostStepDoIt(const G4Track& track, const G4Step& step)
{
fParticleChange.Initialize(track);
if(currentModel->IsActive(track.GetKineticEnergy())) {
currentModel->SampleScattering(track.GetDynamicParticle(),
step.GetPostStepPoint()->GetSafety());
}
return &fParticleChange;
if(val == fMinimal) { facrange = 0.2; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,129 @@
#------------------------------------------------------------------------------
# sources.cmake
# Module : G4emutils
# Package: Geant4.src.G4processes.G4electromagnetic.G4emutils
#
# Sources description for a library.
# Lists the sources and headers of the code explicitely.
# Lists include paths needed.
# Lists the internal granular and global dependencies of the library.
# Source specific properties should be added at the end.
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake,v 1.4 2010/10/26 09:45:09 gcosmo Exp $
#
#------------------------------------------------------------------------------
# List external includes needed.
include_directories(${CLHEP_INCLUDE_DIRS})
# List internal includes needed.
include_directories(${CMAKE_SOURCE_DIR}/source/geometry/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/geometry/navigation/include)
include_directories(${CMAKE_SOURCE_DIR}/source/geometry/volumes/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/HEPGeometry/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/HEPRandom/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/intercoms/include)
include_directories(${CMAKE_SOURCE_DIR}/source/materials/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/bosons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/barions/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/ions/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/mesons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/leptons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/cuts/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/track/include)
#
# Define the Geant4 Module.
#
include(Geant4MacroDefineModule)
GEANT4_DEFINE_MODULE(NAME G4emutils
HEADERS
G4AtomicShell.hh
G4DummyModel.hh
G4ElectronIonPair.hh
G4EmCalculator.hh
G4EmConfigurator.hh
G4EmCorrections.hh
G4EmElementSelector.hh
G4EmModelManager.hh
G4EmMultiModel.hh
G4EmProcessOptions.hh
G4EmProcessSubType.hh
G4EmSaturation.hh
G4EmTableType.hh
G4EnergyLossMessenger.hh
G4EnergyLossTables.hh
G4LossTableBuilder.hh
G4LossTableManager.hh
G4MscStepLimitType.hh
G4VAtomDeexcitation.hh
G4VBremAngularDistribution.hh
G4VEmAngularDistribution.hh
G4VEmFluctuationModel.hh
G4VEmModel.hh
G4VEmProcess.hh
G4VEnergyLoss.hh
G4VEnergyLossProcess.hh
G4VMscModel.hh
G4VMultipleScattering.hh
G4ionEffectiveCharge.hh
SOURCES
G4AtomicShell.cc
G4DummyModel.cc
G4ElectronIonPair.cc
G4EmCalculator.cc
G4EmConfigurator.cc
G4EmCorrections.cc
G4EmElementSelector.cc
G4EmModelManager.cc
G4EmMultiModel.cc
G4EmProcessOptions.cc
G4EmSaturation.cc
G4EnergyLossMessenger.cc
G4EnergyLossTables.cc
G4LossTableBuilder.cc
G4LossTableManager.cc
G4VAtomDeexcitation.cc
G4VBremAngularDistribution.cc
G4VEmAngularDistribution.cc
G4VEmFluctuationModel.cc
G4VEmModel.cc
G4VEmProcess.cc
G4VEnergyLoss.cc
G4VEnergyLossProcess.cc
G4VMscModel.cc
G4VMultipleScattering.cc
G4ionEffectiveCharge.cc
GRANULAR_DEPENDENCIES
G4baryons
G4bosons
G4cuts
G4geometrymng
G4globman
G4intercoms
G4ions
G4leptons
G4materials
G4mesons
G4navigation
G4partman
G4procman
G4track
G4volumes
GLOBAL_DEPENDENCIES
G4geometry
G4global
G4intercoms
G4materials
G4particles
G4track
LINK_LIBRARIES
)
# List any source specific properties here
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ElectronIonPair.cc,v 1.2 2008/10/17 14:46:16 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4ElectronIonPair.cc,v 1.5 2010/10/25 17:23:01 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -45,7 +45,6 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4ElectronIonPair.hh"
#include "G4Gamma.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4StepPoint.hh"
@@ -62,6 +61,7 @@ G4ElectronIonPair::G4ElectronIonPair()
curMaterial = 0;
curMeanEnergy = 0.0;
nMaterials = 0;
FanoFactor = 0.2;
Initialise();
}
@@ -96,7 +96,7 @@ G4double G4ElectronIonPair::MeanNumberOfIonsAlongStep(
curMeanEnergy = FindG4MeanEnergyPerIonPair(material);
}
}
if(curMeanEnergy > 0.0) nion = (edep - niel)/curMeanEnergy;
if(curMeanEnergy > 0.0) { nion = (edep - niel)/curMeanEnergy; }
}
}
return nion;
@@ -105,20 +105,19 @@ G4double G4ElectronIonPair::MeanNumberOfIonsAlongStep(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
std::vector<G4ThreeVector>*
G4ElectronIonPair::SampleIonsAlongStep(const G4ThreeVector& prePos,
const G4ThreeVector& postPos,
G4double meanion)
G4ElectronIonPair::SampleIonsAlongStep(const G4Step* step)
{
std::vector<G4ThreeVector>* v = new std::vector<G4ThreeVector>;
std::vector<G4ThreeVector>* v = 0;
G4double sig = 0.2*std::sqrt(meanion);
G4int nion = G4int(G4RandGauss::shoot(meanion,sig) + 0.5);
G4int nion = SampleNumberOfIonsAlongStep(step);
// sample ionisation along step
if(nion > 0) {
G4ThreeVector deltaPos = postPos - prePos;
for(G4int i=0; i<nion; i++) {
v = new std::vector<G4ThreeVector>;
G4ThreeVector prePos = step->GetPreStepPoint()->GetPosition();
G4ThreeVector deltaPos = step->GetPostStepPoint()->GetPosition() - prePos;
for(G4int i=0; i<nion; ++i) {
v->push_back( prePos + deltaPos*G4UniformRand() );
}
if(verbose > 1 ) {
@@ -137,7 +136,7 @@ G4int G4ElectronIonPair::ResidualeChargePostStep(const G4ParticleDefinition*,
{
G4int nholes = 0;
if(2 == subType || 12 == subType || 13 == subType) nholes = 1;
if(2 == subType || 12 == subType || 13 == subType) { nholes = 1; }
return nholes;
}
@@ -172,7 +171,7 @@ void G4ElectronIonPair:: DumpMeanEnergyPerIonPair()
const G4MaterialTable* mtable = G4Material::GetMaterialTable();
if(nmat > 0) {
G4cout << "### G4ElectronIonPair: mean energy per ion pair avalable:" << G4endl;
for(G4int i=0; i<nmat; i++) {
for(G4int i=0; i<nmat; ++i) {
const G4Material* mat = (*mtable)[i];
G4double x = mat->GetIonisation()->GetMeanEnergyPerIonPair();
if(x > 0.0) {
@@ -190,7 +189,7 @@ void G4ElectronIonPair::DumpG4MeanEnergyPerIonPair()
if(nMaterials > 0) {
G4cout << "### G4ElectronIonPair: mean energy per ion pair "
<< " for Geant4 materials" << G4endl;
for(G4int i=0; i<nMaterials; i++) {
for(G4int i=0; i<nMaterials; ++i) {
G4cout << " " << g4MatNames[i] << " Epair= "
<< g4MatData[i]/eV << " eV" << G4endl;
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCalculator.cc,v 1.49 2009/11/22 17:58:39 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmCalculator.cc,v 1.58 2010/11/21 16:45:12 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -93,14 +93,20 @@ G4EmCalculator::G4EmCalculator()
currentCouple = 0;
currentMaterial = 0;
currentParticle = 0;
lambdaParticle = 0;
baseParticle = 0;
currentLambda = 0;
currentModel = 0;
currentProcess = 0;
loweModel = 0;
chargeSquare = 1.0;
massRatio = 1.0;
mass = 0.0;
currentCut = 0.0;
currentParticleName= "";
currentMaterialName= "";
currentName = "";
lambdaName = "";
theGenericIon = G4GenericIon::GenericIon();
ionEffCharge = new G4ionEffectiveCharge();
isIon = false;
@@ -112,7 +118,7 @@ G4EmCalculator::G4EmCalculator()
G4EmCalculator::~G4EmCalculator()
{
delete ionEffCharge;
for (G4int i=0; i<nLocalMaterials; i++) {
for (G4int i=0; i<nLocalMaterials; ++i) {
delete localCouples[i];
}
}
@@ -309,16 +315,17 @@ G4double G4EmCalculator::GetCrossSectionPerVolume(G4double kinEnergy,
if(couple && UpdateParticle(p, kinEnergy)) {
G4int idx = couple->GetIndex();
FindLambdaTable(p, processName);
if(currentLambda) {
G4double e = kinEnergy*massRatio;
res = (((*currentLambda)[idx])->Value(e))*chargeSquare;
if(verbose>0) {
G4cout << "E(MeV)= " << kinEnergy/MeV
G4cout << "G4EmCalculator::GetXSPerVolume: E(MeV)= " << kinEnergy/MeV
<< " cross(cm-1)= " << res*cm
<< " " << p->GetParticleName()
<< " in " << mat->GetName();
if(verbose>1)
G4cout << " idx= " << idx << " e(MeV)= " << e
G4cout << " idx= " << idx << " Escaled((MeV)= " << e
<< " q2= " << chargeSquare;
G4cout << G4endl;
}
@@ -341,6 +348,23 @@ G4double G4EmCalculator::GetCrossSectionPerVolume(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCalculator::GetShellIonisationCrossSectionPerAtom(
const G4String& particle,
G4int Z,
G4AtomicShellEnumerator shell,
G4double kinEnergy)
{
G4double res = 0.0;
const G4ParticleDefinition* p = FindParticle(particle);
G4VAtomDeexcitation* ad = manager->AtomDeexcitation();
if(p && ad) {
res = ad->GetShellIonisationCrossSectionPerAtom(p, Z, shell, kinEnergy);
}
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCalculator::GetMeanFreePath(G4double kinEnergy,
const G4ParticleDefinition* p,
const G4String& processName,
@@ -349,7 +373,7 @@ G4double G4EmCalculator::GetMeanFreePath(G4double kinEnergy,
{
G4double res = DBL_MAX;
G4double x = GetCrossSectionPerVolume(kinEnergy,p, processName, mat,region);
if(x > 0.0) res = 1.0/x;
if(x > 0.0) { res = 1.0/x; }
if(verbose>1) {
G4cout << "G4EmCalculator::GetMeanFreePath: E(MeV)= " << kinEnergy/MeV
<< " MFP(mm)= " << res/mm
@@ -494,6 +518,7 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
<< " " << p->GetParticleName()
<< " in " << currentMaterialName
<< " Zi^2= " << chargeSquare
<< " isIon=" << isIon
<< G4endl;
}
}
@@ -515,10 +540,11 @@ G4double G4EmCalculator::ComputeElectronicDEDX(G4double kinEnergy,
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; i++) {
for(G4int i=0; i<n; ++i) {
const G4ParticleDefinition* p = (vel[i])->Particle();
if((!isIon && p == part) || (isIon && p == theGenericIon))
if((!isIon && p == part) || (isIon && p == theGenericIon)) {
dedx += ComputeDEDX(kinEnergy,part,(vel[i])->GetProcessName(),mat,cut);
}
}
}
return dedx;
@@ -618,8 +644,9 @@ G4double G4EmCalculator::ComputeCrossSectionPerVolume(
res = currentModel->CrossSectionPerVolume(mat, p, e, cut, e);
}
if(verbose>0) {
G4cout << "E(MeV)= " << kinEnergy/MeV
G4cout << "G4EmCalculator::ComputeXSPerVolume: E(MeV)= " << kinEnergy/MeV
<< " cross(cm-1)= " << res*cm
<< " cut(keV)= " << cut/keV
<< " " << p->GetParticleName()
<< " in " << mat->GetName()
<< G4endl;
@@ -685,7 +712,25 @@ G4double G4EmCalculator::ComputeCrossSectionPerAtom(G4double kinEnergy,
{
return ComputeCrossSectionPerAtom(kinEnergy,FindParticle(particle),
processName,
elm->GetZ(),elm->GetA(),cut);
elm->GetZ(),elm->GetN(),cut);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmCalculator::ComputeShellIonisationCrossSectionPerAtom(
const G4String& particle,
G4int Z,
G4AtomicShellEnumerator shell,
G4double kinEnergy)
{
G4double res = 0.0;
const G4ParticleDefinition* p = FindParticle(particle);
G4VAtomDeexcitation* ad = manager->AtomDeexcitation();
if(p && ad) {
res =
ad->ComputeShellIonisationCrossSectionPerAtom(p, Z, shell, kinEnergy);
}
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -885,7 +930,7 @@ G4bool G4EmCalculator::UpdateCouple(const G4Material* material, G4double cut)
if(!material) return false;
currentMaterial = material;
currentMaterialName = material->GetName();
for (G4int i=0; i<nLocalMaterials; i++) {
for (G4int i=0; i<nLocalMaterials; ++i) {
if(material == localMaterials[i] && cut == localCuts[i]) {
currentCouple = localCouples[i];
currentCoupleIndex = currentCouple->GetIndex();
@@ -910,9 +955,10 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
const G4String& processName)
{
// Search for the process
if (p != currentParticle || processName != currentName) {
currentName = processName;
currentLambda = 0;
if (!currentLambda || p != lambdaParticle || processName != lambdaName) {
lambdaName = processName;
currentLambda = 0;
lambdaParticle = p;
G4String partname = p->GetParticleName();
const G4ParticleDefinition* part = p;
@@ -923,13 +969,17 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; i++) {
if((vel[i])->GetProcessName() == currentName &&
for(G4int i=0; i<n; ++i) {
if((vel[i])->GetProcessName() == lambdaName &&
(vel[i])->Particle() == part)
{
currentLambda = (vel[i])->LambdaTable();
isApplicable = true;
break;
if(verbose>1) {
G4cout << "G4VEnergyLossProcess is found out: "
<< currentName << G4endl;
}
return;
}
}
@@ -937,13 +987,17 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
if(!currentLambda) {
const std::vector<G4VEmProcess*> vem = lManager->GetEmProcessVector();
G4int n = vem.size();
for(G4int i=0; i<n; i++) {
if((vem[i])->GetProcessName() == currentName &&
for(G4int i=0; i<n; ++i) {
if((vem[i])->GetProcessName() == lambdaName &&
(vem[i])->Particle() == part)
{
currentLambda = (vem[i])->LambdaTable();
isApplicable = true;
break;
if(verbose>1) {
G4cout << "G4VEmProcess is found out: "
<< currentName << G4endl;
}
return;
}
}
}
@@ -953,13 +1007,17 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
const std::vector<G4VMultipleScattering*> vmsc =
lManager->GetMultipleScatteringVector();
G4int n = vmsc.size();
for(G4int i=0; i<n; i++) {
if((vmsc[i])->GetProcessName() == currentName &&
for(G4int i=0; i<n; ++i) {
if((vmsc[i])->GetProcessName() == lambdaName &&
(vmsc[i])->Particle() == part)
{
currentLambda = (vmsc[i])->LambdaTable();
isApplicable = true;
break;
if(verbose>1) {
G4cout << "G4VMultipleScattering is found out: "
<< currentName << G4endl;
}
return;
}
}
}
@@ -1001,7 +1059,7 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
G4VEnergyLossProcess* elproc = 0;
for(G4int i=0; i<n; i++) {
for(G4int i=0; i<n; ++i) {
// G4cout << "i= " << i << " part= "
// << (vel[i])->Particle()->GetParticleName()
// << " proc= " << (vel[i])->GetProcessName() << G4endl;
@@ -1022,20 +1080,24 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
if(elproc) {
currentModel = elproc->SelectModelForMaterial(scaledEnergy, idx);
G4double eth = currentModel->LowEnergyLimit();
loweModel = elproc->SelectModelForMaterial(eth - CLHEP::eV, idx);
if(eth > 0.0) {
loweModel = elproc->SelectModelForMaterial(eth - CLHEP::eV, idx);
}
}
// Search for discrete process
if(!currentModel) {
const std::vector<G4VEmProcess*> vem = lManager->GetEmProcessVector();
G4int n = vem.size();
for(G4int i=0; i<n; i++) {
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();
loweModel = (vem[i])->SelectModelForMaterial(eth - CLHEP::eV, idx);
if(eth > 0.0) {
loweModel = (vem[i])->SelectModelForMaterial(eth - CLHEP::eV, idx);
}
break;
}
}
@@ -1046,13 +1108,15 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
const std::vector<G4VMultipleScattering*> vmsc =
lManager->GetMultipleScatteringVector();
G4int n = vmsc.size();
for(G4int i=0; i<n; i++) {
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();
loweModel = (vmsc[i])->SelectModelForMaterial(eth - CLHEP::eV, idx);
if(eth > 0.0) {
loweModel = (vmsc[i])->SelectModelForMaterial(eth - CLHEP::eV, idx);
}
break;
}
}
@@ -1081,15 +1145,19 @@ G4VEnergyLossProcess* G4EmCalculator::FindEnergyLossProcess(
G4String partname = p->GetParticleName();
const G4ParticleDefinition* part = p;
if(p->GetParticleType() == "nucleus" &&
partname != "deuteron" &&
partname != "triton") { part = theGenericIon; }
if(p->GetParticleType() == "nucleus"
&& currentParticleName != "deuteron"
&& currentParticleName != "triton"
&& currentParticleName != "alpha+"
&& currentParticleName != "helium"
&& currentParticleName != "hydrogen"
) { part = theGenericIon; }
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel =
lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; i++) {
for(G4int i=0; i<n; ++i) {
if( (vel[i])->Particle() == part ) {
elp = vel[i];
break;
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmConfigurator.cc,v 1.6 2009/11/22 19:48:30 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmConfigurator.cc,v 1.9 2010/07/29 11:13:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -60,11 +60,9 @@
#include "G4VEmProcess.hh"
#include "G4VMultipleScattering.hh"
enum PType {unknown=0, eloss, discrete, msc};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmConfigurator::G4EmConfigurator()
G4EmConfigurator::G4EmConfigurator(G4int val):verbose(val)
{
index = -10;
}
@@ -76,35 +74,6 @@ G4EmConfigurator::~G4EmConfigurator()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::AddExtraEmModel(const G4String& particleName,
G4VEmModel* em,
G4VEmFluctuationModel* fm)
{
particleList.push_back(particleName);
modelList.push_back(em);
flucModelList.push_back(fm);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::AddModelForRegion(const G4String& particleName,
const G4String& processName,
const G4String& modelName,
const G4String& regionName,
G4double emin, G4double emax,
const G4String& flucModelName)
{
particles.push_back(particleName);
processes.push_back(processName);
models.push_back(modelName);
regions.push_back(regionName);
flucModels.push_back(flucModelName);
lowEnergy.push_back(emin);
highEnergy.push_back(emax);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::SetExtraEmModel(const G4String& particleName,
const G4String& processName,
G4VEmModel* mod,
@@ -113,27 +82,275 @@ void G4EmConfigurator::SetExtraEmModel(const G4String& particleName,
G4double emax,
G4VEmFluctuationModel* fm)
{
AddExtraEmModel(particleName, mod, fm);
G4String fname = "";
if(fm) fname = fm->GetName();
G4String mname = "";
if(mod) mname = mod->GetName();
AddModelForRegion(particleName, processName, mname, regionName,
emin, emax, fname);
if(1 < verbose) {
G4cout << " G4EmConfigurator::SetExtraEmModel " << mod->GetName()
<< " for " << particleName
<< " and " << processName
<< " in the region <" << regionName
<< "> Emin(MeV)= " << emin/MeV
<< " Emax(MeV)= " << emax/MeV
<< G4endl;
}
if(mod || fm) {
models.push_back(mod);
flucModels.push_back(fm);
} else {
models.push_back(new G4DummyModel());
flucModels.push_back(0);
}
particles.push_back(particleName);
processes.push_back(processName);
regions.push_back(regionName);
lowEnergy.push_back(emin);
highEnergy.push_back(emax);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::AddModels()
{
size_t n = particles.size();
//G4cout << " G4EmConfigurator::AddModels n= " << n << G4endl;
size_t n = models.size();
if(0 < verbose) {
G4cout << "### G4EmConfigurator::AddModels n= " << n << G4endl;
}
if(n > 0) {
for(size_t i=0; i<n; i++) {
SetModelForRegion(particles[i],processes[i],models[i],regions[i],
flucModels[i],lowEnergy[i],highEnergy[i]);
for(size_t i=0; i<n; ++i) {
if(models[i]) {
G4Region* reg = FindRegion(regions[i]);
if(reg) {
--index;
SetModelForRegion(models[i],flucModels[i],reg,
particles[i],processes[i],
lowEnergy[i],highEnergy[i]);
}
}
}
}
Clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::SetModelForRegion(G4VEmModel* mod,
G4VEmFluctuationModel* fm,
G4Region* reg,
const G4String& particleName,
const G4String& processName,
G4double emin, G4double emax)
{
if(1 < verbose) {
G4cout << " G4EmConfigurator::SetModelForRegion: " << mod->GetName()
<< G4endl;
G4cout << " For " << particleName
<< " and " << processName
<< " in the region <" << reg->GetName()
<< " Emin(MeV)= " << emin/MeV
<< " Emax(MeV)= " << emax/MeV;
if(fm) { G4cout << " FLmodel " << fm->GetName(); }
G4cout << G4endl;
}
G4ParticleTable::G4PTblDicIterator* theParticleIterator =
G4ParticleTable::GetParticleTable()->GetIterator();
theParticleIterator->reset();
while( (*theParticleIterator)() ) {
const G4ParticleDefinition* part = theParticleIterator->value();
//G4cout << particleName << " " << part->GetParticleName() << G4endl;
if((part->GetParticleName() == particleName) ||
(particleName == "all") ||
(particleName == "charged" && part->GetPDGCharge() != 0.0)) {
// search for process
G4ProcessManager* pmanager = part->GetProcessManager();
G4ProcessVector* plist = pmanager->GetProcessList();
G4int np = pmanager->GetProcessListLength();
//G4cout << processName << " in list of " << np << G4endl;
G4VProcess* proc = 0;
for(G4int i=0; i<np; ++i) {
if(processName == (*plist)[i]->GetProcessName()) {
proc = (*plist)[i];
break;
}
}
if(!proc) {
G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
<< processName << "> for " << particleName << G4endl;
return;
}
if(mod) {
if(!UpdateModelEnergyRange(mod, emin, emax)) { return; }
}
// classify process
G4int ii = proc->GetProcessSubType();
if(10 == ii && mod) {
G4VMultipleScattering* p = static_cast<G4VMultipleScattering*>(proc);
p->AddEmModel(index,mod,reg);
if(1 < verbose) {
G4cout << "### Added msc model order= " << index << " for "
<< particleName << " and " << processName << G4endl;
}
return;
} else if(2 <= ii && 4 >= ii) {
G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc);
if(!mod && fm) {
p->SetFluctModel(fm);
} else {
p->AddEmModel(index,mod,fm,reg);
if(1 < verbose) {
G4cout << "### Added eloss model order= " << index << " for "
<< particleName << " and " << processName << G4endl;
}
}
return;
} else if(mod) {
G4VEmProcess* p = static_cast<G4VEmProcess*>(proc);
p->AddEmModel(index,mod,reg);
if(1 < verbose) {
G4cout << "### Added em model order= " << index << " for "
<< particleName << " and " << processName << G4endl;
}
return;
} else {
return;
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
size_t n = particles.size();
if(1 < verbose) {
G4cout << " G4EmConfigurator::PrepareModels for EnergyLoss n= "
<< n << G4endl;
}
if(n > 0) {
G4String particleName = aParticle->GetParticleName();
G4String processName = p->GetProcessName();
//G4cout << particleName << " " << processName << G4endl;
for(size_t i=0; i<n; ++i) {
//G4cout << particles[i] << " " << processes[i] << G4endl;
if(processName == processes[i]) {
if((particleName == particles[i]) ||
(particles[i] == "all") ||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
G4Region* reg = FindRegion(regions[i]);
//G4cout << "Region " << reg << G4endl;
if(reg) {
--index;
G4VEmModel* mod = models[i];
G4VEmFluctuationModel* fm = flucModels[i];
if(mod) {
if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
p->AddEmModel(index,mod,fm,reg);
if(1 < verbose) {
G4cout << "### Added eloss model order= " << index << " for "
<< particleName << " and " << processName << G4endl;
}
}
} else if(fm) {
p->SetFluctModel(fm);
}
}
}
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
G4VEmProcess* p)
{
size_t n = particles.size();
if(1 < verbose) {
G4cout << " G4EmConfigurator::PrepareModels for EM process n= "
<< n << G4endl;
}
if(n > 0) {
G4String particleName = aParticle->GetParticleName();
G4String processName = p->GetProcessName();
//G4cout << particleName << " " << particleName << G4endl;
for(size_t i=0; i<n; ++i) {
if(processName == processes[i]) {
if((particleName == particles[i]) ||
(particles[i] == "all") ||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
G4Region* reg = FindRegion(regions[i]);
//G4cout << "Region " << reg << G4endl;
if(reg) {
--index;
G4VEmModel* mod = models[i];
if(mod) {
if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
p->AddEmModel(index,mod,reg);
if(1 < verbose) {
G4cout << "### Added em model order= " << index << " for "
<< particleName << " and " << processName << G4endl;
}
}
}
}
}
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
G4VMultipleScattering* p)
{
size_t n = particles.size();
if(1 < verbose) {
G4cout << " G4EmConfigurator::PrepareModels for MSC process n= "
<< n << G4endl;
}
if(n > 0) {
G4String particleName = aParticle->GetParticleName();
G4String processName = p->GetProcessName();
for(size_t i=0; i<n; ++i) {
if(processName == processes[i]) {
if((particleName == particles[i]) ||
(particles[i] == "all") ||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
G4Region* reg = FindRegion(regions[i]);
if(reg) {
--index;
G4VEmModel* mod = models[i];
if(mod) {
if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
p->AddEmModel(index,mod,reg);
G4cout << "### Added msc model order= " << index << " for "
<< particleName << " and " << processName << G4endl;
}
}
}
}
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::Clear()
{
particles.clear();
processes.clear();
models.clear();
@@ -145,147 +362,50 @@ void G4EmConfigurator::AddModels()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmConfigurator::SetModelForRegion(const G4String& particleName,
const G4String& processName,
const G4String& modelName,
const G4String& regionName,
const G4String& flucModelName,
G4double emin, G4double emax)
G4Region* G4EmConfigurator::FindRegion(const G4String& regionName)
{
//G4cout << " G4EmConfigurator::SetModelForRegion" << G4endl;
// new set
--index;
G4ParticleTable::G4PTblDicIterator* theParticleIterator =
G4ParticleTable::GetParticleTable()->GetIterator();
theParticleIterator->reset();
while( (*theParticleIterator)() ) {
const G4ParticleDefinition* part = theParticleIterator->value();
//G4cout << particleName << " " << part->GetParticleName() << G4endl;
if(particleName == part->GetParticleName() ||
(particleName == "charged" && part->GetPDGCharge() != 0.0) ) {
// search for process
G4ProcessManager* pmanager = part->GetProcessManager();
G4ProcessVector* plist = pmanager->GetProcessList();
G4int np = pmanager->GetProcessListLength();
//G4cout << processName << " in list of " << np << G4endl;
G4VProcess* proc = 0;
for(G4int i=0; i<np; i++) {
if(processName == (*plist)[i]->GetProcessName()) {
proc = (*plist)[i];
break;
}
}
if(!proc) {
G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
<< processName << "> for " << particleName << G4endl;
} else {
// classify process
PType ptype = discrete;
G4int ii = proc->GetProcessSubType();
if(10 == ii) ptype = msc;
else if(2 <= ii && 4 >= ii) ptype = eloss;
// find out model
G4VEmModel* mod = 0;
G4VEmFluctuationModel* fluc = 0;
G4int nm = modelList.size();
//G4cout << "Search model " << modelName << " in " << nm << G4endl;
for(G4int i=0; i<nm; i++) {
G4String mname = "";
if(modelList[i]) mname = modelList[i]->GetName();
G4String fname = "";
if(flucModelList[i]) fname = flucModelList[i]->GetName();
if(modelName == mname && flucModelName == fname &&
(particleList[i] == "" || particleList[i] == particleName) ) {
mod = modelList[i];
fluc = flucModelList[i];
break;
}
}
if("dummy" == modelName) mod = new G4DummyModel();
if(!mod) {
// set fluctuation model for ionisation processes
if(fluc && ptype == eloss) {
G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc);
p->SetFluctModel(fluc);
} else {
G4cout << "### G4EmConfigurator WARNING: fails to find a model <"
<< modelName << "> for process <"
<< processName << "> and " << particleName
<< G4endl;
if(flucModelName != "") {
G4cout << " fluctuation model <"
<< flucModelName << G4endl;
}
}
} else {
// search for region
G4Region* reg = 0;
G4RegionStore* regStore = G4RegionStore::GetInstance();
G4String r = regionName;
if(r == "" || r == "world" || r == "World") r = "DefaultRegionForTheWorld";
reg = regStore->GetRegion(r, true);
if(!reg) {
G4cout << "### G4EmConfigurator WARNING: fails to find a region <"
<< r << "> for model <" << modelName << "> of the process "
<< processName << " and " << particleName << G4endl;
return;
}
// energy limits
G4double e1 = std::max(emin,mod->LowEnergyLimit());
G4double e2 = std::min(emax,mod->HighEnergyLimit());
if(e2 < e1) e2 = e1;
mod->SetLowEnergyLimit(e1);
mod->SetHighEnergyLimit(e2);
//G4cout << "index= " << index << " e1= " << e1 << " e2= " << e2 << G4endl;
// added model
if(ptype == eloss) {
G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc);
p->AddEmModel(index,mod,fluc,reg);
//G4cout << "### Added eloss model order= " << index << " for "
// << particleName << " and " << processName << " " << mod << G4endl;
} else if(ptype == discrete) {
G4VEmProcess* p = static_cast<G4VEmProcess*>(proc);
p->AddEmModel(index,mod,reg);
} else if(ptype == msc) {
//G4cout << "### Added msc model order= " << index << " for "
// << particleName << " and " << processName << " " << mod << G4endl;
G4VMultipleScattering* p = static_cast<G4VMultipleScattering*>(proc);
p->AddEmModel(index,mod,reg);
}
}
}
}
// search for region
G4Region* reg = 0;
G4RegionStore* regStore = G4RegionStore::GetInstance();
G4String r = regionName;
if(r == "" || r == "world" || r == "World") {
r = "DefaultRegionForTheWorld";
}
reg = regStore->GetRegion(r, true);
if(!reg) {
G4cout << "### G4EmConfigurator WARNING: fails to find a region <"
<< r << G4endl;
} else if(verbose > 1) {
G4cout << "### G4EmConfigurator finds out G4Region <" << r << ">"
<< G4endl;
}
return reg;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4EmConfigurator::UpdateModelEnergyRange(G4VEmModel* mod,
G4double emin, G4double emax)
{
// energy limits
G4double e1 = std::max(emin,mod->LowEnergyLimit());
G4double e2 = std::min(emax,mod->HighEnergyLimit());
if(e2 <= e1) {
G4cout << "### G4EmConfigurator WARNING: empty energy interval"
<< " for <" << mod->GetName()
<< "> Emin(MeV)= " << e1/CLHEP::MeV
<< "> Emax(MeV)= " << e2/CLHEP::MeV
<< G4endl;
return false;
}
mod->SetLowEnergyLimit(e1);
mod->SetHighEnergyLimit(e2);
if(verbose > 1) {
G4cout << "### G4EmConfigurator for " << mod->GetName()
<< " Emin(MeV)= " << e1/MeV << " Emax(MeV)= " << e2/MeV
<< G4endl;
}
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmCorrections.cc,v 1.54 2009/10/29 17:56:36 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmCorrections.cc,v 1.64 2010/12/02 12:19:40 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -67,6 +67,8 @@
#include "G4PhysicsLogVector.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4AtomicShells.hh"
#include "G4LPhysicsFreeVector.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -90,6 +92,7 @@ G4EmCorrections::G4EmCorrections()
eCorrMax = 250.*MeV;
nist = G4NistManager::Instance();
ionTable = G4ParticleTable::GetParticleTable()->GetIonTable();
BarkasCorr = ThetaK = ThetaL = 0;
Initialise();
}
@@ -97,7 +100,10 @@ G4EmCorrections::G4EmCorrections()
G4EmCorrections::~G4EmCorrections()
{
for(G4int i=0; i<nIons; i++) {delete stopData[i];}
for(G4int i=0; i<nIons; ++i) {delete stopData[i];}
delete BarkasCorr;
delete ThetaK;
delete ThetaL;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -106,15 +112,15 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e, G4double)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
SetupKinematics(p, mat, e);
if(tau <= 0.0) return 0.0;
if(tau <= 0.0) { return 0.0; }
G4double Barkas = BarkasCorrection (p, mat, e);
G4double Bloch = BlochCorrection (p, mat, e);
@@ -122,11 +128,15 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
G4double sum = (2.0*(Barkas + Bloch) + Mott);
if(verbose > 1)
if(verbose > 1) {
G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
<< " Bloch= " << Bloch << " Mott= " << Mott
<< " Sum= " << sum << G4endl;
<< " Sum= " << sum << " q2= " << q2 << G4endl;
G4cout << " ShellCorrection: " << ShellCorrection(p, mat, e)
<< " Kshell= " << KShellCorrection(p, mat, e)
<< " Lshell= " << LShellCorrection(p, mat, e)
<< " " << mat->GetName() << G4endl;
}
sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
return sum;
}
@@ -137,11 +147,11 @@ G4double G4EmCorrections::IonBarkasCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
SetupKinematics(p, mat, e);
G4double res = 0.0;
@@ -157,14 +167,14 @@ G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
SetupKinematics(p, mat, e);
if(tau <= 0.0) return 0.0;
if(tau <= 0.0) { return 0.0; }
G4double Barkas = BarkasCorrection (p, mat, e);
G4double Bloch = BlochCorrection (p, mat, e);
@@ -179,7 +189,7 @@ G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
}
sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2;
if(verbose > 1) G4cout << " Sum= " << sum << G4endl;
if(verbose > 1) { G4cout << " Sum= " << sum << G4endl; }
return sum;
}
@@ -208,7 +218,7 @@ G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
thcorr[Z].resize(ncouples);
G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
for(size_t i=0; i<ncouples; i++) {
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;
@@ -218,7 +228,7 @@ G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e;
if(verbose > 1) G4cout << " Sum= " << sum << " dSum= " << rest/e << G4endl;
if(verbose > 1) { G4cout << " Sum= " << sum << " dSum= " << rest/e << G4endl; }
}
return sum;
}
@@ -255,7 +265,7 @@ G4double G4EmCorrections:: KShellCorrection(const G4ParticleDefinition* p,
{
SetupKinematics(p, mat, e);
G4double term = 0.0;
for (G4int i = 0; i<numberOfElements; i++) {
for (G4int i = 0; i<numberOfElements; ++i) {
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = G4int(Z);
@@ -265,8 +275,10 @@ G4double G4EmCorrections:: KShellCorrection(const G4ParticleDefinition* p,
f = 0.5;
Z2 = 1.0;
}
G4double e0= 13.6*eV*Z2;
term += f*atomDensity[i]*KShell(shells.GetBindingEnergy(iz,0)/e0,ba2/Z2)/Z;
G4double eta = ba2/Z2;
G4double tet = Z2*(1. + Z2*0.25*alpha2);
if(11 < iz) { tet = ThetaK->Value(Z); }
term += f*atomDensity[i]*KShell(tet,eta)/Z;
}
term /= material->GetTotNbOfAtomsPerVolume();
@@ -282,23 +294,27 @@ G4double G4EmCorrections:: LShellCorrection(const G4ParticleDefinition* p,
{
SetupKinematics(p, mat, e);
G4double term = 0.0;
for (G4int i = 0; i<numberOfElements; i++) {
for (G4int i = 0; i<numberOfElements; ++i) {
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = G4int(Z);
if(2 < iz) {
G4double Zeff = Z - ZD[10];
if(iz < 10) Zeff = Z - ZD[iz];
if(iz < 10) { Zeff = Z - ZD[iz]; }
G4double Z2= Zeff*Zeff;
G4double e0= 13.6*eV*Z2*0.25;
G4double f = 0.125;
G4int nmax = std::min(4,shells.GetNumberOfShells(iz));
for(G4int j=1; j<nmax; j++) {
G4double ne = G4double(shells.GetNumberOfElectrons(iz,j));
G4double e1 = shells.GetBindingEnergy(iz,j);
// G4cout << "LShell: j= " << j << " ne= " << ne << " e(eV)= " << e/eV
// << " e0(eV)= " << e0/eV << G4endl;
term += f*ne*atomDensity[i]*LShell(e1/e0,ba2/Z2)/Z;
G4double eta = ba2/Z2;
G4double tet = ThetaL->Value(Z);
G4int nmax = std::min(4,G4AtomicShells::GetNumberOfShells(iz));
for(G4int j=1; j<nmax; ++j) {
G4int ne = G4AtomicShells::GetNumberOfElectrons(iz,j);
if(15 >= iz) {
if(3 > j) { tet = 0.25*Z2*(1.0 + 5*Z2*alpha2/16.); }
else { tet = 0.25*Z2*(1.0 + Z2*alpha2/16.); }
}
//G4cout << " LShell: j= " << j << " ne= " << ne << " e(eV)= " << e/eV
// << " ThetaL= " << tet << G4endl;
term += f*ne*atomDensity[i]*LShell(tet,eta)/Z;
}
}
}
@@ -315,9 +331,16 @@ G4double G4EmCorrections::KShell(G4double tet, G4double eta)
G4double corr = 0.0;
G4double x = tet;
if(tet < TheK[0]) x = TheK[0];
G4int itet = Index(x, TheK, nK);
G4int itet = 0;
G4int ieta = 0;
if(tet < TheK[0]) {
x = TheK[0];
} else if(tet > TheK[nK-1]) {
x = TheK[nK-1];
itet = nK-2;
} else {
itet = Index(x, TheK, nK);
}
// assimptotic case
if(eta >= Eta[nEtaK-1]) {
corr = (Value(x, TheK[itet], TheK[itet+1], UK[itet], UK[itet+1]) +
@@ -325,18 +348,21 @@ G4double G4EmCorrections::KShell(G4double tet, G4double eta)
Value(x, TheK[itet], TheK[itet+1], ZK[itet], ZK[itet+1])/(eta*eta))/eta;
} else {
G4double y = eta;
if(eta < Eta[0]) y = Eta[0];
G4int ieta = Index(y, Eta, nEtaK);
if(eta < Eta[0]) {
y = Eta[0];
} else {
ieta = Index(y, Eta, nEtaK);
}
corr = Value2(x, y, TheK[itet], TheK[itet+1], Eta[ieta], Eta[ieta+1],
CK[itet][ieta], CK[itet+1][ieta],
CK[itet][ieta+1], CK[itet+1][ieta+1]);
//G4cout << " x= " <<x<<" y= "<<y<<" tet= " <<TheK[itet]
//<<" "<< TheK[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
// <<" CK= " << CK[itet][ieta]<<" "<< CK[itet+1][ieta]
//<<" "<< CK[itet][ieta+1]<<" "<< CK[itet+1][ieta+1]<<G4endl;
// <<" "<< TheK[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
// <<" CK= " << CK[itet][ieta]<<" "<< CK[itet+1][ieta]
// <<" "<< CK[itet][ieta+1]<<" "<< CK[itet+1][ieta+1]<<G4endl;
}
//G4cout << "Kshell: tet= " << tet << " eta= " << eta << " C= " << corr
//<< " itet,ieta= " << itet <<G4endl;
// << " itet= " << itet << " ieta= " << ieta <<G4endl;
return corr;
}
@@ -347,26 +373,39 @@ G4double G4EmCorrections::LShell(G4double tet, G4double eta)
G4double corr = 0.0;
G4double x = tet;
if(tet < TheL[0]) x = TheL[0];
G4int itet = Index(x, TheL, nL);
G4int itet = 0;
G4int ieta = 0;
if(tet < TheL[0]) {
x = TheL[0];
} else if(tet > TheL[nL-1]) {
x = TheL[nL-1];
itet = nL-2;
} else {
itet = Index(x, TheL, nL);
}
// assimptotic case
if(eta >= Eta[nEtaL-1]) {
corr = (Value(x, TheL[itet], TheL[itet+1], UL[itet], UL[itet+1])
+ Value(x, TheL[itet], TheL[itet+1], VL[itet], VL[itet+1])/eta
)/eta;
+ Value(x, TheL[itet], TheL[itet+1], VL[itet], VL[itet+1])/eta
)/eta;
} else {
G4double y = eta;
if(eta < Eta[0]) y = Eta[0];
G4int ieta = Index(y, Eta, nEtaL);
if(eta < Eta[0]) {
y = Eta[0];
} else {
ieta = Index(y, Eta, nEtaL);
}
corr = Value2(x, y, TheL[itet], TheL[itet+1], Eta[ieta], Eta[ieta+1],
CL[itet][ieta], CL[itet+1][ieta], CL[itet][ieta+1], CL[itet+1][ieta+1]);
CL[itet][ieta], CL[itet+1][ieta],
CL[itet][ieta+1], CL[itet+1][ieta+1]);
//G4cout << " x= " <<x<<" y= "<<y<<" tet= " <<TheL[itet]
//<<" "<< TheL[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
// <<" CL= " << CL[itet][ieta]<<" "<< CL[itet+1][ieta]
//<<" "<< CL[itet][ieta+1]<<" "<< CL[itet+1][ieta+1]<<G4endl;
// <<" "<< TheL[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
// <<" CL= " << CL[itet][ieta]<<" "<< CL[itet+1][ieta]
// <<" "<< CL[itet][ieta+1]<<" "<< CL[itet+1][ieta+1]<<G4endl;
}
// G4cout << "Lshell: tet= " << tet << " eta= " << eta << " C= " << corr << " itet= " << itet <<G4endl;
//G4cout<<"Lshell: tet= "<<tet<<" eta= "<<eta<<" itet= "<<itet
// <<" ieta= "<<ieta<<" Corr= "<<corr<<G4endl;
return corr;
}
@@ -408,14 +447,17 @@ G4double G4EmCorrections::ShellCorrectionSTD(const G4ParticleDefinition* p,
G4double G4EmCorrections::ShellCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
G4double ekin)
{
SetupKinematics(p, mat, e);
SetupKinematics(p, mat, ekin);
G4double term = 0.0;
//G4cout << "### G4EmCorrections::ShellCorrection " << mat->GetName()
// << " " << ekin/MeV << " MeV " << G4endl;
for (G4int i = 0; i<numberOfElements; ++i) {
for (G4int i = 0; i<numberOfElements; i++) {
G4double res = 0.0;
G4double res0 = 0.0;
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = G4int(Z);
G4double Z2= (Z-0.3)*(Z-0.3);
@@ -424,55 +466,69 @@ G4double G4EmCorrections::ShellCorrection(const G4ParticleDefinition* p,
f = 0.5;
Z2 = 1.0;
}
G4double e0= 13.6*eV*Z2;
term += f*atomDensity[i]*KShell(shells.GetBindingEnergy(iz,0)/e0,ba2/Z2)/Z;
G4double eta = ba2/Z2;
G4double tet = Z2*(1. + Z2*0.25*alpha2);
if(11 < iz) { tet = ThetaK->Value(Z); }
res0 = f*KShell(tet,eta);
res += res0;
//G4cout << " Z= " << iz << " Shell 0" << " tet= " << tet
// << " eta= " << eta << " resK= " << res0 << G4endl;
if(2 < iz) {
G4double Zeff = Z - ZD[10];
if(iz < 10) Zeff = Z - ZD[iz];
if(iz < 10) { Zeff = Z - ZD[iz]; }
Z2= Zeff*Zeff;
e0= 13.6*eV*Z2*0.25;
eta = ba2/Z2;
f = 0.125;
G4double eta = ba2/Z2;
G4int ntot = shells.GetNumberOfShells(iz);
tet = ThetaL->Value(Z);
G4int ntot = G4AtomicShells::GetNumberOfShells(iz);
G4int nmax = std::min(4, ntot);
G4double norm = 0.0;
G4double eshell = 0.0;
for(G4int j=1; j<nmax; j++) {
G4double x = G4double(shells.GetNumberOfElectrons(iz,j));
G4double e1 = shells.GetBindingEnergy(iz,j);
norm += x;
eshell += e1*x;
term += f*x*atomDensity[i]*LShell(e1/e0,eta)/Z;
for(G4int j=1; j<nmax; ++j) {
G4int ne = G4AtomicShells::GetNumberOfElectrons(iz,j);
if(15 >= iz) {
if(3 > j) { tet = 0.25*Z2*(1.0 + 5*Z2*alpha2/16.); }
else { tet = 0.25*Z2*(1.0 + Z2*alpha2/16.); }
}
norm += ne;
eshell += tet*ne;
res0 = f*ne*LShell(tet,eta);
res += res0;
//G4cout << " Z= " << iz << " Shell " << j << " Ne= " << ne
// << " tet= " << tet << " eta= " << eta
// << " resL= " << res0 << G4endl;
}
if(10 < iz) {
if(ntot > nmax) {
eshell /= norm;
G4double eeff = eshell*eta;
for(G4int k=nmax; k<ntot; k++) {
G4double x = G4double(shells.GetNumberOfElectrons(iz,k));
G4double e1 = shells.GetBindingEnergy(iz,k);
term += f*x*atomDensity[i]*LShell(e1/e0,eeff/e1)/Z;
// term += f*x*atomDensity[i]*LShell(eshell/e0,eeff/e1)/Z;
// Add M-shell
if(28 > iz) {
res += f*(iz - 10)*LShell(eshell,HM[iz-11]*eta);
} else if(63 > iz) {
res += f*18*LShell(eshell,HM[iz-11]*eta);
} else {
res += f*18*LShell(eshell,HM[52]*eta);
}
/*
if(28 >= iz) {
term += f*(Z - 10.)*atomDensity[i]*LShell(eshell,HM[iz-11]*eta)/Z;
} else if(32 >= iz) {
term += f*18.0*atomDensity[i]*LShell(eshell,HM[iz-11]*eta)/Z;
} else if(60 >= iz) {
term += f*18.0*atomDensity[i]*LShell(eshell,HM[iz-11]*eta)/Z;
term += f*(Z - 28.)*atomDensity[i]*LShell(eshell,HN[iz-33]*eta)/Z;
} else {
term += f*18.0*atomDensity[i]*LShell(eshell,HM[53]*eta)/Z;
term += f*32.0*atomDensity[i]*LShell(eshell,HN[30]*eta)/Z;
term += f*(Z - 60.)*atomDensity[i]*LShell(eshell,150.*eta)/Z;
// Add N-shell
if(32 < iz) {
if(60 > iz) {
res += f*(iz - 28)*LShell(eshell,HN[iz-33]*eta);
} else if(63 > iz) {
res += 4*LShell(eshell,HN[iz-33]*eta);
} else {
res += 4*LShell(eshell,HN[30]*eta);
}
// Add O-P-shells
if(60 < iz) {
res += f*(iz - 60)*LShell(eshell,150*eta);
}
}
*/
}
}
//term += atomDensity[i]*MSH[iz]/(ba2*ba2);
term += res*atomDensity[i]/Z;
}
term /= material->GetTotNbOfAtomsPerVolume();
//G4cout << "# Shell Correction= " << term << G4endl;
return term;
}
@@ -509,48 +565,54 @@ G4double G4EmCorrections::BarkasCorrection(const G4ParticleDefinition* p,
const G4Material* mat,
G4double e)
{
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pp. 2393-2397
// valid for kineticEnergy > 0.5 MeV
// . Z^3 Barkas effect in the stopping power of matter for charged particles
// J.C Ashley and R.H.Ritchie
// Physical review B Vol.5 No.7 1 April 1972 pp. 2393-2397
// valid for kineticEnergy > 0.5 MeV
SetupKinematics(p, mat, e);
G4double BarkasTerm = 0.0;
for (G4int i = 0; i<numberOfElements; i++) {
for (G4int i = 0; i<numberOfElements; ++i) {
G4double Z = (*theElementVector)[i]->GetZ();
G4int iz = G4int(Z);
if(iz == 47) {
BarkasTerm += atomDensity[i]*0.006812*std::pow(beta,-0.9);
} else if(iz >= 64) {
BarkasTerm += atomDensity[i]*0.002833*std::pow(beta,-1.2);
} else {
G4double X = ba2 / Z;
G4double b = 1.3;
if(1 == iz) {
if(material->GetName() == "G4_lH2") b = 0.6;
else b = 1.8;
G4double X = ba2 / Z;
G4double b = 1.3;
if(1 == iz) {
if(material->GetName() == "G4_lH2") { b = 0.6; }
else { b = 1.8; }
}
else if(2 == iz) { b = 0.6; }
else if(10 >= iz) { b = 1.8; }
else if(17 >= iz) { b = 1.4; }
else if(18 == iz) { b = 1.8; }
else if(25 >= iz) { b = 1.4; }
else if(50 >= iz) { b = 1.35;}
G4double W = b/std::sqrt(X);
G4double val = BarkasCorr->Value(W);
if(W > BarkasCorr->Energy(46)) {
val *= BarkasCorr->Energy(46)/W;
}
// G4cout << "i= " << i << " b= " << b << " W= " << W
// << " Z= " << Z << " X= " << X << " val= " << val<< G4endl;
BarkasTerm += val*atomDensity[i] / (std::sqrt(Z*X)*X);
}
else if(2 == iz) b = 0.6;
else if(10 >= iz) b = 1.8;
else if(17 >= iz) b = 1.4;
else if(18 == iz) b = 1.8;
else if(25 >= iz) b = 1.4;
else if(50 >= iz) b = 1.35;
G4double W = b/std::sqrt(X);
G4double val;
if(W <= engBarkas[0]) val = corBarkas[0];
else if(W >= engBarkas[46]) val = corBarkas[46]*engBarkas[46]/W;
else {
G4int iw = Index(W, engBarkas, 47);
val = Value(W, engBarkas[iw], engBarkas[iw+1],
corBarkas[iw], corBarkas[iw+1]);
}
// G4cout << "i= " << i << " b= " << b << " W= " << W
// << " Z= " << Z << " X= " << X << " val= " << val<< G4endl;
BarkasTerm += val*atomDensity[i] / (std::sqrt(Z*X)*X);
}
BarkasTerm *= 1.29*charge/material->GetTotNbOfAtomsPerVolume();
// temporary protection
//if(charge < -7.0 ) { BarkasTerm *= (-7.0/charge); }
return BarkasTerm;
}
@@ -573,7 +635,11 @@ G4double G4EmCorrections::BlochCorrection(const G4ParticleDefinition* p,
term += del;
} while (del > 0.01*term);
return -y2*term;
G4double res = -y2*term;
// temporary protection
//if(q2 > 49. && res < -0.2) { res = -0.2; }
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -601,7 +667,7 @@ G4double G4EmCorrections::NuclearDEDX(const G4ParticleDefinition* p,
lossFlucFlag = fluct;
// Projectile nucleus
G4double z1 = std::abs(particle->GetPDGCharge()/eplus);
G4double z1 = std::fabs(particle->GetPDGCharge()/eplus);
G4double m1 = mass/amu_c2;
// loop for the elements in the material
@@ -687,7 +753,7 @@ G4double G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition*
massFactor = proton_mass_c2/p->GetPDGMass();
idx = -1;
for(G4int i=0; i<nIons; i++) {
for(G4int i=0; i<nIons; ++i) {
if(materialList[i] == mat && currentZ == Zion[i]) {
idx = i;
break;
@@ -716,7 +782,7 @@ void G4EmCorrections::AddStoppingData(G4int Z, G4int A,
G4PhysicsVector* dVector)
{
G4int i = 0;
for(; i<nIons; i++) {
for(; i<nIons; ++i) {
if(Z == Zion[i] && A == Aion[i] && mname == materialName[i]) break;
}
if(i == nIons) {
@@ -781,7 +847,7 @@ void G4EmCorrections::BuildCorrectionVector()
//G4cout << "Escal(MeV)= "<<escal<<" dedxt0= " <<dedxt
// << " dedxt1= " << dedx1t << G4endl;
for(G4int i=0; i<=nbinCorr; i++) {
for(G4int i=0; i<=nbinCorr; ++i) {
e = vv->Energy(i);
escal = e/massRatio;
eion = escal/A;
@@ -807,7 +873,7 @@ void G4EmCorrections::BuildCorrectionVector()
delete v;
ionList[idx] = ion;
stopData[idx] = vv;
if(verbose>1) G4cout << "End data set " << G4endl;
if(verbose>1) { G4cout << "End data set " << G4endl; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -819,11 +885,11 @@ void G4EmCorrections::InitialiseForNewRun()
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(i=0; i<100; ++i) {thcorr[i].clear();}
for(i=0; i<ncouples; ++i) {
currmat[i] = tb->GetMaterialCutsCouple(i)->GetMaterial();
G4String nam = currmat[i]->GetName();
for(G4int j=0; j<nIons; j++) {
for(G4int j=0; j<nIons; ++j) {
if(nam == materialName[j]) { materialList[j] = currmat[i]; }
}
}
@@ -887,10 +953,9 @@ void G4EmCorrections::Initialise()
{ 9.0, 0.0032},
{ 10.0, 0.0025} };
for(i=0; i<47; i++) {
engBarkas[i] = fTable[i][0];
corBarkas[i] = fTable[i][1];
}
BarkasCorr = new G4LPhysicsFreeVector(47, 0.02, 10.);
for(i=0; i<47; ++i) { BarkasCorr->PutValues(i, fTable[i][0], fTable[i][1]); }
BarkasCorr->SetSpline(true);
const G4double nuca[104][2] = {
{ 1.0E+8, 5.831E-8},
@@ -1011,7 +1076,7 @@ void G4EmCorrections::Initialise()
{ 0.0, 3.166E-3}
};
for(i=0; i<104; i++) {
for(i=0; i<104; ++i) {
ed[i] = nuca[i][0];
a[i] = nuca[i][1];
}
@@ -1023,6 +1088,7 @@ void G4EmCorrections::Initialise()
// G.S. Khandelwal Nucl. Phys. A116(1968)97 - 111.
// "Shell corrections for K- and L- electrons
nK = 20;
nL = 26;
nEtaK = 29;
@@ -1048,9 +1114,9 @@ void G4EmCorrections::Initialise()
8.3191, 8.3199, 8.3211, 8.3218, 8.3226,
8.3244, 8.3264, 8.3285, 8.3308, 8.3320};
for(i=0; i<11; i++) { ZD[i] = d[i];}
for(i=0; i<11; ++i) { ZD[i] = d[i];}
for(i=0; i<nK; i++) {
for(i=0; i<nK; ++i) {
TheK[i] = thek[i];
SK[i] = sk[i];
TK[i] = tk[i];
@@ -1067,7 +1133,7 @@ void G4EmCorrections::Initialise()
7.2506, 7.0327, 6.8362, 6.7452, 6.6584,
6.4969, 6.3498, 6.2154, 6.0923, 6.0345, 5.9792};
const G4double tl[26] = {35.0669, 33.4344, 32.0073, 30.7466, 29.6226,
28.6128, 28.4149, 27.6991, 26.8674, 26.1061,
28.6128, 28.1449, 27.6991, 26.8674, 26.1061,
25.4058, 24.7587, 24.4531, 24.1583, 23.5992,
23.0771, 22.5880, 22.1285, 21.9090, 21.6958,
21.2872, 20.9006, 20.5341, 20.1859, 20.0183, 19.8546};
@@ -1076,7 +1142,7 @@ void G4EmCorrections::Initialise()
1.8036, 1.8543, 1.8756, 1.8945, 1.9262,
1.9508, 1.9696, 1.9836, 1.9890, 1.9935,
2.0001, 2.0039, 2.0053, 2.0049, 2.0040, 2.0028};
for(i=0; i<nL; i++) {
for(i=0; i<nL; ++i) {
TheL[i] = thel[i];
SL[i] = sl[i];
TL[i] = tl[i];
@@ -1339,29 +1405,33 @@ void G4EmCorrections::Initialise()
{5.0, 11.3211, 11.5818, 11.8601, 12.4771, 13.1898, 14.0213, 15.0024, 16.1752},
{7.0, 11.9480, 12.2357, 12.5432, 13.2260, 14.0164, 14.9404, 16.0330, 17.3420}
};
G4double b, bs;
for(i=0; i<nEtaK; i++) {
for(i=0; i<nEtaK; ++i) {
G4double et = eta[i];
G4double loget = std::log(et);
Eta[i] = et;
// G4cout << "### eta[" << i << "]= " << et << " KShell: tet= " << TheK[0]<<" - " <<TheK[nK-1]<< G4endl;
//G4cout << "### eta["<<i<<"]="<<et<<" KShell: tet= "<<TheK[0]<<" - "<<TheK[nK-1]<<G4endl;
for(j=0; j<nK; j++) {
for(j=0; j<nK; ++j) {
if(j < 10) b = bk2[i][10-j];
else b = bk1[i][20-j];
if(j < 10) { b = bk2[i][10-j]; }
else { b = bk1[i][20-j]; }
CK[j][i] = SK[j]*loget + TK[j] - b;
//G4cout << " " << CK[j][i];
if(i == nEtaK-1) ZK[j] = et*(et*et*CK[j][i] - et*UK[j] - VK[j]);
if(i == nEtaK-1) {
ZK[j] = et*(et*et*CK[j][i] - et*UK[j] - VK[j]);
//G4cout << "i= " << i << " j= " << j
// << " CK[j][i]= " << CK[j][i]
// << " ZK[j]= " << ZK[j] << " b= " << b << G4endl;
}
}
//G4cout << G4endl;
if(i < nEtaL) {
//G4cout << " LShell:" <<G4endl;
for(j=0; j<nL; j++) {
for(j=0; j<nL; ++j) {
if(j < 8) {
bs = bls3[i][8-j];
@@ -1375,8 +1445,14 @@ void G4EmCorrections::Initialise()
}
G4double c = SL[j]*loget + TL[j];
CL[j][i] = c - bs - 3.0*b;
//G4cout << " " << CL[j][i];
if(i == nEtaL-1) VL[j] = et*(et*CL[j][i] - UL[j]);
if(i == nEtaL-1) {
VL[j] = et*(et*CL[j][i] - UL[j]);
//G4cout << "i= " << i << " j= " << j
// << " CL[j][i]= " << CL[j][i]
// << " VL[j]= " << VL[j] << " b= " << b << " bs= " << bs
// << " et= " << et << G4endl;
//" UL= " << UL[j] << " TL= " << TL[j] << " SL= " << SL[j] <<G4endl;
}
}
//G4cout << G4endl;
}
@@ -1394,88 +1470,49 @@ void G4EmCorrections::Initialise()
19.5, 19.3, 19.2, 19.1, 18.4, 18.8, 18.7, 18.6, 18.5, 18.4,
18.2
};
for(i=0; i<53; i++) {HM[i] = hm[i];}
for(i=0; i<31; i++) {HN[i] = hn[i];}
for(i=0; i<53; ++i) {HM[i] = hm[i];}
for(i=0; i<31; ++i) {HN[i] = hn[i];}
const G4double mm[93] = {
0.0,
/*
-0.0001577, 5.396e-05, 0.0004194, -0.0001969, -0.0003447, -0.0001904, 9.612e-05, 4.16e-05, 0.0001899, 0.0001322,
0.0001485, 4.698e-05, -7.726e-05, -6.448e-05, 3.269e-05, -0.0001293, 0.0001483, -8.559e-05, 4.018e-05, 6.239e-05,
4.447e-05, 2.212e-05, -5.568e-06, 3.782e-05, 4.398e-05, 8.942e-05, 0.0002202, 0.0001357, 0.0001195, 0.0001812,
0.0002365, 4.508e-05, 0.0001629, 7.75e-05, 0.0001886, 0.0001601, 0.00015, 5.679e-05, 5.956e-06, -7.309e-05,
-0.0001144, -8.585e-05, -0.0001051, -8.209e-05, -5.871e-05, -3.744e-05, -6.707e-05, -9.199e-06, 1.181e-05, 2.252e-05,
1.051e-05, 7.63e-05, 1.71e-05, 1.705e-05, 1.561e-05, 8.987e-06, 4.957e-06, -1.473e-05, -1.902e-05, -1.491e-05,
-9.891e-08, 2.584e-05, 3.696e-05, 8.651e-06, -3.601e-06, 1.647e-05, 4.536e-05, 9.954e-05, 8.922e-05, 0.0001026,
4.094e-05, 3.788e-05, 1.578e-05, 2.731e-05, -6.035e-05, -9.112e-05, -8.846e-05, -0.0001361, -0.0001959, -0.0001883,
-0.0002854, -0.0004129, -0.0004611, -0.0005523, -0.0005869, -0.0005008, -0.000659, -0.0007045, -0.0007322, -0.0008374,
-0.0008731, -0.0009327,
-0.0003427, -4.685e-05, 0.0007304, -0.0003158, -0.0004104, -0.001133, -0.0007987, -0.0001528, 8.976e-05, 8.63e-05,
1.764e-05, -0.000136, -0.0002895, -0.0002618, -0.0002878, -0.0003813, 1.417e-05, -0.0004216, -0.0003859, -0.0001028,
-0.0001617, -0.0002141, -0.0002178, 5.59e-05, 9.964e-07, 7.528e-05, 0.0002261, 4.241e-05, 0.0005255, 0.0002139,
-5.821e-05, -2.661e-05, 0.0001039, 3.359e-05, 0.0004229, -0.0004872, 0.0001374, -2.79e-05, -1.319e-05, -0.0001077,
-0.0001923, -0.0001189, -0.0001091, -8.486e-05, 7.506e-05, 0.0001053, 0.0004596, 0.000177, 4.805e-05, 3.97e-05,
0.0004008, 0.0002194, 0.0001639, 0.0003285, 0.000219, 0.0001339, 6.323e-05, 2.013e-05, 2.568e-05, 4.346e-05,
8.455e-05, 8.785e-05, 0.0001393, 9.907e-05, 0.0001003, 0.0001508, 0.0002189, 0.0003885, 0.0003603, 0.0003839,
0.0003321, 0.0002207, 0.0001627, 0.0002282, 0.0002177, 0.0002156, 0.0002855, 0.0002361, 0.0007735, 0.0001157,
-0.0001214, -0.0002944, -0.0003193, -0.0004025, -0.0002436, -7.573e-05, -0.0003741, -0.0003678, -0.0004839, -0.0003934,
-0.0005817, -0.000726,
const G4double xzk[34] = { 11.7711,
13.3669, 15.5762, 17.1715, 18.7667, 20.8523, 23.0606, 24.901, 26.9861, 29.4394, 31.77,
34.3457, 37.4119, 40.3555, 42.3177, 44.7705, 47.2234, 50.78, 53.8458, 56.4214, 58.3834,
60.9586, 63.6567, 66.5998, 68.807, 71.8728, 74.5706, 77.3911, 81.8056, 85.7297, 89.8988,
93.4549, 96.2753, 99.709};
const G4double yzk[34] = { 0.70663,
0.72033, 0.73651, 0.74647, 0.75518, 0.76388, 0.77258, 0.78129, 0.78625, 0.7937, 0.79991,
0.80611, 0.8123, 0.8185, 0.82097, 0.82467, 0.82838, 0.83457, 0.83702, 0.84198, 0.8432,
0.84565, 0.84936, 0.85181, 0.85303, 0.85548, 0.85794, 0.8604, 0.86283, 0.86527, 0.86646,
0.86891, 0.87011, 0.87381};
-118, 40.37, 313.8, -147.3, -257.9, -142.4, 71.91, 31.12, 142.1, 98.92,
112.3, 41.36, -47.15, -17.84, 46.46, -66.91, 141.3, -19.96, 84.66, 110.2,
113.2, 108.7, 92.89, 127.3, 139.3, 187, 288.5, 233.4, 225.3, 284.6,
344.5, 246.2, 359.7, 324.1, 455, 457.1, 481, 459.8, 447.9, 407.5,
399.7, 457.7, 470.4, 511.8, 545.9, 581, 574.1, 638.6, 685.6, 719.6,
740.8, 817.2, 808.3, 839.7, 866.2, 873.2, 879.3, 886.3, 902, 912.7,
927.7, 942.1, 967.1, 962.2, 961.8, 993.4, 1006, 1060, 1046, 1061,
1036, 1060, 1062, 1084, 1048, 1063, 1098, 1093, 1089, 1117,
1085, 1044, 1033, 1027, 1051, 1150, 1064, 1078, 1090, 1140,
1119, 1097,
*/
const G4double xzl[36] = { 15.5102,
16.7347, 17.9592, 19.551, 21.0204, 22.6122, 24.9388, 27.3878, 29.5918, 31.3061, 32.898,
34.4898, 36.2041, 38.4082, 40.3674, 42.5714, 44.898, 47.4694, 49.9184, 52.7347, 55.9184,
59.3469, 61.9184, 64.6122, 67.4286, 71.4694, 75.2653, 78.3265, 81.2653, 85.551, 88.7347,
91.551, 94.2449, 96.449, 98.4082, 99.7551};
const G4double yzl[36] = { 0.29875,
0.31746, 0.33368, 0.35239, 0.36985, 0.38732, 0.41102, 0.43472, 0.45343, 0.4659, 0.47713,
0.4896, 0.50083, 0.51331, 0.52328, 0.53077, 0.54075, 0.54823, 0.55572, 0.56445, 0.57193,
0.58191, 0.5869, 0.59189, 0.60062, 0.60686, 0.61435, 0.61809, 0.62183, 0.62931, 0.6343,
0.6368, 0.64054, 0.64304, 0.64428, 0.64678};
-511.3, -69.91, 1090, -471.2, -612.4, -1690, -1192, -228, 133.9, 128.8,
28.71, -190.6, -408.7, -326.6, -378.5, -507.3, 93.63, -531, -459.2, -21.83,
-74.93, -121.7, -122.8, 285.2, 217.4, 366.3, 598.7, 341.8, 1078, 634.2,
280.5, 430.7, 663.5, 596.4, 1307, 6.814, 992.6, 887, 967.6, 868,
775.9, 1034, 1050, 1204, 1458, 1541, 2186, 1806, 1676, 1718,
2416, 2204, 2197, 2496, 2371, 2370, 2330, 2318, 2379, 2434,
2513, 2533, 2650, 2650, 2684, 2788, 2868, 3157, 3150, 3196,
3162, 3055, 3008, 3133, 3176, 3212, 3356, 3324, 4170, 3320,
3109, 2941, 2973, 2858, 3088, 3447, 3134, 3121, 3086, 3199,
3115, 2979,
ThetaK = new G4LPhysicsFreeVector(34, xzk[0], xzk[33]);
ThetaL = new G4LPhysicsFreeVector(36, xzl[0], xzl[35]);
for(i=0; i<34; ++i) { ThetaK->PutValues(i, xzk[i], yzk[i]); }
for(i=0; i<36; ++i) { ThetaL->PutValues(i, xzl[i], yzl[i]); }
ThetaK->SetSpline(true);
ThetaL->SetSpline(true);
};
const G4double ntau[93] = {
0.0,
-251.1, 512.8, 1724, 649, 658.8, 594.1, 946.6, 969.2, 1154, 997.8,
939.3, 775.5, 619.9, 848.3, 973.4, 1035, 1252, 698.8, 1043, 1080,
957, 885.6, 772.1, 847.1, 799.7, 901.7, 1042, 880.8, 857.7, 968,
850.4, 482.8, 781.4, 685, 1093, 847.4, 824.4, 751.5, 638, 489.2,
266.5, 371, 319.2, 356.6, 424.9, 405, 390.8, 610.6, 404.3, 444.6,
439, 579, 466.4, 520.5, 551.1, 441.6, 328.8, 264.3, 260.9, 274,
264.8, 235.1, 290, 196, 178.2, 248.4, 224.3, 268.2, 239.5, 253.9,
219.2, 172.7, 169.5, 199, 53.35, 65.78, 120.2, 77.13, 32.76, 45.53,
-148, -331.4, -386.4, -430.8, -361.1, -108.3, -382.4, -400.1, -458.4, -430.8,
-536.9, -627.6,
};
for(i=0; i<93; i++) {
MSH[i] = mm[i];
TAU[i] = ntau[i];
}
const G4double coseb[14] = {0.0,0.05,0.1,0.15,0.2,0.3,0.4,0.5,0.6,0.8,
1.0,1.2,1.5,2.0};
const G4double cosxi[14] = {1.0000, 0.9905, 0.9631, 0.9208, 0.8680,
0.7478, 0.6303, 0.5290, 0.4471, 0.3323,
0.2610, 0.2145, 0.1696, 0.1261};
for(i=0; i<14; i++) {
for(i=0; i<14; ++i) {
COSEB[i] = coseb[i];
COSXI[i] = cosxi[i];
}
for(i=1; i<100; i++) {
for(i=1; i<100; ++i) {
Z23[i] = std::pow(G4double(i),0.23);
}
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmElementSelector.cc,v 1.11 2009/09/29 11:31:37 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmElementSelector.cc,v 1.12 2010/04/27 16:59:52 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04-beta-01 $
//
// -------------------------------------------------------------------
//
@@ -57,7 +57,7 @@ G4EmElementSelector::G4EmElementSelector(G4VEmModel* mod,
G4int bins,
G4double emin,
G4double emax,
G4bool /*spline*/):
G4bool spline):
model(mod), material(mat), nbins(bins), cutEnergy(-1.0),
lowEnergy(emin), highEnergy(emax)
{
@@ -67,9 +67,12 @@ G4EmElementSelector::G4EmElementSelector(G4VEmModel* mod,
element = (*theElementVector)[0];
if(nElmMinusOne > 0) {
xSections.reserve(n);
for(G4int i=0; i<n; ++i) {
G4PhysicsLogVector* v = new G4PhysicsLogVector(lowEnergy,highEnergy,nbins);
//v->SetSpline(spline);
G4PhysicsLogVector* v0 = new G4PhysicsLogVector(lowEnergy,highEnergy,nbins);
xSections.push_back(v0);
v0->SetSpline(spline);
for(G4int i=1; i<n; ++i) {
G4PhysicsLogVector* v = new G4PhysicsLogVector(*v0);
v->SetSpline(spline);
xSections.push_back(v);
}
}
@@ -101,15 +104,13 @@ void G4EmElementSelector::Initialise(const G4ParticleDefinition* part,
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
G4int i;
// loop over bins
for(G4int j=0; j<=nbins; ++j) {
G4double e = (xSections[0])->Energy(j);
model->SetupForMaterial(part, material, e);
cross = 0.0;
//G4cout << "j= " << j << " e(MeV)= " << e/MeV << G4endl;
for (i=0; i<=nElmMinusOne; ++i) {
for (G4int i=0; i<=nElmMinusOne; ++i) {
cross += theAtomNumDensityVector[i]*
model->ComputeCrossSectionPerAtom(part, (*theElementVector)[i], e,
cutEnergy, e);
@@ -118,14 +119,14 @@ void G4EmElementSelector::Initialise(const G4ParticleDefinition* part,
}
// xSections start from null, so use probabilities from the next bin
if(DBL_MIN >= (*xSections[nElmMinusOne])[0]) {
for (i=0; i<=nElmMinusOne; ++i) {
if(0.0 == (*xSections[nElmMinusOne])[0]) {
for (G4int i=0; i<=nElmMinusOne; ++i) {
xSections[i]->PutValue(0, (*xSections[i])[1]);
}
}
// xSections ends with null, so use probabilities from the previous bin
if(DBL_MIN >= (*xSections[nElmMinusOne])[nbins]) {
for (i=0; i<=nElmMinusOne; ++i) {
if(0.0 == (*xSections[nElmMinusOne])[nbins]) {
for (G4int i=0; i<=nElmMinusOne; ++i) {
xSections[i]->PutValue(nbins, (*xSections[i])[nbins-1]);
}
}
@@ -133,8 +134,8 @@ void G4EmElementSelector::Initialise(const G4ParticleDefinition* part,
for(G4int j=0; j<=nbins; ++j) {
cross = (*xSections[nElmMinusOne])[j];
// only for positive X-section
if(cross > DBL_MIN) {
for (i=0; i<nElmMinusOne; ++i) {
if(cross > 0.0) {
for (G4int i=0; i<nElmMinusOne; ++i) {
G4double x = (*xSections[i])[j]/cross;
xSections[i]->PutValue(j, x);
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmModelManager.cc,v 1.58 2009/10/29 18:07:08 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmModelManager.cc,v 1.63 2010/10/15 10:22:13 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -419,11 +419,11 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
// Access to materials and build cuts
size_t idx = 1;
if(secondaryParticle) {
if( secondaryParticle == G4Gamma::Gamma() ) idx = 0;
else if( secondaryParticle == G4Positron::Positron()) idx = 2;
if( secondaryParticle == G4Gamma::Gamma() ) { idx = 0; }
else if( secondaryParticle == G4Positron::Positron()) { idx = 2; }
}
if(numOfCouples > theCuts.size()) {theCuts.resize(numOfCouples);}
if(numOfCouples > theCuts.size()) { theCuts.resize(numOfCouples); }
if(minSubRange < 1.0 && numOfCouples > theSubCuts.size()) {
theSubCuts.resize(numOfCouples);
}
@@ -459,30 +459,11 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
maxSubCutInRange);
G4double tcutmax =
theCoupleTable->ConvertRangeToEnergy(secondaryParticle,material,rcut);
if(tcutmax < subcut) subcut = tcutmax;
}
}
G4int nm = setOfRegionModels[reg]->NumberOfModels();
for(G4int j=0; j<nm; ++j) {
G4VEmModel* model = models[setOfRegionModels[reg]->ModelIndex(j)];
G4double tcutmin = model->MinEnergyCut(particle, couple);
if(cut < tcutmin) cut = tcutmin;
if(subcut < tcutmin) subcut = tcutmin;
if(1 < verboseLevel) {
G4cout << "The model # " << j
<< "; tcutmin(MeV)= " << tcutmin/MeV
<< "; tcut(MeV)= " << cut/MeV
<< "; tsubcut(MeV)= " << subcut/MeV
<< " for " << particle->GetParticleName()
<< G4endl;
if(tcutmax < subcut) { subcut = tcutmax; }
}
}
theCuts[i] = cut;
if(minSubRange < 1.0) theSubCuts[i] = subcut;
if(minSubRange < 1.0) { theSubCuts[i] = subcut; }
}
// initialize models
@@ -496,7 +477,7 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
if(flucModels[jj]) flucModels[jj]->InitialiseMe(particle);
}
}
if(1 == nn) severalModels = false;
if(1 == nn) { severalModels = false; }
if(1 < verboseLevel) {
G4cout << "G4EmModelManager for " << particle->GetParticleName()
@@ -655,7 +636,7 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
void G4EmModelManager::DumpModelList(G4int verb)
{
if(verb == 0) return;
if(verb == 0) { return; }
for(G4int i=0; i<nRegions; ++i) {
G4RegionModels* r = setOfRegionModels[i];
const G4Region* reg = r->Region();
@@ -664,13 +645,15 @@ void G4EmModelManager::DumpModelList(G4int verb)
G4cout << " ===== EM models for the G4Region " << reg->GetName()
<< " ======" << G4endl;;
for(G4int j=0; j<n; ++j) {
const G4VEmModel* m = models[r->ModelIndex(j)];
G4VEmModel* m = models[r->ModelIndex(j)];
G4cout << std::setw(20);
G4cout << m->GetName() << " : Emin= "
<< std::setw(10) << G4BestUnit(r->LowEdgeEnergy(j),"Energy")
<< " Emax= "
<< G4BestUnit(r->LowEdgeEnergy(j+1),"Energy")
<< G4endl;
G4cout << m->GetName() << " : Emin= "
<< std::setw(8) << G4BestUnit(r->LowEdgeEnergy(j),"Energy")
<< " Emax= "
<< std::setw(8) << G4BestUnit(r->LowEdgeEnergy(j+1),"Energy");
G4VEmAngularDistribution* an = m->GetAngularDistribution();
if(an) { G4cout << " " << an->GetName(); }
G4cout << G4endl;
}
}
if(1 == nEmModels) break;
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmMultiModel.cc,v 1.6 2007/05/22 17:31:58 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
// $Id: G4EmMultiModel.cc,v 1.8 2010/08/17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -39,13 +39,7 @@
//
// Modifications:
// 15-04-05 optimize internal interface (V.Ivanchenko)
//
// Class Description:
//
// Energy loss model using several G4VEmModels
// -------------------------------------------------------------------
// 04-07-10 updated interfaces according to g4 9.4 (V.Ivanchenko)
//
@@ -58,23 +52,24 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmMultiModel::G4EmMultiModel(const G4String& nam)
: G4VEmModel(nam),
nModels(0)
: G4VEmModel(nam), nModels(0)
{
model.clear();
tsecmin.clear();
cross_section.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmMultiModel::~G4EmMultiModel()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::AddModel(G4VEmModel* p)
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {
delete model[i];
}
}
cross_section.push_back(0.0);
model.push_back(p);
++nModels;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -82,36 +77,32 @@ G4EmMultiModel::~G4EmMultiModel()
void G4EmMultiModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {
if(nModels > 0) {
G4cout << "### Initialisation of EM MultiModel " << GetName()
<< " including following list of models:" << G4endl;
for(G4int i=0; i<nModels; ++i) {
G4cout << " " << (model[i])->GetName();
(model[i])->SetParticleChange(pParticleChange, GetModelOfFluctuations());
(model[i])->Initialise(p, cuts);
}
G4cout << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel::MinEnergyCut(const G4ParticleDefinition* p,
const G4MaterialCutsCouple* couple)
{
G4double cut = DBL_MAX;
if(nModels) {
cut = (model[0])->MinEnergyCut(p, couple);
}
return cut;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double cutEnergy)
G4double kineticEnergy,
G4double cutEnergy)
{
G4double dedx = 0.0;
SetCurrentCouple(couple);
G4double dedx = 0.0;
if(nModels) {
dedx = (model[0])->ComputeDEDX(couple, p, cutEnergy, kineticEnergy);
if(nModels > 0) {
for(G4int i=0; i<nModels; i++) {
dedx += (model[i])->ComputeDEDX(couple, p, cutEnergy, kineticEnergy);
}
}
return dedx;
@@ -119,20 +110,19 @@ G4double G4EmMultiModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel::CrossSection(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double cutEnergy,
G4double maxKinEnergy)
G4double G4EmMultiModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition* p,
G4double kinEnergy,
G4double Z,
G4double A,
G4double cutEnergy,
G4double maxEnergy)
{
G4double cross = 0.0;
G4double t1 = cutEnergy;
G4double t2 = cutEnergy;
if(nModels) {
for(G4int i=0; i<nModels; i++) {
t1 = std::max(t2, tsecmin[i]);
t2 = std::min(maxKinEnergy, tsecmin[i+1]);
cross += (model[i])->CrossSection(couple, p, kineticEnergy, t1, t2);
G4double cross = 0.0;
if(nModels>0) {
for(G4int i=0; i<nModels; ++i) {
(model[i])->SetCurrentCouple(CurrentCouple());
cross += (model[i])->ComputeCrossSectionPerAtom(p, kinEnergy, Z, A,
cutEnergy, maxEnergy);
}
}
return cross;
@@ -143,31 +133,25 @@ G4double G4EmMultiModel::CrossSection(const G4MaterialCutsCouple* couple,
void G4EmMultiModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double tmin,
G4double minEnergy,
G4double maxEnergy)
{
SetCurrentCouple(couple);
if(nModels > 0) {
G4int i;
G4double cross = 0.0;
G4double t1 = tmin;
G4double t2 = tmin;
for(i=0; i<nModels; i++) {
t1 = std::max(t2, tsecmin[i]);
t2 = std::min(maxEnergy, tsecmin[i+1]);
cross += (model[i])->CrossSection(couple, dp->GetDefinition(),
dp->GetKineticEnergy(), t1, t2);
for(i=0; i<nModels; ++i) {
cross += (model[i])->CrossSection(couple, dp->GetParticleDefinition(),
dp->GetKineticEnergy(), minEnergy, maxEnergy);
cross_section[i] = cross;
}
cross *= G4UniformRand();
t2 = tmin;
for(i=0; i<nModels; i++) {
t1 = std::max(t2, tsecmin[i]);
t2 = std::min(maxEnergy, tsecmin[i+1]);
for(i=0; i<nModels; ++i) {
if(cross <= cross_section[i]) {
(model[i])->SampleSecondaries(vdp, couple, dp, t1, t2);
break;
(model[i])->SampleSecondaries(vdp, couple, dp, minEnergy, maxEnergy);
return;
}
}
}
@@ -175,72 +159,3 @@ void G4EmMultiModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel:: MaxSecondaryEnergy(const G4ParticleDefinition*,
G4double kinEnergy)
{
G4cout << "Warning! G4EmMultiModel::"
<< "MaxSecondaryEnergy(const G4ParticleDefinition*,G4double kinEnergy)"
<< " should not be used!" << G4endl;
return kinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::DefineForRegion(const G4Region* r)
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {(model[i])->DefineForRegion(r);}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::AddModel(G4VEmModel* p, G4double tmin, G4double tmax)
{
if(tmin < tmax && 0.0 < tmin) {
if(nModels == 0) {
tsecmin.push_back(tmin);
tsecmin.push_back(tmax);
cross_section.push_back(0.0);
model.push_back(p);
nModels++;
} else {
G4int i, j;
G4bool increment = false;
for(i=0; i<nModels; i++) {
if(tmin < tsecmin[i]) {
G4double t2 = std::min(tsecmin[i+1],tmax);
if(tmin < t2) {
tsecmin.push_back(0.0);
cross_section.push_back(0.0);
model.push_back(0);
for(j=nModels; j>i; j--) {
model[j] = model[j-1];
tsecmin[j+1] = tsecmin[j];
}
model[i] = p;
tsecmin[i+1] = t2;
tsecmin[i] = tmin;
increment = true;
}
} else if(i == nModels-1) {
G4double t1 = std::min(tsecmin[i+1],tmin);
G4double t2 = std::max(tsecmin[i+1],tmax);
if(t1 < t2) {
tsecmin.push_back(t2);
cross_section.push_back(0.0);
model.push_back(p);
increment = true;
}
}
}
if(increment) nModels++;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmProcessOptions.cc,v 1.27 2009/10/29 19:25:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmProcessOptions.cc,v 1.30 2010/11/23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -59,6 +59,7 @@
#include "G4VMultipleScattering.hh"
#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "G4VAtomDeexcitation.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -78,27 +79,13 @@ G4EmProcessOptions::~G4EmProcessOptions()
void G4EmProcessOptions::SetLossFluctuations(G4bool val)
{
theManager->SetLossFluctuations(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetLossFluctuations(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetSubCutoff(G4bool val, const G4Region* r)
{
theManager->SetSubCutoff(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->ActivateSubCutoff(val, r);
}
theManager->SetSubCutoff(val, r);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -106,13 +93,6 @@ void G4EmProcessOptions::SetSubCutoff(G4bool val, const G4Region* r)
void G4EmProcessOptions::SetIntegral(G4bool val)
{
theManager->SetIntegral(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetIntegral(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -120,13 +100,6 @@ void G4EmProcessOptions::SetIntegral(G4bool val)
void G4EmProcessOptions::SetMinSubRange(G4double val)
{
theManager->SetMinSubRange(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetMinSubRange(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -134,27 +107,6 @@ void G4EmProcessOptions::SetMinSubRange(G4double val)
void G4EmProcessOptions::SetMinEnergy(G4double val)
{
theManager->SetMinEnergy(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetMinKinEnergy(val);
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->SetMinKinEnergy(val);
}
const std::vector<G4VMultipleScattering*>& u =
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
if(s) s->SetMinKinEnergy(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -162,27 +114,6 @@ void G4EmProcessOptions::SetMinEnergy(G4double val)
void G4EmProcessOptions::SetMaxEnergy(G4double val)
{
theManager->SetMaxEnergy(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetMaxKinEnergy(val);
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->SetMaxKinEnergy(val);
}
const std::vector<G4VMultipleScattering*>& u =
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
if(s) s->SetMaxKinEnergy(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -190,13 +121,6 @@ void G4EmProcessOptions::SetMaxEnergy(G4double val)
void G4EmProcessOptions::SetMaxEnergyForCSDARange(G4double val)
{
theManager->SetMaxEnergyForCSDARange(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetMaxKinEnergyForCSDARange(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -204,38 +128,6 @@ void G4EmProcessOptions::SetMaxEnergyForCSDARange(G4double val)
void G4EmProcessOptions::SetMaxEnergyForMuons(G4double val)
{
theManager->SetMaxEnergyForMuons(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) {
if(std::abs(p->Particle()->GetPDGMass() - 105.66*MeV) < MeV)
p->SetMaxKinEnergy(val);
}
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) {
if(std::abs(q->Particle()->GetPDGMass() - 105.66*MeV) < MeV)
q->SetMaxKinEnergy(val);
}
}
/*
const std::vector<G4VMultipleScattering*>& u =
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
if(s) {
if(std::abs(s->Particle()->GetPDGMass() - 105.66*MeV) < MeV)
s->SetMaxKinEnergy(val);
}
}
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -243,13 +135,6 @@ void G4EmProcessOptions::SetMaxEnergyForMuons(G4double val)
void G4EmProcessOptions::SetDEDXBinning(G4int val)
{
theManager->SetDEDXBinning(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetDEDXBinning(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -257,13 +142,6 @@ void G4EmProcessOptions::SetDEDXBinning(G4int val)
void G4EmProcessOptions::SetDEDXBinningForCSDARange(G4int val)
{
theManager->SetDEDXBinningForCSDARange(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetDEDXBinningForCSDARange(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -271,20 +149,6 @@ void G4EmProcessOptions::SetDEDXBinningForCSDARange(G4int val)
void G4EmProcessOptions::SetLambdaBinning(G4int val)
{
theManager->SetLambdaBinning(val);
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->SetLambdaBinning(val);
}
const std::vector<G4VMultipleScattering*>& u =
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
if(s) s->SetBinning(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -292,13 +156,6 @@ void G4EmProcessOptions::SetLambdaBinning(G4int val)
void G4EmProcessOptions::SetStepFunction(G4double v1, G4double v2)
{
theManager->SetStepFunction(v1, v2);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetStepFunction(v1, v2);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -306,13 +163,6 @@ void G4EmProcessOptions::SetStepFunction(G4double v1, G4double v2)
void G4EmProcessOptions::SetRandomStep(G4bool val)
{
theManager->SetRandomStep(val);
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetRandomStep(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -324,7 +174,7 @@ void G4EmProcessOptions::SetApplyCuts(G4bool val)
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->SetApplyCuts(val);
if(q) { q->SetApplyCuts(val); }
}
}
@@ -340,18 +190,20 @@ void G4EmProcessOptions::SetBuildCSDARange(G4bool val)
void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
{
G4bool all = false;
if("all" == name) all = true;
if("all" == name) { all = true; }
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
if(all) theManager->SetVerbose(val);
if(all) {
theManager->SetVerbose(val);
return;
}
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
for(itr = v.begin(); itr != v.end(); ++itr) {
G4VEnergyLossProcess* p = *itr;
if(p) {
if(all) p->SetVerboseLevel(val);
else if (p->GetProcessName() == name) p->SetVerboseLevel(val);
if (p->GetProcessName() == name) { p->SetVerboseLevel(val); }
}
}
const std::vector<G4VEmProcess*>& w =
@@ -360,8 +212,7 @@ void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) {
if(all) q->SetVerboseLevel(val);
else if (q->GetProcessName() == name) q->SetVerboseLevel(val);
if (q->GetProcessName() == name) { q->SetVerboseLevel(val); }
}
}
const std::vector<G4VMultipleScattering*>& u =
@@ -370,8 +221,7 @@ void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
if(s) {
if(all) s->SetVerboseLevel(val);
else if (s->GetProcessName() == name) s->SetVerboseLevel(val);
if (s->GetProcessName() == name) { s->SetVerboseLevel(val); }
}
}
}
@@ -385,9 +235,8 @@ void G4EmProcessOptions::SetLambdaFactor(G4double val)
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetLambdaFactor(val);
if(p) { p->SetLambdaFactor(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -415,7 +264,7 @@ void G4EmProcessOptions::ActivateDeexcitation(const G4String& pname,
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) {
if(pname == p->GetProcessName()) p->ActivateDeexcitation(val,r);
if(pname == p->GetProcessName()) { p->ActivateDeexcitation(val,r); }
}
}
const std::vector<G4VEmProcess*>& w =
@@ -424,13 +273,60 @@ void G4EmProcessOptions::ActivateDeexcitation(const G4String& pname,
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) {
if(pname == q->GetProcessName()) q->ActivateDeexcitation(val,r);
if(pname == q->GetProcessName()) { q->ActivateDeexcitation(val,r); }
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetDeexcitationActive(G4bool val)
{
G4VAtomDeexcitation* ad = theManager-> AtomDeexcitation();
if(ad) { ad->SetActive(val); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4EmProcessOptions::SetDeexcitationActiveRegion(const G4String& rname,
G4bool valDeexcitation,
G4bool valAuger,
G4bool valPIXE)
{
G4VAtomDeexcitation* ad = theManager-> AtomDeexcitation();
if(ad) {
ad->SetDeexcitationActiveRegion(rname, valDeexcitation,
valAuger,valPIXE);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetAugerActive(G4bool val)
{
G4VAtomDeexcitation* ad = theManager-> AtomDeexcitation();
if(ad) { ad->SetAugerActive(val); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetPIXEActive(G4bool val)
{
G4VAtomDeexcitation* ad = theManager-> AtomDeexcitation();
if(ad) { ad->SetPIXEActive(val); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetPIXECrossSectionModel(const G4String& mname)
{
G4VAtomDeexcitation* ad = theManager-> AtomDeexcitation();
if(ad) { ad->SetPIXECrossSectionModel(mname); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetMscStepLimitation(G4MscStepLimitType val)
{
const std::vector<G4VMultipleScattering*>& u =
@@ -449,7 +345,7 @@ void G4EmProcessOptions::SetMscLateralDisplacement(G4bool val)
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
if(*itm) (*itm)->SetLateralDisplasmentFlag(val);
if(*itm) { (*itm)->SetLateralDisplasmentFlag(val); }
}
}
@@ -462,9 +358,7 @@ void G4EmProcessOptions::SetSkin(G4double val)
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
if(*itm) {
(*itm)->SetSkin(val);
}
if(*itm) { (*itm)->SetSkin(val); }
}
}
@@ -477,7 +371,7 @@ void G4EmProcessOptions::SetMscRangeFactor(G4double val)
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
if(*itm) (*itm)->SetRangeFactor(val);
if(*itm) { (*itm)->SetRangeFactor(val); }
}
}
@@ -485,12 +379,12 @@ void G4EmProcessOptions::SetMscRangeFactor(G4double val)
void G4EmProcessOptions::SetMscGeomFactor(G4double val)
{
if(val < 0.0) return;
if(val < 0.0) { return; }
const std::vector<G4VMultipleScattering*>& u =
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
if(*itm) (*itm)->SetGeomFactor(val);
if(*itm) { (*itm)->SetGeomFactor(val); }
}
}
@@ -502,14 +396,14 @@ void G4EmProcessOptions::SetPolarAngleLimit(G4double val)
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
if(*itm) (*itm)->SetPolarAngleLimit(val);
if(*itm) { (*itm)->SetPolarAngleLimit(val); }
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->SetPolarAngleLimit(val);
if(q) { q->SetPolarAngleLimit(val); }
}
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4EmSaturation.cc,v 1.10 2009/09/25 09:16:40 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EmSaturation.cc,v 1.11 2010/10/25 17:23:01 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -58,12 +58,17 @@ G4EmSaturation::G4EmSaturation()
{
verbose = 1;
manager = 0;
curMaterial = 0;
curBirks = 0.0;
curRatio = 1.0;
curBirks = 0.0;
curRatio = 1.0;
curChargeSq = 1.0;
nMaterials = 0;
nMaterials = 0;
electron = 0;
proton = 0;
nist = G4NistManager::Instance();
Initialise();
}
@@ -81,7 +86,7 @@ G4double G4EmSaturation::VisibleEnergyDeposition(
G4double edep,
G4double niel)
{
if(edep <= 0.0) return 0.0;
if(edep <= 0.0) { return 0.0; }
G4double evis = edep;
G4double bfactor = FindBirksCoefficient(couple->GetMaterial());
@@ -108,11 +113,11 @@ G4double G4EmSaturation::VisibleEnergyDeposition(
}
// continues energy loss
if(eloss > 0.0) eloss /= (1.0 + bfactor*eloss/length);
if(eloss > 0.0) { eloss /= (1.0 + bfactor*eloss/length); }
// non-ionizing energy loss
if(nloss > 0.0) {
if(!proton) {proton = G4Proton::Proton();}
if(!proton) { proton = G4Proton::Proton(); }
G4double escaled = nloss*curRatio;
G4double s = manager->GetRange(proton,escaled,couple)/curChargeSq;
nloss /= (1.0 + bfactor*nloss/s);
@@ -132,7 +137,7 @@ G4double G4EmSaturation::FindG4BirksCoefficient(const G4Material* mat)
G4String name = mat->GetName();
// is this material in the vector?
for(G4int j=0; j<nG4Birks; j++) {
for(G4int j=0; j<nG4Birks; ++j) {
if(name == g4MatNames[j]) {
if(verbose > 0)
G4cout << "### G4EmSaturation::FindG4BirksCoefficient for "
@@ -151,12 +156,10 @@ G4double G4EmSaturation::FindBirksCoefficient(const G4Material* mat)
// electron should exist in any case
if(!manager) {
manager = G4LossTableManager::Instance();
nist = G4NistManager::Instance();
electron= G4Electron::Electron();
proton = 0;
}
if(mat == curMaterial) return curBirks;
if(mat == curMaterial) { return curBirks; }
curMaterial = mat;
curBirks = 0.0;
@@ -164,7 +167,7 @@ G4double G4EmSaturation::FindBirksCoefficient(const G4Material* mat)
curChargeSq = 1.0;
// seach in the run-time list
for(G4int i=0; i<nMaterials; i++) {
for(G4int i=0; i<nMaterials; ++i) {
if(mat == matPointers[i]) {
curBirks = mat->GetIonisation()->GetBirksConstant();
curRatio = massFactors[i];
@@ -179,7 +182,7 @@ G4double G4EmSaturation::FindBirksCoefficient(const G4Material* mat)
// material has no Birks coeffitient defined
// seach in the Geant4 list
if(curBirks == 0.0) {
for(G4int j=0; j<nG4Birks; j++) {
for(G4int j=0; j<nG4Birks; ++j) {
if(name == g4MatNames[j]) {
mat->GetIonisation()->SetBirksConstant(g4MatData[j]);
curBirks = g4MatData[j];
@@ -200,7 +203,7 @@ G4double G4EmSaturation::FindBirksCoefficient(const G4Material* mat)
const G4ElementVector* theElementVector = mat->GetElementVector();
const G4double* theAtomNumDensityVector = mat->GetVecNbOfAtomsPerVolume();
size_t nelm = mat->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
for (size_t i=0; i<nelm; ++i) {
const G4Element* elm = (*theElementVector)[i];
G4double Z = elm->GetZ();
G4double w = Z*Z*theAtomNumDensityVector[i];
@@ -230,7 +233,7 @@ void G4EmSaturation::DumpBirksCoefficients()
{
if(nMaterials > 0) {
G4cout << "### Birks coeffitients used in run time" << G4endl;
for(G4int i=0; i<nMaterials; i++) {
for(G4int i=0; i<nMaterials; ++i) {
G4double br = matPointers[i]->GetIonisation()->GetBirksConstant();
G4cout << " " << matNames[i] << " "
<< br*MeV/mm << " mm/MeV" << " "
@@ -247,7 +250,7 @@ void G4EmSaturation::DumpG4BirksCoefficients()
{
if(nG4Birks > 0) {
G4cout << "### Birks coeffitients for Geant4 materials" << G4endl;
for(G4int i=0; i<nG4Birks; i++) {
for(G4int i=0; i<nG4Birks; ++i) {
G4cout << " " << g4MatNames[i] << " "
<< g4MatData[i]*MeV/mm << " mm/MeV" << G4endl;
}
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4EnergyLossMessenger.cc,v 1.38 2009/10/29 19:25:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4EnergyLossMessenger.cc,v 1.40 2010/11/23 19:01:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -177,21 +177,48 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
aplCmd->SetDefaultValue(false);
aplCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
deCmd = new G4UIcmdWithABool("/process/em/fluo",this);
deCmd->SetGuidance("The flag to enable/disable deexcitation");
deCmd->SetParameterName("fluoFlag",true);
deCmd->SetDefaultValue(false);
deCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
auCmd = new G4UIcmdWithABool("/process/em/auger",this);
auCmd->SetGuidance("The flag to enable/disable Auger electrons");
auCmd->SetParameterName("augerFlag",true);
auCmd->SetDefaultValue(false);
auCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
pixeCmd = new G4UIcmdWithABool("/process/em/pixe",this);
pixeCmd->SetGuidance("The flag to enable/disable PIXE");
pixeCmd->SetParameterName("pixeFlag",true);
pixeCmd->SetDefaultValue(false);
pixeCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
pixeXsCmd = new G4UIcmdWithAString("/process/em/pixeXSmodel",this);
pixeXsCmd->SetGuidance("The name of PIXE cross section");
pixeXsCmd->SetParameterName("pixeXS",true);
pixeXsCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
deexCmd = new G4UIcommand("/process/em/deexcitation",this);
deexCmd->SetGuidance("Set deexcitation flag per process and G4Region.");
deexCmd->SetGuidance(" procName : process name");
deexCmd->SetGuidance(" flag : flag");
deexCmd->SetGuidance("Set deexcitation flags per G4Region.");
deexCmd->SetGuidance(" regName : G4Region name");
G4UIparameter* pName = new G4UIparameter("pName",'s',false);
deexCmd->SetParameter(pName);
G4UIparameter* flag = new G4UIparameter("flag",'s',false);
deexCmd->SetParameter(flag);
deexCmd->SetGuidance(" flagFluo : Fluorescence");
deexCmd->SetGuidance(" flagAuger : Auger");
deexCmd->SetGuidance(" flagPIXE : PIXE");
G4UIparameter* regName = new G4UIparameter("regName",'s',false);
deexCmd->SetParameter(regName);
G4UIparameter* flagFluo = new G4UIparameter("flagFluo",'b',false);
deexCmd->SetParameter(flagFluo);
G4UIparameter* flagAuger = new G4UIparameter("flagAuger",'b',false);
deexCmd->SetParameter(flagAuger);
G4UIparameter* flagPIXE = new G4UIparameter("flagPIXE",'b',false);
deexCmd->SetParameter(flagPIXE);
dedxCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsDEDX",this);
dedxCmd->SetGuidance("Set number of bins for DEDX tables");
dedxCmd->SetParameterName("binsDEDX",true);
@@ -296,6 +323,10 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
delete ver1Cmd;
delete mscCmd;
delete dedxCmd;
delete deCmd;
delete auCmd;
delete pixeCmd;
delete pixeXsCmd;
delete frCmd;
delete fgCmd;
delete lllCmd;
@@ -315,24 +346,24 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
if (command == RndmStepCmd) {
G4VEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
opt->SetRandomStep(RndmStepCmd->GetNewBoolValue(newValue));
return;
}
if (command == EnlossFlucCmd) {
G4VEnergyLoss::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
opt->SetLossFluctuations(EnlossFlucCmd->GetNewBoolValue(newValue));
return;
}
if (command == SubSecCmd) {
G4VEnergyLoss::SetSubSec(SubSecCmd->GetNewBoolValue(newValue));
opt->SetSubCutoff(SubSecCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == MinSubSecCmd) {
opt->SetMinSubRange(MinSubSecCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == StepFuncCmd) {
G4double v1,v2;
G4String unt;
@@ -341,17 +372,35 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
v2 *= G4UIcommand::ValueOf(unt);
G4VEnergyLoss::SetStepFunction(v1,v2);
opt->SetStepFunction(v1,v2);
return;
}
if (command == deexCmd) {
G4String s1 (""), s2(""), s3("");
G4bool b = false;
G4String s1 (""), s2(""), s3(""), s4("");
G4bool b2(false), b3(false), b4(false);
std::istringstream is(newValue);
is >> s1 >> s2 >> s3;
if(s2 == "true") b = true;
opt->ActivateDeexcitation(s1,b,s3);
is >> s1 >> s2 >> s3 >> s4;
if(s2 == "true") { b2 = true; }
if(s3 == "true") { b3 = true; }
if(s4 == "true") { b4 = true; }
opt->SetDeexcitationActiveRegion(s1,b2,b3,b4);
return;
}
if (command == deCmd) {
opt->SetDeexcitationActive(deCmd->GetNewBoolValue(newValue));
return;
}
if (command == auCmd) {
opt->SetAugerActive(auCmd->GetNewBoolValue(newValue));
return;
}
if (command == pixeCmd) {
opt->SetPIXEActive(pixeCmd->GetNewBoolValue(newValue));
return;
}
if (command == pixeXsCmd) {
opt->SetPIXECrossSectionModel(newValue);
return;
}
if (command == mscCmd) {
if(newValue == "Minimal")
opt->SetMscStepLimitation(fMinimal);
@@ -368,80 +417,91 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
return;
}
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == MinEnCmd) {
opt->SetMinEnergy(MinEnCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == MaxEnCmd) {
opt->SetMaxEnergy(MaxEnCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == IntegCmd) {
opt->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
return;
}
if (command == rangeCmd) {
opt->SetBuildCSDARange(rangeCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == lpmCmd) {
opt->SetLPMFlag(lpmCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == splCmd) {
opt->SetSplineFlag(splCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == aplCmd) {
opt->SetApplyCuts(aplCmd->GetNewBoolValue(newValue));
return;
}
if (command == latCmd) {
opt->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == verCmd) {
opt->SetVerbose(verCmd->GetNewIntValue(newValue));
return;
}
if (command == ver1Cmd) {
opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
return;
}
if (command == lllCmd) {
opt->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue));
return;
}
if (command == labCmd) {
opt->SetLambdaFactor(labCmd->GetNewDoubleValue(newValue));
return;
}
if (command == skinCmd) {
opt->SetSkin(skinCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == dedxCmd) {
opt->SetDEDXBinning(dedxCmd->GetNewIntValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == lamCmd) {
opt->SetLambdaBinning(lamCmd->GetNewIntValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == frCmd) {
opt->SetMscRangeFactor(frCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == fgCmd) {
opt->SetMscGeomFactor(fgCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == mscfCmd) {
opt->SetFactorForAngleLimit(mscfCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
return;
}
if (command == angCmd) {
opt->SetPolarAngleLimit(angCmd->GetNewDoubleValue(newValue));
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LossTableManager.cc,v 1.97 2009/10/29 19:25:28 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4LossTableManager.cc,v 1.105 2010/11/04 12:55:09 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -69,7 +69,8 @@
// left ionisation table for further usage (VI)
// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
// 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
// 21-02-08 Add G4EmSaturation (V.Ivanchenko)
// 21-02-08 Added G4EmSaturation (V.Ivanchenko)
// 12-04-10 Added PreparePhsyicsTables and BuildPhysicsTables entries (V.Ivanchenko)
//
// Class Description:
//
@@ -93,8 +94,11 @@
#include "G4EmCorrections.hh"
#include "G4EmSaturation.hh"
#include "G4EmConfigurator.hh"
#include "G4ElectronIonPair.hh"
#include "G4EmTableType.hh"
#include "G4LossTableBuilder.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4Region.hh"
G4LossTableManager* G4LossTableManager::theInstance = 0;
@@ -113,30 +117,33 @@ G4LossTableManager* G4LossTableManager::Instance()
G4LossTableManager::~G4LossTableManager()
{
for (G4int i=0; i<n_loss; i++) {
if( loss_vector[i] ) delete loss_vector[i];
for (G4int i=0; i<n_loss; ++i) {
if( loss_vector[i] ) { delete loss_vector[i]; }
}
size_t msc = msc_vector.size();
for (size_t j=0; j<msc; j++) {
if( msc_vector[j] ) delete msc_vector[j];
for (size_t j=0; j<msc; ++j) {
if( msc_vector[j] ) { delete msc_vector[j]; }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; k++) {
if( emp_vector[k] ) delete emp_vector[k];
for (size_t k=0; k<emp; ++k) {
if( emp_vector[k] ) { delete emp_vector[k]; }
}
size_t mod = mod_vector.size();
for (size_t a=0; a<mod; a++) {
if( mod_vector[a] ) delete mod_vector[a];
for (size_t a=0; a<mod; ++a) {
if( mod_vector[a] ) { delete mod_vector[a]; }
}
size_t fmod = fmod_vector.size();
for (size_t b=0; b<fmod; b++) {
if( fmod_vector[b] ) delete fmod_vector[b];
for (size_t b=0; b<fmod; ++b) {
if( fmod_vector[b] ) { delete fmod_vector[b]; }
}
Clear();
delete theMessenger;
delete tableBuilder;
delete emCorrections;
delete emSaturation;
delete emConfigurator;
delete emElectronIonPair;
delete atomDeexcitation;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -145,11 +152,11 @@ G4LossTableManager::G4LossTableManager()
{
n_loss = 0;
run = 0;
// first_entry = true;
startInitialisation = false;
all_tables_are_built = false;
all_tables_are_stored = false;
currentLoss = 0;
currentParticle = 0;
firstParticle = 0;
lossFluctuationFlag = true;
subCutoffFlag = false;
rndmStepFlag = false;
@@ -157,14 +164,10 @@ G4LossTableManager::G4LossTableManager()
maxRangeVariation = 1.0;
maxFinalStep = 0.0;
minKinEnergy = 0.1*keV;
maxKinEnergy = 100.0*TeV;
maxKinEnergyForMuons = 100.*TeV;
theMessenger = new G4EnergyLossMessenger();
theElectron = G4Electron::Electron();
tableBuilder = new G4LossTableBuilder();
emCorrections= new G4EmCorrections();
emSaturation = new G4EmSaturation();
emConfigurator = new G4EmConfigurator();
maxKinEnergy = 10.0*TeV;
nbinsLambda = 77;
nbinsPerDecade = 7;
maxKinEnergyForMuons = 10.*TeV;
integral = true;
integralActive = false;
buildCSDARange = false;
@@ -177,7 +180,15 @@ G4LossTableManager::G4LossTableManager()
bremsTh = DBL_MAX;
factorForAngleLimit = 1.0;
verbose = 1;
theMessenger = new G4EnergyLossMessenger();
theElectron = G4Electron::Electron();
tableBuilder = new G4LossTableBuilder();
emCorrections= new G4EmCorrections();
emSaturation = new G4EmSaturation();
emConfigurator = new G4EmConfigurator(verbose);
emElectronIonPair = new G4ElectronIonPair();
tableBuilder->SetSplineFlag(splineFlag);
atomDeexcitation = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -206,7 +217,7 @@ void G4LossTableManager::Clear()
void G4LossTableManager::Register(G4VEnergyLossProcess* p)
{
n_loss++;
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(0);
base_part_vector.push_back(0);
@@ -216,13 +227,13 @@ void G4LossTableManager::Register(G4VEnergyLossProcess* p)
tables_are_built.push_back(false);
isActive.push_back(true);
all_tables_are_built = false;
if(!lossFluctuationFlag) p->SetLossFluctuations(false);
if(subCutoffFlag) p->ActivateSubCutoff(true);
if(rndmStepFlag) p->SetRandomStep(true);
if(stepFunctionActive) p->SetStepFunction(maxRangeVariation, maxFinalStep);
if(integralActive) p->SetIntegral(integral);
if(minEnergyActive) p->SetMinKinEnergy(minKinEnergy);
if(maxEnergyActive) p->SetMaxKinEnergy(maxKinEnergy);
if(!lossFluctuationFlag) { p->SetLossFluctuations(false); }
if(subCutoffFlag) { p->ActivateSubCutoff(true); }
if(rndmStepFlag) { p->SetRandomStep(true); }
if(stepFunctionActive) { p->SetStepFunction(maxRangeVariation, maxFinalStep); }
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;
@@ -232,8 +243,8 @@ void G4LossTableManager::Register(G4VEnergyLossProcess* p)
void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
{
for (G4int i=0; i<n_loss; i++) {
if(loss_vector[i] == p) loss_vector[i] = 0;
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { loss_vector[i] = 0; }
}
}
@@ -253,8 +264,8 @@ void G4LossTableManager::Register(G4VMultipleScattering* p)
void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
{
size_t msc = msc_vector.size();
for (size_t i=0; i<msc; i++) {
if(msc_vector[i] == p) msc_vector[i] = 0;
for (size_t i=0; i<msc; ++i) {
if(msc_vector[i] == p) { msc_vector[i] = 0; }
}
}
@@ -274,8 +285,8 @@ void G4LossTableManager::Register(G4VEmProcess* p)
void G4LossTableManager::DeRegister(G4VEmProcess* p)
{
size_t emp = emp_vector.size();
for (size_t i=0; i<emp; i++) {
if(emp_vector[i] == p) emp_vector[i] = 0;
for (size_t i=0; i<emp; ++i) {
if(emp_vector[i] == p) { emp_vector[i] = 0; }
}
}
@@ -295,8 +306,8 @@ void G4LossTableManager::Register(G4VEmModel* p)
void G4LossTableManager::DeRegister(G4VEmModel* p)
{
size_t n = mod_vector.size();
for (size_t i=0; i<n; i++) {
if(mod_vector[i] == p) mod_vector[i] = 0;
for (size_t i=0; i<n; ++i) {
if(mod_vector[i] == p) { mod_vector[i] = 0; }
}
}
@@ -316,8 +327,8 @@ void G4LossTableManager::Register(G4VEmFluctuationModel* p)
void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p)
{
size_t n = fmod_vector.size();
for (size_t i=0; i<n; i++) {
if(fmod_vector[i] == p) fmod_vector[i] = 0;
for (size_t i=0; i<n; ++i) {
if(fmod_vector[i] == p) { fmod_vector[i] = 0; }
}
}
@@ -335,7 +346,7 @@ void G4LossTableManager::RegisterExtraParticle(
const G4ParticleDefinition* part,
G4VEnergyLossProcess* p)
{
n_loss++;
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(part);
base_part_vector.push_back(p->BaseParticle());
@@ -348,65 +359,25 @@ void G4LossTableManager::RegisterExtraParticle(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::EnergyLossProcessIsInitialised(
const G4ParticleDefinition* particle,
G4VEnergyLossProcess* p)
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEnergyLossProcess* p)
{
if (run == 0 || (particle == firstParticle && all_tables_are_built) ) {
all_tables_are_built = true;
if(1 < verbose)
G4cout << "### G4LossTableManager start initilisation of tables"
<< G4endl;
for (G4int i=0; i<n_loss; i++) {
G4VEnergyLossProcess* el = loss_vector[i];
if(el) {
const G4ProcessManager* pm = el->GetProcessManager();
isActive[i] = pm->GetProcessActivation(el);
tables_are_built[i] = false;
all_tables_are_built = false;
if(!isActive[i]) el->SetIonisation(false);
if(1 < verbose) {
G4cout << i <<". "<< el->GetProcessName()
<< " for " << pm->GetParticleType()->GetParticleName()
<< " active= " << pm->GetProcessActivation(el)
<< " table= " << tables_are_built[i]
<< " isIonisation= " << el->IsIonisationProcess()
<< G4endl;
}
} else {
tables_are_built[i] = true;
part_vector[i] = 0;
}
}
if (0 == run) firstParticle = particle;
run++;
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << " run= " << run << G4endl;
}
// start initialisation for the first run
startInitialisation = true;
currentParticle = 0;
if( 0 == run ) {
emConfigurator->PrepareModels(particle, p);
SetParameters(p);
for (G4int j=0; j<n_loss; j++) {
if (p == loss_vector[j]) {
if (!part_vector[j]) {
part_vector[j] = particle;
base_part_vector[j] = p->BaseParticle();
}
if(maxEnergyForMuonsActive) {
G4double dm = std::abs(particle->GetPDGMass() - 105.7*MeV);
if(dm < 5.*MeV) p->SetMaxKinEnergy(maxKinEnergyForMuons);
}
if(1 < verbose) {
G4cout << "For " << p->GetProcessName()
<< " for " << part_vector[j]->GetParticleName()
<< " tables_are_built= " << tables_are_built[j]
<< " procFlag= " << loss_vector[j]->TablesAreBuilt()
<< " all_tables_are_built= " << all_tables_are_built
<< G4endl;
// initialise particles for given process
for (G4int j=0; j<n_loss; ++j) {
if (p == loss_vector[j]) {
if (!part_vector[j]) { part_vector[j] = particle; }
}
}
}
@@ -414,28 +385,47 @@ void G4LossTableManager::EnergyLossProcessIsInitialised(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4EnergyLossMessenger* G4LossTableManager::GetMessenger()
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEmProcess* p)
{
return theMessenger;
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
// start initialisation for the first run
if( 0 == run ) {
emConfigurator->PrepareModels(particle, p);
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::ParticleHaveNoLoss(
const G4ParticleDefinition* aParticle)
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VMultipleScattering* p)
{
G4String s = " dE/dx table not found for "
+ aParticle->GetParticleName() + " !";
G4Exception("G4LossTableManager::ParticleHaveNoLoss", "EM01",
FatalException, s);
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
// start initialisation for the first run
if( 0 == run ) {
emConfigurator->PrepareModels(particle, p);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4bool G4LossTableManager::BuildCSDARange() const
void
G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition*)
{
return buildCSDARange;
if(0 == run && startInitialisation) {
emConfigurator->Clear();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -450,31 +440,86 @@ void G4LossTableManager::BuildPhysicsTable(
<< " and process " << p->GetProcessName()
<< G4endl;
}
if (all_tables_are_built) return;
all_tables_are_built = true;
// clear configurator
if(0 == run && startInitialisation) {
emConfigurator->Clear();
firstParticle = aParticle;
}
if(startInitialisation && atomDeexcitation) {
atomDeexcitation->InitialiseAtomicDeexcitation();
}
startInitialisation = false;
for(G4int i=0; i<n_loss; i++) {
if(!tables_are_built[i] && !base_part_vector[i]) {
const G4ParticleDefinition* curr_part = part_vector[i];
G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
if(curr_proc) CopyTables(curr_part, curr_proc);
// initialisation before any table is built
if ( aParticle == firstParticle ) {
all_tables_are_built = true;
if(1 < verbose) {
G4cout << "### G4LossTableManager start initilisation for first particle "
<< firstParticle->GetParticleName()
<< G4endl;
}
for (G4int i=0; i<n_loss; ++i) {
G4VEnergyLossProcess* el = loss_vector[i];
if(el) {
const G4ProcessManager* pm = el->GetProcessManager();
isActive[i] = pm->GetProcessActivation(el);
if(0 == run) { base_part_vector[i] = el->BaseParticle(); }
tables_are_built[i] = false;
all_tables_are_built= false;
if(!isActive[i]) { el->SetIonisation(false); }
if(1 < verbose) {
G4cout << i <<". "<< el->GetProcessName()
<< " for " << pm->GetParticleType()->GetParticleName()
<< " active= " << pm->GetProcessActivation(el)
<< " table= " << tables_are_built[i]
<< " isIonisation= " << el->IsIonisationProcess();
if(base_part_vector[i]) {
G4cout << " base particle " << base_part_vector[i]->GetParticleName();
}
G4cout << G4endl;
}
} else {
tables_are_built[i] = true;
part_vector[i] = 0;
}
}
++run;
currentParticle = 0;
}
for (G4int ii=0; ii<n_loss; ii++) {
if ( !tables_are_built[ii] ) {
all_tables_are_built = false;
break;
// Set run time parameters
SetParameters(aParticle, p);
if (all_tables_are_built) { return; }
// Build tables for given particle
all_tables_are_built = true;
for(G4int i=0; i<n_loss; ++i) {
if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
const G4ParticleDefinition* curr_part = part_vector[i];
if(1 < verbose) {
G4cout << "### BuildPhysicsTable for " << p->GetProcessName()
<< " and " << curr_part->GetParticleName()
<< " start BuildTable " << G4endl;
}
G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
if(curr_proc) { CopyTables(curr_part, curr_proc); }
}
if ( !tables_are_built[i] ) { all_tables_are_built = false; }
}
if(1 < verbose) {
G4cout << "### G4LossTableManager::BuildDEDXTable end: "
<< "all_tables_are_built= " << all_tables_are_built
<< G4endl;
if(all_tables_are_built)
if(all_tables_are_built) {
G4cout << "### All dEdx and Range tables are built #####" << G4endl;
}
}
}
@@ -483,11 +528,11 @@ void G4LossTableManager::BuildPhysicsTable(
void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
G4VEnergyLossProcess* base_proc)
{
for (G4int j=0; j<n_loss; j++) {
for (G4int j=0; j<n_loss; ++j) {
G4VEnergyLossProcess* proc = loss_vector[j];
if(proc == base_proc || proc->Particle() == part)
tables_are_built[j] = true;
//if(proc == base_proc || proc->Particle() == part)
// tables_are_built[j] = true;
if (!tables_are_built[j] && part == base_part_vector[j]) {
tables_are_built[j] = true;
@@ -510,8 +555,9 @@ void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
}
}
if (theElectron == part && theElectron == proc->SecondaryParticle() )
if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
}
}
}
@@ -534,7 +580,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
G4PhysicsTable* dedx = 0;
G4int i;
for (i=0; i<n_loss; i++) {
for (i=0; i<n_loss; ++i) {
p = loss_vector[i];
if (p && aParticle == part_vector[i] && !tables_are_built[i]) {
if ((p->IsIonisationProcess() && isActive[i]) ||
@@ -553,7 +599,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
}
G4int n_dedx = t_list.size();
if (!n_dedx) {
if (0 == n_dedx || !em) {
G4cout << "G4LossTableManager WARNING: no DEDX processes for "
<< aParticle->GetParticleName() << G4endl;
return 0;
@@ -601,7 +647,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
std::vector<G4PhysicsTable*> listSub;
std::vector<G4PhysicsTable*> listCSDA;
for (i=0; i<n_dedx; i++) {
for (i=0; i<n_dedx; ++i) {
p = loss_list[i];
p->SetIonisation(false);
p->SetLambdaTable(p->BuildLambdaTable(fRestricted));
@@ -657,21 +703,47 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4EnergyLossMessenger* G4LossTableManager::GetMessenger()
{
return theMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::ParticleHaveNoLoss(
const G4ParticleDefinition* aParticle)
{
G4String s = " dE/dx table not found for "
+ aParticle->GetParticleName() + " !";
G4Exception("G4LossTableManager::ParticleHaveNoLoss", "EM01",
FatalException, s);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4bool G4LossTableManager::BuildCSDARange() const
{
return buildCSDARange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::SetLossFluctuations(G4bool val)
{
lossFluctuationFlag = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetLossFluctuations(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetLossFluctuations(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::SetSubCutoff(G4bool val)
void G4LossTableManager::SetSubCutoff(G4bool val, const G4Region* r)
{
subCutoffFlag = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->ActivateSubCutoff(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->ActivateSubCutoff(val, r); }
}
}
@@ -681,12 +753,12 @@ void G4LossTableManager::SetIntegral(G4bool val)
{
integral = val;
integralActive = true;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetIntegral(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetIntegral(val); }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; k++) {
if(emp_vector[k]) emp_vector[k]->SetIntegral(val);
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetIntegral(val); }
}
}
@@ -695,8 +767,8 @@ void G4LossTableManager::SetIntegral(G4bool val)
void G4LossTableManager::SetMinSubRange(G4double val)
{
minSubRange = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetMinSubRange(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetMinSubRange(val); }
}
}
@@ -705,8 +777,8 @@ void G4LossTableManager::SetMinSubRange(G4double val)
void G4LossTableManager::SetRandomStep(G4bool val)
{
rndmStepFlag = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetRandomStep(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetRandomStep(val); }
}
}
@@ -716,16 +788,16 @@ void G4LossTableManager::SetMinEnergy(G4double val)
{
minEnergyActive = true;
minKinEnergy = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetMinKinEnergy(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);
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);
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetMinKinEnergy(val); }
}
}
@@ -735,16 +807,16 @@ void G4LossTableManager::SetMaxEnergy(G4double val)
{
maxEnergyActive = true;
maxKinEnergy = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetMaxKinEnergy(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);
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);
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetMaxKinEnergy(val); }
}
}
@@ -752,8 +824,8 @@ void G4LossTableManager::SetMaxEnergy(G4double val)
void G4LossTableManager::SetMaxEnergyForCSDARange(G4double val)
{
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetMaxKinEnergyForCSDARange(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergyForCSDARange(val); }
}
}
@@ -769,8 +841,8 @@ void G4LossTableManager::SetMaxEnergyForMuons(G4double val)
void G4LossTableManager::SetDEDXBinning(G4int val)
{
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetDEDXBinning(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetDEDXBinning(val); }
}
}
@@ -778,8 +850,8 @@ void G4LossTableManager::SetDEDXBinning(G4int val)
void G4LossTableManager::SetDEDXBinningForCSDARange(G4int val)
{
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetDEDXBinningForCSDARange(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetDEDXBinningForCSDARange(val); }
}
}
@@ -787,32 +859,54 @@ void G4LossTableManager::SetDEDXBinningForCSDARange(G4int val)
void G4LossTableManager::SetLambdaBinning(G4int val)
{
G4int n = val/G4int(std::log10(maxKinEnergy/minKinEnergy));
if(n < 5) {
G4cout << "G4LossTableManager::SetLambdaBinning WARNING "
<< "too small number of bins " << val << " ignored"
<< G4endl;
return;
}
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);
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);
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetLambdaBinning(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4int G4LossTableManager::GetNumberOfBinsPerDecade() const
{
return nbinsPerDecade;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::SetVerbose(G4int val)
{
verbose = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetVerboseLevel(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetVerboseLevel(val); }
}
size_t msc = msc_vector.size();
for (size_t j=0; j<msc; j++) {
if(msc_vector[j]) msc_vector[j]->SetVerboseLevel(val);
for (size_t j=0; j<msc; ++j) {
if(msc_vector[j]) { msc_vector[j]->SetVerboseLevel(val); }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; k++) {
if(emp_vector[k]) emp_vector[k]->SetVerboseLevel(val);
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetVerboseLevel(val); }
}
emConfigurator->SetVerbose(val);
//tableBuilder->SetVerbose(val);
//emCorrections->SetVerbose(val);
emSaturation->SetVerbose(val);
emElectronIonPair->SetVerbose(val);
if(atomDeexcitation) { atomDeexcitation->SetVerboseLevel(val); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -822,8 +916,8 @@ void G4LossTableManager::SetStepFunction(G4double v1, G4double v2)
stepFunctionActive = true;
maxRangeVariation = v1;
maxFinalStep = v2;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetStepFunction(v1, v2);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetStepFunction(v1, v2); }
}
}
@@ -831,8 +925,8 @@ void G4LossTableManager::SetStepFunction(G4double v1, G4double v2)
void G4LossTableManager::SetLinearLossLimit(G4double val)
{
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetLinearLossLimit(val);
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetLinearLossLimit(val); }
}
}
@@ -845,19 +939,25 @@ void G4LossTableManager::SetBuildCSDARange(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::SetParameters(G4VEnergyLossProcess* p)
void
G4LossTableManager::SetParameters(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(stepFunctionActive) p->SetStepFunction(maxRangeVariation, maxFinalStep);
if(integralActive) p->SetIntegral(integral);
if(minEnergyActive) p->SetMinKinEnergy(minKinEnergy);
if(maxEnergyActive) p->SetMaxKinEnergy(maxKinEnergy);
if(stepFunctionActive) { p->SetStepFunction(maxRangeVariation, maxFinalStep); }
if(integralActive) { p->SetIntegral(integral); }
if(minEnergyActive) { p->SetMinKinEnergy(minKinEnergy); }
if(maxEnergyActive) { p->SetMaxKinEnergy(maxKinEnergy); }
p->SetVerboseLevel(verbose);
if(maxEnergyForMuonsActive) {
G4double dm = std::abs(aParticle->GetPDGMass() - 105.7*MeV);
if(dm < 5.*MeV) { p->SetMaxKinEnergy(maxKinEnergyForMuons); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
const std::vector<G4VEnergyLossProcess*>&
G4LossTableManager::GetEnergyLossProcessVector()
G4LossTableManager::GetEnergyLossProcessVector()
{
return loss_vector;
}
@@ -872,7 +972,7 @@ const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
const std::vector<G4VMultipleScattering*>&
G4LossTableManager::GetMultipleScatteringVector()
G4LossTableManager::GetMultipleScatteringVector()
{
return msc_vector;
}
@@ -924,7 +1024,7 @@ G4double G4LossTableManager::BremsstrahlungTh() const
void G4LossTableManager::SetFactorForAngleLimit(G4double val)
{
if(val > 0.0) factorForAngleLimit = val;
if(val > 0.0) { factorForAngleLimit = val; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -955,4 +1055,24 @@ G4EmConfigurator* G4LossTableManager::EmConfigurator()
return emConfigurator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ElectronIonPair* G4LossTableManager::ElectronIonPair()
{
return emElectronIonPair;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VAtomDeexcitation* G4LossTableManager::AtomDeexcitation()
{
return atomDeexcitation;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4LossTableManager::SetAtomDeexcitation(G4VAtomDeexcitation* p)
{
atomDeexcitation = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,276 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VAtomDeexcitation.cc,v 1.7 2010/11/22 18:18:08 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class class file
//
//
// File name: G4VAtomDeexcitation
//
// Author: Alfonso Mantero & Vladimir Ivanchenko
//
// Creation date: 21.04.2010
//
// Modifications:
//
// Class Description:
//
// Abstract interface to energy loss models
// -------------------------------------------------------------------
//
#include "G4VAtomDeexcitation.hh"
#include "G4ParticleDefinition.hh"
#include "G4DynamicParticle.hh"
#include "G4Step.hh"
#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Material.hh"
#include "G4Element.hh"
#include "G4ElementVector.hh"
#include "Randomize.hh"
#include "G4VParticleChange.hh"
G4VAtomDeexcitation::G4VAtomDeexcitation(const G4String& modname,
const G4String& pname)
: lowestKinEnergy(keV), verbose(1), name(modname), namePIXE(pname),
isActive(false), flagAuger(false), flagPIXE(false)
{
vdyn.reserve(5);
secVect.reserve(5);
theCoupleTable = 0;
SetDeexcitationActiveRegion("World");
}
G4VAtomDeexcitation::~G4VAtomDeexcitation()
{}
void G4VAtomDeexcitation::InitialiseAtomicDeexcitation()
{
// Define list of couples
theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
activeDeexcitationMedia.resize(numOfCouples, false);
activeAugerMedia.resize(numOfCouples, false);
activePIXEMedia.resize(numOfCouples, false);
activeZ.resize(93, false);
// check if deexcitation is active for the given run
if( !isActive ) { return; }
// Define list of regions
size_t nRegions = activeRegions.size();
// There is no active regions
if(0 == nRegions) { return; }
if(0 < verbose) {
G4cout << G4endl;
G4cout << "### === Deexcitation model " << name
<< " is activated for regions:" << G4endl;
}
// Identify active media
G4RegionStore* regionStore = G4RegionStore::GetInstance();
for(size_t j=0; j<nRegions; ++j) {
const G4Region* reg = regionStore->GetRegion(activeRegions[j], false);
const G4ProductionCuts* rpcuts = reg->GetProductionCuts();
if(0 < verbose) {
G4cout << " " << activeRegions[j] << G4endl;
}
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) { activeZ[Z] = true; }
}
}
}
}
}
}
// Initialise derived class
InitialiseForNewRun();
if(0 < verbose && flagPIXE) {
G4cout << "### === PIXE model: " << namePIXE
<< " " << IsPIXEActive()
<< G4endl;
}
}
void
G4VAtomDeexcitation::SetDeexcitationActiveRegion(const G4String& rname,
G4bool valDeexcitation,
G4bool valAuger,
G4bool valPIXE)
{
G4String s = rname;
if(s == "world" || s == "World" || s == "WORLD") {
s = "DefaultRegionForTheWorld";
}
size_t n = activeRegions.size();
if(n > 0) {
for(size_t i=0; i<n; ++i) {
// Region already exist
if(s == activeRegions[i]) {
deRegions[i] = valDeexcitation;
AugerRegions[i] = valAuger;
PIXERegions[i] = valPIXE;
return;
}
}
}
// New region
activeRegions.push_back(s);
deRegions.push_back(valDeexcitation);
AugerRegions.push_back(valAuger);
PIXERegions.push_back(valPIXE);
}
void
G4VAtomDeexcitation::AlongStepDeexcitation(G4VParticleChange* pParticleChange,
const G4Step& step,
G4double& eLoss,
G4int coupleIndex)
{
if(!CheckDeexcitationActiveRegion(coupleIndex) || !flagPIXE
|| !activePIXEMedia[coupleIndex] || eLoss == 0.0) { return; }
// step parameters
const G4StepPoint* preStep = step.GetPreStepPoint();
G4ThreeVector prePos = preStep->GetPosition();
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; }
// media parameters
G4double gCut = (*(theCoupleTable->GetEnergyCutsVector(0)))[coupleIndex];
G4double eCut = DBL_MAX;
if(flagAuger && CheckAugerActiveRegion(coupleIndex)) {
eCut = (*(theCoupleTable->GetEnergyCutsVector(1)))[coupleIndex];
}
const G4Material* material = preStep->GetMaterial();
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
G4int nelm = material->GetNumberOfElements();
//G4cout<<"!Sample PIXE gCut(MeV)= "<<gCut<<" eCut(MeV)= "<<eCut
// <<" Ekin(MeV)= " << ekin/MeV <<G4endl;
// loop over deexcitations
secVect.clear();
for(G4int i=0; i<nelm; ++i) {
G4int Z = G4int((*theElementVector)[i]->GetZ());
if(Z >= 93) { continue; }
if(!activeZ[Z]) { continue; }
G4double rho = theAtomNumDensityVector[i];
//G4cout << " Z " << Z <<" is active x(mm)= " << truelength/mm << G4endl;
if(truelength*rho > 0.0) {
for(G4int ii=0; ii<9; ++ii) {
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(ii);
const G4AtomicShell* shell = GetAtomicShell(Z, as);
if(gCut < shell->BindingEnergy()) {
G4double sig = rho*
GetShellIonisationCrossSectionPerAtom(part, Z, as, ekin);
// mfp is mean free path in units of step size
if(sig > 0.0) {
G4double mfp = 1.0/(sig*truelength);
G4double stot = 0.0;
//G4cout << " Shell " << ii << " mfp(mm)= " << mfp/mm << G4endl;
// sample ionisation points
do {
stot -= mfp*std::log(G4UniformRand());
if( stot <= 1.0) {
// 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);
secVect.push_back(t);
eLoss -= e;
} else {
delete dp;
}
}
}
}
} while ( stot < 1.0 && eLoss > 0.0);
}
}
}
}
}
G4int nsec = secVect.size();
//G4cout << " !!!! Nsec= " << nsec << G4endl;
if(nsec > 0) {
G4int secondariesBefore = pParticleChange->GetNumberOfSecondaries();
pParticleChange->SetNumberOfSecondaries(nsec+secondariesBefore);
for(G4int j=0; j<nsec; ++j) {
pParticleChange->AddSecondary(secVect[j]);
}
}
}
@@ -0,0 +1,72 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * 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: geant4-09-04 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VBremAngularDistribution
//
// Author: Andreia Trindade (andreia@lip.pt)
// Pedro Rodrigues (psilva@lip.pt)
// Luis Peralta (luis@lip.pt)
// Maria Grazia Pia (MariaGrazia.Pia@ge.infn.it)
//
// Creation date: 21 March 2003
//
// Modifications:
// 13 Oct 2010 V.Ivanchenko Moved to utils
//
// Class Description:
//
// Abstract base class for Bremsstrahlung Angular Distribution Generation
//
// Class Description: End
// -------------------------------------------------------------------
//
//
#include "G4VBremAngularDistribution.hh"
//
G4VBremAngularDistribution::G4VBremAngularDistribution(const G4String& name)
: G4VEmAngularDistribution(name)
{}
//
G4VBremAngularDistribution::~G4VBremAngularDistribution()
{}
void G4VBremAngularDistribution::PrintGeneratorInformation() const
{}
//
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * 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: geant4-09-04 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// File name: G4VEmAngularDistribution
//
// Author: V. Ivanchenko using design of existing
// interface G4VBremAngularDistribution
//
// Creation date: 13 October 2010
//
// Modifications:
//
// Class Description:
//
// Abstract base class for polar angle sampling
//
// Class Description: End
// -------------------------------------------------------------------
//
//
#include "G4VEmAngularDistribution.hh"
G4VEmAngularDistribution::G4VEmAngularDistribution(const G4String& name)
: fName(name)
{}
G4VEmAngularDistribution::~G4VEmAngularDistribution()
{}
//
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmModel.cc,v 1.30 2009/09/23 14:42:47 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VEmModel.cc,v 1.37 2010/10/14 16:27:35 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -60,10 +60,10 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VEmModel::G4VEmModel(const G4String& nam):
fluc(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV),
flucModel(0),anglModel(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV),
eMinActive(0.0),eMaxActive(DBL_MAX),
polarAngleLimit(0.0),secondaryThreshold(DBL_MAX),theLPMflag(false),
pParticleChange(0),nuclearStopping(false),
pParticleChange(0),/*nuclearStopping(false),*/
currentCouple(0),currentElement(0),
nsec(5),flagDeexcitation(false)
{
@@ -79,10 +79,11 @@ G4VEmModel::~G4VEmModel()
G4LossTableManager::Instance()->DeRegister(this);
G4int n = elmSelectors.size();
if(n > 0) {
for(G4int i=0; i<n; i++) {
for(G4int i=0; i<n; ++i) {
delete elmSelectors[i];
}
}
delete anglModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -120,34 +121,37 @@ void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p,
{
// initialise before run
flagDeexcitation = false;
G4LossTableManager* man = G4LossTableManager::Instance();
G4bool spline = man->SplineFlag();
G4int nbins = G4int(std::log10(highLimit/lowLimit) + 0.5);
if(nbins < 3) nbins = 3;
G4bool spline = G4LossTableManager::Instance()->SplineFlag();
// two times less bins because probability functon is normalized
// so correspondingly is more smooth
G4int nbins = (man->GetNumberOfBinsPerDecade()/3)*
G4int(std::log10(highLimit/lowLimit) + 0.5);
if(nbins < 5) { nbins = 5; }
G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
G4int numOfCouples = theCoupleTable->GetTableSize();
// prepare vector
if(numOfCouples > nSelectors) elmSelectors.reserve(numOfCouples);
if(numOfCouples > nSelectors) {
elmSelectors.reserve(numOfCouples);
for(G4int i=nSelectors; i<numOfCouples; ++i) { elmSelectors.push_back(0); }
nSelectors = numOfCouples;
}
// initialise vector
for(G4int i=0; i<numOfCouples; i++) {
for(G4int i=0; i<numOfCouples; ++i) {
currentCouple = theCoupleTable->GetMaterialCutsCouple(i);
const G4Material* material = currentCouple->GetMaterial();
G4int idx = currentCouple->GetIndex();
// selector already exist check if should be deleted
G4bool create = true;
if(i < nSelectors) {
if(elmSelectors[i]) {
if(material == elmSelectors[i]->GetMaterial()) create = false;
else delete elmSelectors[i];
}
} else {
nSelectors++;
elmSelectors.push_back(0);
if(elmSelectors[i]) {
if(material == elmSelectors[i]->GetMaterial()) { create = false; }
else { delete elmSelectors[i]; }
}
if(create) {
elmSelectors[i] = new G4EmElementSelector(this,material,nbins,
@@ -194,6 +198,30 @@ G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4Element* G4VEmModel::SelectRandomAtom(const G4Material* material,
const G4ParticleDefinition* pd,
G4double kinEnergy,
G4double tcut,
G4double tmax)
{
const G4ElementVector* theElementVector = material->GetElementVector();
G4int n = material->GetNumberOfElements() - 1;
currentElement = (*theElementVector)[n];
if (n > 0) {
G4double x = G4UniformRand()*
G4VEmModel::CrossSectionPerVolume(material,pd,kinEnergy,tcut,tmax);
for(G4int i=0; i<n; ++i) {
if (x <= xsec[i]) {
currentElement = (*theElementVector)[i];
break;
}
}
}
return currentElement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
G4double, G4double, G4double,
G4double, G4double)
@@ -216,6 +244,14 @@ G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::ChargeSquareRatio(const G4Track& track)
{
return GetChargeSquareRatio(track.GetParticleDefinition(),
track.GetMaterial(), track.GetKineticEnergy());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
const G4Material*, G4double)
{
@@ -260,3 +296,12 @@ void G4VEmModel::SetupForMaterial(const G4ParticleDefinition*,
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4VEmModel::SetParticleChange(G4VParticleChange* p, G4VEmFluctuationModel* f)
{
if(p && pParticleChange != p) { pParticleChange = p; }
flucModel = f;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEmProcess.cc,v 1.79 2009/11/10 20:30:55 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VEmProcess.cc,v 1.88 2010/08/17 17:36:59 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -52,6 +52,7 @@
// 12-04-07 remove double call to Clear model manager (V.Ivanchenko)
// 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)
//
// Class Description:
//
@@ -97,6 +98,7 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
idxDERegions(0),
currentModel(0),
particle(0),
currentParticle(0),
currentCouple(0)
{
SetVerboseLevel(1);
@@ -164,7 +166,7 @@ void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* p,
{
G4VEmFluctuationModel* fm = 0;
modelManager->AddEmModel(order, p, fm, region);
if(p) p->SetParticleChange(pParticleChange);
if(p) { p->SetParticleChange(pParticleChange); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -204,7 +206,7 @@ G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver)
void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if(!particle) particle = &part;
if(!particle) { SetParticle(&part); }
if(1 < verboseLevel) {
G4cout << "G4VEmProcess::PreparePhysicsTable() for "
<< GetProcessName()
@@ -213,7 +215,7 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
<< G4endl;
}
(G4LossTableManager::Instance())->EmConfigurator()->AddModels();
(G4LossTableManager::Instance())->PreparePhysicsTable(&part, this);
if(particle == &part) {
Clear();
@@ -229,7 +231,8 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
}
}
theCuts = modelManager->Initialise(particle,secondaryParticle,2.,verboseLevel);
theCuts = modelManager->Initialise(particle,secondaryParticle,
2.,verboseLevel);
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
theCutsGamma = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
@@ -241,7 +244,7 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
}
}
// Sub Cutoff and Deexcitation
// Deexcitation
if (nDERegions>0) {
const G4ProductionCutsTable* theCoupleTable=
@@ -286,6 +289,7 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
<< G4endl;
}
(G4LossTableManager::Instance())->BuildPhysicsTable(particle);
if(buildLambdaTable) {
BuildLambdaTable();
FindLambdaMax();
@@ -293,7 +297,8 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
// reduce printout for nuclear stopping
G4bool gproc = true;
if(GetProcessName() == "nuclearStopping" &&
G4int st = GetProcessSubType();
if(st == fCoulombScattering && part.GetParticleType() == "nucleus" &&
partname != "GenericIon" && partname != "alpha") { gproc = false; }
if(gproc && 0 < verboseLevel) { PrintInfoDefinition(); }
@@ -353,9 +358,6 @@ void G4VEmProcess::BuildLambdaTable()
G4cout << "Lambda table is built for "
<< particle->GetParticleName()
<< G4endl;
if(2 < verboseLevel) {
G4cout << *theLambdaTable << G4endl;
}
}
}
@@ -384,7 +386,7 @@ void G4VEmProcess::PrintInfoDefinition()
if(verboseLevel > 2 && buildLambdaTable) {
G4cout << " LambdaTable address= " << theLambdaTable << G4endl;
if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
if(theLambdaTable) { G4cout << (*theLambdaTable) << G4endl; }
}
}
@@ -398,9 +400,9 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
// condition is set to "Not Forced"
*condition = NotForced;
G4double x = DBL_MAX;
if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0;
if(previousStepSize <= DBL_MIN) { theNumberOfInteractionLengthLeft = -1.0; }
InitialiseStep(track);
if(!currentModel->IsActive(preStepKinEnergy)) return x;
if(!currentModel->IsActive(preStepKinEnergy)) { return x; }
if(preStepKinEnergy < mfpKinEnergy) {
if (integral) ComputeIntegralLambda(preStepKinEnergy);
@@ -427,7 +429,7 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
if (verboseLevel>2){
G4cout << "G4VEmProcess::PostStepGetPhysicalInteractionLength ";
G4cout << "[ " << GetProcessName() << "]" << G4endl;
G4cout << " for " << particle->GetParticleName()
G4cout << " for " << currentParticle->GetParticleName()
<< " in Material " << currentMaterial->GetName()
<< " Ekin(MeV)= " << preStepKinEnergy/MeV
<<G4endl;
@@ -460,7 +462,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
// Do not make anything if particle is stopped, the annihilation then
// should be performed by the AtRestDoIt!
if (track.GetTrackStatus() == fStopButAlive) return &fParticleChange;
if (track.GetTrackStatus() == fStopButAlive) { return &fParticleChange; }
G4double finalT = track.GetKineticEnergy();
@@ -468,7 +470,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
if (integral) {
G4double lx = GetLambda(finalT, currentCouple);
if(preStepLambda<lx && 1 < verboseLevel) {
G4cout << "WARING: for " << particle->GetParticleName()
G4cout << "WARING: for " << currentParticle->GetParticleName()
<< " and " << GetProcessName()
<< " E(MeV)= " << finalT/MeV
<< " preLambda= " << preStepLambda << " < " << lx << " (postLambda) "
@@ -482,7 +484,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
}
SelectModel(finalT, currentCoupleIndex);
if(!currentModel->IsActive(finalT)) return &fParticleChange;
if(!currentModel->IsActive(finalT)) { return &fParticleChange; }
if(useDeexcitation) {
currentModel->SetDeexcitationFlag(idxDERegions[currentCoupleIndex]);
}
@@ -513,7 +515,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
for (G4int i=0; i<num; ++i) {
G4DynamicParticle* dp = secParticles[i];
const G4ParticleDefinition* p = dp->GetDefinition();
const G4ParticleDefinition* p = dp->GetParticleDefinition();
G4double e = dp->GetKineticEnergy();
G4bool good = true;
if(applyCuts) {
@@ -661,9 +663,10 @@ G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
} else {
SelectModel(kineticEnergy, currentCoupleIndex);
cross = currentModel->CrossSectionPerVolume(currentMaterial,
particle,kineticEnergy);
currentParticle,kineticEnergy);
}
if(cross < 0.0) { cross = 0.0; }
return cross;
}
@@ -679,6 +682,32 @@ G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEmProcess::MeanFreePath(const G4Track& track)
{
DefineMaterial(track.GetMaterialCutsCouple());
preStepLambda = GetCurrentLambda(track.GetKineticEnergy());
G4double x = DBL_MAX;
if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4VEmProcess::ComputeCrossSectionPerAtom(G4double kineticEnergy,
G4double Z, G4double A, G4double cut)
{
SelectModel(kineticEnergy, currentCoupleIndex);
G4double x = 0.0;
if(currentModel) {
x = currentModel->ComputeCrossSectionPerAtom(currentParticle,kineticEnergy,
Z,A,cut);
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::FindLambdaMax()
{
if(1 < verboseLevel) {
@@ -713,7 +742,7 @@ void G4VEmProcess::FindLambdaMax()
}
theEnergyOfCrossSectionMax[i] = emax;
theCrossSectionMax[i] = smax;
if(2 < verboseLevel) {
if(1 < verboseLevel) {
G4cout << "For " << particle->GetParticleName()
<< " Max CS at i= " << i << " emax(MeV)= " << emax/MeV
<< " lambda= " << smax << G4endl;
@@ -732,3 +761,12 @@ G4PhysicsVector* G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple*)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4Element* G4VEmProcess::GetCurrentElement() const
{
const G4Element* elm = 0;
if(currentModel) {elm = currentModel->GetCurrentElement(); }
return elm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VEnergyLossProcess.cc,v 1.158 2009/10/29 18:07:08 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VEnergyLossProcess.cc,v 1.172 2010/11/18 21:36:41 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -107,6 +107,7 @@
// 25-04-07 move initialisation of safety helper to BuildPhysicsTable (VI)
// 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)
//
// Class Description:
//
@@ -143,6 +144,7 @@
#include "G4SafetyHelper.hh"
#include "G4TransportationManager.hh"
#include "G4EmConfigurator.hh"
#include "G4VAtomDeexcitation.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -221,6 +223,7 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name,
// initialise model
(G4LossTableManager::Instance())->Register(this);
fluctModel = 0;
atomDeexcitation = 0;
scTracks.reserve(5);
secParticles.reserve(5);
@@ -335,7 +338,7 @@ void G4VEnergyLossProcess::AddEmModel(G4int order, G4VEmModel* p,
const G4Region* region)
{
modelManager->AddEmModel(order, p, fluc, region);
if(p) p->SetParticleChange(pParticleChange, fluc);
if(p) { p->SetParticleChange(pParticleChange, fluc); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -405,7 +408,7 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
if( !particle ) {
particle = &part;
if(part.GetParticleType() == "nucleus") {
if(!theGenericIon) theGenericIon = G4GenericIon::GenericIon();
if(!theGenericIon) { theGenericIon = G4GenericIon::GenericIon(); }
if(particle == theGenericIon) { isIon = true; }
else if(part.GetPDGCharge() > eplus) {
isIon = true;
@@ -425,11 +428,15 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
} else {
lManager->RegisterExtraParticle(&part, this);
}
if(1 < verboseLevel) {
G4cout << "### G4VEnergyLossProcess::PreparePhysicsTable() end for "
<< part.GetParticleName() << G4endl;
}
return;
}
Clean();
lManager->EmConfigurator()->AddModels();
lManager->PreparePhysicsTable(&part, this);
// Base particle and set of models can be defined here
InitialiseEnergyLossProcess(particle, baseParticle);
@@ -501,22 +508,20 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
if(nSCoffRegions>0) {
G4bool reg = false;
for(G4int i=0; i<nSCoffRegions; ++i) {
if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = true;
if( pcuts == scoffRegions[i]->GetProductionCuts()) { reg = true; }
}
idxSCoffRegions[j] = reg;
}
if(nDERegions>0) {
G4bool reg = false;
for(G4int i=0; i<nDERegions; ++i) {
if( pcuts == deRegions[i]->GetProductionCuts()) reg = true;
if( pcuts == deRegions[i]->GetProductionCuts()) { reg = true; }
}
idxDERegions[j] = reg;
}
}
}
lManager->EnergyLossProcessIsInitialised(particle, this);
if (1 < verboseLevel) {
G4cout << "G4VEnergyLossProcess::Initialise() is done "
<< " for local " << particle->GetParticleName()
@@ -567,13 +572,19 @@ void G4VEnergyLossProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
}
// Added tracking cut to avoid tracking artifacts
if(isIonisation) fParticleChange.SetLowEnergyLimit(lowestKinEnergy);
if(isIonisation) {
fParticleChange.SetLowEnergyLimit(lowestKinEnergy);
atomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
if(atomDeexcitation) {
if(atomDeexcitation->IsPIXEActive()) { useDeexcitation = true; }
}
}
if(1 < verboseLevel) {
G4cout << "### G4VEnergyLossProcess::BuildPhysicsTable() done for "
<< GetProcessName()
<< " and particle " << part.GetParticleName();
if(isIonisation) G4cout << " isIonisation flag = 1";
if(isIonisation) { G4cout << " isIonisation flag = 1"; }
G4cout << G4endl;
}
}
@@ -589,7 +600,6 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildDEDXTable(G4EmTableType tType)
<< G4endl;
}
G4PhysicsTable* table = 0;
G4double emin = minKinEnergy;
G4double emax = maxKinEnergy;
G4int bin = nBins;
@@ -618,7 +628,8 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildDEDXTable(G4EmTableType tType)
if(1 < verboseLevel) {
G4cout << numOfCouples << " materials"
<< " minKinEnergy= " << minKinEnergy
<< " maxKinEnergy= " << maxKinEnergy
<< " maxKinEnergy= " << emax
<< " nbin= " << bin
<< " EmTableType= " << tType
<< " table= " << table
<< G4endl;
@@ -641,16 +652,15 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildDEDXTable(G4EmTableType tType)
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
if(!bVector) {
aVector = new G4PhysicsLogVector(emin, emax, bin);
aVector = new G4PhysicsLogVector(minKinEnergy, emax, bin);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
}
// G4PhysicsVector* aVector = new G4PhysicsLogVector(emin, emax, bin);
aVector->SetSpline(splineFlag);
modelManager->FillDEDXVector(aVector, couple, tType);
if(splineFlag) aVector->FillSecondDerivatives();
if(splineFlag) { aVector->FillSecondDerivatives(); }
// Insert vector for this material into the table
G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
@@ -700,6 +710,8 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildLambdaTable(G4EmTableType tType)
size_t numOfCouples = theCoupleTable->GetTableSize();
G4bool splineFlag = (G4LossTableManager::Instance())->SplineFlag();
G4PhysicsLogVector* aVector = 0;
G4PhysicsLogVector* bVector = 0;
for(size_t i=0; i<numOfCouples; ++i) {
@@ -708,13 +720,16 @@ G4PhysicsTable* G4VEnergyLossProcess::BuildLambdaTable(G4EmTableType tType)
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
G4double cut = (*theCuts)[i];
if(fSubRestricted == tType) cut = (*theSubCuts)[i];
G4PhysicsVector* aVector = LambdaPhysicsVector(couple, cut);
if(!bVector) {
aVector = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nBins);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
}
aVector->SetSpline(splineFlag);
modelManager->FillLambdaVector(aVector, couple, true, tType);
if(splineFlag) aVector->FillSecondDerivatives();
if(splineFlag) { aVector->FillSecondDerivatives(); }
// Insert vector for this material into the table
G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
@@ -845,7 +860,7 @@ void G4VEnergyLossProcess::ActivateDeexcitation(G4bool val, const G4Region* r)
if (nDERegions) {
for (G4int i=0; i<nDERegions; ++i) {
if (reg == deRegions[i]) {
if(!val) deRegions[i] = 0;
if(!val) { deRegions[i] = 0; }
return;
}
}
@@ -880,7 +895,7 @@ G4double G4VEnergyLossProcess::AlongStepGetPhysicalInteractionLength(
if(x > finalRange && y < currentMinStep) {
x = y + finalRange*(1.0 - dRoverRange)*(2.0 - finalRange/fRange);
} else if (rndmStepFlag) {x = SampleRange();}
} else if (rndmStepFlag) { x = SampleRange(); }
//G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
// <<" range= "<<fRange <<" cMinSt="<<currentMinStep
// << " limit= " << x <<G4endl;
@@ -904,30 +919,29 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
// initialisation of material, mass, charge, model at the beginning of the step
DefineMaterial(track.GetMaterialCutsCouple());
const G4ParticleDefinition* currPart = track.GetDefinition();
const G4ParticleDefinition* currPart = track.GetParticleDefinition();
if(theGenericIon == particle) {
massRatio = proton_mass_c2/currPart->GetPDGMass();
}
preStepKinEnergy = track.GetKineticEnergy();
preStepScaledEnergy = preStepKinEnergy*massRatio;
SelectModel(preStepScaledEnergy);
if(!currentModel->IsActive(preStepScaledEnergy)) return x;
if(!currentModel->IsActive(preStepScaledEnergy)) { return x; }
if(isIon) {
chargeSqRatio =
currentModel->GetChargeSquareRatio(currPart,currentMaterial,preStepKinEnergy);
if(isIon) {
chargeSqRatio = currentModel->ChargeSquareRatio(track);
reduceFactor = 1.0/(chargeSqRatio*massRatio);
}
//G4cout << "q2= " << chargeSqRatio << " massRatio= " << massRatio << G4endl;
// initialisation for sampling of the interaction length
if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0;
if(theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
if(previousStepSize <= DBL_MIN) { theNumberOfInteractionLengthLeft = -1.0; }
if(theNumberOfInteractionLengthLeft < 0.0) { mfpKinEnergy = DBL_MAX; }
// compute mean free path
if(preStepScaledEnergy < mfpKinEnergy) {
if (integral) ComputeLambdaForScaledEnergy(preStepScaledEnergy);
else preStepLambda = GetLambdaForScaledEnergy(preStepScaledEnergy);
if(preStepLambda <= DBL_MIN) mfpKinEnergy = 0.0;
if (integral) { ComputeLambdaForScaledEnergy(preStepScaledEnergy); }
else { preStepLambda = GetLambdaForScaledEnergy(preStepScaledEnergy); }
if(preStepLambda <= DBL_MIN) { mfpKinEnergy = 0.0; }
}
// non-zero cross section
@@ -939,8 +953,9 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
} else if(currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft
SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.)
if(theNumberOfInteractionLengthLeft < 0.) {
theNumberOfInteractionLengthLeft = perMillion;
}
}
// get mean free path and step limit
@@ -965,8 +980,9 @@ G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft
SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.)
if(theNumberOfInteractionLengthLeft < 0.) {
theNumberOfInteractionLengthLeft = perMillion;
}
}
currentInteractionLength = DBL_MAX;
}
@@ -986,13 +1002,12 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
// Get the actual (true) Step length
G4double length = step.GetStepLength();
if(length <= DBL_MIN) return &fParticleChange;
if(length <= DBL_MIN) { return &fParticleChange; }
G4double eloss = 0.0;
G4double esecdep = 0.0;
/*
if(-1 < verboseLevel) {
const G4ParticleDefinition* d = track.GetDefinition();
const G4ParticleDefinition* d = track.GetParticleDefinition();
G4cout << "AlongStepDoIt for "
<< GetProcessName() << " and particle "
<< d->GetParticleName()
@@ -1012,10 +1027,13 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
if (length >= fRange) {
eloss = preStepKinEnergy;
if (useDeexcitation) {
if(idxDERegions[currentMaterialIndex]) {
if(atomDeexcitation) {
atomDeexcitation->AlongStepDeexcitation(&fParticleChange, step,
eloss, currentMaterialIndex);
} else if(idxDERegions[currentMaterialIndex]) {
currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss);
if(eloss < 0.0) eloss = 0.0;
}
if(eloss < 0.0) { eloss = 0.0; }
}
fParticleChange.SetProposedKineticEnergy(0.0);
fParticleChange.ProposeLocalEnergyDeposit(eloss);
@@ -1070,7 +1088,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
G4StepPoint* prePoint = step.GetPreStepPoint();
// Check boundary
if(prePoint->GetStepStatus() == fGeomBoundary) yes = true;
if(prePoint->GetStepStatus() == fGeomBoundary) { yes = true; }
// Check PrePoint
else {
@@ -1082,7 +1100,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
preSafety = safetyHelper->ComputeSafety(prePoint->GetPosition());
}
if(preSafety < rcut) yes = true;
if(preSafety < rcut) { yes = true; }
// Check PostPoint
else {
@@ -1090,7 +1108,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
if(postSafety < rcut) {
postSafety =
safetyHelper->ComputeSafety(step.GetPostStepPoint()->GetPosition());
if(postSafety < rcut) yes = true;
if(postSafety < rcut) { yes = true; }
}
}
}
@@ -1102,8 +1120,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
eloss -= GetSubDEDXForScaledEnergy(preStepScaledEnergy)*length;
scTracks.clear();
SampleSubCutSecondaries(scTracks, step,
currentModel,currentMaterialIndex,
esecdep);
currentModel,currentMaterialIndex);
// add bremsstrahlung sampling
/*
if(nProcesses > 0) {
@@ -1111,7 +1128,7 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
(scProcesses[i])->SampleSubCutSecondaries(
scTracks, step, (scProcesses[i])->
SelectModelForMaterial(preStepKinEnergy, currentMaterialIndex),
currentMaterialIndex,esecdep);
currentMaterialIndex);
}
}
*/
@@ -1122,7 +1139,9 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
for(G4int i=0; i<n; ++i) {
G4Track* t = scTracks[i];
G4double e = t->GetKineticEnergy();
if (t->GetDefinition() == thePositron) e += 2.0*electron_mass_c2;
if (t->GetParticleDefinition() == thePositron) {
e += 2.0*electron_mass_c2;
}
esec += e;
pParticleChange->AddSecondary(t);
}
@@ -1132,14 +1151,17 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
}
// Corrections, which cannot be tabulated
currentModel->CorrectionsAlongStep(currentCouple, dynParticle,
eloss, esecdep, length);
if(isIon) {
G4double eadd = 0.0;
currentModel->CorrectionsAlongStep(currentCouple, dynParticle,
eloss, eadd, length);
}
// Sample fluctuations
if (lossFluctuationFlag) {
G4VEmFluctuationModel* fluc = currentModel->GetModelOfFluctuations();
if(fluc &&
(eloss + esec + esecdep + lowestKinEnergy) < preStepKinEnergy) {
(eloss + esec + lowestKinEnergy) < preStepKinEnergy) {
G4double tmax =
std::min(currentModel->MaxSecondaryKinEnergy(dynParticle),cut);
@@ -1157,28 +1179,31 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
*/
}
}
// add low-energy subcutoff particles
eloss += esecdep;
if(eloss < 0.0) eloss = 0.0;
// deexcitation
else if (useDeexcitation) {
if(idxDERegions[currentMaterialIndex]) {
if (useDeexcitation) {
G4double eloss_before = eloss;
if(atomDeexcitation) {
atomDeexcitation->AlongStepDeexcitation(&fParticleChange, step,
eloss, currentMaterialIndex);
} else if(idxDERegions[currentMaterialIndex] && eloss > 0.0) {
currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss);
if(eloss < 0.0) eloss = 0.0;
}
esec += eloss_before - eloss;
}
// Energy balanse
G4double finalT = preStepKinEnergy - eloss - esec;
if (finalT <= lowestKinEnergy) {
eloss = preStepKinEnergy - esec;
eloss += finalT;
finalT = 0.0;
} else if(isIon) {
fParticleChange.SetProposedCharge(
currentModel->GetParticleCharge(track.GetDefinition(),currentMaterial,finalT));
currentModel->GetParticleCharge(track.GetParticleDefinition(),
currentMaterial,finalT));
}
if(eloss < 0.0) { eloss = 0.0; }
fParticleChange.SetProposedKineticEnergy(finalT);
fParticleChange.ProposeLocalEnergyDeposit(eloss);
@@ -1202,13 +1227,12 @@ void G4VEnergyLossProcess::SampleSubCutSecondaries(
std::vector<G4Track*>& tracks,
const G4Step& step,
G4VEmModel* model,
G4int idx,
G4double& /*extraEdep*/)
G4int idx)
{
// Fast check weather subcutoff can work
G4double subcut = (*theSubCuts)[idx];
G4double cut = (*theCuts)[idx];
if(cut <= subcut) return;
if(cut <= subcut) { return; }
const G4Track* track = step.GetTrack();
const G4DynamicParticle* dp = track->GetDynamicParticle();
@@ -1217,7 +1241,7 @@ void G4VEnergyLossProcess::SampleSubCutSecondaries(
G4double length = step.GetStepLength();
// negligible probability to get any interaction
if(length*cross < perMillion) return;
if(length*cross < perMillion) { return; }
/*
if(-1 < verboseLevel)
G4cout << "<<< Subcutoff for " << GetProcessName()
@@ -1255,7 +1279,7 @@ void G4VEnergyLossProcess::SampleSubCutSecondaries(
G4bool addSec = true;
/*
// do not track very low-energy delta-electrons
if(theSecondaryRangeTable && (*it)->GetDefinition() == theElectron) {
if(theSecondaryRangeTable && (*it)->GetParticleDefinition() == theElectron) {
G4double ekin = (*it)->GetKineticEnergy();
G4double rg = ((*theSecondaryRangeTable)[idx]->Value(ekin));
// if(rg < currentMinSafety) {
@@ -1268,13 +1292,12 @@ void G4VEnergyLossProcess::SampleSubCutSecondaries(
*/
if(addSec) {
G4Track* t = new G4Track((*it), pretime + fragment*dt, r);
//G4Track* t = new G4Track((*it), pretime, r);
t->SetTouchableHandle(track->GetTouchableHandle());
tracks.push_back(t);
/*
if(-1 < verboseLevel)
G4cout << "New track " << t->GetDefinition()->GetParticleName()
G4cout << "New track " << t->GetParticleDefinition()->GetParticleName()
<< " e(keV)= " << t->GetKineticEnergy()/keV
<< " fragment= " << fragment
<< G4endl;
@@ -1289,13 +1312,16 @@ void G4VEnergyLossProcess::SampleSubCutSecondaries(
G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
const G4Step&)
{
// In all cases clear number of interaction lengths
theNumberOfInteractionLengthLeft = -1.0;
fParticleChange.InitializeForPostStep(track);
G4double finalT = track.GetKineticEnergy();
if(finalT <= lowestKinEnergy) return &fParticleChange;
if(finalT <= lowestKinEnergy) { return &fParticleChange; }
G4double postStepScaledEnergy = finalT*massRatio;
if(!currentModel->IsActive(postStepScaledEnergy)) return &fParticleChange;
if(!currentModel->IsActive(postStepScaledEnergy)) { return &fParticleChange; }
/*
if(-1 < verboseLevel) {
G4cout << GetProcessName()
@@ -1317,14 +1343,15 @@ G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
++nWarnings;
}
*/
if(preStepLambda*G4UniformRand() > lx) {
ClearNumberOfInteractionLengthLeft();
if(lx <= 0.0) {
return &fParticleChange;
} else if(preStepLambda*G4UniformRand() > lx) {
return &fParticleChange;
}
}
SelectModel(postStepScaledEnergy);
if(useDeexcitation) {
if(useDeexcitation && !atomDeexcitation) {
currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]);
}
@@ -1356,7 +1383,6 @@ G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
<< G4endl;
}
*/
ClearNumberOfInteractionLengthLeft();
return &fParticleChange;
}
@@ -1505,38 +1531,36 @@ G4VEnergyLossProcess::RetrieveTable(const G4ParticleDefinition* part,
const G4String& tname,
G4bool mandatory)
{
G4bool res = true;
G4bool isRetrieved = false;
G4String filename = GetPhysicsTableFileName(part,directory,tname,ascii);
G4bool yes = aTable->ExistPhysicsTable(filename);
if(yes) {
if(!aTable) aTable = G4PhysicsTableHelper::PreparePhysicsTable(0);
yes = G4PhysicsTableHelper::RetrievePhysicsTable(aTable,filename,ascii);
if((G4LossTableManager::Instance())->SplineFlag()) {
size_t n = aTable->length();
for(size_t i=0; i<n; ++i) {
if((*aTable)[i]) {
(*aTable)[i]->SetSpline(true);
if(aTable) {
if(aTable->ExistPhysicsTable(filename)) {
if(G4PhysicsTableHelper::RetrievePhysicsTable(aTable,filename,ascii)) {
isRetrieved = true;
if((G4LossTableManager::Instance())->SplineFlag()) {
size_t n = aTable->length();
for(size_t i=0; i<n; ++i) {
if((*aTable)[i]) { (*aTable)[i]->SetSpline(true); }
}
}
if (0 < verboseLevel) {
G4cout << tname << " table for " << part->GetParticleName()
<< " is Retrieved from <" << filename << ">"
<< G4endl;
}
}
}
}
if(yes) {
if (0 < verboseLevel) {
G4cout << tname << " table for " << part->GetParticleName()
<< " is Retrieved from <" << filename << ">"
<< G4endl;
}
} else {
if(mandatory) res = false;
if(mandatory || 1 < verboseLevel) {
if(mandatory && !isRetrieved) {
if(0 < verboseLevel) {
G4cout << tname << " table for " << part->GetParticleName()
<< " from file <"
<< filename << "> is not Retrieved"
<< G4endl;
}
return false;
}
return res;
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1573,7 +1597,7 @@ G4double G4VEnergyLossProcess::CrossSectionPerVolume(
particle, kineticEnergy,
(*theCuts)[currentMaterialIndex]);
}
if(cross < 0.0) { cross = 0.0; }
return cross;
}
@@ -1584,7 +1608,7 @@ G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track)
DefineMaterial(track.GetMaterialCutsCouple());
preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio);
G4double x = DBL_MAX;
if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
if(DBL_MIN < preStepLambda) { x = 1.0/preStepLambda; }
return x;
}
@@ -1621,14 +1645,18 @@ G4double G4VEnergyLossProcess::GetContinuousStepLimit(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(
const G4MaterialCutsCouple* couple, G4double cut)
G4PhysicsVector*
G4VEnergyLossProcess::LambdaPhysicsVector(const G4MaterialCutsCouple* /*couple*/,
G4double /*cut*/)
{
/*
G4double tmin =
std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),
minKinEnergy);
if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;
if(tmin >= maxKinEnergy) { tmin = 0.5*maxKinEnergy; }
G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins);
*/
G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nBins);
v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
return v;
}
@@ -1639,7 +1667,7 @@ void G4VEnergyLossProcess::AddCollaborativeProcess(
G4VEnergyLossProcess* p)
{
G4bool add = true;
if(p->GetProcessName() != "eBrem") add = false;
if(p->GetProcessName() != "eBrem") { add = false; }
if(add && nProcesses > 0) {
for(G4int i=0; i<nProcesses; ++i) {
if(p == scProcesses[i]) {
@@ -1698,7 +1726,7 @@ void G4VEnergyLossProcess::SetDEDXTable(G4PhysicsTable* p, G4EmTableType tType)
void G4VEnergyLossProcess::SetCSDARangeTable(G4PhysicsTable* p)
{
if(theCSDARangeTable != p) theCSDARangeTable = p;
if(theCSDARangeTable != p) { theCSDARangeTable = p; }
if(p) {
size_t n = p->length();
@@ -1767,7 +1795,7 @@ void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
<< " for " << particle->GetParticleName()
<< " and process " << GetProcessName() << G4endl;
}
if(theLambdaTable != p) theLambdaTable = p;
if(theLambdaTable != p) { theLambdaTable = p; }
tablesAreBuilt = true;
if(p) {
@@ -1821,3 +1849,12 @@ void G4VEnergyLossProcess::SetSubLambdaTable(G4PhysicsTable* p)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4Element* G4VEnergyLossProcess::GetCurrentElement() const
{
const G4Element* elm = 0;
if(currentModel) { elm = currentModel->GetCurrentElement(); }
return elm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMscModel.cc,v 1.13 2009/07/20 17:32:47 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VMscModel.cc,v 1.18 2010/09/07 16:05:33 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -60,10 +60,11 @@ G4VMscModel::G4VMscModel(const G4String& nam):
facrange(0.04),
facgeom(2.5),
facsafety(0.3),
skin(3.0),
skin(1.0),
dtrl(0.05),
lambdalimit(mm),
geommax(1.e50*mm),
geomMin(1.e-6*CLHEP::mm),
geomMax(1.e50*CLHEP::mm),
steppingAlgorithm(fUseSafety),
samplez(false),
latDisplasment(true)
@@ -105,35 +106,30 @@ void G4VMscModel::ComputeDisplacement(G4ParticleChangeForMSC* fParticleChange,
G4double displacement,
G4double postsafety)
{
if(displacement <= geomMin) { return; }
const G4ThreeVector* pos = fParticleChange->GetProposedPosition();
G4double r = displacement;
if(r > postsafety) {
G4double newsafety = safetyHelper->ComputeSafety(*pos);
if(r > newsafety) r = newsafety;
// 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;
}
if(r > 0.) {
// 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;
// definitely not on boundary
if(displacement == r) {
safetyHelper->ReLocateWithinVolume(newPosition);
} else {
// check safety after displacement
G4double postsafety = safetyHelper->ComputeSafety(newPosition);
// displacement to boundary
if(postsafety <= 0.0) {
safetyHelper->Locate(newPosition,
*fParticleChange->GetProposedMomentumDirection());
// not on the boundary
} else {
safetyHelper->ReLocateWithinVolume(newPosition);
}
}
safetyHelper->ReLocateWithinVolume(newPosition);
fParticleChange->ProposePosition(newPosition);
}
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VMultipleScattering.cc,v 1.77 2009/10/29 18:07:08 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-03 $
// $Id: G4VMultipleScattering.cc,v 1.86 2010/10/26 11:30:46 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-04 $
//
// -------------------------------------------------------------------
//
@@ -94,7 +94,7 @@ G4VMultipleScattering::G4VMultipleScattering(const G4String& name,
theLambdaTable(0),
firstParticle(0),
stepLimit(fUseSafety),
skin(3.0),
skin(1.0),
facrange(0.04),
facgeom(2.5),
latDisplasment(true),
@@ -143,7 +143,7 @@ void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p,
{
G4VEmFluctuationModel* fm = 0;
modelManager->AddEmModel(order, p, fm, region);
if(p) p->SetParticleChange(pParticleChange);
if(p) { p->SetParticleChange(pParticleChange); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -173,6 +173,75 @@ G4VMultipleScattering::GetModelByIndex(G4int idx, G4bool ver) const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
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;
}
(G4LossTableManager::Instance())->PreparePhysicsTable(&part, this);
if(1 < verboseLevel) {
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< " local particle " << firstParticle->GetParticleName()
<< G4endl;
}
if(firstParticle == &part) {
InitialiseProcess(firstParticle);
// initialisation of models
G4int nmod = modelManager->NumberOfModels();
for(G4int i=0; i<nmod; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
if(isIon) {
msc->SetStepLimitType(fMinimal);
msc->SetLateralDisplasmentFlag(false);
msc->SetRangeFactor(0.2);
} else {
msc->SetStepLimitType(StepLimitType());
msc->SetLateralDisplasmentFlag(LateralDisplasmentFlag());
msc->SetSkin(Skin());
msc->SetRangeFactor(RangeFactor());
msc->SetGeomFactor(GeomFactor());
}
msc->SetPolarAngleLimit(polarAngleLimit);
if(msc->HighEnergyLimit() > maxKinEnergy) {
msc->SetHighEnergyLimit(maxKinEnergy);
}
}
modelManager->Initialise(firstParticle, G4Electron::Electron(),
10.0, verboseLevel);
// prepare tables
if(buildLambdaTable) {
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
{
G4String num = part.GetParticleName();
@@ -183,6 +252,8 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
<< G4endl;
}
(G4LossTableManager::Instance())->BuildPhysicsTable(firstParticle);
if (buildLambdaTable && firstParticle == &part) {
const G4ProductionCutsTable* theCoupleTable=
@@ -222,7 +293,7 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
}
if(verboseLevel>0 && ( num == "e-" || num == "mu+" ||
num == "proton" || num == "pi-" ||
num == "GenericIon")) {
num == "kaon+" || num == "GenericIon")) {
PrintInfoDefinition();
if(2 < verboseLevel && theLambdaTable) G4cout << *theLambdaTable << G4endl;
}
@@ -237,75 +308,6 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
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(1 < verboseLevel) {
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< " local particle " << firstParticle->GetParticleName()
<< G4endl;
}
(G4LossTableManager::Instance())->EmConfigurator()->AddModels();
if(firstParticle == &part) {
InitialiseProcess(firstParticle);
// initialisation of models
G4int nmod = modelManager->NumberOfModels();
for(G4int i=0; i<nmod; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
if(isIon) {
msc->SetStepLimitType(fMinimal);
msc->SetLateralDisplasmentFlag(false);
msc->SetRangeFactor(0.2);
} else {
msc->SetStepLimitType(StepLimitType());
msc->SetLateralDisplasmentFlag(LateralDisplasmentFlag());
msc->SetSkin(Skin());
msc->SetRangeFactor(RangeFactor());
msc->SetGeomFactor(GeomFactor());
}
msc->SetPolarAngleLimit(polarAngleLimit);
if(msc->HighEnergyLimit() > maxKinEnergy) {
msc->SetHighEnergyLimit(maxKinEnergy);
}
}
modelManager->Initialise(firstParticle, G4Electron::Electron(),
10.0, verboseLevel);
// prepare tables
if(buildLambdaTable) {
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::PrintInfoDefinition()
{
if (0 < verboseLevel) {
@@ -345,12 +347,12 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
G4double x = currentMinimalStep;
DefineMaterial(track.GetMaterialCutsCouple());
G4double ekin = track.GetKineticEnergy();
if(isIon) { ekin *= proton_mass_c2/track.GetDefinition()->GetPDGMass(); }
if(isIon) { ekin *= proton_mass_c2/track.GetParticleDefinition()->GetPDGMass(); }
currentModel = static_cast<G4VMscModel*>(SelectModel(ekin));
if(x > 0.0 && ekin > 0.0 && currentModel->IsActive(ekin)) {
G4double tPathLength =
currentModel->ComputeTruePathLengthLimit(track, theLambdaTable, x);
if (tPathLength < x) *selection = CandidateForSelection;
if (tPathLength < x) { *selection = CandidateForSelection; }
x = currentModel->ComputeGeomPathLength(tPathLength);
// G4cout << "tPathLength= " << tPathLength
// << " stepLimit= " << x
@@ -361,15 +363,63 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4VMultipleScattering::PostStepGetPhysicalInteractionLength(
const G4Track&, G4double, G4ForceCondition* condition)
{
*condition = Forced;
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange*
G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step)
{
if(currentModel->IsActive(track.GetKineticEnergy())) {
fParticleChange.ProposeTrueStepLength(currentModel->ComputeTrueStepLength(step.GetStepLength()));
}
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange*
G4VMultipleScattering::PostStepDoIt(const G4Track& track, const G4Step& step)
{
fParticleChange.Initialize(track);
if(currentModel->IsActive(track.GetKineticEnergy())) {
currentModel->SampleScattering(track.GetDynamicParticle(),
step.GetPostStepPoint()->GetSafety());
}
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VMultipleScattering::GetContinuousStepLimit(
const G4Track& track,
G4double previousStepSize,
G4double currentMinimalStep,
G4double& currentSafety)
{
G4GPILSelection* selection = 0;
return AlongStepGetPhysicalInteractionLength(track,previousStepSize,currentMinimalStep,
currentSafety, selection);
G4GPILSelection selection = NotCandidateForSelection;
G4double x = AlongStepGetPhysicalInteractionLength(track,previousStepSize,
currentMinimalStep,
currentSafety, &selection);
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VMultipleScattering::ContinuousStepLimit(
const G4Track& track,
G4double previousStepSize,
G4double currentMinimalStep,
G4double& currentSafety)
{
return GetContinuousStepLimit(track,previousStepSize,currentMinimalStep,
currentSafety);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....