Import Geant4 10.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 11:51:14 +02:00
parent e2d2f9810a
commit 286caacf06
12421 changed files with 730077 additions and 502383 deletions
@@ -7,7 +7,7 @@
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt,v 1.1 2010-09-29 18:54:13 bmorgan Exp $
# $Id: CMakeLists.txt 66791 2013-01-12 15:24:24Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -1,4 +1,4 @@
# $Id: GNUmakefile,v 1.7 2003-10-20 10:27:50 grichine Exp $
# $Id: GNUmakefile 66791 2013-01-12 15:24:24Z gcosmo $
# --------------------------------------------------------------------
# GNUmakefile for electromagnetic sub-library. John Allison, 25/6/98.
# --------------------------------------------------------------------
+313 -1
View File
@@ -1,4 +1,4 @@
$Id: History,v 1.448 2011-01-04 11:23:55 vnivanch Exp $
$Id: History 77290 2013-11-22 10:57:50Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,318 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
21 November 13: V.Ivant (emutils-V09-06-67)
- G4EnergyLossTables - removed G4ThreadLocal (this class is obsolete)
19 November 13: V.Ivant (emutils-V09-06-66)
- G4VEmProcess, G4VEnergyLossProcess - complete fix for base
materials for the case of positrons
18 November 13: V.Ivant (emutils-V09-06-65)
- G4VEmProcess, G4VEnergyLossProcess - fixed bug seen in B5 example
when based materail approach was used
- G4EmModelMananger - improved debug printout
14 November 13: V.Ivant (emutils-V09-06-64)
- G4EmBiasingManager - fixed bug reported by Andrey Karpov
(<karpov@viva64.com>) static code analysis
08 November 13: V.Ivant (emutils-V09-06-63)
- Cleanup comments in destructors
06 November 13: V.Ivant (emutils-V09-06-62)
- G4LossTableManager uses G4ThreadLocalSingleton patern
- G4VEmProcess, G4VEnergyLossProcess, G4VEmModel - do not delete
G4PhysicsVectors
01 November 13: V.Ivant (emutils-V09-06-61)
- G4VEmProcess, G4VEnergyLossProcess - fixed bug in GPIL computation
when a particle enter a volume in whihc current EM model has
different activation energy range than in the previous region
- G4VEmModel - improved definition of min and max energy for
element selectors
21 October 13: V.Ivant (emutils-V09-06-60)
- G4VEmModel - added extra flag useAngularGenerator and Get/Set methods
20 October 13: V.Ivant (emutils-V09-06-59)
- G4VEmModel - added extra method SelectRandomAtomNumber
17 October 13: V.Ivant (emutils-V09-06-58)
- G4VMultipleScattering - increased lowestLimit from 1 eV to 10 eV
because Urban msc model cannot handle low-energy e- below 10 eV;
added Get/Set methods for this parameter
- G4EmModelManager - fixed control on cut value per G4Region, the
problem was observed when PAI model is used in a some region
with very low cut
06 October 13: V.Ivant (emutils-V09-06-57)
- G4VEmModel - fixed bug in fanoCavity test - element selectors are created
even if cut value is high
03 October 13: V.Ivant (emutils-V09-06-56)
- G4AngleDirect - dummy angular generator
- G4ionEffectiveCharge - use G4Log, G4Exp, G4Pow
- G4VEmProcess, G4VEnergyLossProcess, G4VAtomDeexcitation - added modelID
for secondary tracks (different mecanisms of production of secondaries
may be distingwished)
- G4EnergyLossMessenger, G4EmProcessOptions - added UI command and c++
interface to set verbose level for worker thread
20 September 13: V.Ivant (emutils-V09-06-55)
- G4VEmProcess - fixed Coverity warning
13 September 13: V.Ivant (emutils-V09-06-54)
- G4VMultipleScattering, G4VEnergyLossProcess - removed obsolete
methods SlavePreparePhysicsTable(..) and SlaveBuildPhysicsTable(..)
- G4VEmAngularDistribution - added extra virtual method
SampleDirectionForShell(...)
07 August 13: V.Ivant (emutils-V09-06-53)
- G4VEmModel - added pointer to G4ElementData and GetElementData method
in order to allow sharing G4ElementData between threads
- G4EmModelManager - check MinEnergyCut method to address bug #1481
27 July 13: V.Ivant (emutils-V09-06-52)
- G4VEnergyLossProcess, G4VMultipleScattering - use GetMasterProcess
method in PreparePhysicsTable and BuildPhysicsTable methods
23 July 13: V.Ivant (emutils-V09-06-51)
23 July 13: V.Ivant (emutils-V09-06-50)
- G4VEmProcess - extra fix master/worker initialisation
22 July 13: V.Ivant (emutils-V09-06-49)
- G4VEmProcess - fixed master/worker initialisation
21 July 13: V.Ivant (emutils-V09-06-48)
- G4VEmProcess, G4LossTableManager - added master/worker initialisation
to discrete processes
12 July 13: V.Ivant (emutils-V09-06-47)
- G4VMultipleScattering - return back logic which was in 10.0beta (tag
emutils-V09-06-42)
12 July 13: V.Ivant (emutils-V09-06-46)
- G4VMultipleScattering - compute safety defining not only position but
also radius of possible displacement
11 July 13: V.Ivant (emutils-V09-06-45)
- G4VMultipleScattering - return back tag 43 with more strict control of
safety
09 July 13: V.Ivant (emutils-V09-06-44)
- G4VEmModel - changed signature of the method MinPrimaryEnergy(..)
by addition "G4double cut"; return back virtual method MinEnergyCut;
more accurate usage of inlined methods
- G4VMultipleScattering - more accurate postStepSafety
08 July 13: V.Ivant (emutils-V09-06-43)
- G4VMultipleScattering - moved displacement AlongStep
03 July 13: V.Ivant (emutils-V09-06-42)
- G4LossTableManager - foxed Coverity report
- G4VEmFluctuationModel changed interface in SampleFluctuations
method - G4Material pointer is substituted by G4MaterialCutsCouple
pointer - modification is needed to PAI model
- G4VEnergyLossProcess - changed interface to G4VEmFluctuationModel
27 June 13: V.Ivant (emutils-V09-06-41)
- G4LossTableManager - return back to tag-39, because setup of min/max
energies inside EM tables in some tables is done incorrectly,
also order of EM printout is not optimal
20 June 13: V.Ivant (emutils-V09-06-40)
- G4LossTableManager - attempt to fix Coverity report
19 June 13: V.Ivant (emutils-V09-06-39)
- G4VEnergyLossProcess - fixed Coverity report
17 June 13: V.Ivant (emutils-V09-06-38)
- G4LossTableManager - return back ThreadLocal partern for the
singleton (it was correct)
- G4VMultipleScattering - fixed list models per msc process for ions
15 June 13: V.Ivant (emutils-V09-06-37)
- G4VEnergyLossProcess - avoid unnecessary deletion of tables
between runs
15 June 13: V.Ivant (emutils-V09-06-36)
- G4LossTableManager - fixed ThreadLocal partern for the singleton
14 June 13: V.Ivant (emutils-V09-06-35)
- G4VEnergyLossProcess, G4VEmProcess, G4VEmModel, G4VMscModel
introduced cache for indexes in tables, CPU performance
restored without any effect on results
14 June 13: V.Ivant (emutils-V09-06-34)
- G4LossTableBuilder - optimized number of bins for tables
built for models
14 June 13: V.Ivant (emutils-V09-06-33)
- G4VEnergyLossProcess - fixed CrossSectionPerVolume method
- G4VEmModel - take into account reaction threshold when initialise
G4EmElementSelectors; set smallest number of bins to 3 (was 5);
fixed initialisation
- G4LossTableBuilder - do not use copy constructor when a new
G4PhysicsLogVector for a model
13 June 13: V.Ivant (emutils-V09-06-32)
- G4VEmProcess - fixed CrossSectionPerVolume method - use tablePrim for
high energy if this table is defined
13 June 13: V.Ivant (emutils-V09-06-31)
- G4VEnergyLossProcess, G4LossTableManager - cleanup comments
12 June 13: V.Ivant (emutils-V09-06-30)
- G4VEnergyLossProcess - removed parasitic printout
12 June 13: V.Ivant (emutils-V09-06-29)
- G4VEnergyLossProcess, G4LossTableManager, G4lossTableBuilder - cleanup
table management
11 June 13: V.Ivant (emutils-V09-06-28)
- G4VEnergyLossProcess, G4LossTableManager - cleanup table management
for case of many runs in one session, improved printouts
10 June 13: V.Ivant (emutils-V09-06-27)
- G4VEmModel - fixed SetCrossSectionTable method
- G4VEnergyLossProcess - make ion initialisation assuming that each ion
may have an individual process
07 June 13: G.Cosmo (emutils-V09-06-26)
- Cleanup from automatic MT changes in G4LossTableManager
and G4EnergyLossTables.cc.
06 June 13: V.Ivant (emutils-V09-06-25)
- G4VEnergyLossProcess - do not destroy old tables in worker thread
for the new run
06 June 13: V.Ivant (emutils-V09-06-24)
- G4VEnergyLossProcess, G4VEmProcess - density factor correction
array is assined to a process in BuildPhysicsTable instead of
PreparePhysicsTable in order to get correct pointers in worker
threads
06 June 13: V.Ivant (emutils-V09-06-23)
- G4VEnergyLossProcess - an attempt to fix extra problem seen
in CDASH by changing PrintInfoDefinition method signature
06 June 13: V.Ivant (emutils-V09-06-22)
- G4VEnergyLossProcess - restore correct printout at initialisation
of protons and anti_protons
05 June 13: V.Ivant (emutils-V09-06-21)
- G4VEmModel - fixed crash in copy of element selectors from
master to worker threads
- G4VEnergyLossProcess - restore printout at initialisation
of worker thread
05 June 13: V.Ivant (emutils-V09-06-20)
- G4LossTableManager - SetIon method from previous is removed, old
code to Get dedx, range, inverse range is restored
- G4VEnergyLossProcess - removed debug printout
04 June 13: V.Ivant (emutils-V09-06-19)
- G4LossTableManager - optimisation for MT mode: do not insert
concrete ions into particle/energy loss process map, only
G4GenericIon is inserted; added LocalPhysicsTables methods
to copy pointers of G4PhysicsTables from master to local threads;
SetIon method is added to define ion state
- G4VEnergyLossProcess - optimisation for MT mode, added local
cache inside GetRangeForLoss method, cleanup
- G4VMultipleScattering, G4VMscModel - adaptation to MT mode
30 May 13: V.Ivant (emutils-V09-06-18)
- G4LossTableManager, G4VEnergyLossProcess, G4VMultipleScattering,
G4VEmModel, G4VMscModel - implemented copy of transport cross
sections tables from master to worker threads; implemented
a possibility to copy element selectors from master to worker
threads (model may use or not this feature)
29 May 13: V.Ivant (emutils-V09-06-17)
- G4EmCorrections - fixed typo
29 May 13: V.Ivant (emutils-V09-06-16)
- G4EmCorrections - substituted FindIon from the G4ParticleTable by
G4IonTable::GetIon(Z,A,0)
29 May 13: V.Ivant (emutils-V09-06-15)
- G4LossTableMananger, G4VMultipleScattering - removed unused internal
methods, cleanup code from old unused implementation for MT
- G4EmCalculator - use GetIon(Z,A,0) method from G4IonTable, as
recommended by particle category (instead of FindIon from particle
table)
27 May 13: V.Ivant (emutils-V09-06-14)
- G4EmCalculator - fixed typo
27 May 13: V.Ivant (emutils-V09-06-13)
- G4EmCalculator - fixed compillation warning at gcc 4.1
27 May 13: V.Ivant (emutils-V09-06-12)
- G4EmMessenger is renamed to G4EmManagerMessenger to avoid a clash
with name of already existing file
26 May 13: V.Ivant (emutils-V09-06-11)
- G4VEmModel - added extra methods needed for MT: InitialiseLocal,
InitialiseForMaterial, InitialiseForElement, GetElementSelectors
- G4VMultipleScattering, G4VEnegryLossProcess - more accurate
initialisation for MT (some part of initialisation for worker
thread was commented out in the first implementation).
- G4LossTableManager - added new method SlavePhysicsTable which
provides a correct copy and setup process parameters in MT mode
- G4EmCalculator - added call to InitialiseForMaterial to give a
possibility to a model to read data in any thread
- G4EmElementSelector - make it be thread safe
- G4EmManager, G4EmMessenger - new classes
30 April 13: V.Ivant (emutils-V09-06-10)
- G4ElectronIonPair - fixed typo
30 April 13: V.Ivant (emutils-V09-06-09)
- G4ElectronIonPair - CLHEP::RandGamma substituted by G4RandGamma
- G4LossTableManager - fixed Coverity report (disable sub-cutoff
for MT temporary)
04 April 13: V.Ivant (emutils-V09-06-08)
- G4VEnergyLossProcess, G4VEmProcess - clean up filling of
secondary particles to particle change, use AddSecondary
from G4VParticleChange in all cases; little performance
improvement expected
22 March 13: V.Ivant (emutils-V09-06-07)
- G4VMultipleScattering, G4ionEffectiveCharge - for const parameters
used "static const G4double"
18 March 13: V.Ivant (emutils-V09-06-06)
- G4VMultipleScattering - L.Urban reduced geom limit from 1 um
to 0.01 um (result of discussion at Space User Workshop)
15 March 13: V.Ivant (emutils-V09-06-05)
- G4LossTableManager - fixed Coverity reports
24 February 13: V.Ivant (emutils-V09-06-04)
- G4ionEffectiveCharge - static array become "const G4double"
- G4VEnergyLossProcess - uncomment verbose output in new "Slave" methods
- G4LossTableManager, G4EmModelManager - removed G4endl from description
of exceptions
23 December 12: V.Ivant (emutils-V09-06-03)
- G4VMultipleScattering - position is changed PostStep as it was in 9.6
23 December 12: V.Ivant (emutils-V09-06-02)
- G4VMultipleScattering, G4VMscModel - used momentum direction from
PostStepPoint and not from G4Track - major bug of migration
of msc sampling from PostStepDoIt to AlongStepDoIt
12 December 12: V.Ivant (emutils-V09-06-01)
- G4LossTableManager - removed calls to obsolete methods
07 December 12: V.Ivant (emutils-V09-06-00)
- Removed obsolete classes G4VEnergyLoss, G4VBremAngularDistribution
- G4VEmProcess, G4VMultipleScattering - removed obsolete methods
SetModel(), Model()
09 November 12: V.Ivant (emutils-V09-05-56)
08 November 12: V.Ivant (emutils-V09-05-55)
- G4VEnergyLossProcess - fixed non-reproducibility for ions
@@ -23,52 +23,58 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4AngleDirect.hh 73844 2013-09-13 14:16:30Z vnivanch $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
// GEANT4 Class header file
//
// File name: G4AngleDirect
//
// 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)
// Author: V. Ivanchenko
//
// Creation date: 21 March 2003
// Creation date: 03 October 2013
//
// Modifications:
// 13 Oct 2010 V.Ivanchenko Moved to utils
//
// Class Description:
//
// Abstract base class for Bremsstrahlung Angular Distribution Generation
// Secondary particle has the same direction as a primary
//
// Class Description: End
// -------------------------------------------------------------------
//
//
#include "G4VBremAngularDistribution.hh"
#ifndef G4AngleDirect_h
#define G4AngleDirect_h 1
//
#include "G4VEmAngularDistribution.hh"
G4VBremAngularDistribution::G4VBremAngularDistribution(const G4String& name)
: G4VEmAngularDistribution(name)
class G4Material;
class G4AngleDirect : public G4VEmAngularDistribution
{
G4cout << "### G4VBremAngularDistribution interface class is obsolete "
<< "and will be removed for the next release." << G4endl;
}
public:
//
G4AngleDirect();
G4VBremAngularDistribution::~G4VBremAngularDistribution()
{}
virtual ~G4AngleDirect();
void G4VBremAngularDistribution::PrintGeneratorInformation() const
{}
// Sample direction in global coordinate system,
// this means for zero scattering angle this direction is the same
// as the direction of primary
virtual G4ThreeVector& SampleDirection(const G4DynamicParticle* dp,
G4double, G4int,
const G4Material*);
private:
// hide assignment operator
G4AngleDirect & operator=(const G4AngleDirect &right);
G4AngleDirect(const G4AngleDirect&);
};
#endif
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4AtomicShell.hh 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
// $Id: G4VAtomDeexcitation.hh,v 1.9 2011-01-03 19:34:03 vnivanch Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4DummyModel.hh 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4ElectronIonPair.hh 69580 2013-05-08 13:57:53Z gcosmo $
//
//
#ifndef G4ElectronIonPair_h
@@ -64,6 +64,7 @@
#include "G4ParticleDefinition.hh"
#include "G4ThreeVector.hh"
#include "G4VProcess.hh"
#include "Randomize.hh"
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -149,7 +150,7 @@ G4int G4ElectronIonPair::SampleNumberOfIonsAlongStep(const G4Step* step)
// use gamma distribution with mean value n=meanion and
// dispersion D=meanion/invFanoFactor
G4double meanion = MeanNumberOfIonsAlongStep(step);
return G4lrint(CLHEP::RandGamma::shoot(meanion*invFanoFactor,invFanoFactor));
return G4lrint(G4RandGamma::shoot(meanion*invFanoFactor,invFanoFactor));
}
inline
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmBiasingManager.hh 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmCalculator.hh 70371 2013-05-29 15:18:07Z gcosmo $
//
//
// -------------------------------------------------------------------
@@ -75,6 +75,7 @@ class G4ionEffectiveCharge;
class G4Region;
class G4Element;
class G4EmCorrections;
class G4IonTable;
class G4EmCalculator
{
@@ -278,6 +279,7 @@ private:
std::vector<const G4MaterialCutsCouple*> localCouples;
G4LossTableManager* manager;
G4IonTable* ionTable;
G4EmCorrections* corr;
G4DataVector localCuts;
G4int nLocalMaterials;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmConfigurator.hh 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmCorrections.hh 70371 2013-05-29 15:18:07Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -267,7 +267,7 @@ private:
G4ionEffectiveCharge effCharge;
G4NistManager* nist;
const G4IonTable* ionTable;
G4IonTable* ionTable;
G4VEmModel* ionLEModel;
G4VEmModel* ionHEModel;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmElementSelector.hh 71484 2013-06-17 08:12:51Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -75,7 +75,7 @@ public:
void Dump(const G4ParticleDefinition* p = 0);
inline const G4Element* SelectRandomAtom(G4double kineticEnergy);
inline const G4Element* SelectRandomAtom(G4double kineticEnergy) const;
inline const G4Material* GetMaterial() const;
@@ -87,7 +87,6 @@ private:
G4VEmModel* model;
const G4Material* material;
const G4Element* element;
const G4ElementVector* theElementVector;
G4int nElmMinusOne;
@@ -104,11 +103,11 @@ private:
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
inline const G4Element* G4EmElementSelector::SelectRandomAtom(G4double e)
inline const G4Element* G4EmElementSelector::SelectRandomAtom(G4double e) const
{
const G4Element* element = (*theElementVector)[nElmMinusOne];
if (nElmMinusOne > 0) {
G4double x = G4UniformRand();
element = (*theElementVector)[nElmMinusOne];
for(G4int i=0; i<nElmMinusOne; ++i) {
if (x <= (xSections[i])->Value(e)) {
element = (*theElementVector)[i];
@@ -0,0 +1,290 @@
//
// ********************************************************************
// * 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: G4EmManager.hh 66885 2013-01-16 17:37:13Z gunter $
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
//
// File name: G4EmManager
//
// Author: Vladimir Ivanchenko for migration to MT
//
//
// Creation date: 17.05.2013
//
// Modifications:
//
//
// Class Description:
//
// A utility static class, responsable for keeping pointers
// of all shared objects and main static parameters
// for EM physics models.
//
// It is a singleton which is initialized by the master thread.
// It keeps pointers to shared objects and is read-only in run time
//
// EM processes have to register their tables with this
// class. The responsibility of creating and deleting the tables
// remains with the energy loss classes.
//
// -------------------------------------------------------------------
//
#ifndef G4EmManager_h
#define G4EmManager_h 1
#include <map>
#include <vector>
#include "globals.hh"
class G4PhysicsTable;
class G4MaterialCutsCouple;
class G4EmManagerMessenger;
class G4ParticleDefinition;
class G4VMultipleScattering;
class G4VEmProcess;
class G4VEnergyLossProcess;
class G4EmSaturation;
class G4EmConfigurator;
class G4ElectronIonPair;
class G4LossTableBuilder;
class G4Region;
class G4EmManager
{
public:
static G4EmManager* Instance();
~G4EmManager();
//-------------------------------------------------
// Initialisation
//-------------------------------------------------
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);
void InitialiseProcess(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess*);
void InitialiseProcess(const G4ParticleDefinition* aParticle,
G4VEmProcess*);
void InitialiseProcess(const G4ParticleDefinition* aParticle,
G4VMultipleScattering*);
//-------------------------------------------------
// Registration of processes and tables
//-------------------------------------------------
void Register(G4VEnergyLossProcess* p);
void Register(G4VMultipleScattering* p);
void Register(G4VEmProcess* p);
void RegisterExtraParticle(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void Register(G4PhysicsTable* p);
void DeRegister(G4PhysicsTable* p);
//-------------------------------------------------
// Parameter set methods
//-------------------------------------------------
void SetLossFluctuations(G4bool val);
void SetSubCutoff(G4bool val, const G4Region* r=0);
void SetIntegral(G4bool val);
void SetRandomStep(G4bool val);
void SetMinSubRange(G4double val);
void SetMinEnergy(G4double val);
void SetMaxEnergy(G4double val);
void SetMaxEnergyForCSDARange(G4double val);
void SetMaxEnergyForMuons(G4double val);
void SetDEDXBinning(G4int val);
void SetDEDXBinningForCSDARange(G4int val);
void SetLambdaBinning(G4int val);
G4int GetNumberOfBinsPerDecade() const;
void SetStepFunction(G4double v1, G4double v2);
void SetBuildCSDARange(G4bool val);
void SetLPMFlag(G4bool val);
void SetSplineFlag(G4bool val);
void SetLinearLossLimit(G4double val);
void SetBremsstrahlungTh(G4double val);
void SetFactorForAngleLimit(G4double val);
void SetVerbose(G4int val);
//-------------------------------------------------
// Access methods
//-------------------------------------------------
G4bool BuildCSDARange() const;
G4bool LPMFlag() const;
G4bool SplineFlag() const;
G4double BremsstrahlungTh() const;
G4double FactorForAngleLimit() const;
G4double MinKinEnergy() const;
G4double MaxKinEnergy() const;
G4EmSaturation* EmSaturation();
G4EmConfigurator* EmConfigurator();
G4ElectronIonPair* ElectronIonPair();
G4LossTableBuilder* GetTableBuilder();
private:
//-------------------------------------------------
// Private methods and members
//-------------------------------------------------
G4EmManager();
G4VEnergyLossProcess* BuildTables(const G4ParticleDefinition* aParticle);
void CopyTables(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess*);
void CopyDEDXTables();
void SetParameters(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess*);
G4EmManager(G4EmManager &);
G4EmManager & operator=(const G4EmManager &right);
static G4EmManager* theInstance;
typedef const G4ParticleDefinition* PD;
std::map<PD,G4VEnergyLossProcess*,std::less<PD> > loss_map;
std::vector<G4VEnergyLossProcess*> loss_vector;
std::vector<PD> part_vector;
std::vector<PD> base_part_vector;
std::vector<G4bool> tables_are_built;
std::vector<G4bool> isActive;
std::vector<G4PhysicsTable*> dedx_vector;
std::vector<G4PhysicsTable*> range_vector;
std::vector<G4PhysicsTable*> inv_range_vector;
std::vector<G4PhysicsTable*> xsection_vector;
std::vector<G4VMultipleScattering*> msc_vector;
std::vector<G4VEmProcess*> emp_vector;
G4int n_loss;
G4int run;
PD firstParticle;
PD theElectron;
G4bool all_tables_are_built;
G4bool startInitialisation;
G4bool lossFluctuationFlag;
G4bool subCutoffFlag;
G4bool rndmStepFlag;
G4bool integral;
G4bool integralActive;
G4bool buildCSDARange;
G4bool minEnergyActive;
G4bool maxEnergyActive;
G4bool maxEnergyForMuonsActive;
G4bool stepFunctionActive;
G4bool flagLPM;
G4bool splineFlag;
G4double minSubRange;
G4double maxRangeVariation;
G4double maxFinalStep;
G4double minKinEnergy;
G4double maxKinEnergy;
G4double maxKinEnergyForMuons;
G4double bremsTh;
G4double factorForAngleLimit;
G4LossTableBuilder* tableBuilder;
G4EmManagerMessenger* theMessenger;
G4EmSaturation* emSaturation;
G4EmConfigurator* emConfigurator;
G4ElectronIonPair* emElectronIonPair;
G4int nbinsLambda;
G4int nbinsPerDecade;
G4int verbose;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,125 @@
//
// ********************************************************************
// * 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: G4EmManagerMessenger.hh 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// File name: G4EmManagerMessenger
//
// Author: Vladimir Ivanchenko created from G4EnergyLossMessenger
//
// Creation date: 22-05-2013
//
// Modifications:
//
// -------------------------------------------------------------------
//
// Class Description:
// This is a messenger class to interface to exchange information
// between G4VEm and UI.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#ifndef G4EmManagerMessenger_h
#define G4EmManagerMessenger_h 1
#include "globals.hh"
#include "G4UImessenger.hh"
class G4UIdirectory;
class G4UIcommand;
class G4UIcmdWithABool;
class G4UIcmdWithAnInteger;
class G4UIcmdWithADouble;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithAString;
class G4EmManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class G4EmManagerMessenger: public G4UImessenger
{
public: // with description
G4EmManagerMessenger(G4EmManager*);
virtual ~G4EmManagerMessenger();
virtual void SetNewValue(G4UIcommand*, G4String);
private:
G4EmManager* theManager;
G4UIdirectory* eLossDirectory;
G4UIdirectory* mscDirectory;
G4UIdirectory* emDirectory;
G4UIcmdWithABool* RndmStepCmd;
G4UIcmdWithABool* EnlossFlucCmd;
G4UIcmdWithABool* SubSecCmd;
G4UIcmdWithADouble* MinSubSecCmd;
G4UIcommand* StepFuncCmd;
G4UIcmdWithADoubleAndUnit* MinEnCmd;
G4UIcmdWithADoubleAndUnit* MaxEnCmd;
G4UIcmdWithABool* IntegCmd;
G4UIcmdWithABool* rangeCmd;
G4UIcmdWithABool* lpmCmd;
G4UIcmdWithABool* splCmd;
G4UIcommand* deexCmd;
/*
G4UIcmdWithABool* aplCmd;
G4UIcmdWithABool* deCmd;
G4UIcmdWithABool* auCmd;
G4UIcmdWithABool* pixeCmd;
G4UIcmdWithAString* pixeXsCmd;
G4UIcmdWithAString* pixeeXsCmd;
G4UIcmdWithAnInteger* verCmd;
G4UIcmdWithAnInteger* ver1Cmd;
*/
G4UIcmdWithAnInteger* dedxCmd;
G4UIcmdWithAnInteger* lamCmd;
G4UIcmdWithADouble* lllCmd;
/*
G4UIcmdWithAString* mscCmd;
G4UIcmdWithADouble* labCmd;
G4UIcmdWithABool* latCmd;
G4UIcmdWithADouble* skinCmd;
G4UIcmdWithADouble* frCmd;
G4UIcmdWithADouble* fgCmd;
G4UIcmdWithADouble* mscfCmd;
G4UIcmdWithADoubleAndUnit* angCmd;
G4UIcommand* bfCmd;
G4UIcommand* fiCmd;
G4UIcommand* brCmd;
*/
};
#endif
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmModelManager.hh 72944 2013-08-14 13:43:07Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -149,16 +149,17 @@ public:
void Clear();
const G4DataVector* Initialise(const G4ParticleDefinition*,
const G4ParticleDefinition*,
G4double,
G4int);
const G4DataVector* Initialise(const G4ParticleDefinition* part,
const G4ParticleDefinition* secPart,
G4double minSubRange,
G4int verb);
void FillDEDXVector(G4PhysicsVector*, const G4MaterialCutsCouple*,
G4EmTableType t = fRestricted);
void FillLambdaVector(G4PhysicsVector*, const G4MaterialCutsCouple*,
G4bool startFromNull = true, G4EmTableType t = fRestricted);
G4bool startFromNull = true,
G4EmTableType t = fRestricted);
G4VEmModel* GetModel(G4int, G4bool ver = false);
@@ -195,8 +196,9 @@ private:
private:
const G4DataVector* theCuts;
G4DataVector* theSubCuts;
const G4DataVector* theCuts;
G4DataVector* theCutsNew;
G4DataVector* theSubCuts;
std::vector<G4VEmModel*> models;
std::vector<G4VEmFluctuationModel*> flucModels;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmMultiModel.hh 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmProcessOptions.hh 74376 2013-10-04 08:25:47Z gcosmo $
//
//
// -------------------------------------------------------------------
@@ -99,7 +99,8 @@ public:
void SetBuildCSDARange(G4bool val);
void SetVerbose(G4int val, const G4String& name = "all");
void SetVerbose(G4int val, const G4String& name = "all",
G4bool worker = false);
void SetLambdaFactor(G4double val);
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmProcessSubType.hh 66241 2012-12-13 18:34:42Z gunter $
//
//---------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmSaturation.hh 66241 2012-12-13 18:34:42Z gunter $
//
//
#ifndef G4EmSaturation_h
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id$
// $Id: G4EmTableType.hh 66241 2012-12-13 18:34:42Z gunter $
//
//---------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EnergyLossMessenger.hh 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -110,6 +110,7 @@ private:
G4UIcmdWithAString* pixeeXsCmd;
G4UIcmdWithAnInteger* verCmd;
G4UIcmdWithAnInteger* ver1Cmd;
G4UIcmdWithAnInteger* ver2Cmd;
G4UIcmdWithAnInteger* dedxCmd;
G4UIcmdWithAnInteger* lamCmd;
G4UIcmdWithADouble* lllCmd;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id$
// $Id: G4EnergyLossTables.hh 77290 2013-11-22 10:57:50Z gcosmo $
//
// $Id:
//
@@ -205,16 +205,34 @@ public:
private:
static void CPRWarning();
static void ParticleHaveNoLoss(const G4ParticleDefinition* aParticle, const G4String&);
static void ParticleHaveNoLoss(const G4ParticleDefinition* aParticle,
const G4String&);
/*
typedef std::map<K,G4EnergyLossTablesHelper,std::less<K> > helper_map;
static helper_map dict;
static G4ThreadLocal helper_map *dict;
static G4EnergyLossTablesHelper GetTables(const G4ParticleDefinition* p);
static G4EnergyLossTablesHelper t ;
static G4EnergyLossTablesHelper null_loss ;
static const G4ParticleDefinition* lastParticle ;
static G4ThreadLocal G4EnergyLossTablesHelper *t;
static G4ThreadLocal G4EnergyLossTablesHelper *null_loss;
static G4ThreadLocal G4ParticleDefinition* lastParticle ;
static G4ThreadLocal G4double QQPositron ;
static G4ThreadLocal G4double Chargesquare ;
static G4ThreadLocal G4int oldIndex ;
static G4ThreadLocal G4double rmin,rmax,Thigh ;
static G4ThreadLocal G4int let_counter;
static G4ThreadLocal G4int let_max_num_warnings;
static G4ThreadLocal G4bool first_loss;
*/
typedef std::map<K,G4EnergyLossTablesHelper,std::less<K> > helper_map;
static helper_map *dict;
static G4EnergyLossTablesHelper GetTables(const G4ParticleDefinition* p);
static G4EnergyLossTablesHelper *t;
static G4EnergyLossTablesHelper *null_loss;
static G4ParticleDefinition* lastParticle ;
static G4double QQPositron ;
static G4double Chargesquare ;
static G4int oldIndex ;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4LossTableBuilder.hh 66241 2012-12-13 18:34:42Z gunter $
//
//
// -------------------------------------------------------------------
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4LossTableManager.hh 76333 2013-11-08 14:31:50Z gcosmo $
//
//
// -------------------------------------------------------------------
@@ -60,6 +60,7 @@
// 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)
// 04-06-13 Adaptation for MT mode, new method LocalPhysicsTables (V.Ivanchenko)
//
// Class Description:
//
@@ -80,7 +81,7 @@
#include <vector>
#include "globals.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4EnergyLossTables.hh"
#include "G4ThreadLocalSingleton.hh"
class G4PhysicsTable;
class G4MaterialCutsCouple;
@@ -99,6 +100,8 @@ class G4Region;
class G4LossTableManager
{
friend class G4ThreadLocalSingleton<G4LossTableManager>;
public:
static G4LossTableManager* Instance();
@@ -116,19 +119,22 @@ public:
//-------------------------------------------------
void PreparePhysicsTable(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
G4VEnergyLossProcess* p, G4bool theMaster);
void PreparePhysicsTable(const G4ParticleDefinition* aParticle,
G4VEmProcess* p);
G4VEmProcess* p, G4bool theMaster);
void PreparePhysicsTable(const G4ParticleDefinition* aParticle,
G4VMultipleScattering* p);
G4VMultipleScattering* p, G4bool theMaster);
void BuildPhysicsTable(const G4ParticleDefinition* aParticle);
void BuildPhysicsTable(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void LocalPhysicsTables(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
//-------------------------------------------------
// Run time access to DEDX, range, energy for a given particle,
// energy, and G4MaterialCutsCouple
@@ -193,9 +199,6 @@ public:
void DeRegister(G4VEmFluctuationModel* p);
void RegisterIon(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
void RegisterExtraParticle(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p);
@@ -253,6 +256,8 @@ public:
G4bool SplineFlag() const;
G4bool IsMaster() const;
G4double BremsstrahlungTh() const;
G4double FactorForAngleLimit() const;
@@ -306,7 +311,7 @@ private:
G4LossTableManager(G4LossTableManager &);
G4LossTableManager & operator=(const G4LossTableManager &right);
static G4LossTableManager* theInstance;
//static G4ThreadLocal G4LossTableManager* theInstance;
typedef const G4ParticleDefinition* PD;
@@ -329,6 +334,7 @@ private:
G4VEnergyLossProcess* currentLoss;
PD currentParticle;
PD theElectron;
PD theGenericIon;
PD firstParticle;
G4int n_loss;
@@ -349,6 +355,7 @@ private:
G4bool stepFunctionActive;
G4bool flagLPM;
G4bool splineFlag;
G4bool isMaster;
G4double minSubRange;
G4double maxRangeVariation;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id$
// $Id: G4MscStepLimitType.hh 66241 2012-12-13 18:34:42Z gunter $
//
//---------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VAtomDeexcitation.hh 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -170,6 +170,8 @@ private:
G4VAtomDeexcitation(G4VAtomDeexcitation &);
G4VAtomDeexcitation & operator=(const G4VAtomDeexcitation &right);
const G4ParticleDefinition* gamma;
G4ProductionCutsTable* theCoupleTable;
G4double lowestKinEnergy;
G4int verbose;
@@ -188,6 +190,9 @@ private:
std::vector<G4bool> AugerRegions;
std::vector<G4bool> PIXERegions;
std::vector<G4DynamicParticle*> vdyn;
static G4int pixeIDg;
static G4int pixeIDe;
};
inline void G4VAtomDeexcitation::SetFluo(G4bool val)
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmAngularDistribution.hh 73847 2013-09-13 14:32:39Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -73,6 +73,16 @@ public:
G4int Z,
const G4Material*) = 0;
// Sample direction in global coordinate system for given electronic shell,
// this means for zero scattering angle this direction is the same
// as the direction of primary
virtual G4ThreeVector& SampleDirectionForShell(
const G4DynamicParticle* dp,
G4double finalTotalEnergy,
G4int Z,
G4int shellID,
const G4Material*);
inline const G4String& GetName() const;
protected:
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmFluctuationModel.hh 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -62,6 +62,8 @@
class G4ParticleDefinition;
class G4DynamicParticle;
class G4Material;
class G4MaterialCutsCouple;
class G4LossTableManager;
class G4VEmFluctuationModel
{
@@ -76,16 +78,16 @@ public:
// Virtual methods to be implemented for the concrete model
//------------------------------------------------------------------------
virtual G4double SampleFluctuations(const G4Material*,
virtual G4double SampleFluctuations(const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double& tmax,
G4double& length,
G4double& meanLoss) = 0;
G4double tmax,
G4double length,
G4double meanLoss) = 0;
virtual G4double Dispersion(const G4Material*,
const G4DynamicParticle*,
G4double& tmax,
G4double& length) = 0;
G4double tmax,
G4double length) = 0;
//------------------------------------------------------------------------
// Methods with standard implementation; may be overwritten if needed
@@ -107,7 +109,8 @@ private:
G4VEmFluctuationModel & operator=(const G4VEmFluctuationModel &right);
G4VEmFluctuationModel(const G4VEmFluctuationModel&);
const G4String name;
const G4String name;
G4LossTableManager* fManager;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmModel.hh 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -91,12 +91,14 @@
#include "Randomize.hh"
#include <vector>
class G4ElementData;
class G4PhysicsTable;
class G4Region;
class G4VParticleChange;
class G4ParticleChangeForLoss;
class G4ParticleChangeForGamma;
class G4Track;
class G4LossTableManager;
class G4VEmModel
{
@@ -120,6 +122,22 @@ public:
G4double tmin = 0.0,
G4double tmax = DBL_MAX) = 0;
//------------------------------------------------------------------------
// Methods for initialisation of MT; may be overwritten if needed
//------------------------------------------------------------------------
// initilisation in local thread
virtual void InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel* masterModel);
// initilisation of a new material at run time
virtual void InitialiseForMaterial(const G4ParticleDefinition*,
const G4Material*);
// initilisation of a new element at run time
virtual void InitialiseForElement(const G4ParticleDefinition*,
G4int Z);
//------------------------------------------------------------------------
// Methods with standard implementation; may be overwritten if needed
//------------------------------------------------------------------------
@@ -175,7 +193,12 @@ public:
// threshold for zero value
virtual G4double MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*);
const G4ParticleDefinition*,
G4double cut = 0.0);
// model can define low-energy limit for the cut
virtual G4double MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*);
// initilisation at run time for a given material
virtual void SetupForMaterial(const G4ParticleDefinition*,
@@ -207,6 +230,12 @@ public:
void InitialiseElementSelectors(const G4ParticleDefinition*,
const G4DataVector&);
// should be called at initialisation to access element selectors
inline std::vector<G4EmElementSelector*>* GetElementSelectors();
// should be called at initialisation to set element selectors
inline void SetElementSelectors(std::vector<G4EmElementSelector*>*);
// dEdx per unit length
inline G4double ComputeDEDX(const G4MaterialCutsCouple*,
const G4ParticleDefinition*,
@@ -251,13 +280,18 @@ public:
G4double cutEnergy = 0.0,
G4double maxEnergy = DBL_MAX);
// to select atom if cross section is proportional number of electrons
inline G4int SelectRandomAtomNumber(const G4Material*);
//------------------------------------------------------------------------
// Get/Set methods
//------------------------------------------------------------------------
void SetParticleChange(G4VParticleChange*, G4VEmFluctuationModel* f=0);
void SetCrossSectionTable(G4PhysicsTable*);
void SetCrossSectionTable(G4PhysicsTable*, G4bool isLocal);
inline G4ElementData* GetElementData();
inline G4PhysicsTable* GetCrossSectionTable();
@@ -285,6 +319,10 @@ public:
inline G4bool ForceBuildTableFlag() const;
inline G4bool UseAngularGeneratorFlag() const;
inline void SetAngularGeneratorFlag(G4bool);
inline void SetHighEnergyLimit(G4double);
inline void SetLowEnergyLimit(G4double);
@@ -303,7 +341,11 @@ public:
inline void SetDeexcitationFlag(G4bool val);
inline void ForceBuildTable(G4bool val);
inline void SetForceBuildTable(G4bool val);
inline void SetMasterThread(G4bool val);
inline G4bool IsMaster() const;
inline G4double MaxSecondaryKinEnergy(const G4DynamicParticle* dynParticle);
@@ -342,21 +384,28 @@ private:
G4bool theLPMflag;
G4bool flagDeexcitation;
G4bool flagForceBuildTable;
G4bool isMaster;
G4bool localTable;
G4bool localElmSelectors;
G4bool useAngularGenerator;
G4int nSelectors;
std::vector<G4EmElementSelector*> elmSelectors;
std::vector<G4EmElementSelector*>* elmSelectors;
protected:
G4ElementData* fElementData;
G4VParticleChange* pParticleChange;
G4PhysicsTable* xSectionTable;
const std::vector<G4double>* theDensityFactor;
const std::vector<G4int>* theDensityIdx;
size_t idxTable;
// ======== Cashed values - may be state dependent ================
private:
G4LossTableManager* fManager;
const G4MaterialCutsCouple* fCurrentCouple;
const G4Element* fCurrentElement;
@@ -372,28 +421,28 @@ inline void G4VEmModel::SetCurrentCouple(const G4MaterialCutsCouple* p)
fCurrentCouple = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4MaterialCutsCouple* G4VEmModel::CurrentCouple() const
{
return fCurrentCouple;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetCurrentElement(const G4Element* elm)
{
fCurrentElement = elm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4Element* G4VEmModel::GetCurrentElement() const
{
return fCurrentElement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline
G4double G4VEmModel::MaxSecondaryKinEnergy(const G4DynamicParticle* dynPart)
@@ -402,44 +451,46 @@ G4double G4VEmModel::MaxSecondaryKinEnergy(const G4DynamicParticle* dynPart)
dynPart->GetKineticEnergy());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::ComputeDEDX(const G4MaterialCutsCouple* c,
const G4ParticleDefinition* p,
inline G4double G4VEmModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* part,
G4double kinEnergy,
G4double cutEnergy)
{
fCurrentCouple = c;
return ComputeDEDXPerVolume(c->GetMaterial(),p,kinEnergy,cutEnergy);
SetCurrentCouple(couple);
return ComputeDEDXPerVolume(couple->GetMaterial(),part,kinEnergy,cutEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::CrossSection(const G4MaterialCutsCouple* c,
const G4ParticleDefinition* p,
inline G4double G4VEmModel::CrossSection(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* part,
G4double kinEnergy,
G4double cutEnergy,
G4double maxEnergy)
{
fCurrentCouple = c;
return CrossSectionPerVolume(c->GetMaterial(),p,kinEnergy,cutEnergy,maxEnergy);
SetCurrentCouple(couple);
return CrossSectionPerVolume(couple->GetMaterial(),part,kinEnergy,
cutEnergy,maxEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
G4double ekin,
const G4Material* material,
G4double emin,
G4double emax)
inline
G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* part,
G4double ekin,
const G4Material* material,
G4double emin,
G4double emax)
{
G4double mfp = DBL_MAX;
G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax);
G4double cross = CrossSectionPerVolume(material,part,ekin,emin,emax);
if (cross > DBL_MIN) { mfp = 1./cross; }
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::ComputeCrossSectionPerAtom(
const G4ParticleDefinition* part,
@@ -448,16 +499,16 @@ inline G4double G4VEmModel::ComputeCrossSectionPerAtom(
G4double cutEnergy,
G4double maxEnergy)
{
fCurrentElement = elm;
SetCurrentElement(elm);
return ComputeCrossSectionPerAtom(part,kinEnergy,elm->GetZ(),elm->GetN(),
cutEnergy,maxEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4Element*
G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
const G4ParticleDefinition* part,
G4double kinEnergy,
G4double cutEnergy,
G4double maxEnergy)
@@ -465,19 +516,38 @@ G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple,
fCurrentCouple = couple;
if(nSelectors > 0) {
fCurrentElement =
elmSelectors[couple->GetIndex()]->SelectRandomAtom(kinEnergy);
((*elmSelectors)[couple->GetIndex()])->SelectRandomAtom(kinEnergy);
} else {
fCurrentElement = SelectRandomAtom(couple->GetMaterial(),p,kinEnergy,
fCurrentElement = SelectRandomAtom(couple->GetMaterial(),part,kinEnergy,
cutEnergy,maxEnergy);
}
return fCurrentElement;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4int G4VEmModel::SelectRandomAtomNumber(const G4Material* mat)
{
size_t nn = mat->GetNumberOfElements();
const G4ElementVector* elmv = mat->GetElementVector();
G4int Z = G4int((*elmv)[0]->GetZ());
if(1 < nn) {
const G4double* at = mat->GetVecNbOfAtomsPerVolume();
G4double tot = mat->GetTotNbOfAtomsPerVolume()*G4UniformRand();
for( size_t i=0; i<nn; ++i) {
Z = G4int((*elmv)[0]->GetZ());
tot -= Z*at[i];
if(tot <= 0.0) { break; }
}
}
return Z;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4int G4VEmModel::SelectIsotopeNumber(const G4Element* elm)
{
fCurrentElement = elm;
SetCurrentElement(elm);
G4int N = G4int(elm->GetN() + 0.5);
G4int ni = elm->GetNumberOfIsotopes();
if(ni > 0) {
@@ -503,56 +573,56 @@ inline G4VEmFluctuationModel* G4VEmModel::GetModelOfFluctuations()
return flucModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmAngularDistribution* G4VEmModel::GetAngularDistribution()
{
return anglModel;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetAngularDistribution(G4VEmAngularDistribution* p)
{
anglModel = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::HighEnergyLimit() const
{
return highLimit;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::LowEnergyLimit() const
{
return lowLimit;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::HighEnergyActivationLimit() const
{
return eMaxActive;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::LowEnergyActivationLimit() const
{
return eMinActive;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::PolarAngleLimit() const
{
return polarAngleLimit;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmModel::SecondaryThreshold() const
{
@@ -580,49 +650,77 @@ inline G4bool G4VEmModel::ForceBuildTableFlag() const
return flagForceBuildTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4VEmModel::UseAngularGeneratorFlag() const
{
return useAngularGenerator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetAngularGeneratorFlag(G4bool val)
{
useAngularGenerator = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetMasterThread(G4bool val)
{
isMaster = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4VEmModel::IsMaster() const
{
return isMaster;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetHighEnergyLimit(G4double val)
{
highLimit = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetLowEnergyLimit(G4double val)
{
lowLimit = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetActivationHighEnergyLimit(G4double val)
{
eMaxActive = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetActivationLowEnergyLimit(G4double val)
{
eMinActive = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4VEmModel::IsActive(G4double kinEnergy)
{
return (kinEnergy >= eMinActive && kinEnergy <= eMaxActive);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetPolarAngleLimit(G4double val)
{
polarAngleLimit = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::SetSecondaryThreshold(G4double val)
{
@@ -645,24 +743,50 @@ inline void G4VEmModel::SetDeexcitationFlag(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEmModel::ForceBuildTable(G4bool val)
inline void G4VEmModel::SetForceBuildTable(G4bool val)
{
flagForceBuildTable = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4String& G4VEmModel::GetName() const
{
return name;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline std::vector<G4EmElementSelector*>* G4VEmModel::GetElementSelectors()
{
return elmSelectors;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void
G4VEmModel::SetElementSelectors(std::vector<G4EmElementSelector*>* p)
{
elmSelectors = p;
if(elmSelectors) { nSelectors = elmSelectors->size(); }
localElmSelectors = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4ElementData* G4VEmModel::GetElementData()
{
return fElementData;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEmModel::GetCrossSectionTable()
{
return xSectionTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#endif
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmProcess.hh 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -85,6 +85,7 @@ class G4VParticleChange;
class G4PhysicsTable;
class G4PhysicsVector;
class G4EmBiasingManager;
class G4LossTableManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -128,8 +129,6 @@ public:
// Build physics table during initialisation
void BuildPhysicsTable(const G4ParticleDefinition&);
void PrintInfoDefinition();
// Called before tracking of each new G4Track
void StartTracking(G4Track*);
@@ -195,8 +194,9 @@ public:
// Min kinetic energy for high energy table
inline void SetMinKinEnergyPrim(G4double e);
// Cross section table pointer
inline const G4PhysicsTable* LambdaTable() const;
// Cross section table pointers
inline G4PhysicsTable* LambdaTable() const;
inline G4PhysicsTable* LambdaTablePrim() const;
//------------------------------------------------------------------------
// Define and access particle type
@@ -222,14 +222,8 @@ public:
// model will be selected for a given energy interval
void AddEmModel(G4int, G4VEmModel*, const G4Region* region = 0);
// Assign a model to a process - obsolete will be removed
void SetModel(G4VEmModel*, G4int index = 1);
// return the assigned model - obsolete will be removed
G4VEmModel* Model(G4int index = 1);
// return the assigned model
G4VEmModel* EmModel(G4int index = 1);
G4VEmModel* EmModel(G4int index = 1) const;
// Assign a model to a process
void SetEmModel(G4VEmModel*, G4int index = 1);
@@ -238,7 +232,7 @@ public:
void UpdateEmModel(const G4String&, G4double, G4double);
// Access to models
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false);
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
// access atom on which interaction happens
const G4Element* GetCurrentElement() const;
@@ -306,6 +300,8 @@ private:
void BuildLambdaTable();
void PrintInfoProcess(const G4ParticleDefinition&);
void FindLambdaMax();
inline void DefineMaterial(const G4MaterialCutsCouple* couple);
@@ -326,6 +322,7 @@ private:
// ======== Parameters of the class fixed at construction =========
G4LossTableManager* lManager;
G4EmModelManager* modelManager;
G4EmBiasingManager* biasManager;
const G4ParticleDefinition* theGamma;
@@ -346,6 +343,9 @@ private:
std::vector<G4double> theEnergyOfCrossSectionMax;
std::vector<G4double> theCrossSectionMax;
size_t idxLambda;
size_t idxLambdaPrim;
const std::vector<G4double>* theCuts;
const std::vector<G4double>* theCutsGamma;
const std::vector<G4double>* theCutsElectron;
@@ -396,7 +396,11 @@ private:
G4bool biasFlag;
G4bool weightFlag;
G4int warn;
G4int mainSecondaries;
G4int secID;
G4int fluoID;
G4int augerID;
G4int biasID;
};
// ======== Run time inline methods ================
@@ -433,6 +437,7 @@ inline void G4VEmProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
fFactor = biasFactor*(*theDensityFactor)[currentCoupleIndex];
if(!baseMaterial) { baseMaterial = currentMaterial; }
mfpKinEnergy = DBL_MAX;
idxLambda = idxLambdaPrim = 0;
}
}
@@ -461,14 +466,14 @@ G4VEmModel* G4VEmProcess::SelectModelForMaterial(G4double kinEnergy,
inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
{
return ((*theLambdaTable)[basedCoupleIndex])->Value(e);
return ((*theLambdaTable)[basedCoupleIndex])->Value(e, idxLambda);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEmProcess::GetLambdaFromTablePrim(G4double e)
{
return ((*theLambdaTablePrim)[basedCoupleIndex])->Value(e)/e;
return ((*theLambdaTablePrim)[basedCoupleIndex])->Value(e, idxLambdaPrim)/e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -594,13 +599,20 @@ inline G4double G4VEmProcess::CrossSectionBiasingFactor() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4PhysicsTable* G4VEmProcess::LambdaTable() const
inline G4PhysicsTable* G4VEmProcess::LambdaTable() const
{
return theLambdaTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEmProcess::LambdaTablePrim() const
{
return theLambdaTablePrim;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4ParticleDefinition* G4VEmProcess::Particle() const
{
return particle;
@@ -1,249 +0,0 @@
//
// ********************************************************************
// * 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$
//
//
// ------------------------------------------------------------
// 26.10.01 static inline functions moved to .cc file (mma)
// 08.11.01 some static methods,data members are not static L.Urban
// 15.01.03 Migrade to cut per region (V.Ivanchenko)
// ------------------------------------------------------------
//
// Class Description
//
// General service class for the energy loss classes
//
// It contains code needed to compute the range tables,
// time tables, the inverse range tables and some auxiliary
// tables.
// The energy loss fluctuation code is here,too.
//
// All the EnergyLoss classes are inherited from G4VEnergyLoss
// class.
//
// -----------------------------------------------------------
// created on 28 January 2000 by L. Urban
// -----------------------------------------------------------
#ifndef G4VEnergyLoss_h
#define G4VEnergyLoss_h 1
#include "globals.hh"
#include "G4ios.hh"
#include "Randomize.hh"
#include "G4Poisson.hh"
#include "G4Electron.hh"
#include "G4VContinuousDiscreteProcess.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsLinearVector.hh"
#include "G4MaterialCutsCouple.hh"
class G4EnergyLossMessenger;
class G4VEnergyLoss : public G4VContinuousDiscreteProcess
{
public:
G4VEnergyLoss(const G4String&,G4ProcessType aType = fNotDefined );
virtual ~G4VEnergyLoss();
virtual G4double GetContinuousStepLimit(const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& currentSafety) = 0 ;
virtual G4VParticleChange* AlongStepDoIt(const G4Track& track,
const G4Step& Step) = 0 ;
virtual G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) = 0;
virtual G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& Step) = 0;
protected:// with description
// code for the energy loss fluctuation
G4double GetLossWithFluct(const G4DynamicParticle* aParticle,
const G4MaterialCutsCouple* couple,
G4double ChargeSquare,
G4double MeanLoss,
G4double step);
// Build range table starting from the DEDXtable
G4PhysicsTable*
BuildRangeTable(G4PhysicsTable* theDEDXTable,
G4PhysicsTable* theRangeTable,
G4double Tmin,G4double Tmax,G4int nbin);
// Build time tables starting from the DEDXtable
G4PhysicsTable*
BuildLabTimeTable(G4PhysicsTable* theDEDXTable,
G4PhysicsTable* theLabTimeTable,
G4double Tmin,G4double Tmax,G4int nbin);
G4PhysicsTable*
BuildProperTimeTable(G4PhysicsTable* theDEDXTable,
G4PhysicsTable* ProperTimeTable,
G4double Tmin,G4double Tmax,G4int nbin);
// Build tables of coefficients needed for inverting the range table
G4PhysicsTable*
BuildRangeCoeffATable(G4PhysicsTable* theRangeTable,
G4PhysicsTable* theCoeffATable,
G4double Tmin,G4double Tmax,G4int nbin);
G4PhysicsTable*
BuildRangeCoeffBTable(G4PhysicsTable* theRangeTable,
G4PhysicsTable* theCoeffBTable,
G4double Tmin,G4double Tmax,G4int nbin);
G4PhysicsTable*
BuildRangeCoeffCTable(G4PhysicsTable* theRangeTable,
G4PhysicsTable* theCoeffCTable,
G4double Tmin,G4double Tmax,G4int nbin);
// Invert range table
G4PhysicsTable*
BuildInverseRangeTable(G4PhysicsTable* theRangeTable,
G4PhysicsTable* theRangeCoeffATable,
G4PhysicsTable* theRangeCoeffBTable,
G4PhysicsTable* theRangeCoeffCTable,
G4PhysicsTable* theInverseRangeTable,
G4double Tmin,G4double Tmax,G4int nbin);
private:
void BuildRangeVector(G4PhysicsTable* theDEDXTable,
G4double Tmin,G4double Tmax,G4int nbin,
G4int materialIndex,G4PhysicsLogVector* rangeVector);
G4double RangeIntLin(G4PhysicsVector* physicsVector,G4int nbin);
G4double RangeIntLog(G4PhysicsVector* physicsVector,G4int nbin);
void BuildLabTimeVector(G4PhysicsTable* theDEDXTable,
G4double Tmin,G4double Tmax,G4int nbin,
G4int materialIndex,G4PhysicsLogVector* rangeVector);
void BuildProperTimeVector(G4PhysicsTable* theDEDXTable,
G4double Tmin,G4double Tmax,G4int nbin,
G4int materialIndex,G4PhysicsLogVector* rangeVector);
G4double LabTimeIntLog(G4PhysicsVector* physicsVector,G4int nbin);
G4double ProperTimeIntLog(G4PhysicsVector* physicsVector,G4int nbin);
void InvertRangeVector(G4PhysicsTable* theRangeTable,
G4PhysicsTable* theRangeCoeffATable,
G4PhysicsTable* theRangeCoeffBTable,
G4PhysicsTable* theRangeCoeffCTable,
G4double Tmin,G4double Tmax,G4int nbin,
G4int materialIndex,G4PhysicsLogVector* rangeVector);
protected:
G4double ParticleMass;
private:
// data members to speed up the fluctuation calculation
const G4Material* lastMaterial;
G4int imat;
G4double f1Fluct,f2Fluct,e1Fluct,e2Fluct,rateFluct,ipotFluct;
G4double e1LogFluct,e2LogFluct,ipotLogFluct;
const G4int nmaxCont1,nmaxCont2 ;
// for some integration routines
G4double taulow,tauhigh,ltaulow,ltauhigh;
// static part of the class
public: // With description
static void SetRndmStep(G4bool value);
// use / do not use randomisation in energy loss steplimit
// ( default = no randomisation)
static void SetEnlossFluc(G4bool value);
// compute energy loss with/without fluctuation
// ( default : with fluctuation)
static void SetSubSec(G4bool value);
// switch on/off the generation of the subcutoff secondaries
// ( default = no subcutoff secondary generation )
static void SetMinDeltaCutInRange(G4double value);
// sets minimal cut value for the subcutoff secondaries
// (i.e. the kinetic energy of these secondaries can not be
// smaller than the energy corresponds to MinDeltaCutInRange).
static void SetStepFunction (G4double c1, G4double c2);
// sets values for data members used to compute the step limit:
// dRoverRange : max. relative range change in one step,
// finalRange : if range <= finalRange --> last step for the particle.
protected: // With description
static G4bool EqualCutVectors( G4double* vec1, G4double* vec2 );
static G4double* CopyCutVectors( G4double* dest, G4double* source );
G4bool CutsWhereModified();
// data members
protected:
static G4double dRoverRange; // dRoverRange is the maximum allowed
// deltarange/range in one Step
static G4double finalRange; // final step before stopping
static G4double finalRangeRequested; //from UI command
static G4double c1lim,c2lim,c3lim ; // coeffs for computing steplimit
static G4bool rndmStepFlag; // control the randomization of the step
static G4bool EnlossFlucFlag; // control the energy loss fluctuation
static G4bool subSecFlag; // control the generation of subcutoff delta
static G4double MinDeltaCutInRange; // minimum cut for delta rays
static G4double* MinDeltaEnergy ;
static G4bool* LowerLimitForced ;
static G4bool setMinDeltaCutInRange ;
static G4EnergyLossMessenger* ELossMessenger;
};
#endif
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEnergyLossProcess.hh 76333 2013-11-08 14:31:50Z gcosmo $
// GEANT4 tag $Name:
//
// -------------------------------------------------------------------
@@ -115,6 +115,7 @@ class G4Region;
class G4SafetyHelper;
class G4VAtomDeexcitation;
class G4EmBiasingManager;
class G4LossTableManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -172,7 +173,7 @@ public:
G4PhysicsTable* BuildLambdaTable(G4EmTableType tType = fRestricted);
// summary printout after initialisation
void PrintInfoDefinition();
void PrintInfoDefinition(const G4ParticleDefinition& part);
// Called before tracking of each new G4Track
void StartTracking(G4Track*);
@@ -233,6 +234,7 @@ private:
//------------------------------------------------------------------------
public:
// access to dispersion of restricted energy loss
G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple,
const G4DynamicParticle* dp,
@@ -274,8 +276,6 @@ protected:
inline size_t CurrentMaterialCutsCoupleIndex() const;
inline G4double GetCurrentRange() const;
//------------------------------------------------------------------------
// Specific methods to set, access, modify models
//------------------------------------------------------------------------
@@ -302,12 +302,12 @@ public:
void SetEmModel(G4VEmModel*, G4int index=1);
// return the assigned model
G4VEmModel* EmModel(G4int index=1);
G4VEmModel* EmModel(G4int index=1) const;
// Access to models
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false);
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
G4int NumberOfModels();
G4int NumberOfModels() const;
// Assign a fluctuation model to a process
void SetFluctModel(G4VEmFluctuationModel*);
@@ -422,10 +422,11 @@ public:
inline G4PhysicsTable* IonisationTable() const;
inline G4PhysicsTable* IonisationTableForSubsec() const;
inline G4PhysicsTable* CSDARangeTable() const;
inline G4PhysicsTable* SecondaryRangeTable() const;
inline G4PhysicsTable* RangeTableForLoss() const;
inline G4PhysicsTable* InverseRangeTable() const;
inline G4PhysicsTable* LambdaTable();
inline G4PhysicsTable* SubLambdaTable();
inline G4PhysicsTable* LambdaTable() const;
inline G4PhysicsTable* SubLambdaTable() const;
//------------------------------------------------------------------------
// Run time method for simulation of ionisation
@@ -467,6 +468,7 @@ private:
// ======== Parameters of the class fixed at construction =========
G4LossTableManager* lManager;
G4EmModelManager* modelManager;
G4EmBiasingManager* biasManager;
G4SafetyHelper* safetyHelper;
@@ -504,6 +506,18 @@ private:
G4PhysicsTable* theLambdaTable;
G4PhysicsTable* theSubLambdaTable;
size_t idxDEDX;
size_t idxDEDXSub;
size_t idxDEDXunRestricted;
size_t idxIonisation;
size_t idxIonisationSub;
size_t idxRange;
size_t idxCSDA;
size_t idxSecRange;
size_t idxInverseRange;
size_t idxLambda;
size_t idxSubLambda;
std::vector<G4double> theDEDXAtMaxEnergy;
std::vector<G4double> theRangeAtMaxEnergy;
std::vector<G4double> theEnergyOfCrossSectionMax;
@@ -542,12 +556,13 @@ private:
G4bool useDeexcitation;
G4bool biasFlag;
G4bool weightFlag;
G4bool isMaster;
protected:
G4ParticleChangeForLoss fParticleChange;
// ======== Cashed values - may be state dependent ================
// ======== Cached values - may be state dependent ================
private:
@@ -561,6 +576,7 @@ private:
const G4MaterialCutsCouple* currentCouple;
size_t currentCoupleIndex;
size_t basedCoupleIndex;
size_t lastIdx;
G4int nWarnings;
@@ -571,12 +587,17 @@ private:
G4double preStepLambda;
G4double fRange;
G4double computedRange;
G4double preStepKinEnergy;
G4double preStepScaledEnergy;
G4double preStepRangeEnergy;
G4double mfpKinEnergy;
G4GPILSelection aGPILSelection;
G4int secID;
G4int subsecID;
G4int biasID;
};
// ======== Run time inline methods ================
@@ -586,13 +607,6 @@ inline size_t G4VEnergyLossProcess::CurrentMaterialCutsCoupleIndex() const
return currentCoupleIndex;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VEnergyLossProcess::GetCurrentRange() const
{
return fRange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VEnergyLossProcess::SelectModel(G4double kinEnergy)
@@ -622,6 +636,7 @@ G4VEnergyLossProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
fFactor = chargeSqRatio*biasFactor*(*theDensityFactor)[currentCoupleIndex];
reduceFactor = 1.0/(fFactor*massRatio);
mfpKinEnergy = DBL_MAX;
idxLambda = idxSubLambda = 0;
}
}
@@ -631,7 +646,7 @@ inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
G4double charge2ratio)
{
massRatio = massratio;
fFactor *= charge2ratio/chargeSqRatio;
fFactor = charge2ratio*biasFactor*(*theDensityFactor)[currentCoupleIndex];
chargeSqRatio = charge2ratio;
reduceFactor = 1.0/(fFactor*massRatio);
}
@@ -640,9 +655,12 @@ inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
{
//G4cout << "G4VEnergyLossProcess::GetDEDX: Idx= "
// << basedCoupleIndex << " E(MeV)= " << e << G4endl;
G4double x = fFactor*(*theDEDXTable)[basedCoupleIndex]->Value(e);
/*
G4cout << "G4VEnergyLossProcess::GetDEDX: Idx= "
<< basedCoupleIndex << " E(MeV)= " << e
<< " Emin= " << minKinEnergy << " Factor= " << fFactor
<< " " << theDEDXTable << G4endl; */
G4double x = fFactor*(*theDEDXTable)[basedCoupleIndex]->Value(e, idxDEDX);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
@@ -651,7 +669,8 @@ inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e)
{
G4double x = fFactor*(*theDEDXSubTable)[basedCoupleIndex]->Value(e);
G4double x =
fFactor*(*theDEDXSubTable)[basedCoupleIndex]->Value(e, idxDEDXSub);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
@@ -660,7 +679,8 @@ inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e)
inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
{
G4double x = fFactor*(*theIonisationTable)[basedCoupleIndex]->Value(e);
G4double x =
fFactor*(*theIonisationTable)[basedCoupleIndex]->Value(e, idxIonisation);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
@@ -670,7 +690,8 @@ inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
inline
G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
{
G4double x = fFactor*(*theIonisationSubTable)[basedCoupleIndex]->Value(e);
G4double x = fFactor*
(*theIonisationSubTable)[basedCoupleIndex]->Value(e, idxIonisationSub);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
}
@@ -679,11 +700,21 @@ G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
{
//G4cout << "G4VEnergyLossProcess::GetRange: Idx= "
// << basedCoupleIndex << " E(MeV)= " << e << G4endl;
G4double x = ((*theRangeTableForLoss)[basedCoupleIndex])->Value(e);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
return x;
//G4cout << "G4VEnergyLossProcess::GetScaledRange: Idx= "
// << basedCoupleIndex << " E(MeV)= " << e
// << " lastIdx= " << lastIdx << " " << theRangeTableForLoss << G4endl;
if(basedCoupleIndex != lastIdx || preStepRangeEnergy != e) {
lastIdx = basedCoupleIndex;
preStepRangeEnergy = e;
computedRange =
((*theRangeTableForLoss)[basedCoupleIndex])->Value(e, idxRange);
if(e < minKinEnergy) { computedRange *= std::sqrt(e/minKinEnergy); }
}
//G4cout << "G4VEnergyLossProcess::GetScaledRange: Idx= "
// << basedCoupleIndex << " E(MeV)= " << e
// << " R= " << fRange << " " << theRangeTableForLoss << G4endl;
return computedRange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -693,7 +724,7 @@ G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(G4double e)
{
G4double x;
if (e < maxKinEnergyCSDA) {
x = ((*theCSDARangeTable)[basedCoupleIndex])->Value(e);
x = ((*theCSDARangeTable)[basedCoupleIndex])->Value(e, idxCSDA);
if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
} else {
x = theRangeAtMaxEnergy[basedCoupleIndex] +
@@ -707,11 +738,12 @@ G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(G4double e)
inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
{
//G4cout << "G4VEnergyLossProcess::GetEnergy: Idx= "
// << basedCoupleIndex << " R(mm)= " << r << G4endl;
// << basedCoupleIndex << " R(mm)= " << r << " "
// << theInverseRangeTable << G4endl;
G4PhysicsVector* v = (*theInverseRangeTable)[basedCoupleIndex];
G4double rmin = v->Energy(0);
G4double e = 0.0;
if(r >= rmin) { e = v->Value(r); }
if(r >= rmin) { e = v->Value(r, idxInverseRange); }
else if(r > 0.0) {
G4double x = r/rmin;
e = minKinEnergy*x*x;
@@ -723,7 +755,7 @@ inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e)
{
return fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e);
return fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e, idxLambda);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -753,14 +785,12 @@ G4VEnergyLossProcess::GetRange(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x = fRange;
if(couple != currentCouple || kineticEnergy != preStepKinEnergy) {
DefineMaterial(couple);
if(theCSDARangeTable) {
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
* reduceFactor;
} else if(theRangeTableForLoss) {
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
}
DefineMaterial(couple);
if(theCSDARangeTable) {
x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
* reduceFactor;
} else if(theRangeTableForLoss) {
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
}
return x;
}
@@ -785,12 +815,11 @@ inline G4double
G4VEnergyLossProcess::GetRangeForLoss(G4double& kineticEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x = fRange;
if(couple != currentCouple || kineticEnergy != preStepKinEnergy) {
DefineMaterial(couple);
x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
}
// G4cout << "Range from " << GetProcessName()
// G4cout << "GetRangeForLoss: Range from " << GetProcessName() << G4endl;
DefineMaterial(couple);
G4double x =
GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
//G4cout << "GetRangeForLoss: Range from " << GetProcessName()
// << " e= " << kineticEnergy << " r= " << x << G4endl;
return x;
}
@@ -968,8 +997,6 @@ void G4VEnergyLossProcess::SetStepFunction(G4double v1, G4double v2)
dRoverRange = v1;
finalRange = v2;
if (dRoverRange > 0.999) { dRoverRange = 1.0; }
currentCouple = 0;
mfpKinEnergy = DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1082,18 +1109,14 @@ inline G4PhysicsTable* G4VEnergyLossProcess::DEDXunRestrictedTable() const
inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const
{
G4PhysicsTable* t = theDEDXTable;
if(theIonisationTable) { t = theIonisationTable; }
return t;
return theIonisationTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTableForSubsec() const
{
G4PhysicsTable* t = theDEDXSubTable;
if(theIonisationSubTable) { t = theIonisationSubTable; }
return t;
return theIonisationSubTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1105,6 +1128,13 @@ inline G4PhysicsTable* G4VEnergyLossProcess::CSDARangeTable() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEnergyLossProcess::SecondaryRangeTable() const
{
return theSecondaryRangeTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEnergyLossProcess::RangeTableForLoss() const
{
return theRangeTableForLoss;
@@ -1119,14 +1149,14 @@ inline G4PhysicsTable* G4VEnergyLossProcess::InverseRangeTable() const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEnergyLossProcess::LambdaTable()
inline G4PhysicsTable* G4VEnergyLossProcess::LambdaTable() const
{
return theLambdaTable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4PhysicsTable* G4VEnergyLossProcess::SubLambdaTable()
inline G4PhysicsTable* G4VEnergyLossProcess::SubLambdaTable() const
{
return theSubLambdaTable;
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VMscModel.hh 71484 2013-06-17 08:12:51Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -81,7 +81,7 @@ public:
virtual G4double ComputeTrueStepLength(G4double geomPathLength);
virtual G4ThreeVector& SampleScattering(const G4DynamicParticle*,
virtual G4ThreeVector& SampleScattering(const G4ThreeVector&,
G4double safety);
// empty method
@@ -288,13 +288,17 @@ inline G4double
G4VMscModel::GetRange(const G4ParticleDefinition* part,
G4double kinEnergy, const G4MaterialCutsCouple* couple)
{
//G4cout << "G4VMscModel::GetRange E(MeV)= " << kinEnergy << " " << ionisation
// << " " << part->GetParticleName()
// << G4endl;
localtkin = kinEnergy;
if(ionisation) {
localrange = ionisation->GetRangeForLoss(kinEnergy, couple);
} else {
G4double q = part->GetPDGCharge()/CLHEP::eplus;
localrange = kinEnergy/(dedx*q*q*couple->GetMaterial()->GetDensity());
localtkin = kinEnergy;
}
//G4cout << "R(mm)= " << localrange << " " << ionisation << G4endl;
return localrange;
}
@@ -305,6 +309,9 @@ G4VMscModel::GetEnergy(const G4ParticleDefinition* part,
G4double range, const G4MaterialCutsCouple* couple)
{
G4double e;
//G4cout << "G4VMscModel::GetEnergy R(mm)= " << range << " " << ionisation
// << " Rlocal(mm)= " << localrange << " Elocal(MeV)= " << localtkin
// << G4endl;
if(ionisation) { e = ionisation->GetKineticEnergy(range, couple); }
else {
e = localtkin;
@@ -316,11 +323,15 @@ G4VMscModel::GetEnergy(const G4ParticleDefinition* part,
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4VEnergyLossProcess* G4VMscModel::GetIonisation() const
{
return ionisation;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4VMscModel::SetIonisation(G4VEnergyLossProcess* p,
const G4ParticleDefinition* part)
{
@@ -328,6 +339,8 @@ inline void G4VMscModel::SetIonisation(G4VEnergyLossProcess* p,
currentPart = part;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetTransportMeanFreePath(const G4ParticleDefinition* part,
G4double ekin)
@@ -335,7 +348,7 @@ G4VMscModel::GetTransportMeanFreePath(const G4ParticleDefinition* part,
G4double x;
if(xSectionTable) {
G4int idx = CurrentCouple()->GetIndex();
x = (*xSectionTable)[(*theDensityIdx)[idx]]->Value(ekin)
x = (*xSectionTable)[(*theDensityIdx)[idx]]->Value(ekin, idxTable)
*(*theDensityFactor)[idx]/(ekin*ekin);
} else {
x = CrossSectionPerVolume(CurrentCouple()->GetMaterial(), part, ekin,
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VMultipleScattering.hh 74657 2013-10-18 08:13:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -117,7 +117,7 @@ public:
// Initialise for build of tables
void PreparePhysicsTable(const G4ParticleDefinition&);
// Build physics table during initialisation
void BuildPhysicsTable(const G4ParticleDefinition&);
@@ -184,17 +184,11 @@ public:
// model will be selected for a given energy interval
void AddEmModel(G4int order, G4VEmModel*, const G4Region* region = 0);
// Assign a model to a process - obsolete method will be removed
void SetModel(G4VMscModel*, G4int index = 1);
// return the assigned model - obsolete method will be removed
G4VMscModel* Model(G4int index = 1);
// Assign a model to a process
void SetEmModel(G4VMscModel*, G4int index = 1);
// return the assigned model
G4VMscModel* EmModel(G4int index = 1);
G4VMscModel* EmModel(G4int index = 1) const;
// Access to models by index
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
@@ -223,6 +217,9 @@ public:
inline G4MscStepLimitType StepLimitType() const;
inline void SetStepLimitType(G4MscStepLimitType val);
inline G4double LowestKinEnergy() const;
inline void SetLowestKinEnergy(G4double val);
inline const G4ParticleDefinition* FirstParticle() const;
//------------------------------------------------------------------------
@@ -399,6 +396,20 @@ inline void G4VMultipleScattering::SetStepLimitType(G4MscStepLimitType val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4VMultipleScattering::LowestKinEnergy() const
{
return lowestKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4VMultipleScattering::SetLowestKinEnergy(G4double val)
{
lowestKinEnergy = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4ParticleDefinition* G4VMultipleScattering::FirstParticle() const
{
return firstParticle;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4ionEffectiveCharge.hh 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -57,7 +57,7 @@
#include "G4ParticleDefinition.hh"
class G4Material;
class G4NistManager;
class G4Pow;
class G4ionEffectiveCharge
{
@@ -83,7 +83,7 @@ private:
G4ionEffectiveCharge & operator=(const G4ionEffectiveCharge &right);
G4ionEffectiveCharge(const G4ionEffectiveCharge&);
G4NistManager* nist;
G4Pow* g4pow;
const G4ParticleDefinition* lastPart;
const G4Material* lastMat;
@@ -11,7 +11,7 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake,v 1.4 2010-10-26 09:45:09 gcosmo Exp $
# $Id: sources.cmake 74376 2013-10-04 08:25:47Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -43,6 +43,7 @@ include_directories(${CMAKE_SOURCE_DIR}/source/track/include)
include(Geant4MacroDefineModule)
GEANT4_DEFINE_MODULE(NAME G4emutils
HEADERS
G4AngleDirect.hh
G4AtomicShell.hh
G4AtomicShellEnumerator.hh
G4DummyModel.hh
@@ -52,6 +53,8 @@ GEANT4_DEFINE_MODULE(NAME G4emutils
G4EmConfigurator.hh
G4EmCorrections.hh
G4EmElementSelector.hh
G4EmManager.hh
G4EmManagerMessenger.hh
G4EmModelManager.hh
G4EmMultiModel.hh
G4EmProcessOptions.hh
@@ -64,17 +67,16 @@ GEANT4_DEFINE_MODULE(NAME G4emutils
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
G4AngleDirect.cc
G4AtomicShell.cc
G4DummyModel.cc
G4ElectronIonPair.cc
@@ -82,7 +84,9 @@ GEANT4_DEFINE_MODULE(NAME G4emutils
G4EmCalculator.cc
G4EmConfigurator.cc
G4EmCorrections.cc
G4EmElementSelector.cc
G4EmElementSelector.cc
G4EmManager.cc
G4EmManagerMessenger.cc
G4EmModelManager.cc
G4EmMultiModel.cc
G4EmProcessOptions.cc
@@ -92,12 +96,10 @@ GEANT4_DEFINE_MODULE(NAME G4emutils
G4LossTableBuilder.cc
G4LossTableManager.cc
G4VAtomDeexcitation.cc
G4VBremAngularDistribution.cc
G4VEmAngularDistribution.cc
G4VEmFluctuationModel.cc
G4VEmModel.cc
G4VEmProcess.cc
G4VEnergyLoss.cc
G4VEnergyLossProcess.cc
G4VMscModel.cc
G4VMultipleScattering.cc
@@ -23,61 +23,38 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4AngleDirect.cc 73844 2013-09-13 14:16:30Z vnivanch $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// File name: G4AngleDirect
//
// 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)
//
// Author: V. Ivanchenko
//
// Creation date: 21 March 2003
// Creation date: 03 October 2013
//
// 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 "G4AngleDirect.hh"
#include "globals.hh"
#include "G4VEmAngularDistribution.hh"
G4AngleDirect::G4AngleDirect() : G4VEmAngularDistribution("AngleDirect")
{}
class G4VBremAngularDistribution : public G4VEmAngularDistribution
G4AngleDirect::~G4AngleDirect()
{}
G4ThreeVector& G4AngleDirect::SampleDirection(const G4DynamicParticle* dp,
G4double, G4int,
const G4Material*)
{
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
fLocalDirection = dp->GetMomentumDirection();
return fLocalDirection;
}
//
@@ -25,7 +25,6 @@
//
//
// $Id: G4AtomicShell.cc,v 1.2 ????
// GEANT4 tag $Name: not supported by cvs2svn $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4DummyModel.cc 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4ElectronIonPair.cc 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmBiasingManager.cc 76765 2013-11-15 09:38:15Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -198,8 +198,8 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
}
const G4Region* reg = regionStore->GetRegion(name, false);
if(!reg) {
G4cout << "### G4EmBiasingManager::ActivateBremsstrahlungSplitting WARNING: "
<< " G4Region <"
G4cout << "### G4EmBiasingManager::ActivateBremsstrahlungSplitting "
<< "WARNING: G4Region <"
<< rname << "> is unknown" << G4endl;
return;
}
@@ -344,7 +344,7 @@ G4EmBiasingManager::ApplySecondaryBiasing(
if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
// Russian Roulette
} if(1 == nsplit) {
} else if(1 == nsplit) {
weight = ApplyRussianRoulette(vd, index);
// Splitting
@@ -405,14 +405,16 @@ G4EmBiasingManager::ApplyRangeCut(std::vector<G4DynamicParticle*>& vd,
{
size_t n = vd.size();
if(!eIonisation) {
eIonisation = G4LossTableManager::Instance()->GetEnergyLossProcess(theElectron);
eIonisation =
G4LossTableManager::Instance()->GetEnergyLossProcess(theElectron);
}
if(eIonisation) {
for(size_t k=0; k<n; ++k) {
const G4DynamicParticle* dp = vd[k];
if(dp->GetDefinition() == theElectron) {
G4double e = dp->GetKineticEnergy();
if(eIonisation->GetRangeForLoss(e, track.GetMaterialCutsCouple()) < safety) {
if(eIonisation->GetRangeForLoss(e, track.GetMaterialCutsCouple())
< safety) {
eloss += e;
delete dp;
vd[k] = 0;
@@ -455,7 +457,8 @@ G4EmBiasingManager::ApplySplitting(std::vector<G4DynamicParticle*>& vd,
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
for(G4int k=1; k<nsplit; ++k) {
tmpSecondaries.clear();
currentModel->SampleSecondaries(&tmpSecondaries, couple, dynParticle, tcut);
currentModel->SampleSecondaries(&tmpSecondaries, couple, dynParticle,
tcut);
for (size_t kk=0; kk<tmpSecondaries.size(); ++kk) {
vd.push_back(tmpSecondaries[kk]);
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmCalculator.cc 70371 2013-05-29 15:18:07Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -72,6 +72,7 @@
#include "G4MaterialCutsCouple.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4PhysicsTable.hh"
#include "G4ProductionCutsTable.hh"
#include "G4ProcessManager.hh"
@@ -111,6 +112,7 @@ G4EmCalculator::G4EmCalculator()
lambdaName = "";
theGenericIon = G4GenericIon::GenericIon();
ionEffCharge = new G4ionEffectiveCharge();
ionTable = G4ParticleTable::GetParticleTable()->GetIonTable();
isIon = false;
isApplicable = false;
}
@@ -702,9 +704,11 @@ G4double G4EmCalculator::ComputeCrossSectionPerAtom(
G4double e = kinEnergy;
if(baseParticle) {
e *= kinEnergy*massRatio;
currentModel->InitialiseForElement(baseParticle, G4lrint(Z));
res = currentModel->ComputeCrossSectionPerAtom(
baseParticle, e, Z, A, cut) * chargeSquare;
} else {
currentModel->InitialiseForElement(p, G4lrint(Z));
res = currentModel->ComputeCrossSectionPerAtom(p, e, Z, A, cut);
}
if(verbose>0) {
@@ -906,8 +910,7 @@ const G4ParticleDefinition* G4EmCalculator::FindParticle(const G4String& name)
const G4ParticleDefinition* G4EmCalculator::FindIon(G4int Z, G4int A)
{
const G4ParticleDefinition* p =
G4ParticleTable::GetParticleTable()->FindIon(Z,A,0,Z);
const G4ParticleDefinition* p = ionTable->GetIon(Z,A,0);
return p;
}
@@ -1115,6 +1118,10 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
if(currentModel) {
if(loweModel == currentModel) { loweModel = 0; }
isApplicable = true;
currentModel->InitialiseForMaterial(part, currentMaterial);
if(loweModel) {
loweModel->InitialiseForMaterial(part, currentMaterial);
}
if(verbose > 1) {
G4cout << " Model <" << currentModel->GetName()
<< "> Emin(MeV)= " << currentModel->LowEnergyLimit()/MeV
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmConfigurator.cc 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmCorrections.cc 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -102,10 +102,10 @@ G4EmCorrections::G4EmCorrections()
G4EmCorrections::~G4EmCorrections()
{
for(G4int i=0; i<nIons; ++i) {delete stopData[i];}
delete BarkasCorr;
delete ThetaK;
delete ThetaL;
// for(G4int i=0; i<nIons; ++i) {delete stopData[i];}
// delete BarkasCorr;
// delete ThetaK;
// delete ThetaL;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -822,7 +822,7 @@ void G4EmCorrections::BuildCorrectionVector()
const G4ParticleDefinition* ion = curParticle;
G4int Z = Zion[idx];
if(currentZ != Z) {
ion = G4ParticleTable::GetParticleTable()->FindIon(Z, Aion[idx], 0, Z);
ion = ionTable->GetIon(Z, Aion[idx], 0);
}
//G4cout << "BuildCorrectionVector: idx= " << idx << " Z= " << Z
// << " curZ= " << currentZ << G4endl;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmElementSelector.cc 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -47,6 +47,7 @@
#include "G4EmElementSelector.hh"
#include "G4VEmModel.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -56,44 +57,43 @@ G4EmElementSelector::G4EmElementSelector(G4VEmModel* mod,
G4int bins,
G4double emin,
G4double emax,
G4bool spline):
G4bool):
model(mod), material(mat), nbins(bins), cutEnergy(-1.0),
lowEnergy(emin), highEnergy(emax)
{
G4int n = material->GetNumberOfElements();
nElmMinusOne = n - 1;
theElementVector = material->GetElementVector();
element = (*theElementVector)[0];
// element = (*theElementVector)[0];
if(nElmMinusOne > 0) {
xSections.reserve(n);
G4PhysicsLogVector* v0 = new G4PhysicsLogVector(lowEnergy,highEnergy,nbins);
xSections.push_back(v0);
v0->SetSpline(spline);
v0->SetSpline(false);
for(G4int i=1; i<n; ++i) {
G4PhysicsLogVector* v = new G4PhysicsLogVector(*v0);
xSections.push_back(v);
}
}
//G4cout << "G4EmElementSelector for " << mat->GetName() << " n= " << n << G4endl;
/*
G4cout << "G4EmElementSelector for " << mat->GetName() << " n= " << n
<< " nbins= " << nbins << " Emin= " << lowEnergy
<< " Emax= " << highEnergy << G4endl;
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmElementSelector::~G4EmElementSelector()
{
if(nElmMinusOne > 0) {
for(G4int i=0; i<=nElmMinusOne; ++i) {
delete xSections[i];
}
}
}
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmElementSelector::Initialise(const G4ParticleDefinition* part,
G4double cut)
{
//G4cout << "G4EmElementSelector initialise for " << material->GetName() << G4endl;
//G4cout << "G4EmElementSelector initialise for " << material->GetName()
// << G4endl;
if(0 == nElmMinusOne || cut == cutEnergy) { return; }
cutEnergy = cut;
@@ -139,7 +139,8 @@ void G4EmElementSelector::Initialise(const G4ParticleDefinition* part,
}
}
}
//G4cout << "======== G4EmElementSelector for the " << model->GetName();
//G4cout << "======== G4EmElementSelector for the " << model->GetName()
// << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,958 @@
//
// ********************************************************************
// * 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: G4EmManager.cc 69320 2013-04-30 15:59:36Z vnivanch $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4EmManager
//
// Author: Vladimir Ivanchenko
//
// Creation date: 18.05.2013
//
// Modifications:
//
//
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4EmManagerMessenger.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4ParticleDefinition.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ProcessManager.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4VMultipleScattering.hh"
#include "G4VEmProcess.hh"
#include "G4EmSaturation.hh"
#include "G4EmConfigurator.hh"
#include "G4ElectronIonPair.hh"
#include "G4LossTableBuilder.hh"
#include "G4Region.hh"
#include "G4NistManager.hh"
G4EmManager* G4EmManager::theInstance = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4EmManager* G4EmManager::Instance()
{
if(0 == theInstance) {
static G4EmManager manager;
theInstance = &manager;
}
return theInstance;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4EmManager::~G4EmManager()
{
G4cout << "G4EmManager::~G4EmManager()" << G4endl;
G4int nmax = dedx_vector.size();
for (G4int i=0; i<nmax; ++i) {
if( dedx_vector[i] ) {
dedx_vector[i]->clearAndDestroy();
delete dedx_vector[i];
}
}
nmax = range_vector.size();
for (G4int i=0; i<nmax; ++i) {
if( range_vector[i] ) {
range_vector[i]->clearAndDestroy();
delete range_vector[i];
}
}
nmax = inv_range_vector.size();
for (G4int i=0; i<nmax; ++i) {
if( inv_range_vector[i] ) {
inv_range_vector[i]->clearAndDestroy();
delete inv_range_vector[i];
}
}
nmax = xsection_vector.size();
for (G4int i=0; i<nmax; ++i) {
if( xsection_vector[i] ) {
xsection_vector[i]->clearAndDestroy();
delete xsection_vector[i];
}
}
G4cout << "G4EmManager::~G4EmManager() 1" << G4endl;
delete theMessenger;
delete tableBuilder;
delete emSaturation;
delete emConfigurator;
delete emElectronIonPair;
G4cout << "G4EmManager::~G4EmManager() 2" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4EmManager::G4EmManager()
{
G4NistManager::Instance();
n_loss = 0;
run = 0;
startInitialisation = false;
all_tables_are_built = false;
firstParticle = 0;
lossFluctuationFlag = true;
subCutoffFlag = false;
rndmStepFlag = false;
minSubRange = 0.0;
maxRangeVariation = 1.0;
maxFinalStep = 0.0;
minKinEnergy = 0.1*keV;
maxKinEnergy = 10.0*TeV;
nbinsLambda = 77;
nbinsPerDecade = 7;
maxKinEnergyForMuons = 10.*TeV;
integral = true;
integralActive = false;
buildCSDARange = false;
minEnergyActive = false;
maxEnergyActive = false;
maxEnergyForMuonsActive = false;
stepFunctionActive = false;
flagLPM = true;
splineFlag = true;
bremsTh = DBL_MAX;
factorForAngleLimit = 1.0;
verbose = 1;
theMessenger = 0;
tableBuilder = 0;
emSaturation = 0;
emConfigurator = 0;
emElectronIonPair = 0;
//theMessenger = new G4EmManagerMessenger(this);
theElectron = G4Electron::Electron();
//tableBuilder = new G4LossTableBuilder();
//emSaturation = new G4EmSaturation();
//emConfigurator = new G4EmConfigurator(verbose);
//emElectronIonPair = new G4ElectronIonPair();
//tableBuilder->SetSplineFlag(splineFlag);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::Register(G4VEnergyLossProcess* p)
{
if(!p) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4EmManager::Register G4VEnergyLossProcess : "
<< p->GetProcessName() << " idx= " << n_loss << G4endl;
}
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(0);
base_part_vector.push_back(0);
dedx_vector.push_back(0);
range_vector.push_back(0);
inv_range_vector.push_back(0);
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); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::Register(G4VMultipleScattering* p)
{
if(!p) { return; }
G4int n = msc_vector.size();
for (G4int i=0; i<n; ++i) {
if(msc_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4EmManager::Register G4VMultipleScattering : "
<< p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
}
msc_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::Register(G4VEmProcess* p)
{
if(!p) { return; }
G4int n = emp_vector.size();
for (G4int i=0; i<n; ++i) {
if(emp_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4EmManager::Register G4VEmProcess : "
<< p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
}
emp_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::RegisterExtraParticle(
const G4ParticleDefinition* part,
G4VEnergyLossProcess* p)
{
if(!p || !part) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4EmManager::RegisterExtraParticle "
<< part->GetParticleName() << " G4VEnergyLossProcess : "
<< p->GetProcessName() << " idx= " << n_loss << G4endl;
}
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(part);
base_part_vector.push_back(p->BaseParticle());
dedx_vector.push_back(0);
range_vector.push_back(0);
inv_range_vector.push_back(0);
tables_are_built.push_back(false);
all_tables_are_built = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4EmManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEnergyLossProcess* p)
{
if (1 < verbose) {
G4cout << "G4EmManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << " run= " << run
<< " loss_vector " << loss_vector.size() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
// start initialisation for the first run
startInitialisation = true;
if( 0 == run ) {
emConfigurator->PrepareModels(particle, p);
// 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; }
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4EmManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEmProcess* p)
{
if (1 < verbose) {
G4cout << "G4EmManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
// start initialisation for the first run
if( 0 == run ) {
emConfigurator->PrepareModels(particle, p);
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4EmManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VMultipleScattering* p)
{
if (1 < verbose) {
G4cout << "G4EmManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
// start initialisation for the first run
if( 0 == run ) {
emConfigurator->PrepareModels(particle, p);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4EmManager::BuildPhysicsTable(const G4ParticleDefinition*)
{
if(0 == run && startInitialisation) {
emConfigurator->Clear();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4EmManager::BuildPhysicsTable(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(1 < verbose) {
G4cout << "### G4EmManager::BuildDEDXTable() is requested for "
<< aParticle->GetParticleName()
<< " and process " << p->GetProcessName() << G4endl;
}
// clear configurator
if(0 == run && startInitialisation) {
emConfigurator->Clear();
firstParticle = aParticle;
}
startInitialisation = false;
// initialisation before any table is built
if ( aParticle == firstParticle ) {
all_tables_are_built = true;
if(1 < verbose) {
G4cout << "### G4EmManager 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] = false;
if(pm) { 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();
if(el->Particle()) {
G4cout << " for " << el->Particle()->GetParticleName();
}
G4cout << " active= " << isActive[i]
<< " 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;
}
// 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 << "### G4EmManager::BuildDEDXTable end: "
<< "all_tables_are_built= " << all_tables_are_built
<< G4endl;
if(all_tables_are_built) {
G4cout << "### All dEdx and Range tables are built #####" << G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::CopyTables(const G4ParticleDefinition* part,
G4VEnergyLossProcess* base_proc)
{
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 (!tables_are_built[j] && part == base_part_vector[j]) {
tables_are_built[j] = true;
proc->SetDEDXTable(base_proc->DEDXTable(),fRestricted);
proc->SetDEDXTable(base_proc->DEDXTableForSubsec(),fSubRestricted);
proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
proc->SetCSDARangeTable(base_proc->CSDARangeTable());
proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
proc->SetInverseRangeTable(base_proc->InverseRangeTable());
proc->SetLambdaTable(base_proc->LambdaTable());
proc->SetSubLambdaTable(base_proc->SubLambdaTable());
proc->SetIonisation(base_proc->IsIonisationProcess());
loss_map[part_vector[j]] = proc;
if (1 < verbose) {
G4cout << "For " << proc->GetProcessName()
<< " for " << part_vector[j]->GetParticleName()
<< " base_part= " << part->GetParticleName()
<< " tables are assigned "
<< G4endl;
}
}
if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4VEnergyLossProcess*
G4EmManager::BuildTables(const G4ParticleDefinition* aParticle)
{
if(1 < verbose) {
G4cout << "G4EmManager::BuildTables() for "
<< aParticle->GetParticleName() << G4endl;
}
std::vector<G4PhysicsTable*> t_list;
std::vector<G4VEnergyLossProcess*> loss_list;
loss_list.clear();
G4VEnergyLossProcess* em = 0;
G4VEnergyLossProcess* p = 0;
G4int iem = 0;
G4PhysicsTable* dedx = 0;
G4int 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]) ||
!em || (em && !isActive[iem]) ) {
em = p;
iem= i;
}
dedx = p->BuildDEDXTable(fRestricted);
// G4cout << "Build DEDX table for " << aParticle->GetParticleName()
// << " " << dedx << " " << dedx->length() << G4endl;
p->SetDEDXTable(dedx,fRestricted);
t_list.push_back(dedx);
loss_list.push_back(p);
tables_are_built[i] = true;
}
}
G4int n_dedx = t_list.size();
if (0 == n_dedx || !em) {
G4cout << "G4EmManager WARNING: no DEDX processes for "
<< aParticle->GetParticleName() << G4endl;
return 0;
}
G4int nSubRegions = em->NumberOfSubCutoffRegions();
if (1 < verbose) {
G4cout << "G4EmManager::BuildTables() start to build range tables"
<< " and the sum of " << n_dedx << " processes"
<< " iem= " << iem << " em= " << em->GetProcessName()
<< " buildCSDARange= " << buildCSDARange
<< " nSubRegions= " << nSubRegions
<< G4endl;
}
dedx = em->IonisationTable();
if (1 < n_dedx) {
em->SetDEDXTable(dedx, fIsIonisation);
dedx = 0;
dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
tableBuilder->BuildDEDXTable(dedx, t_list);
em->SetDEDXTable(dedx, fRestricted);
}
dedx_vector[iem] = dedx;
G4PhysicsTable* range = em->RangeTableForLoss();
if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
range_vector[iem] = range;
G4PhysicsTable* invrange = em->InverseRangeTable();
if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
inv_range_vector[iem] = invrange;
G4bool flag = em->IsIonisationProcess();
tableBuilder->BuildRangeTable(dedx, range, flag);
tableBuilder->BuildInverseRangeTable(range, invrange, flag);
// if(1<verbose) G4cout << *dedx << G4endl;
em->SetRangeTableForLoss(range);
em->SetInverseRangeTable(invrange);
// if(1<verbose) G4cout << *range << G4endl;
std::vector<G4PhysicsTable*> listSub;
std::vector<G4PhysicsTable*> listCSDA;
for (i=0; i<n_dedx; ++i) {
p = loss_list[i];
p->SetIonisation(false);
p->SetLambdaTable(p->BuildLambdaTable(fRestricted));
if (0 < nSubRegions) {
dedx = p->BuildDEDXTable(fSubRestricted);
p->SetDEDXTable(dedx,fSubRestricted);
listSub.push_back(dedx);
p->SetSubLambdaTable(p->BuildLambdaTable(fSubRestricted));
if(p != em) em->AddCollaborativeProcess(p);
}
if(buildCSDARange) {
dedx = p->BuildDEDXTable(fTotal);
p->SetDEDXTable(dedx,fTotal);
listCSDA.push_back(dedx);
}
}
if (0 < nSubRegions) {
G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
if (1 < listSub.size()) {
em->SetDEDXTable(dedxSub, fIsSubIonisation);
dedxSub = 0;
dedxSub = G4PhysicsTableHelper::PreparePhysicsTable(dedxSub);
tableBuilder->BuildDEDXTable(dedxSub, listSub);
em->SetDEDXTable(dedxSub, fSubRestricted);
}
}
if(buildCSDARange) {
G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
if (1 < n_dedx) {
dedxCSDA = 0;
dedxCSDA = G4PhysicsTableHelper::PreparePhysicsTable(dedxCSDA);
tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
em->SetDEDXTable(dedxCSDA,fTotal);
}
G4PhysicsTable* rCSDA = em->CSDARangeTable();
if(!rCSDA) rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA);
tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, flag);
em->SetCSDARangeTable(rCSDA);
}
em->SetIonisation(true);
loss_map[aParticle] = em;
if (1 < verbose) {
G4cout << "G4EmManager::BuildTables: Tables are built for "
<< aParticle->GetParticleName()
<< "; ionisation process: " << em->GetProcessName()
<< G4endl;
}
return em;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4bool G4EmManager::BuildCSDARange() const
{
return buildCSDARange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetLossFluctuations(G4bool val)
{
lossFluctuationFlag = val;
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetLossFluctuations(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::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, r); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetIntegral(G4bool val)
{
integral = val;
integralActive = true;
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); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetMinSubRange(G4double val)
{
minSubRange = val;
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetMinSubRange(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetRandomStep(G4bool val)
{
rndmStepFlag = val;
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetRandomStep(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetMinEnergy(G4double val)
{
minEnergyActive = true;
minKinEnergy = val;
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->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); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetMaxEnergy(G4double val)
{
maxEnergyActive = true;
maxKinEnergy = val;
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->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); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetMaxEnergyForCSDARange(G4double val)
{
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergyForCSDARange(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetMaxEnergyForMuons(G4double val)
{
maxEnergyForMuonsActive = true;
maxKinEnergyForMuons = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetDEDXBinning(G4int val)
{
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetDEDXBinning(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetDEDXBinningForCSDARange(G4int val)
{
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetDEDXBinningForCSDARange(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetLambdaBinning(G4int val)
{
G4int n = val/G4int(std::log10(maxKinEnergy/minKinEnergy) + 0.5);
if(n < 5) {
G4cout << "G4EmManager::SetLambdaBinning WARNING "
<< "too small number of bins " << val << " ignored"
<< G4endl;
return;
}
nbinsLambda = val;
nbinsPerDecade = n;
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetLambdaBinning(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4int G4EmManager::GetNumberOfBinsPerDecade() const
{
return nbinsPerDecade;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetVerbose(G4int val)
{
verbose = 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); }
}
size_t emp = emp_vector.size();
for (size_t k=0; k<emp; ++k) {
if(emp_vector[k]) { emp_vector[k]->SetVerboseLevel(val); }
}
*/
G4cout << "1 " << emConfigurator << G4endl;
emConfigurator->SetVerbose(val);
G4cout << "2 " << emSaturation << G4endl;
//tableBuilder->SetVerbose(val);
emSaturation->SetVerbose(val);
G4cout << "3 " << emElectronIonPair << G4endl;
emElectronIonPair->SetVerbose(val);
G4cout << "4 " << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::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); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetLinearLossLimit(G4double val)
{
for(G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) { loss_vector[i]->SetLinearLossLimit(val); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetBuildCSDARange(G4bool val)
{
buildCSDARange = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::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); }
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.....
void G4EmManager::InitialiseProcess(const G4ParticleDefinition* /*aParticle*/,
G4VEnergyLossProcess* /*p*/)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::InitialiseProcess(const G4ParticleDefinition* /*aParticle*/,
G4VEmProcess* /*p*/)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::InitialiseProcess(const G4ParticleDefinition* /*aParticle*/,
G4VMultipleScattering*)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetLPMFlag(G4bool val)
{
flagLPM = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4bool G4EmManager::LPMFlag() const
{
return flagLPM;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4EmManager::SetSplineFlag(G4bool val)
{
splineFlag = val;
tableBuilder->SetSplineFlag(splineFlag);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4bool G4EmManager::SplineFlag() const
{
return splineFlag;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmManager::SetBremsstrahlungTh(G4double val)
{
bremsTh = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmManager::BremsstrahlungTh() const
{
return bremsTh;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmManager::SetFactorForAngleLimit(G4double val)
{
if(val > 0.0) { factorForAngleLimit = val; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmManager::FactorForAngleLimit() const
{
return factorForAngleLimit;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4EmManager::MinKinEnergy() const
{
return minKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4EmManager::MaxKinEnergy() const
{
return maxKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmSaturation* G4EmManager::EmSaturation()
{
return emSaturation;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmConfigurator* G4EmManager::EmConfigurator()
{
return emConfigurator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ElectronIonPair* G4EmManager::ElectronIonPair()
{
return emElectronIonPair;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4LossTableBuilder* G4EmManager::GetTableBuilder()
{
return tableBuilder;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,553 @@
//
// ********************************************************************
// * 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: G4EmManagerMessenger.cc 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// File name: G4EmManagerMessenger
//
// Author: Vladimir Ivanchenko created from G4EnergyLossMessenger
//
// Creation date: 22-05-2013
//
// Modifications:
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmManagerMessenger.hh"
#include "G4UIdirectory.hh"
#include "G4UIcommand.hh"
#include "G4UIparameter.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UImanager.hh"
#include "G4MscStepLimitType.hh"
#include "G4EmManager.hh"
#include <sstream>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmManagerMessenger::G4EmManagerMessenger(G4EmManager* p) : theManager(p)
{
eLossDirectory = new G4UIdirectory("/process/eLoss/");
eLossDirectory->SetGuidance("Commands for EM processes.");
mscDirectory = new G4UIdirectory("/process/msc/");
mscDirectory->SetGuidance("Commands for EM scattering processes.");
emDirectory = new G4UIdirectory("/process/em/");
emDirectory->SetGuidance("General commands for EM processes.");
EnlossFlucCmd = new G4UIcmdWithABool("/process/eLoss/fluct",this);
EnlossFlucCmd->SetGuidance("Enable/disable energy loss fluctuations.");
EnlossFlucCmd->SetParameterName("choice",true);
EnlossFlucCmd->SetDefaultValue(true);
EnlossFlucCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/useCutAsFinalRange",this);
RndmStepCmd->SetGuidance("Use cut in range as a final range");
RndmStepCmd->SetParameterName("choice",true);
RndmStepCmd->SetDefaultValue(false);
RndmStepCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
SubSecCmd = new G4UIcmdWithABool("/process/eLoss/subsec",this);
SubSecCmd->SetGuidance("Switch true/false the subcutoff generation.");
SubSecCmd->SetParameterName("choice",true);
SubSecCmd->SetDefaultValue(true);
SubSecCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
MinSubSecCmd = new G4UIcmdWithADouble("/process/eLoss/minsubsec",this);
MinSubSecCmd->SetGuidance("Set the ratio subcut/cut ");
MinSubSecCmd->SetParameterName("rcmin",true);
MinSubSecCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
StepFuncCmd = new G4UIcommand("/process/eLoss/StepFunction",this);
StepFuncCmd->SetGuidance("Set the energy loss step limitation parameters.");
StepFuncCmd->SetGuidance(" dRoverR : max Range variation per step");
StepFuncCmd->SetGuidance(" finalRange: range for final step");
G4UIparameter* dRoverRPrm = new G4UIparameter("dRoverR",'d',false);
dRoverRPrm->SetGuidance("max Range variation per step (fractional number)");
dRoverRPrm->SetParameterRange("dRoverR>0. && dRoverR<=1.");
StepFuncCmd->SetParameter(dRoverRPrm);
G4UIparameter* finalRangePrm = new G4UIparameter("finalRange",'d',false);
finalRangePrm->SetGuidance("range for final step");
finalRangePrm->SetParameterRange("finalRange>0.");
StepFuncCmd->SetParameter(finalRangePrm);
G4UIparameter* unitPrm = new G4UIparameter("unit",'s',true);
unitPrm->SetGuidance("unit of finalRange");
unitPrm->SetDefaultValue("mm");
G4String unitCandidates =
G4UIcommand::UnitsList(G4UIcommand::CategoryOf("mm"));
unitPrm->SetParameterCandidates(unitCandidates);
StepFuncCmd->SetParameter(unitPrm);
StepFuncCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
MinEnCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/minKinEnergy",this);
MinEnCmd->SetGuidance("Set the min kinetic energy");
MinEnCmd->SetParameterName("emin",true);
MinEnCmd->SetUnitCategory("Energy");
MinEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
MaxEnCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/maxKinEnergy",this);
MaxEnCmd->SetGuidance("Set the max kinetic energy");
MaxEnCmd->SetParameterName("emax",true);
MaxEnCmd->SetUnitCategory("Energy");
MaxEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this);
IntegCmd->SetGuidance("Switch true/false the integral option");
IntegCmd->SetParameterName("integ",true);
IntegCmd->SetDefaultValue(true);
IntegCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
rangeCmd = new G4UIcmdWithABool("/process/eLoss/CSDARange",this);
rangeCmd->SetGuidance("Switch true/false the CSDA range calculation");
rangeCmd->SetParameterName("range",true);
rangeCmd->SetDefaultValue(true);
rangeCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
lpmCmd = new G4UIcmdWithABool("/process/eLoss/LPM",this);
lpmCmd->SetGuidance("The flag of the LPM effect calculation");
lpmCmd->SetParameterName("lpm",true);
lpmCmd->SetDefaultValue(true);
lpmCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
splCmd = new G4UIcmdWithABool("/process/em/spline",this);
splCmd->SetGuidance("The flag of usage spline for Physics Vectors");
splCmd->SetParameterName("spl",true);
splCmd->SetDefaultValue(false);
splCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
/*
aplCmd = new G4UIcmdWithABool("/process/em/applyCuts",this);
aplCmd->SetGuidance("The flag to Apply Cuts for gamma processes");
aplCmd->SetParameterName("apl",true);
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);
pixeeXsCmd = new G4UIcmdWithAString("/process/em/pixeElecXSmodel",this);
pixeeXsCmd->SetGuidance("The name of PIXE cross section for electron");
pixeeXsCmd->SetParameterName("pixeEXS",true);
pixeeXsCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
deexCmd = new G4UIcommand("/process/em/deexcitation",this);
deexCmd->SetGuidance("Set deexcitation flags per G4Region.");
deexCmd->SetGuidance(" regName : G4Region name");
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",'s',false);
deexCmd->SetParameter(flagFluo);
G4UIparameter* flagAuger = new G4UIparameter("flagAuger",'s',false);
deexCmd->SetParameter(flagAuger);
G4UIparameter* flagPIXE = new G4UIparameter("flagPIXE",'s',false);
deexCmd->SetParameter(flagPIXE);
*/
dedxCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsDEDX",this);
dedxCmd->SetGuidance("Set number of bins for DEDX tables");
dedxCmd->SetParameterName("binsDEDX",true);
dedxCmd->SetDefaultValue(77);
dedxCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
lamCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsLambda",this);
lamCmd->SetGuidance("Set number of bins for Lambda tables");
lamCmd->SetParameterName("binsL",true);
lamCmd->SetDefaultValue(77);
lamCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
/*
verCmd = new G4UIcmdWithAnInteger("/process/eLoss/verbose",this);
verCmd->SetGuidance("Set verbose level for EM physics");
verCmd->SetParameterName("verb",true);
verCmd->SetDefaultValue(1);
verCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
ver1Cmd = new G4UIcmdWithAnInteger("/process/em/verbose",this);
ver1Cmd->SetGuidance("Set verbose level for EM physics");
ver1Cmd->SetParameterName("verb1",true);
ver1Cmd->SetDefaultValue(1);
ver1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
*/
lllCmd = new G4UIcmdWithADouble("/process/eLoss/linLossLimit",this);
lllCmd->SetGuidance("Set linearLossLimit parameter");
lllCmd->SetParameterName("linlim",true);
lllCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
/*
labCmd = new G4UIcmdWithADouble("/process/eLoss/LambdaFactor",this);
labCmd->SetGuidance("Set lambdaFactor parameter for integral option");
labCmd->SetParameterName("Fl",true);
labCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
mscCmd = new G4UIcmdWithAString("/process/msc/StepLimit",this);
mscCmd->SetGuidance("Set msc step limitation type");
mscCmd->SetParameterName("StepLim",true);
mscCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
latCmd = new G4UIcmdWithABool("/process/msc/LateralDisplacement",this);
latCmd->SetGuidance("Set flag of sampling of lateral displacement");
latCmd->SetParameterName("lat",true);
latCmd->SetDefaultValue(true);
latCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
frCmd = new G4UIcmdWithADouble("/process/msc/RangeFactor",this);
frCmd->SetGuidance("Set RangeFactor parameter for msc processes");
frCmd->SetParameterName("Fr",true);
frCmd->SetRange("Fr>0");
frCmd->SetDefaultValue(0.04);
frCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
fgCmd = new G4UIcmdWithADouble("/process/msc/GeomFactor",this);
fgCmd->SetGuidance("Set GeomFactor parameter for msc processes");
fgCmd->SetParameterName("Fg",true);
fgCmd->SetRange("Fg>0");
fgCmd->SetDefaultValue(3.5);
fgCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
mscfCmd = new G4UIcmdWithADouble("/process/msc/FactorForAngleLimit",this);
mscfCmd->SetGuidance("Set factor for computation of a limit for -t (invariant trasfer)");
mscfCmd->SetParameterName("Fact",true);
mscfCmd->SetRange("Fact>0");
mscfCmd->SetDefaultValue(1.);
mscfCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
skinCmd = new G4UIcmdWithADouble("/process/msc/Skin",this);
skinCmd->SetGuidance("Set skin parameter for msc processes");
skinCmd->SetParameterName("skin",true);
skinCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
angCmd = new G4UIcmdWithADoubleAndUnit("/process/msc/ThetaLimit",this);
angCmd->SetGuidance("Set the limit on the polar angle for msc and single scattering");
angCmd->SetParameterName("theta",true);
angCmd->SetUnitCategory("Angle");
angCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
bfCmd = new G4UIcommand("/process/em/setBiasingFactor",this);
bfCmd->SetGuidance("Set factor for the process cross section.");
bfCmd->SetGuidance(" procName : process name");
bfCmd->SetGuidance(" procFact : factor");
bfCmd->SetGuidance(" flagFact : flag to change weight");
G4UIparameter* procName = new G4UIparameter("procName",'s',false);
bfCmd->SetParameter(procName);
G4UIparameter* procFact = new G4UIparameter("procFact",'d',false);
bfCmd->SetParameter(procFact);
G4UIparameter* flagFact = new G4UIparameter("flagFact",'s',false);
bfCmd->SetParameter(flagFact);
bfCmd->AvailableForStates(G4State_Idle);
fiCmd = new G4UIcommand("/process/em/setForcedInteraction",this);
fiCmd->SetGuidance("Set factor for the process cross section.");
fiCmd->SetGuidance(" procNam : process name");
fiCmd->SetGuidance(" regNam : region name");
fiCmd->SetGuidance(" tlength : fixed target length");
fiCmd->SetGuidance(" tflag : flag to change weight");
G4UIparameter* procNam = new G4UIparameter("procNam",'s',false);
fiCmd->SetParameter(procNam);
G4UIparameter* regNam = new G4UIparameter("regNam",'s',false);
fiCmd->SetParameter(regNam);
G4UIparameter* tlength = new G4UIparameter("tlength",'d',false);
fiCmd->SetParameter(tlength);
G4UIparameter* unitT = new G4UIparameter("unitT",'s',true);
fiCmd->SetParameter(unitT);
unitT->SetGuidance("unit of tlength");
G4UIparameter* flagT = new G4UIparameter("tflag",'s',true);
fiCmd->SetParameter(flagT);
fiCmd->AvailableForStates(G4State_Idle);
brCmd = new G4UIcommand("/process/em/setSecBiasing",this);
brCmd->SetGuidance("Set bremsstrahlung or delta-electron splitting/Russian roullette per region.");
brCmd->SetGuidance(" bProcNam : process name");
brCmd->SetGuidance(" bRegNam : region name");
brCmd->SetGuidance(" bFactor : number of splitted gamma or probability of Russian roulette");
brCmd->SetGuidance(" bEnergy : max energy of a secondary for this biasing method");
G4UIparameter* bProcNam = new G4UIparameter("bProcNam",'s',false);
brCmd->SetParameter(bProcNam);
G4UIparameter* bRegNam = new G4UIparameter("bRegNam",'s',false);
brCmd->SetParameter(bRegNam);
G4UIparameter* bFactor = new G4UIparameter("bFactor",'d',false);
brCmd->SetParameter(bFactor);
G4UIparameter* bEnergy = new G4UIparameter("bEnergy",'d',false);
brCmd->SetParameter(bEnergy);
G4UIparameter* bUnit = new G4UIparameter("bUnit",'s',true);
brCmd->SetParameter(bUnit);
brCmd->SetGuidance("unit of energy");
brCmd->AvailableForStates(G4State_Idle);
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmManagerMessenger::~G4EmManagerMessenger()
{
delete RndmStepCmd;
delete EnlossFlucCmd;
delete SubSecCmd;
delete MinSubSecCmd;
delete StepFuncCmd;
delete deexCmd;
delete eLossDirectory;
delete mscDirectory;
delete emDirectory;
delete MinEnCmd;
delete MaxEnCmd;
delete IntegCmd;
delete rangeCmd;
delete lpmCmd;
delete splCmd;
delete lllCmd;
delete lamCmd;
delete dedxCmd;
/*
delete aplCmd;
delete latCmd;
delete verCmd;
delete ver1Cmd;
delete mscCmd;
delete deCmd;
delete auCmd;
delete pixeCmd;
delete pixeXsCmd;
delete pixeeXsCmd;
delete frCmd;
delete fgCmd;
delete labCmd;
delete skinCmd;
delete angCmd;
delete mscfCmd;
delete bfCmd;
delete fiCmd;
delete brCmd;
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmManagerMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == RndmStepCmd) {
theManager->SetRandomStep(RndmStepCmd->GetNewBoolValue(newValue));
} else if (command == EnlossFlucCmd) {
theManager->SetLossFluctuations(EnlossFlucCmd->GetNewBoolValue(newValue));
} else if(command == SubSecCmd) {
theManager->SetSubCutoff(SubSecCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == MinSubSecCmd) {
theManager->SetMinSubRange(MinSubSecCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == StepFuncCmd) {
G4double v1,v2;
G4String unt;
std::istringstream is(newValue);
is >> v1 >> v2 >> unt;
v2 *= G4UIcommand::ValueOf(unt);
theManager->SetStepFunction(v1,v2);
/*
} else if (command == deexCmd) {
G4String s1 (""), s2(""), s3(""), s4("");
G4bool b2(false), b3(false), b4(false);
std::istringstream is(newValue);
is >> s1 >> s2 >> s3 >> s4;
if(s2 == "true") { b2 = true; }
if(s3 == "true") { b3 = true; }
if(s4 == "true") { b4 = true; }
theManager->SetDeexcitationActiveRegion(s1,b2,b3,b4);
} else if (command == deCmd) {
theManager->SetFluo(deCmd->GetNewBoolValue(newValue));
} else if (command == auCmd) {
theManager->SetAuger(auCmd->GetNewBoolValue(newValue));
} else if (command == pixeCmd) {
theManager->SetPIXE(pixeCmd->GetNewBoolValue(newValue));
} else if (command == pixeXsCmd) {
G4String name;
if (newValue == "ecpssr_analytical")
{name = "ECPSSR_Analytical";}
else if (newValue == "ecpssr_interpolated")
{name = "ECPSSR_FormFactor";}
else
{name = newValue;}
theManager->SetPIXECrossSectionModel(name);
} else if (command == pixeeXsCmd) {
theManager->SetPIXEElectronCrossSectionModel(newValue);
} else if (command == mscCmd) {
if(newValue == "Minimal")
theManager->SetMscStepLimitation(fMinimal);
else if(newValue == "UseDistanceToBoundary")
theManager->SetMscStepLimitation(fUseDistanceToBoundary);
else if(newValue == "UseSafety")
theManager->SetMscStepLimitation(fUseSafety);
else {
G4cout << "### G4EmManagerMessenger WARNING: StepLimit type <"
<< newValue << "> unknown!" << G4endl;
return;
}
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
*/
} else if (command == MinEnCmd) {
theManager->SetMinEnergy(MinEnCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == MaxEnCmd) {
theManager->SetMaxEnergy(MaxEnCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == IntegCmd) {
theManager->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
} else if (command == rangeCmd) {
theManager->SetBuildCSDARange(rangeCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == lpmCmd) {
theManager->SetLPMFlag(lpmCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == splCmd) {
theManager->SetSplineFlag(splCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
/*
} else if (command == aplCmd) {
theManager->SetApplyCuts(aplCmd->GetNewBoolValue(newValue));
} else if (command == latCmd) {
theManager->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == verCmd) {
theManager->SetVerbose(verCmd->GetNewIntValue(newValue));
} else if (command == ver1Cmd) {
theManager->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
*/
} else if (command == lllCmd) {
theManager->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue));
/*
} else if (command == labCmd) {
theManager->SetLambdaFactor(labCmd->GetNewDoubleValue(newValue));
} else if (command == skinCmd) {
theManager->SetSkin(skinCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
*/
} else if (command == dedxCmd) {
theManager->SetDEDXBinning(dedxCmd->GetNewIntValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == lamCmd) {
theManager->SetLambdaBinning(lamCmd->GetNewIntValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
/*
} else if (command == frCmd) {
theManager->SetMscRangeFactor(frCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == fgCmd) {
theManager->SetMscGeomFactor(fgCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == mscfCmd) {
theManager->SetFactorForAngleLimit(mscfCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == angCmd) {
theManager->SetPolarAngleLimit(angCmd->GetNewDoubleValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == bfCmd) {
G4double v1(1.0);
G4String s0(""),s1("");
std::istringstream is(newValue);
is >> s0 >> v1 >> s1;
G4bool yes = false;
if(s1 == "true") { yes = true; }
theManager->SetProcessBiasingFactor(s0,v1,yes);
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == fiCmd) {
G4double v1(0.0);
G4String s1(""),s2(""),s3(""),unt("mm");
std::istringstream is(newValue);
is >> s1 >> s2 >> v1 >> unt >> s3;
G4bool yes = false;
if(s3 == "true") { yes = true; }
v1 *= G4UIcommand::ValueOf(unt);
theManager->ActivateForcedInteraction(s1,v1,s2,yes);
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == brCmd) {
G4double fb(1.0),en(1.e+30);
G4String s1(""),s2(""),unt("MeV");
std::istringstream is(newValue);
is >> s1 >> s2 >> fb >> en >> unt;
en *= G4UIcommand::ValueOf(unt);
if (s1=="phot"||s1=="compt"||s1=="conv")
theManager->ActivateSecondaryBiasingForGamma(s1,s2,fb,en);
else theManager->ActivateSecondaryBiasing(s1,s2,fb,en);
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
*/
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmModelManager.cc 76957 2013-11-19 15:07:20Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -137,7 +137,8 @@ G4EmModelManager::G4EmModelManager():
fluoFlag = false;
currRegionModel = 0;
currModel = 0;
theCuts = 0;
theCuts = 0;
theCutsNew = 0;
theSubCuts = 0;
}
@@ -147,6 +148,7 @@ G4EmModelManager::~G4EmModelManager()
{
verboseLevel = 0; // no verbosity at destruction
Clear();
delete theCutsNew;
delete theSubCuts;
}
@@ -230,6 +232,8 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
{
verboseLevel = val;
G4String partname = p->GetParticleName();
// if(partname == "proton") verboseLevel = 2;
//else verboseLevel = 0;
if(1 < verboseLevel) {
G4cout << "G4EmModelManager::Initialise() for "
<< partname << G4endl;
@@ -238,7 +242,7 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
if(nEmModels < 1) {
G4ExceptionDescription ed;
ed << "No models found out for " << p->GetParticleName()
<< " !" << G4endl;
<< " !";
G4Exception("G4EmModelManager::Initialise","em0002",
FatalException, ed);
}
@@ -265,7 +269,7 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
G4bool newRegion = true;
if (nRegions>1) {
for (G4int j=1; j<nRegions; ++j) {
if ( r == setr[j] ) newRegion = false;
if ( r == setr[j] ) { newRegion = false; }
}
}
if (newRegion) {
@@ -277,8 +281,8 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
// Are models defined?
if(!isWorld) {
G4ExceptionDescription ed;
ed << "No models defined for the World volume for " << p->GetParticleName()
<< " !" << G4endl;
ed << "No models defined for the World volume for "
<< p->GetParticleName() << " !";
G4Exception("G4EmModelManager::Initialise","em0002",
FatalException, ed);
}
@@ -288,20 +292,25 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
size_t numOfCouples = theCoupleTable->GetTableSize();
// prepare vectors, shortcut for the case of only 1 model
// or only one region
if(nRegions > 1 && nEmModels > 1) {
if(numOfCouples > idxOfRegionModels.size()) {
idxOfRegionModels.resize(numOfCouples);
}
idxOfRegionModels.resize(numOfCouples,0);
setOfRegionModels.resize((size_t)nRegions,0);
} else {
idxOfRegionModels.resize(1,0);
setOfRegionModels.resize(1,0);
}
size_t nr = 1;
if(nEmModels > 1) { nr = nRegions; }
if(nr > setOfRegionModels.size()) { setOfRegionModels.resize(nr); }
std::vector<G4int> modelAtRegion(nEmModels);
std::vector<G4int> modelOrd(nEmModels);
G4DataVector eLow(nEmModels+1);
G4DataVector eHigh(nEmModels);
if(1 < verboseLevel) {
G4cout << " Nregions= " << nRegions
<< " Nmodels= " << nEmModels << G4endl;
}
// Order models for regions
for (G4int reg=0; reg<nRegions; ++reg) {
const G4Region* region = setr[reg];
@@ -420,17 +429,19 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
if(1 < verboseLevel) {
G4cout << "New G4RegionModels set with " << n << " models for region <";
if (region) G4cout << region->GetName();
if (region) { G4cout << region->GetName(); }
G4cout << "> Elow(MeV)= ";
for(G4int ii=0; ii<=n; ++ii) {G4cout << eLow[ii]/MeV << " ";}
G4cout << G4endl;
}
G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow, region);
setOfRegionModels[reg] = rm;
// shortcut
if(1 == nEmModels) { break; }
}
currRegionModel = setOfRegionModels[0];
currModel = models[0];
// Access to materials and build cuts
size_t idx = 1;
@@ -439,13 +450,19 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
else if( secondaryParticle == G4Positron::Positron()) { idx = 2; }
}
//theCuts = theCoupleTable->GetEnergyCutsVector(idx);
theCuts = static_cast<const G4DataVector*>(theCoupleTable->GetEnergyCutsVector(idx));
theCuts =
static_cast<const G4DataVector*>(theCoupleTable->GetEnergyCutsVector(idx));
// for the second run the check on cuts should be repeated
if(theCutsNew) { *theCutsNew = *theCuts; }
if(minSubRange < 1.0) {
if( !theSubCuts ) { theSubCuts = new G4DataVector(); }
theSubCuts->resize(numOfCouples,DBL_MAX);
}
// G4cout << "========Start define cuts" << G4endl;
// define cut values
for(size_t i=0; i<numOfCouples; ++i) {
const G4MaterialCutsCouple* couple =
@@ -476,12 +493,45 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
G4double rcut = std::min(minSubRange*pcuts->GetProductionCut(idx),
maxSubCutInRange);
G4double tcutmax =
theCoupleTable->ConvertRangeToEnergy(secondaryParticle,material,rcut);
theCoupleTable->ConvertRangeToEnergy(secondaryParticle,
material,rcut);
if(tcutmax < subcut) { subcut = tcutmax; }
(*theSubCuts)[i] = subcut;
}
// note that idxOfRegionModels[] not always filled
G4int inn = 0;
G4int nnm = 1;
if(nRegions > 1 && nEmModels > 1) {
inn = idxOfRegionModels[i];
}
// check cuts and introduce upper limits
//G4cout << "idx= " << i << " cut(keV)= " << cut/keV << G4endl;
currRegionModel = setOfRegionModels[inn];
nnm = currRegionModel->NumberOfModels();
//G4cout << "idx= " << i << " Nmod= " << nnm << G4endl;
for(G4int jj=0; jj<nnm; ++jj) {
//G4cout << "jj= " << jj << " modidx= "
// << currRegionModel->ModelIndex(jj) << G4endl;
currModel = models[currRegionModel->ModelIndex(jj)];
G4double cutlim = currModel->MinEnergyCut(particle,couple);
if(cutlim > cut) {
if(!theCutsNew) { theCutsNew = new G4DataVector(*theCuts); }
(*theCutsNew)[i] = cutlim;
/*
G4cout << "### " << partname << " energy loss model in "
<< material->GetName()
<< " Cut was changed from " << cut/keV << " keV to "
<< cutlim/keV << " keV " << " due to "
<< currModel->GetName() << G4endl;
*/
}
}
}
}
if(theCutsNew) { theCuts = theCutsNew; }
// initialize models
G4int nn = 0;
@@ -497,8 +547,9 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
if(1 == nn) { severalModels = false; }
if(1 < verboseLevel) {
G4cout << "G4EmModelManager for " << particle->GetParticleName()
G4cout << "G4EmModelManager for " << partname
<< " is initialised; nRegions= " << nRegions
<< " severalModels: " << severalModels
<< G4endl;
}
@@ -606,8 +657,8 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
G4cout << "G4EmModelManager::FillLambdaVector() for "
<< particle->GetParticleName()
<< " in " << couple->GetMaterial()->GetName()
<< " Ecut(MeV)= " << cut
<< " Emax(MeV)= " << tmax
<< " Emin(MeV)= " << aVector->Energy(0)
<< " Emax(MeV)= " << aVector->GetMaxEnergy()
<< " Type " << tType
<< " nmod= " << nmod
<< G4endl;
@@ -698,12 +749,18 @@ void G4EmModelManager::DumpModelList(G4int verb)
}
G4VEmAngularDistribution* an = model->GetAngularDistribution();
if(an) { G4cout << " " << an->GetName(); }
if(fluoFlag && model->DeexcitationFlag()) { G4cout << " FluoActive"; }
if(fluoFlag && model->DeexcitationFlag()) {
G4cout << " FluoActive";
}
G4cout << G4endl;
}
}
if(1 == nEmModels) { break; }
}
if(theCutsNew) {
G4cout << " ===== Limit on energy threshold has been applied "
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmMultiModel.cc 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmProcessOptions.cc 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -61,6 +61,7 @@
#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4Threading.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -188,18 +189,21 @@ void G4EmProcessOptions::SetBuildCSDARange(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name,
G4bool worker)
{
G4bool all = false;
if("all" == name) { all = true; }
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
if(worker && !G4Threading::IsWorkerThread()) { return; }
if(all) {
theManager->SetVerbose(val);
return;
}
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); ++itr) {
G4VEnergyLossProcess* p = *itr;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EmSaturation.cc 66241 2012-12-13 18:34:42Z gunter $
//
// -------------------------------------------------------------------
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4EnergyLossMessenger.cc 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -244,6 +244,12 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
ver1Cmd->SetDefaultValue(1);
ver1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
ver2Cmd = new G4UIcmdWithAnInteger("/process/em/workerVerbose",this);
ver2Cmd->SetGuidance("Set worker verbose level for EM physics");
ver2Cmd->SetParameterName("verb2",true);
ver2Cmd->SetDefaultValue(1);
ver2Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
lllCmd = new G4UIcmdWithADouble("/process/eLoss/linLossLimit",this);
lllCmd->SetGuidance("Set linearLossLimit parameter");
lllCmd->SetParameterName("linlim",true);
@@ -387,6 +393,7 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
delete latCmd;
delete verCmd;
delete ver1Cmd;
delete ver2Cmd;
delete mscCmd;
delete dedxCmd;
delete deCmd;
@@ -495,9 +502,11 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
opt->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue));
G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
} else if (command == verCmd) {
opt->SetVerbose(verCmd->GetNewIntValue(newValue));
opt->SetVerbose(verCmd->GetNewIntValue(newValue),"all",false);
} else if (command == ver1Cmd) {
opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue),"all",false);
} else if (command == ver2Cmd) {
opt->SetVerbose(ver2Cmd->GetNewIntValue(newValue),"all",true);
} else if (command == lllCmd) {
opt->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue));
} else if (command == labCmd) {
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id$
// $Id: G4EnergyLossTables.cc 77290 2013-11-22 10:57:50Z gcosmo $
//
// -------------------------------------------------------------------
// first version created by P.Urban , 06/04/1998
@@ -49,11 +49,26 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
/*
G4ThreadLocal G4EnergyLossTablesHelper *G4EnergyLossTables::t = 0;
G4ThreadLocal G4EnergyLossTablesHelper *G4EnergyLossTables::null_loss = 0;
G4ThreadLocal G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
G4ThreadLocal G4double G4EnergyLossTables::QQPositron = 1.0; // e_squared
G4ThreadLocal G4double G4EnergyLossTables::Chargesquare ;
G4ThreadLocal G4int G4EnergyLossTables::oldIndex = -1 ;
G4ThreadLocal G4double G4EnergyLossTables::rmin = 0. ;
G4ThreadLocal G4double G4EnergyLossTables::rmax = 0. ;
G4ThreadLocal G4double G4EnergyLossTables::Thigh = 0. ;
G4ThreadLocal G4int G4EnergyLossTables::let_counter = 0;
G4ThreadLocal G4int G4EnergyLossTables::let_max_num_warnings = 100;
G4ThreadLocal G4bool G4EnergyLossTables::first_loss = true;
G4EnergyLossTablesHelper G4EnergyLossTables::t ;
G4EnergyLossTablesHelper G4EnergyLossTables::null_loss ;
const G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
G4double G4EnergyLossTables::QQPositron = eplus*eplus ;
G4ThreadLocal G4EnergyLossTables::helper_map *G4EnergyLossTables::dict = 0;
*/
G4EnergyLossTablesHelper *G4EnergyLossTables::t = 0;
G4EnergyLossTablesHelper *G4EnergyLossTables::null_loss = 0;
G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
G4double G4EnergyLossTables::QQPositron = 1.0; // e_squared
G4double G4EnergyLossTables::Chargesquare ;
G4int G4EnergyLossTables::oldIndex = -1 ;
G4double G4EnergyLossTables::rmin = 0. ;
@@ -63,7 +78,7 @@ G4int G4EnergyLossTables::let_counter = 0;
G4int G4EnergyLossTables::let_max_num_warnings = 100;
G4bool G4EnergyLossTables::first_loss = true;
G4EnergyLossTables::helper_map G4EnergyLossTables::dict;
G4EnergyLossTables::helper_map *G4EnergyLossTables::dict = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -112,16 +127,20 @@ void G4EnergyLossTables::Register(
G4double massRatio,
G4int NumberOfBins)
{
dict[p]= G4EnergyLossTablesHelper(tDEDX, tRange,tInverseRange,
if (!dict) dict = new G4EnergyLossTables::helper_map;
if (!null_loss) null_loss = new G4EnergyLossTablesHelper;
if (!t) t = new G4EnergyLossTablesHelper;
(*dict)[p]= G4EnergyLossTablesHelper(tDEDX, tRange,tInverseRange,
tLabTime,tProperTime,lowestKineticEnergy,
highestKineticEnergy, massRatio,NumberOfBins);
t = GetTables(p) ; // important for cache !!!!!
lastParticle = p ;
*t = GetTables(p) ; // important for cache !!!!!
lastParticle = (G4ParticleDefinition*) p ;
Chargesquare = (p->GetPDGCharge())*(p->GetPDGCharge())/
QQPositron ;
if (first_loss ) {
null_loss = G4EnergyLossTablesHelper(0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0);
*null_loss = G4EnergyLossTablesHelper(0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0);
first_loss = false;
}
}
@@ -131,8 +150,9 @@ void G4EnergyLossTables::Register(
const G4PhysicsTable* G4EnergyLossTables::GetDEDXTable(
const G4ParticleDefinition* p)
{
if (!dict) dict = new G4EnergyLossTables::helper_map;
helper_map::iterator it;
if((it=dict.find(p))==dict.end()) return 0;
if((it=dict->find(p))==dict->end()) return 0;
return (*it).second.theDEDXTable;
}
@@ -141,8 +161,9 @@ const G4PhysicsTable* G4EnergyLossTables::GetDEDXTable(
const G4PhysicsTable* G4EnergyLossTables::GetRangeTable(
const G4ParticleDefinition* p)
{
if (!dict) dict = new G4EnergyLossTables::helper_map;
helper_map::iterator it;
if((it=dict.find(p))==dict.end()) return 0;
if((it=dict->find(p))==dict->end()) return 0;
return (*it).second.theRangeTable;
}
@@ -151,8 +172,9 @@ const G4PhysicsTable* G4EnergyLossTables::GetRangeTable(
const G4PhysicsTable* G4EnergyLossTables::GetInverseRangeTable(
const G4ParticleDefinition* p)
{
if (!dict) dict = new G4EnergyLossTables::helper_map;
helper_map::iterator it;
if((it=dict.find(p))==dict.end()) return 0;
if((it=dict->find(p))==dict->end()) return 0;
return (*it).second.theInverseRangeTable;
}
@@ -161,8 +183,9 @@ const G4PhysicsTable* G4EnergyLossTables::GetInverseRangeTable(
const G4PhysicsTable* G4EnergyLossTables::GetLabTimeTable(
const G4ParticleDefinition* p)
{
if (!dict) dict = new G4EnergyLossTables::helper_map;
helper_map::iterator it;
if((it=dict.find(p))==dict.end()) return 0;
if((it=dict->find(p))==dict->end()) return 0;
return (*it).second.theLabTimeTable;
}
@@ -171,8 +194,9 @@ const G4PhysicsTable* G4EnergyLossTables::GetLabTimeTable(
const G4PhysicsTable* G4EnergyLossTables::GetProperTimeTable(
const G4ParticleDefinition* p)
{
if (!dict) dict = new G4EnergyLossTables::helper_map;
helper_map::iterator it;
if((it=dict.find(p))==dict.end()) return 0;
if((it=dict->find(p))==dict->end()) return 0;
return (*it).second.theProperTimeTable;
}
@@ -181,12 +205,12 @@ const G4PhysicsTable* G4EnergyLossTables::GetProperTimeTable(
G4EnergyLossTablesHelper G4EnergyLossTables::GetTables(
const G4ParticleDefinition* p)
{
if (!dict) dict = new G4EnergyLossTables::helper_map;
if (!null_loss) null_loss = new G4EnergyLossTablesHelper;
helper_map::iterator it;
if ((it=dict.find(p))==dict.end()) {
// G4cout << "Table is not found out for " << p->GetParticleName() << G4endl;
// G4Exception("G4EnergyLossTables::GetTables: table not found!");
// exit(1);
return null_loss;
if ((it=dict->find(p))==dict->end()) {
return *null_loss;
}
return (*it).second;
}
@@ -198,37 +222,39 @@ G4double G4EnergyLossTables::GetDEDX(
G4double KineticEnergy,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if(aParticle != lastParticle)
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if (!dEdxTable) {
ParticleHaveNoLoss(aParticle,"dEdx");
return 0.0;
}
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double dEdx;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
dEdx =(*dEdxTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut)
*std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
t->theLowestKineticEnergy,isOut)
*std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
dEdx = (*dEdxTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -247,14 +273,16 @@ G4double G4EnergyLossTables::GetLabTime(
G4double KineticEnergy,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if(aParticle != lastParticle)
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
oldIndex = -1 ;
}
const G4PhysicsTable* labtimeTable= t.theLabTimeTable;
const G4PhysicsTable* labtimeTable= t->theLabTimeTable;
if (!labtimeTable) {
ParticleHaveNoLoss(aParticle,"LabTime");
return 0.0;
@@ -262,21 +290,21 @@ G4double G4EnergyLossTables::GetLabTime(
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double time;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
time = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
time = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
(*labtimeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
time = (*labtimeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -285,7 +313,7 @@ G4double G4EnergyLossTables::GetLabTime(
}
return time/t.theMassRatio ;
return time/t->theMassRatio ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -296,14 +324,16 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
G4double KineticEnergyEnd,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if(aParticle != lastParticle)
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
oldIndex = -1 ;
}
const G4PhysicsTable* labtimeTable= t.theLabTimeTable;
const G4PhysicsTable* labtimeTable= t->theLabTimeTable;
if (!labtimeTable) {
ParticleHaveNoLoss(aParticle,"LabTime");
return 0.0;
@@ -315,19 +345,19 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
G4bool isOut;
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergyStart*t->theMassRatio;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
timestart = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
timestart = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
(*labtimeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
timestart = (*labtimeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -339,21 +369,21 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
if( dTT < dToverT )
scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
scaledKineticEnergy = facT*KineticEnergyStart*t->theMassRatio;
else
scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
scaledKineticEnergy = KineticEnergyEnd*t->theMassRatio;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
timeend = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
timeend = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
(*labtimeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
timeend = (*labtimeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -367,7 +397,7 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
if( dTT < dToverT )
deltatime *= dTT/dToverT;
return deltatime/t.theMassRatio ;
return deltatime/t->theMassRatio ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -377,14 +407,16 @@ G4double G4EnergyLossTables::GetProperTime(
G4double KineticEnergy,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if(aParticle != lastParticle)
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
oldIndex = -1 ;
}
const G4PhysicsTable* propertimeTable= t.theProperTimeTable;
const G4PhysicsTable* propertimeTable= t->theProperTimeTable;
if (!propertimeTable) {
ParticleHaveNoLoss(aParticle,"ProperTime");
return 0.0;
@@ -392,21 +424,21 @@ G4double G4EnergyLossTables::GetProperTime(
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double time;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
time = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
time = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
(*propertimeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
time = (*propertimeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -415,7 +447,7 @@ G4double G4EnergyLossTables::GetProperTime(
}
return time/t.theMassRatio ;
return time/t->theMassRatio ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -426,14 +458,16 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
G4double KineticEnergyEnd,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if(aParticle != lastParticle)
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
oldIndex = -1 ;
}
const G4PhysicsTable* propertimeTable= t.theProperTimeTable;
const G4PhysicsTable* propertimeTable= t->theProperTimeTable;
if (!propertimeTable) {
ParticleHaveNoLoss(aParticle,"ProperTime");
return 0.0;
@@ -445,19 +479,19 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
G4bool isOut;
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergyStart*t->theMassRatio;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
timestart = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
timestart = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
(*propertimeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
timestart = (*propertimeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -469,21 +503,21 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
if( dTT < dToverT )
scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
scaledKineticEnergy = facT*KineticEnergyStart*t->theMassRatio;
else
scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
scaledKineticEnergy = KineticEnergyEnd*t->theMassRatio;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
timeend = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
timeend = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
(*propertimeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
timeend = (*propertimeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -497,7 +531,7 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
if( dTT < dToverT )
deltatime *= dTT/dToverT ;
return deltatime/t.theMassRatio ;
return deltatime/t->theMassRatio ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -507,41 +541,43 @@ G4double G4EnergyLossTables::GetRange(
G4double KineticEnergy,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if(aParticle != lastParticle)
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* rangeTable= t.theRangeTable;
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* rangeTable= t->theRangeTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if (!rangeTable) {
ParticleHaveNoLoss(aParticle,"Range");
return 0.0;
}
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double Range;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
(*rangeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
Range = (*rangeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut)+
(scaledKineticEnergy-t.theHighestKineticEnergy)/
t->theHighestKineticEnergy,isOut)+
(scaledKineticEnergy-t->theHighestKineticEnergy)/
(*dEdxTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -550,7 +586,7 @@ G4double G4EnergyLossTables::GetRange(
}
return Range/(Chargesquare*t.theMassRatio);
return Range/(Chargesquare*t->theMassRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -561,18 +597,20 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
const G4Material *aMaterial)
// it returns the value of the kinetic energy for a given range
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if( aParticle != lastParticle)
if( aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
const G4PhysicsTable* inverseRangeTable= t->theInverseRangeTable;
if (!inverseRangeTable) {
ParticleHaveNoLoss(aParticle,"InverseRange");
return 0.0;
@@ -589,16 +627,16 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
rmin = (*inverseRangeTable)(materialIndex)->
GetLowEdgeEnergy(0) ;
rmax = (*inverseRangeTable)(materialIndex)->
GetLowEdgeEnergy(t.theNumberOfBins-2) ;
GetLowEdgeEnergy(t->theNumberOfBins-2) ;
Thigh = (*inverseRangeTable)(materialIndex)->
GetValue(rmax,isOut) ;
}
scaledrange = range*Chargesquare*t.theMassRatio ;
scaledrange = range*Chargesquare*t->theMassRatio ;
if(scaledrange < rmin)
{
scaledKineticEnergy = t.theLowestKineticEnergy*
scaledKineticEnergy = t->theLowestKineticEnergy*
scaledrange*scaledrange/(rmin*rmin) ;
}
else
@@ -617,7 +655,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
}
}
return scaledKineticEnergy/t.theMassRatio ;
return scaledKineticEnergy/t->theMassRatio ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -627,37 +665,39 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
G4double KineticEnergy,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if( aParticle != lastParticle)
if( aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if (!dEdxTable) {
ParticleHaveNoLoss(aParticle,"dEdx");
return 0.0;
}
G4int materialIndex = aMaterial->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double dEdx;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
dEdx = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
dEdx = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)
*(*dEdxTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
dEdx = (*dEdxTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -676,37 +716,39 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
G4double KineticEnergy,
const G4Material *aMaterial)
{
if (!t) t = new G4EnergyLossTablesHelper;
CPRWarning();
if( aParticle != lastParticle)
if( aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* rangeTable= t.theRangeTable;
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* rangeTable= t->theRangeTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if (!rangeTable) {
ParticleHaveNoLoss(aParticle,"Range");
return 0.0;
}
G4int materialIndex = aMaterial->GetIndex();
G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
G4double Thighr = t->theHighestKineticEnergy*t->theLowestKineticEnergy/
(*rangeTable)(materialIndex)->
GetLowEdgeEnergy(1) ;
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double Range;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
(*rangeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>Thighr) {
@@ -723,7 +765,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
}
return Range/(Chargesquare*t.theMassRatio);
return Range/(Chargesquare*t->theMassRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -734,16 +776,18 @@ G4double G4EnergyLossTables::GetDEDX(
const G4MaterialCutsCouple *couple,
G4bool check)
{
if(aParticle != lastParticle)
if (!t) t = new G4EnergyLossTablesHelper;
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if (!dEdxTable ) {
if (check) return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
@@ -752,20 +796,20 @@ G4double G4EnergyLossTables::GetDEDX(
}
G4int materialIndex = couple->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double dEdx;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
dEdx =(*dEdxTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut)
*std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
t->theLowestKineticEnergy,isOut)
*std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
dEdx = (*dEdxTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -785,17 +829,19 @@ G4double G4EnergyLossTables::GetRange(
const G4MaterialCutsCouple *couple,
G4bool check)
{
if(aParticle != lastParticle)
if (!t) t = new G4EnergyLossTablesHelper;
if(aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle ;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle ;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* rangeTable= t.theRangeTable;
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* rangeTable= t->theRangeTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if (!rangeTable) {
if(check) return G4LossTableManager::Instance()->GetRange(aParticle,KineticEnergy,couple);
else return DBL_MAX;
@@ -803,23 +849,23 @@ G4double G4EnergyLossTables::GetRange(
}
G4int materialIndex = couple->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double Range;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
(*rangeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
Range = (*rangeTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut)+
(scaledKineticEnergy-t.theHighestKineticEnergy)/
t->theHighestKineticEnergy,isOut)+
(scaledKineticEnergy-t->theHighestKineticEnergy)/
(*dEdxTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -828,7 +874,7 @@ G4double G4EnergyLossTables::GetRange(
}
return Range/(Chargesquare*t.theMassRatio);
return Range/(Chargesquare*t->theMassRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -840,17 +886,19 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
G4bool check)
// it returns the value of the kinetic energy for a given range
{
if( aParticle != lastParticle)
if (!t) t = new G4EnergyLossTablesHelper;
if( aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
const G4PhysicsTable* inverseRangeTable= t->theInverseRangeTable;
if (!inverseRangeTable) {
if(check) return G4LossTableManager::Instance()->GetEnergy(aParticle,range,couple);
@@ -869,16 +917,16 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
rmin = (*inverseRangeTable)(materialIndex)->
GetLowEdgeEnergy(0) ;
rmax = (*inverseRangeTable)(materialIndex)->
GetLowEdgeEnergy(t.theNumberOfBins-2) ;
GetLowEdgeEnergy(t->theNumberOfBins-2) ;
Thigh = (*inverseRangeTable)(materialIndex)->
GetValue(rmax,isOut) ;
}
scaledrange = range*Chargesquare*t.theMassRatio ;
scaledrange = range*Chargesquare*t->theMassRatio ;
if(scaledrange < rmin)
{
scaledKineticEnergy = t.theLowestKineticEnergy*
scaledKineticEnergy = t->theLowestKineticEnergy*
scaledrange*scaledrange/(rmin*rmin) ;
}
else
@@ -897,7 +945,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
}
}
return scaledKineticEnergy/t.theMassRatio ;
return scaledKineticEnergy/t->theMassRatio ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -907,35 +955,36 @@ G4double G4EnergyLossTables::GetPreciseDEDX(
G4double KineticEnergy,
const G4MaterialCutsCouple *couple)
{
if (!t) t = new G4EnergyLossTablesHelper;
if( aParticle != lastParticle)
if( aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if ( !dEdxTable )
return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
G4int materialIndex = couple->GetIndex();
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double dEdx;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
dEdx = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
dEdx = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)
*(*dEdxTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
} else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
dEdx = (*dEdxTable)(materialIndex)->GetValue(
t.theHighestKineticEnergy,isOut);
t->theHighestKineticEnergy,isOut);
} else {
@@ -954,35 +1003,37 @@ G4double G4EnergyLossTables::GetPreciseRangeFromEnergy(
G4double KineticEnergy,
const G4MaterialCutsCouple *couple)
{
if( aParticle != lastParticle)
if (!t) t = new G4EnergyLossTablesHelper;
if( aParticle != (const G4ParticleDefinition*) lastParticle)
{
t= GetTables(aParticle);
lastParticle = aParticle;
*t= GetTables(aParticle);
lastParticle = (G4ParticleDefinition*) aParticle;
Chargesquare = (aParticle->GetPDGCharge())*
(aParticle->GetPDGCharge())/
QQPositron ;
oldIndex = -1 ;
}
const G4PhysicsTable* rangeTable= t.theRangeTable;
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
const G4PhysicsTable* rangeTable= t->theRangeTable;
const G4PhysicsTable* dEdxTable= t->theDEDXTable;
if ( !dEdxTable || !rangeTable)
return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
G4int materialIndex = couple->GetIndex();
G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
G4double Thighr = t->theHighestKineticEnergy*t->theLowestKineticEnergy/
(*rangeTable)(materialIndex)->
GetLowEdgeEnergy(1) ;
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
G4double Range;
G4bool isOut;
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
if (scaledKineticEnergy<t->theLowestKineticEnergy) {
Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
(*rangeTable)(materialIndex)->GetValue(
t.theLowestKineticEnergy,isOut);
t->theLowestKineticEnergy,isOut);
} else if (scaledKineticEnergy>Thighr) {
@@ -999,7 +1050,7 @@ G4double G4EnergyLossTables::GetPreciseRangeFromEnergy(
}
return Range/(Chargesquare*t.theMassRatio);
return Range/(Chargesquare*t->theMassRatio);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -1015,10 +1066,6 @@ void G4EnergyLossTables::CPRWarning()
G4cout << "##### Obsolete interface will be removed soon" << G4endl;
G4cout << G4endl;
let_counter++;
// if ((G4RegionStore::GetInstance())->size() > 1) {
// G4Exception("G4EnergyLossTables:: More than 1 region - table can't be accessed with obsolete interface");
// exit(1);
// }
} else if (let_counter == let_max_num_warnings) {
@@ -1033,10 +1080,6 @@ void
G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition*,
const G4String& /*q*/)
{
//G4String s = " " + q + " table not found for "
// + aParticle->GetParticleName() + " !";
//G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01",
// FatalException, s);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4LossTableBuilder.cc 71484 2013-06-17 08:12:51Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -107,7 +107,11 @@ G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
if(pv0) {
size_t npoints = pv0->GetVectorLength();
G4PhysicsLogVector* pv = new G4PhysicsLogVector(*pv0);
// pv = new G4PhysicsLogVector(elow, ehigh, npoints-1);
/*
G4PhysicsLogVector* pv = new G4PhysicsLogVector(pv0->Energy(0),
pv0->GetMaxEnergy(),
npoints-1);
*/
pv->SetSpline(splineFlag);
for (size_t j=0; j<npoints; ++j) {
G4double dedx = 0.0;
@@ -414,9 +418,7 @@ G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
}
InitialiseBaseMaterials(table);
G4int nbins = G4int(std::log10(emax/emin) + 0.5)
*G4LossTableManager::Instance()->GetNumberOfBinsPerDecade();
if(nbins < 3) { nbins = 3; }
G4int nbins = G4LossTableManager::Instance()->GetNumberOfBinsPerDecade();
// Access to materials
const G4ProductionCutsTable* theCoupleTable=
@@ -424,7 +426,7 @@ G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
size_t numOfCouples = theCoupleTable->GetTableSize();
G4PhysicsLogVector* aVector = 0;
G4PhysicsLogVector* bVector = 0;
//G4PhysicsLogVector* bVector = 0;
for(size_t i=0; i<numOfCouples; ++i) {
@@ -443,27 +445,19 @@ G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
G4double tmin = std::max(emin,model->MinPrimaryEnergy(mat,part));
if(0.0 >= tmin) { tmin = eV; }
G4int n = nbins + 1;
G4int n = nbins;
if(tmin >= emax) {
aVector = 0;
} else if(tmin > emin) {
G4int bin = nbins*G4int(std::log10(emax/tmin) + 0.5);
if(bin < 3) { bin = 3; }
n = bin + 1;
aVector = new G4PhysicsLogVector(tmin, emax, bin);
} else if(!bVector) {
aVector = new G4PhysicsLogVector(emin, emax, nbins);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
n *= G4int(std::log10(emax/tmin) + 0.5);
if(n < 3) { n = 3; }
aVector = new G4PhysicsLogVector(tmin, emax, n);
}
if(aVector) {
aVector->SetSpline(spline);
for(G4int j=0; j<n; ++j) {
for(G4int j=0; j<=n; ++j) {
aVector->PutValue(j, model->Value(couple, part, aVector->Energy(j)));
}
if(spline) { aVector->FillSecondDerivatives(); }
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4LossTableManager.cc 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -69,7 +69,10 @@
// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
// 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
// 21-02-08 Added G4EmSaturation (V.Ivanchenko)
// 12-04-10 Added PreparePhsyicsTables and BuildPhysicsTables entries (V.Ivanchenko)
// 12-04-10 Added PreparePhysicsTables and BuildPhysicsTables entries (V.Ivanchenko)
// 04-06-13 (V.Ivanchenko) Adaptation for MT mode; new method LocalPhysicsTables;
// ions expect G4GenericIon are not included in the map of energy loss
// processes for performnc reasons
//
// Class Description:
//
@@ -99,24 +102,29 @@
#include "G4LossTableBuilder.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4Region.hh"
#include "G4PhysicalConstants.hh"
G4LossTableManager* G4LossTableManager::theInstance = 0;
//G4ThreadLocal G4LossTableManager* G4LossTableManager::theInstance = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4LossTableManager* G4LossTableManager::Instance()
{
if(0 == theInstance) {
static G4LossTableManager manager;
theInstance = &manager;
/*
if(!theInstance) {
theInstance = new G4LossTableManager;
}
return theInstance;
*/
static G4ThreadLocalSingleton<G4LossTableManager> instance;
return instance.Instance();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4LossTableManager::~G4LossTableManager()
{
//G4cout << "### G4LossTableManager::~G4LossTableManager()" << G4endl;
for (G4int i=0; i<n_loss; ++i) {
if( loss_vector[i] ) { delete loss_vector[i]; }
}
@@ -129,10 +137,17 @@ G4LossTableManager::~G4LossTableManager()
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]; }
}
size_t fmod = fmod_vector.size();
for (size_t a=0; a<mod; ++a) {
if( mod_vector[a] ) {
for (size_t b=0; b<fmod; ++b) {
if((G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
fmod_vector[b] = 0;
}
}
delete mod_vector[a];
}
}
for (size_t b=0; b<fmod; ++b) {
if( fmod_vector[b] ) { delete fmod_vector[b]; }
}
@@ -151,7 +166,7 @@ G4LossTableManager::~G4LossTableManager()
G4LossTableManager::G4LossTableManager()
{
n_loss = 0;
run = 0;
run = -1;
startInitialisation = false;
all_tables_are_built = false;
currentLoss = 0;
@@ -177,11 +192,13 @@ G4LossTableManager::G4LossTableManager()
stepFunctionActive = false;
flagLPM = true;
splineFlag = true;
isMaster = false;
bremsTh = DBL_MAX;
factorForAngleLimit = 1.0;
verbose = 1;
theMessenger = new G4EnergyLossMessenger();
theElectron = G4Electron::Electron();
theGenericIon= 0;
tableBuilder = new G4LossTableBuilder();
emCorrections= new G4EmCorrections();
emSaturation = new G4EmSaturation();
@@ -238,7 +255,8 @@ void G4LossTableManager::Register(G4VEnergyLossProcess* p)
if(!lossFluctuationFlag) { p->SetLossFluctuations(false); }
if(subCutoffFlag) { p->ActivateSubCutoff(true); }
if(rndmStepFlag) { p->SetRandomStep(true); }
if(stepFunctionActive) { p->SetStepFunction(maxRangeVariation, maxFinalStep); }
if(stepFunctionActive) { p->SetStepFunction(maxRangeVariation,
maxFinalStep); }
if(integralActive) { p->SetIntegral(integral); }
if(minEnergyActive) { p->SetMinKinEnergy(minKinEnergy); }
if(maxEnergyActive) { p->SetMaxKinEnergy(maxKinEnergy); }
@@ -352,14 +370,6 @@ void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::RegisterIon(const G4ParticleDefinition* ion,
G4VEnergyLossProcess* p)
{
loss_map[ion] = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::RegisterExtraParticle(
const G4ParticleDefinition* part,
G4VEnergyLossProcess* p)
@@ -388,7 +398,8 @@ void G4LossTableManager::RegisterExtraParticle(
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEnergyLossProcess* p)
G4VEnergyLossProcess* p,
G4bool theMaster)
{
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
@@ -396,38 +407,57 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
<< " and " << p->GetProcessName() << " run= " << run
<< " loss_vector " << loss_vector.size() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
isMaster = theMaster;
if(!startInitialisation) {
tableBuilder->SetInitialisationFlag(false);
if (1 < verbose) {
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
<< G4endl;
}
}
// start initialisation for the first run
startInitialisation = true;
if( 0 == run ) {
if( -1 == run ) {
emConfigurator->PrepareModels(particle, p);
// 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; }
if (p == loss_vector[j] && !part_vector[j]) {
part_vector[j] = particle;
if(particle->GetParticleName() == "GenericIon") {
theGenericIon = particle;
}
}
}
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEmProcess* p)
G4VEmProcess* p, G4bool theMaster)
{
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
isMaster = theMaster;
if(!startInitialisation) {
tableBuilder->SetInitialisationFlag(false);
if (1 < verbose) {
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
<< G4endl;
}
}
// start initialisation for the first run
if( 0 == run ) {
if( -1 == run ) {
emConfigurator->PrepareModels(particle, p);
}
startInitialisation = true;
@@ -437,19 +467,30 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VMultipleScattering* p)
G4VMultipleScattering* p,
G4bool theMaster)
{
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
if(!startInitialisation) { tableBuilder->SetInitialisationFlag(false); }
isMaster = theMaster;
if(!startInitialisation) {
tableBuilder->SetInitialisationFlag(false);
if (1 < verbose) {
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
<< G4endl;
}
}
// start initialisation for the first run
if( 0 == run ) {
if( -1 == run ) {
emConfigurator->PrepareModels(particle, p);
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
@@ -457,35 +498,132 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
void
G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition*)
{
if(0 == run && startInitialisation) {
if(-1 == run && startInitialisation) {
emConfigurator->Clear();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::LocalPhysicsTables(
const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(1 < verbose) {
G4cout << "### G4LossTableManager::SlavePhysicsTable() for "
<< aParticle->GetParticleName()
<< " and process " << p->GetProcessName()
<< G4endl;
}
if(-1 == run && startInitialisation) {
emConfigurator->Clear();
firstParticle = aParticle;
}
if(startInitialisation) {
++run;
if(1 < verbose) {
G4cout << "===== G4LossTableManager::SlavePhysicsTable() for run "
<< run << " =====" << G4endl;
}
if(atomDeexcitation) {
atomDeexcitation->InitialiseAtomicDeexcitation();
}
currentParticle = 0;
startInitialisation = false;
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) {
tables_are_built[i] = false;
} else {
tables_are_built[i] = true;
part_vector[i] = 0;
}
}
}
all_tables_are_built= true;
for (G4int i=0; i<n_loss; ++i) {
if(p == loss_vector[i]) {
tables_are_built[i] = true;
isActive[i] = true;
/*
const G4ProcessManager* pm = p->GetProcessManager();
isActive[i] = false;
if(pm) { isActive[i] = pm->GetProcessActivation(p); }
*/
part_vector[i] = p->Particle();
base_part_vector[i] = p->BaseParticle();
dedx_vector[i] = p->DEDXTable();
range_vector[i] = p->RangeTableForLoss();
inv_range_vector[i] = p->InverseRangeTable();
if(0 == run && p->IsIonisationProcess()) {
loss_map[part_vector[i]] = loss_vector[i];
}
if(1 < verbose) {
G4cout << i <<". "<< p->GetProcessName();
if(part_vector[i]) {
G4cout << " for " << part_vector[i]->GetParticleName();
}
G4cout << " active= " << isActive[i]
<< " table= " << tables_are_built[i]
<< " isIonisation= " << p->IsIonisationProcess()
<< G4endl;
}
break;
} else if(!tables_are_built[i]) {
all_tables_are_built = false;
}
}
// Set run time parameters
SetParameters(aParticle, p);
if(1 < verbose) {
G4cout << "### G4LossTableManager::SlavePhysicsTable end"
<< G4endl;
}
if(all_tables_are_built) {
if(1 < verbose) {
G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
<< run << " %%%%%" << G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::BuildPhysicsTable(
const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(1 < verbose) {
G4cout << "### G4LossTableManager::BuildDEDXTable() is requested for "
G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
<< aParticle->GetParticleName()
<< " and process " << p->GetProcessName() << G4endl;
}
// clear configurator
if(0 == run && startInitialisation) {
if(-1 == run && startInitialisation) {
emConfigurator->Clear();
firstParticle = aParticle;
}
if(startInitialisation && atomDeexcitation) {
atomDeexcitation->InitialiseAtomicDeexcitation();
if(startInitialisation) {
++run;
if(1 < verbose) {
G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
<< run << " =====" << G4endl;
}
if(atomDeexcitation) {
atomDeexcitation->InitialiseAtomicDeexcitation();
}
currentParticle = 0;
startInitialisation = false;
all_tables_are_built= true;
}
startInitialisation = false;
// initialisation before any table is built
if ( aParticle == firstParticle ) {
all_tables_are_built = true;
if(1 < verbose) {
G4cout << "### G4LossTableManager start initilisation for first particle "
@@ -496,13 +634,19 @@ void G4LossTableManager::BuildPhysicsTable(
G4VEnergyLossProcess* el = loss_vector[i];
if(el) {
const G4ProcessManager* pm = el->GetProcessManager();
isActive[i] = true;
/*
const G4ProcessManager* pm = el->GetProcessManager();
isActive[i] = false;
if(pm) { isActive[i] = pm->GetProcessActivation(el); }
if(0 == run) { base_part_vector[i] = el->BaseParticle(); }
*/
base_part_vector[i] = el->BaseParticle();
tables_are_built[i] = false;
all_tables_are_built= false;
if(!isActive[i]) { el->SetIonisation(false); }
if(!isActive[i]) {
el->SetIonisation(false);
tables_are_built[i] = true;
}
if(1 < verbose) {
G4cout << i <<". "<< el->GetProcessName();
@@ -513,17 +657,17 @@ void G4LossTableManager::BuildPhysicsTable(
<< " table= " << tables_are_built[i]
<< " isIonisation= " << el->IsIonisationProcess();
if(base_part_vector[i]) {
G4cout << " base particle " << base_part_vector[i]->GetParticleName();
G4cout << " base particle "
<< base_part_vector[i]->GetParticleName();
}
G4cout << G4endl;
}
} else {
tables_are_built[i] = true;
part_vector[i] = 0;
isActive[i] = false;
}
}
++run;
currentParticle = 0;
}
// Set run time parameters
@@ -538,23 +682,25 @@ void G4LossTableManager::BuildPhysicsTable(
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;
G4cout << "### Build Table for " << p->GetProcessName()
<< " and " << curr_part->GetParticleName() << 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(0 == run && p->IsIonisationProcess()) { loss_map[aParticle] = p; }
if(1 < verbose) {
G4cout << "### G4LossTableManager::BuildDEDXTable end: "
G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
<< "all_tables_are_built= " << all_tables_are_built
<< G4endl;
if(all_tables_are_built) {
G4cout << "### All dEdx and Range tables are built #####" << G4endl;
}
if(all_tables_are_built) {
if(1 < verbose) {
G4cout << "%%%%% All dEdx and Range tables are built for master run= "
<< run << " %%%%%" << G4endl;
}
}
}
@@ -562,13 +708,11 @@ void G4LossTableManager::BuildPhysicsTable(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
G4VEnergyLossProcess* base_proc)
G4VEnergyLossProcess* base_proc)
{
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 (!tables_are_built[j] && part == base_part_vector[j]) {
tables_are_built[j] = true;
@@ -581,7 +725,11 @@ void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
proc->SetLambdaTable(base_proc->LambdaTable());
proc->SetSubLambdaTable(base_proc->SubLambdaTable());
proc->SetIonisation(base_proc->IsIonisationProcess());
loss_map[part_vector[j]] = proc;
if(proc->IsIonisationProcess()) {
range_vector[j] = base_proc->RangeTableForLoss();
inv_range_vector[j] = base_proc->InverseRangeTable();
loss_map[part_vector[j]] = proc;
}
if (1 < verbose) {
G4cout << "For " << proc->GetProcessName()
<< " for " << part_vector[j]->GetParticleName()
@@ -619,13 +767,12 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
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]) ||
!em || (em && !isActive[iem]) ) {
if ((p->IsIonisationProcess() && isActive[i]) || !em) {
em = p;
iem= i;
}
dedx = p->BuildDEDXTable(fRestricted);
// G4cout << "Build DEDX table for " << aParticle->GetParticleName()
//G4cout << "Build DEDX table for " << aParticle->GetParticleName()
// << " " << dedx << " " << dedx->length() << G4endl;
p->SetDEDXTable(dedx,fRestricted);
t_list.push_back(dedx);
@@ -651,14 +798,25 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
<< G4endl;
}
dedx = em->IonisationTable();
dedx = em->DEDXTable();
em->SetIonisation(true);
if (1 < n_dedx) {
em->SetDEDXTable(dedx, fIsIonisation);
dedx = 0;
dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
tableBuilder->BuildDEDXTable(dedx, t_list);
em->SetDEDXTable(dedx, fRestricted);
}
/*
if(2==run && "e-" == aParticle->GetParticleName()) {
G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
G4cout << (*dedx) << G4endl;
G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
}
*/
dedx_vector[iem] = dedx;
G4PhysicsTable* range = em->RangeTableForLoss();
@@ -669,9 +827,8 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
inv_range_vector[iem] = invrange;
G4bool flag = em->IsIonisationProcess();
tableBuilder->BuildRangeTable(dedx, range, flag);
tableBuilder->BuildInverseRangeTable(range, invrange, flag);
tableBuilder->BuildRangeTable(dedx, range, true);
tableBuilder->BuildInverseRangeTable(range, invrange, true);
// if(1<verbose) G4cout << *dedx << G4endl;
@@ -685,14 +842,14 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
for (i=0; i<n_dedx; ++i) {
p = loss_list[i];
p->SetIonisation(false);
if(p != em) { p->SetIonisation(false); }
p->SetLambdaTable(p->BuildLambdaTable(fRestricted));
if (0 < nSubRegions) {
dedx = p->BuildDEDXTable(fSubRestricted);
p->SetDEDXTable(dedx,fSubRestricted);
listSub.push_back(dedx);
p->SetSubLambdaTable(p->BuildLambdaTable(fSubRestricted));
if(p != em) em->AddCollaborativeProcess(p);
if(p != em) { em->AddCollaborativeProcess(p); }
}
if(buildCSDARange) {
dedx = p->BuildDEDXTable(fTotal);
@@ -720,14 +877,11 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
em->SetDEDXTable(dedxCSDA,fTotal);
}
G4PhysicsTable* rCSDA = em->CSDARangeTable();
if(!rCSDA) rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA);
tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, flag);
if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, true);
em->SetCSDARangeTable(rCSDA);
}
em->SetIonisation(true);
loss_map[aParticle] = em;
if (1 < verbose) {
G4cout << "G4LossTableManager::BuildTables: Tables are built for "
<< aParticle->GetParticleName()
@@ -751,7 +905,7 @@ void G4LossTableManager::ParticleHaveNoLoss(
{
G4ExceptionDescription ed;
ed << "Energy loss process not found for " << aParticle->GetParticleName()
<< " !" << G4endl;
<< " !";
G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
FatalException, ed);
@@ -968,7 +1122,9 @@ void
G4LossTableManager::SetParameters(const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(stepFunctionActive) { p->SetStepFunction(maxRangeVariation, maxFinalStep); }
if(stepFunctionActive) {
p->SetStepFunction(maxRangeVariation, maxFinalStep);
}
if(integralActive) { p->SetIntegral(integral); }
if(minEnergyActive) { p->SetMinKinEnergy(minKinEnergy); }
if(maxEnergyActive) { p->SetMaxKinEnergy(maxKinEnergy); }
@@ -1031,6 +1187,13 @@ G4bool G4LossTableManager::SplineFlag() const
return splineFlag;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4bool G4LossTableManager::IsMaster() const
{
return isMaster;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4LossTableManager::SetBremsstrahlungTh(G4double val)
@@ -1134,7 +1297,11 @@ G4LossTableManager::GetEnergyLossProcess(const G4ParticleDefinition *aParticle)
currentLoss = (*pos).second;
} else {
currentLoss = 0;
//ParticleHaveNoLoss(aParticle);
if(aParticle->GetParticleType() == "nucleus") {
if ((pos = loss_map.find(theGenericIon)) != loss_map.end()) {
currentLoss = (*pos).second;
}
}
}
}
return currentLoss;
@@ -1149,8 +1316,6 @@ G4double G4LossTableManager::GetDEDX(const G4ParticleDefinition *aParticle,
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x = 0.0;
if(currentLoss) { x = currentLoss->GetDEDX(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetDEDX(currentParticle,
kineticEnergy,couple,false); }
return x;
}
@@ -1180,16 +1345,14 @@ G4double G4LossTableManager::GetCSDARange(const G4ParticleDefinition *aParticle,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double
G4LossTableManager::GetRangeFromRestricteDEDX(const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
G4double G4LossTableManager::GetRangeFromRestricteDEDX(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
G4double x = DBL_MAX;
if(currentLoss) { x = currentLoss->GetRangeForLoss(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetRange(currentParticle,kineticEnergy,
couple,false); }
return x;
}
@@ -1200,10 +1363,8 @@ G4double G4LossTableManager::GetRange(const G4ParticleDefinition *aParticle,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
G4double x = DBL_MAX;
if(currentLoss) { x = currentLoss->GetRange(kineticEnergy, couple); }
else { x = G4EnergyLossTables::GetRange(currentParticle,kineticEnergy,
couple,false); }
return x;
}
@@ -1214,18 +1375,17 @@ G4double G4LossTableManager::GetEnergy(const G4ParticleDefinition *aParticle,
const G4MaterialCutsCouple *couple)
{
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
G4double x;
G4double x = 0;
if(currentLoss) { x = currentLoss->GetKineticEnergy(range, couple); }
else { x = G4EnergyLossTables::GetPreciseEnergyFromRange(currentParticle,range,
couple,false); }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossTableManager::GetDEDXDispersion(const G4MaterialCutsCouple *couple,
const G4DynamicParticle* dp,
G4double& length)
G4double G4LossTableManager::GetDEDXDispersion(
const G4MaterialCutsCouple *couple,
const G4DynamicParticle* dp,
G4double& length)
{
const G4ParticleDefinition* aParticle = dp->GetParticleDefinition();
if(aParticle != currentParticle) { GetEnergyLossProcess(aParticle); }
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VAtomDeexcitation.cc 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -59,9 +59,14 @@
#include "G4ElementVector.hh"
#include "Randomize.hh"
#include "G4VParticleChange.hh"
#include "G4PhysicsModelCatalog.hh"
#include "G4Gamma.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4VAtomDeexcitation::pixeIDg = -1;
G4int G4VAtomDeexcitation::pixeIDe = -1;
G4VAtomDeexcitation::G4VAtomDeexcitation(const G4String& modname,
const G4String& pname)
: lowestKinEnergy(keV), verbose(1), name(modname), namePIXE(pname),
@@ -69,6 +74,11 @@ G4VAtomDeexcitation::G4VAtomDeexcitation(const G4String& modname,
{
vdyn.reserve(5);
theCoupleTable = 0;
G4String gg = "gammaPIXE";
G4String ee = "e-PIXE";
if(pixeIDg < 0) { pixeIDg = G4PhysicsModelCatalog::Register(gg); }
if(pixeIDe < 0) { pixeIDe = G4PhysicsModelCatalog::Register(ee); }
gamma = G4Gamma::Gamma();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -228,16 +238,18 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
const G4Material* material = preStep->GetMaterial();
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
const G4double* theAtomNumDensityVector =
material->GetVecNbOfAtomsPerVolume();
G4int nelm = material->GetNumberOfElements();
// loop over deexcitations
for(G4int i=0; i<nelm; ++i) {
G4int Z = G4lrint((*theElementVector)[i]->GetZ());
if(activeZ[Z] && Z < 93) {
G4int nshells = std::min(9,(*theElementVector)[i]->GetNbOfAtomicShells());
G4int nshells =
std::min(9,(*theElementVector)[i]->GetNbOfAtomicShells());
G4double rho = truelength*theAtomNumDensityVector[i];
//G4cout << " Z " << Z <<" is active x(mm)= " << truelength/mm << G4endl;
//G4cout<<" Z "<< Z <<" is active x(mm)= " << truelength/mm << G4endl;
for(G4int ii=0; ii<nshells; ++ii) {
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(ii);
const G4AtomicShell* shell = GetAtomicShell(Z, as);
@@ -247,7 +259,7 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
if(eLossMax > bindingEnergy) {
G4double sig = rho*
GetShellIonisationCrossSectionPerAtom(part, Z, as, ekin, material);
GetShellIonisationCrossSectionPerAtom(part, Z, as, ekin, material);
// mfp is mean free path in units of step size
if(sig > 0.0) {
@@ -273,6 +285,14 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
if(eLossMax >= e) {
eLossMax -= e;
G4Track* t = new G4Track(dp, time, r);
// defined secondary type
if(dp->GetDefinition() == gamma) {
t->SetCreatorModelIndex(pixeIDg);
} else {
t->SetCreatorModelIndex(pixeIDe);
}
tracks.push_back(t);
} else {
delete dp;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmAngularDistribution.cc 73847 2013-09-13 14:32:39Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -59,4 +59,13 @@ G4VEmAngularDistribution::G4VEmAngularDistribution(const G4String& name)
G4VEmAngularDistribution::~G4VEmAngularDistribution()
{}
G4ThreeVector& G4VEmAngularDistribution::SampleDirectionForShell(
const G4DynamicParticle* dp,
G4double finalTotalEnergy,
G4int Z, G4int,
const G4Material* mat)
{
return SampleDirection(dp, finalTotalEnergy, Z, mat);
}
//
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmFluctuationModel.cc 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -55,12 +55,13 @@
G4VEmFluctuationModel::G4VEmFluctuationModel(const G4String& nam)
: name(nam)
{
G4LossTableManager::Instance()->Register(this);
fManager = G4LossTableManager::Instance();
fManager->Register(this);
}
G4VEmFluctuationModel::~G4VEmFluctuationModel()
{
G4LossTableManager::Instance()->DeRegister(this);
fManager->DeRegister(this);
}
void G4VEmFluctuationModel::InitialiseMe(const G4ParticleDefinition*)
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmModel.cc 76333 2013-11-08 14:31:50Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -54,40 +54,52 @@
#include "G4ProductionCutsTable.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4SystemOfUnits.hh"
#include "G4Log.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4double log106 = 6*G4Log(10.);
G4VEmModel::G4VEmModel(const G4String& nam):
flucModel(0),anglModel(0), name(nam), lowLimit(0.1*CLHEP::keV),
highLimit(100.0*CLHEP::TeV),eMinActive(0.0),eMaxActive(DBL_MAX),
polarAngleLimit(CLHEP::pi),secondaryThreshold(DBL_MAX),
theLPMflag(false),flagDeexcitation(false),flagForceBuildTable(false),
pParticleChange(0),xSectionTable(0),theDensityFactor(0),theDensityIdx(0),
fCurrentCouple(0),fCurrentElement(0),
isMaster(true),fElementData(0),pParticleChange(0),xSectionTable(0),
theDensityFactor(0),theDensityIdx(0),fCurrentCouple(0),fCurrentElement(0),
nsec(5)
{
xsec.resize(nsec);
nSelectors = 0;
G4LossTableManager::Instance()->Register(this);
elmSelectors = 0;
localElmSelectors = true;
localTable = true;
useAngularGenerator = false;
idxTable = 0;
fManager = G4LossTableManager::Instance();
fManager->Register(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VEmModel::~G4VEmModel()
{
G4LossTableManager::Instance()->DeRegister(this);
G4int n = elmSelectors.size();
if(n > 0) {
for(G4int i=0; i<n; ++i) {
delete elmSelectors[i];
if(localElmSelectors) {
if(nSelectors > 0) {
for(G4int i=0; i<nSelectors; ++i) {
delete (*elmSelectors)[i];
}
}
delete elmSelectors;
}
delete anglModel;
if(xSectionTable) {
xSectionTable->clearAndDestroy();
delete xSectionTable;
}
if(localTable) { delete xSectionTable; }
fManager->DeRegister(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -120,60 +132,107 @@ G4ParticleChangeForGamma* G4VEmModel::GetParticleChangeForGamma()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p,
void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* part,
const G4DataVector& cuts)
{
// initialise before run
G4LossTableManager* man = G4LossTableManager::Instance();
// using spline for element selectors should be investigated in details
// because small number of points may provide biased results
// large number of points requires significant increase of memory
//G4bool spline = man->SplineFlag();
//G4bool spline = fManager->SplineFlag();
G4bool spline = false;
//G4cout << "IES: for " << GetName() << " Emin(MeV)= " << lowLimit/MeV
// << " Emax(MeV)= " << highLimit/MeV << G4endl;
// two times less bins because probability functon is normalized
// so correspondingly is more smooth
G4int nbins = G4int(man->GetNumberOfBinsPerDecade()
* std::log10(highLimit/lowLimit) / 6.0);
if(nbins < 5) { nbins = 5; }
if(highLimit <= lowLimit) { return; }
G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
G4int numOfCouples = theCoupleTable->GetTableSize();
// prepare vector
if(!elmSelectors) {
elmSelectors = new std::vector<G4EmElementSelector*>;
}
if(numOfCouples > nSelectors) {
elmSelectors.resize(numOfCouples,0);
for(G4int i=nSelectors; i<numOfCouples; ++i) {
elmSelectors->push_back(0);
}
nSelectors = numOfCouples;
}
// initialise vector
for(G4int i=0; i<numOfCouples; ++i) {
// no need in element selectors for infionite cuts
if(cuts[i] == DBL_MAX) { continue; }
fCurrentCouple = theCoupleTable->GetMaterialCutsCouple(i);
const G4Material* material = fCurrentCouple->GetMaterial();
G4int idx = fCurrentCouple->GetIndex();
// selector already exist check if should be deleted
G4bool create = true;
if(elmSelectors[i]) {
if(material == elmSelectors[i]->GetMaterial()) { create = false; }
else { delete elmSelectors[i]; }
if((*elmSelectors)[i]) {
if(material == ((*elmSelectors)[i])->GetMaterial()) { create = false; }
else { delete (*elmSelectors)[i]; }
}
if(create) {
elmSelectors[i] = new G4EmElementSelector(this,material,nbins,
lowLimit,highLimit,spline);
G4double emin = std::max(lowLimit,
MinPrimaryEnergy(material, part, cuts[i]));
G4double emax = std::max(highLimit, 10*emin);
G4int nbins = G4int(fManager->GetNumberOfBinsPerDecade()
*G4Log(emax/emin)/log106);
if(nbins < 3) { nbins = 3; }
(*elmSelectors)[i] = new G4EmElementSelector(this,material,nbins,
emin,emax,spline);
}
elmSelectors[i]->Initialise(p, cuts[idx]);
//elmSelectors[i]->Dump(p);
((*elmSelectors)[i])->Initialise(part, cuts[i]);
/*
G4cout << "G4VEmModel::InitialiseElmSelectors i= " << i
<< " idx= " << fCurrentCouple->GetIndex()
<< " " << part->GetParticleName()
<< " for " << GetName() << " cut= " << cuts[i]
<< " " << (*elmSelectors)[i] << G4endl;
((*elmSelectors)[i])->Dump(part);
*/
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel*)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::InitialiseForMaterial(const G4ParticleDefinition* part,
const G4Material* material)
{
if(material) {
const G4ElementVector* theElementVector = material->GetElementVector();
G4int n = material->GetNumberOfElements();
for(G4int i=0; i<n; ++i) {
G4int Z = G4lrint(((*theElementVector)[i])->GetZ());
InitialiseForElement(part, Z);
}
} else {
//G4cout << "G4VEmModel::InitialiseForMaterial for " << GetName();
//if(part) { G4cout << " and " << part->GetParticleName(); }
//G4cout << " with no material" << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::InitialiseForElement(const G4ParticleDefinition*, G4int)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::ComputeDEDXPerVolume(const G4Material*,
const G4ParticleDefinition*,
G4double,G4double)
@@ -192,7 +251,8 @@ G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
SetupForMaterial(p, material, ekin);
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
const G4double* theAtomNumDensityVector =
material->GetVecNbOfAtomsPerVolume();
G4int nelm = material->GetNumberOfElements();
if(nelm > nsec) {
xsec.resize(nelm);
@@ -224,7 +284,7 @@ const G4Element* G4VEmModel::SelectRandomAtom(const G4Material* material,
fCurrentElement = (*theElementVector)[n];
if (n > 0) {
G4double x = G4UniformRand()*
G4VEmModel::CrossSectionPerVolume(material,pd,kinEnergy,tcut,tmax);
G4VEmModel::CrossSectionPerVolume(material,pd,kinEnergy,tcut,tmax);
for(G4int i=0; i<n; ++i) {
if (x <= xsec[i]) {
fCurrentElement = (*theElementVector)[i];
@@ -286,14 +346,23 @@ void G4VEmModel::CorrectionsAlongStep(const G4MaterialCutsCouple*,
G4double G4VEmModel::Value(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p, G4double e)
{
fCurrentCouple = couple;
SetCurrentCouple(couple);
return e*e*CrossSectionPerVolume(couple->GetMaterial(),p,e,0.0,DBL_MAX);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::MinPrimaryEnergy(const G4Material*,
const G4ParticleDefinition*)
const G4ParticleDefinition*,
G4double)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*)
{
return 0.0;
}
@@ -323,15 +392,16 @@ G4VEmModel::SetParticleChange(G4VParticleChange* p, G4VEmFluctuationModel* f)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4VEmModel::SetCrossSectionTable(G4PhysicsTable* p)
void G4VEmModel::SetCrossSectionTable(G4PhysicsTable* p, G4bool isLocal)
{
if(p != xSectionTable) {
if(xSectionTable) {
if(xSectionTable && localTable) {
xSectionTable->clearAndDestroy();
delete xSectionTable;
}
xSectionTable = p;
}
localTable = isLocal;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VEmProcess.cc 76957 2013-11-19 15:07:20Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -83,6 +83,7 @@
#include "G4PhysicsTableHelper.hh"
#include "G4EmBiasingManager.hh"
#include "G4GenericIon.hh"
#include "G4Log.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -125,17 +126,25 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
thePositron = G4Positron::Positron();
pParticleChange = &fParticleChange;
fParticleChange.SetSecondaryWeightByProcess(true);
secParticles.reserve(5);
preStepLambda = 0.0;
mfpKinEnergy = DBL_MAX;
idxLambda = idxLambdaPrim = 0;
modelManager = new G4EmModelManager();
biasManager = 0;
biasFlag = false;
weightFlag = false;
(G4LossTableManager::Instance())->Register(this);
warn = 0;
lManager = G4LossTableManager::Instance();
lManager->Register(this);
secID = fluoID = augerID = biasID = -1;
mainSecondaries = 100;
if("phot" == GetProcessName() || "compt" == GetProcessName()) {
mainSecondaries = 1;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -146,18 +155,14 @@ G4VEmProcess::~G4VEmProcess()
G4cout << "G4VEmProcess destruct " << GetProcessName()
<< " " << this << " " << theLambdaTable <<G4endl;
}
Clear();
if(theLambdaTable) {
theLambdaTable->clearAndDestroy();
if(lManager->IsMaster()) {
delete theLambdaTable;
}
if(theLambdaTablePrim) {
theLambdaTablePrim->clearAndDestroy();
delete theLambdaTablePrim;
}
delete modelManager;
delete biasManager;
(G4LossTableManager::Instance())->DeRegister(this);
lManager->DeRegister(this);
//G4cout << "G4VEmProcess removed " << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -167,6 +172,7 @@ void G4VEmProcess::Clear()
currentCouple = 0;
preStepLambda = 0.0;
mfpKinEnergy = DBL_MAX;
idxLambda = idxLambdaPrim = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -189,36 +195,7 @@ void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* p,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetModel(G4VEmModel* p, G4int index)
{
++warn;
if(warn < 10) {
G4cout << "### G4VEmProcess::SetModel is obsolete method and will be "
<< "removed for the next release." << G4endl;
G4cout << " Please, use SetEmModel" << G4endl;
}
G4int n = emModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) {emModels.push_back(0);} }
emModels[index] = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel* G4VEmProcess::Model(G4int index)
{
if(warn < 10) {
G4cout << "### G4VEmProcess::Model is obsolete method and will be "
<< "removed for the next release." << G4endl;
G4cout << " Please, use EmModel" << G4endl;
}
G4VEmModel* p = 0;
if(index >= 0 && index < G4int(emModels.size())) { p = emModels[index]; }
return p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetEmModel(G4VEmModel* p, G4int index)
void G4VEmProcess::SetEmModel(G4VEmModel* p, G4int index)
{
G4int n = emModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) {emModels.push_back(0);} }
@@ -227,7 +204,7 @@ void G4VEmProcess::SetEmModel(G4VEmModel* p, G4int index)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel* G4VEmProcess::EmModel(G4int index)
G4VEmModel* G4VEmProcess::EmModel(G4int index) const
{
G4VEmModel* p = 0;
if(index >= 0 && index < G4int(emModels.size())) { p = emModels[index]; }
@@ -244,7 +221,7 @@ void G4VEmProcess::UpdateEmModel(const G4String& nam,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver)
G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver) const
{
return modelManager->GetModel(idx, ver);
}
@@ -253,6 +230,8 @@ G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver)
void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
G4bool isMaster = false;
if(GetMasterProcess() == this) { isMaster = true; }
if(!particle) { SetParticle(&part); }
if(part.GetParticleType() == "nucleus" &&
@@ -276,65 +255,80 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
<< G4endl;
}
G4LossTableManager* man = G4LossTableManager::Instance();
G4LossTableBuilder* bld = man->GetTableBuilder();
if(particle != &part) { return; }
man->PreparePhysicsTable(&part, this);
G4LossTableBuilder* bld = lManager->GetTableBuilder();
if(particle == &part) {
Clear();
InitialiseProcess(particle);
lManager->PreparePhysicsTable(&part, this, isMaster);
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t n = theCoupleTable->GetTableSize();
Clear();
InitialiseProcess(particle);
theEnergyOfCrossSectionMax.resize(n, 0.0);
theCrossSectionMax.resize(n, DBL_MAX);
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t n = theCoupleTable->GetTableSize();
// initialisation of models
numberOfModels = modelManager->NumberOfModels();
for(G4int i=0; i<numberOfModels; ++i) {
G4VEmModel* mod = modelManager->GetModel(i);
if(0 == i) { currentModel = mod; }
mod->SetPolarAngleLimit(polarAngleLimit);
if(mod->HighEnergyLimit() > maxKinEnergy) {
mod->SetHighEnergyLimit(maxKinEnergy);
}
}
theEnergyOfCrossSectionMax.resize(n, 0.0);
theCrossSectionMax.resize(n, DBL_MAX);
if(man->AtomDeexcitation()) { modelManager->SetFluoFlag(true); }
theCuts = modelManager->Initialise(particle,secondaryParticle,
2.,verboseLevel);
theCutsGamma = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
theCutsElectron = theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut);
theCutsPositron = theCoupleTable->GetEnergyCutsVector(idxG4PositronCut);
// prepare tables
if(buildLambdaTable){
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
bld->InitialiseBaseMaterials(theLambdaTable);
}
// high energy table
if(minKinEnergyPrim < maxKinEnergy){
theLambdaTablePrim =
G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTablePrim);
bld->InitialiseBaseMaterials(theLambdaTablePrim);
}
// forced biasing
if(biasManager) {
biasManager->Initialise(part,GetProcessName(),verboseLevel);
biasFlag = false;
// initialisation of models
numberOfModels = modelManager->NumberOfModels();
for(G4int i=0; i<numberOfModels; ++i) {
G4VEmModel* mod = modelManager->GetModel(i);
if(0 == i) { currentModel = mod; }
mod->SetPolarAngleLimit(polarAngleLimit);
mod->SetMasterThread(isMaster);
if(mod->HighEnergyLimit() > maxKinEnergy) {
mod->SetHighEnergyLimit(maxKinEnergy);
}
}
theDensityFactor = bld->GetDensityFactors();
theDensityIdx = bld->GetCoupleIndexes();
if(lManager->AtomDeexcitation()) { modelManager->SetFluoFlag(true); }
theCuts = modelManager->Initialise(particle,secondaryParticle,
2.,verboseLevel);
theCutsGamma = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
theCutsElectron = theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut);
theCutsPositron = theCoupleTable->GetEnergyCutsVector(idxG4PositronCut);
// prepare tables
if(buildLambdaTable && isMaster){
theLambdaTable =
G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
bld->InitialiseBaseMaterials(theLambdaTable);
}
// high energy table
if(isMaster && minKinEnergyPrim < maxKinEnergy){
theLambdaTablePrim =
G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTablePrim);
bld->InitialiseBaseMaterials(theLambdaTablePrim);
}
// forced biasing
if(biasManager) {
biasManager->Initialise(part,GetProcessName(),verboseLevel);
biasFlag = false;
}
// defined ID of secondary particles
if(isMaster) {
G4String nam1 = GetProcessName();
G4String nam2 = nam1 + "_fluo" ;
G4String nam3 = nam1 + "_auger";
G4String nam4 = nam1 + "_split";
secID = G4PhysicsModelCatalog::Register(nam1);
fluoID = G4PhysicsModelCatalog::Register(nam2);
augerID = G4PhysicsModelCatalog::Register(nam3);
biasID = G4PhysicsModelCatalog::Register(nam4);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
{
const G4VEmProcess* masterProc = 0;
if(GetMasterProcess() != this) {
masterProc = static_cast<const G4VEmProcess*>(GetMasterProcess());
}
G4String num = part.GetParticleName();
if(1 < verboseLevel) {
G4cout << "G4VEmProcess::BuildPhysicsTable() for "
@@ -344,10 +338,40 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
<< G4endl;
}
(G4LossTableManager::Instance())->BuildPhysicsTable(particle);
if(particle == &part) {
if(buildLambdaTable || minKinEnergyPrim < maxKinEnergy) {
BuildLambdaTable();
G4LossTableBuilder* bld = lManager->GetTableBuilder();
// worker initialisation
if(masterProc) {
theLambdaTable = masterProc->LambdaTable();
theLambdaTablePrim = masterProc->LambdaTablePrim();
if(theLambdaTable) {
bld->InitialiseBaseMaterials(theLambdaTable);
} else if(theLambdaTablePrim) {
bld->InitialiseBaseMaterials(theLambdaTablePrim);
}
theDensityFactor = bld->GetDensityFactors();
theDensityIdx = bld->GetCoupleIndexes();
if(theLambdaTable) { FindLambdaMax(); }
// local initialisation of models
G4bool printing = true;
numberOfModels = modelManager->NumberOfModels();
for(G4int i=0; i<numberOfModels; ++i) {
G4VEmModel* mod = GetModelByIndex(i, printing);
G4VEmModel* mod0= masterProc->GetModelByIndex(i, printing);
mod->InitialiseLocal(particle, mod0);
}
// master thread
} else {
theDensityFactor = bld->GetDensityFactors();
theDensityIdx = bld->GetCoupleIndexes();
if(buildLambdaTable || minKinEnergyPrim < maxKinEnergy) {
BuildLambdaTable();
}
}
}
// explicitly defined printout by particle name
@@ -360,8 +384,7 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
num == "alpha" || num == "anti_proton" ||
num == "GenericIon")))
{
particle = &part;
PrintInfoDefinition();
PrintInfoProcess(part);
}
if(1 < verboseLevel) {
@@ -388,19 +411,15 @@ void G4VEmProcess::BuildLambdaTable()
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
G4LossTableBuilder* bld = (G4LossTableManager::Instance())->GetTableBuilder();
G4LossTableBuilder* bld = lManager->GetTableBuilder();
G4PhysicsLogVector* aVector = 0;
G4PhysicsLogVector* bVector = 0;
G4PhysicsLogVector* aVectorPrim = 0;
G4PhysicsLogVector* bVectorPrim = 0;
G4double scale = 1.0;
G4double scale = G4Log(maxKinEnergy/minKinEnergy);
G4double emax1 = maxKinEnergy;
if(startFromNull || minKinEnergyPrim < maxKinEnergy ) {
scale = std::log(maxKinEnergy/minKinEnergy);
if(minKinEnergyPrim < maxKinEnergy) { emax1 = minKinEnergyPrim; }
}
if(minKinEnergyPrim < maxKinEnergy) { emax1 = minKinEnergyPrim; }
for(size_t i=0; i<numOfCouples; ++i) {
@@ -414,29 +433,21 @@ void G4VEmProcess::BuildLambdaTable()
if(buildLambdaTable) {
delete (*theLambdaTable)[i];
G4bool startNull = startFromNull;
// if start from zero then change the scale
if(startFromNull || minKinEnergyPrim < maxKinEnergy) {
G4double emin = MinPrimaryEnergy(particle,couple->GetMaterial());
if(emin < minKinEnergy) {
emin = minKinEnergy;
startNull = false;
G4double emin = minKinEnergy;
G4bool startNull = false;
if(startFromNull) {
G4double e = MinPrimaryEnergy(particle,couple->GetMaterial());
if(e >= emin) {
emin = e;
startNull = true;
}
G4double emax = emax1;
if(emax <= emin) { emax = 2*emin; }
G4int bin =
G4lrint(nLambdaBins*std::log(emax/emin)/scale);
if(bin < 3) { bin = 3; }
aVector = new G4PhysicsLogVector(emin, emax, bin);
// start not from zero
} else if(!bVector) {
aVector =
new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
bVector = aVector;
} else {
aVector = new G4PhysicsLogVector(*bVector);
}
G4double emax = emax1;
if(emax <= emin) { emax = 2*emin; }
G4int bin = G4lrint(nLambdaBins*G4Log(emax/emin)/scale);
if(bin < 3) { bin = 3; }
aVector = new G4PhysicsLogVector(emin, emax, bin);
aVector->SetSpline(splineFlag);
modelManager->FillLambdaVector(aVector, couple, startNull);
if(splineFlag) { aVector->FillSecondDerivatives(); }
@@ -449,7 +460,7 @@ void G4VEmProcess::BuildLambdaTable()
// start not from zero
if(!bVectorPrim) {
G4int bin =
G4lrint(nLambdaBins*std::log(maxKinEnergy/minKinEnergyPrim)/scale);
G4lrint(nLambdaBins*G4Log(maxKinEnergy/minKinEnergyPrim)/scale);
if(bin < 3) { bin = 3; }
aVectorPrim =
new G4PhysicsLogVector(minKinEnergyPrim, maxKinEnergy, bin);
@@ -462,7 +473,8 @@ void G4VEmProcess::BuildLambdaTable()
modelManager->FillLambdaVector(aVectorPrim, couple, false,
fIsCrossSectionPrim);
aVectorPrim->FillSecondDerivatives();
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTablePrim, i, aVectorPrim);
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTablePrim, i,
aVectorPrim);
}
}
}
@@ -478,11 +490,11 @@ void G4VEmProcess::BuildLambdaTable()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::PrintInfoDefinition()
void G4VEmProcess::PrintInfoProcess(const G4ParticleDefinition& part)
{
if(verboseLevel > 0) {
G4cout << G4endl << GetProcessName() << ": for "
<< particle->GetParticleName();
<< part.GetParticleName();
if(integral) { G4cout << ", integral: 1 "; }
if(applyCuts) { G4cout << ", applyCuts: 1 "; }
G4cout << " SubType= " << GetProcessSubType();;
@@ -566,12 +578,16 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
DefineMaterial(track.GetMaterialCutsCouple());
SelectModel(preStepKinEnergy, currentCoupleIndex);
if(!currentModel->IsActive(preStepKinEnergy)) { return x; }
if(!currentModel->IsActive(preStepKinEnergy)) {
currentInteractionLength = DBL_MAX;
return x;
}
// forced biasing only for primary particles
if(biasManager) {
if(0 == track.GetParentID()) {
if(biasFlag && biasManager->ForcedInteractionRegion(currentCoupleIndex)) {
if(biasFlag &&
biasManager->ForcedInteractionRegion(currentCoupleIndex)) {
return biasManager->GetStepLimit(currentCoupleIndex, previousStepSize);
}
}
@@ -595,16 +611,19 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
if (theNumberOfInteractionLengthLeft < 0.0) {
// beggining of tracking (or just after DoIt of this process)
ResetNumberOfInteractionLengthLeft();
// ResetNumberOfInteractionLengthLeft();
theNumberOfInteractionLengthLeft = -G4Log( G4UniformRand() );
theInitialNumberOfInteractionLength = theNumberOfInteractionLengthLeft;
} else if(currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft using previous step
theNumberOfInteractionLengthLeft -= previousStepSize/currentInteractionLength;
theNumberOfInteractionLengthLeft -=
previousStepSize/currentInteractionLength;
//SubtractNumberOfInteractionLengthLeft(previousStepSize);
if(theNumberOfInteractionLengthLeft < 0.) {
theNumberOfInteractionLengthLeft = 0.0;
//theNumberOfInteractionLengthLeft = perMillion;
}
}
@@ -696,16 +715,16 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
track.GetDynamicParticle(),
(*theCuts)[currentCoupleIndex]);
// bremsstrahlung splitting or Russian roulette
G4int num0 = secParticles.size();
// splitting or Russian roulette
if(biasManager) {
if(biasManager->SecondaryBiasingRegion(currentCoupleIndex)) {
G4double eloss = 0.0;
weight *= biasManager->ApplySecondaryBiasing(secParticles,
track, currentModel,
&fParticleChange,
eloss, currentCoupleIndex,
(*theCuts)[currentCoupleIndex],
step.GetPostStepPoint()->GetSafety());
weight *= biasManager->ApplySecondaryBiasing(
secParticles, track, currentModel, &fParticleChange, eloss,
currentCoupleIndex, (*theCuts)[currentCoupleIndex],
step.GetPostStepPoint()->GetSafety());
if(eloss > 0.0) {
eloss += fParticleChange.GetLocalEnergyDeposit();
fParticleChange.ProposeLocalEnergyDeposit(eloss);
@@ -719,6 +738,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
fParticleChange.SetNumberOfSecondaries(num);
G4double edep = fParticleChange.GetLocalEnergyDeposit();
G4double time = track.GetGlobalTime();
for (G4int i=0; i<num; ++i) {
if (secParticles[i]) {
@@ -743,12 +763,25 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
// added secondary if it is good
}
if (good) {
G4Track* t = new G4Track(dp, track.GetGlobalTime(), track.GetPosition());
G4Track* t = new G4Track(dp, time, track.GetPosition());
t->SetTouchableHandle(track.GetTouchableHandle());
t->SetWeight(weight);
pParticleChange->AddSecondary(t);
pParticleChange->AddSecondary(t);
// define type of secondary
if(i < mainSecondaries) { t->SetCreatorModelIndex(secID); }
else if(i < num0) {
if(p == theGamma) {
t->SetCreatorModelIndex(fluoID);
} else {
t->SetCreatorModelIndex(augerID);
}
} else {
t->SetCreatorModelIndex(biasID);
}
//G4cout << "Secondary(post step) has weight " << t->GetWeight()
// << ", Ekin= " << t->GetKineticEnergy()/MeV << " MeV" <<G4endl;
// << ", Ekin= " << t->GetKineticEnergy()/MeV << " MeV" <<G4endl;
} else {
delete dp;
edep += e;
@@ -801,7 +834,8 @@ G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
yes = theLambdaTablePrim->StorePhysicsTable(name,ascii);
if ( yes ) {
G4cout << "Physics table prim is stored for " << particle->GetParticleName()
G4cout << "Physics table prim is stored for "
<< particle->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
@@ -846,7 +880,7 @@ G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
<< filename << ">"
<< G4endl;
}
if((G4LossTableManager::Instance())->SplineFlag()) {
if(lManager->SplineFlag()) {
size_t n = theLambdaTable->length();
for(size_t i=0; i<n; ++i) {
if((* theLambdaTable)[i]) {
@@ -873,7 +907,7 @@ G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
<< filename << ">"
<< G4endl;
}
if((G4LossTableManager::Instance())->SplineFlag()) {
if(lManager->SplineFlag()) {
size_t n = theLambdaTablePrim->length();
for(size_t i=0; i<n; ++i) {
if((* theLambdaTablePrim)[i]) {
@@ -902,13 +936,13 @@ G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
// Cross section per atom is calculated
DefineMaterial(couple);
G4double cross = 0.0;
if(theLambdaTable) {
cross = (*theDensityFactor)[currentCoupleIndex]*
(((*theLambdaTable)[basedCoupleIndex])->Value(kineticEnergy));
if(buildLambdaTable && theLambdaTable) {
cross = GetCurrentLambda(kineticEnergy);
} else {
SelectModel(kineticEnergy, currentCoupleIndex);
cross = currentModel->CrossSectionPerVolume(currentMaterial,
currentParticle,kineticEnergy);
cross = fFactor*currentModel->CrossSectionPerVolume(currentMaterial,
currentParticle,
kineticEnergy);
}
if(cross < 0.0) { cross = 0.0; }
@@ -958,7 +992,7 @@ void G4VEmProcess::FindLambdaMax()
if(1 < verboseLevel) {
G4cout << "### G4VEmProcess::FindLambdaMax: "
<< particle->GetParticleName()
<< " and process " << GetProcessName() << G4endl;
<< " and process " << GetProcessName() << " " << G4endl;
}
size_t n = theLambdaTable->length();
G4PhysicsVector* pv;
@@ -1010,7 +1044,7 @@ G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple*)
{
G4PhysicsVector* v =
new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
v->SetSpline(lManager->SplineFlag());
return v;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VMscModel.cc 71484 2013-06-17 08:12:51Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -88,6 +88,7 @@ G4VMscModel::~G4VMscModel()
G4ParticleChangeForMSC*
G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition* p)
{
// recomputed for each new run
if(!safetyHelper) {
safetyHelper = G4TransportationManager::GetTransportationManager()
->GetSafetyHelper();
@@ -111,13 +112,19 @@ G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition* p)
// table is always built for low mass particles
} else if(p->GetPDGMass() < 4.5*GeV || ForceBuildTableFlag()) {
G4double emin = std::max(LowEnergyLimit(), LowEnergyActivationLimit());
G4double emax = std::min(HighEnergyLimit(), HighEnergyActivationLimit());
emin = std::max(emin, man->MinKinEnergy());
emax = std::min(emax, man->MaxKinEnergy());
idxTable = 0;
G4LossTableBuilder* builder = man->GetTableBuilder();
xSectionTable = builder->BuildTableForModel(xSectionTable, this, p,
emin, emax, true);
if(IsMaster()) {
G4double emin = std::max(LowEnergyLimit(), LowEnergyActivationLimit());
G4double emax = std::min(HighEnergyLimit(), HighEnergyActivationLimit());
emin = std::max(emin, man->MinKinEnergy());
emax = std::min(emax, man->MaxKinEnergy());
if(emin < emax) {
xSectionTable = builder->BuildTableForModel(xSectionTable, this, p,
emin, emax, true);
}
}
theDensityFactor = builder->GetDensityFactors();
theDensityIdx = builder->GetCoupleIndexes();
}
@@ -128,7 +135,7 @@ G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition* p)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ThreeVector&
G4VMscModel::SampleScattering(const G4DynamicParticle*, G4double)
G4VMscModel::SampleScattering(const G4ThreeVector&, G4double)
{
return fDisplacement;
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4VMultipleScattering.cc 78171 2013-12-04 13:22:18Z gunter $
//
// -------------------------------------------------------------------
//
@@ -55,6 +55,7 @@
// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
// 11-03-08 Set skin value does not effect step limit type (V.Ivanchenko)
// 24-06-09 Removed hidden bin in G4PhysicsVector (V.Ivanchenko)
// 04-06-13 Adoptation to MT mode (V.Ivanchenko)
//
// Class Description:
//
@@ -80,10 +81,14 @@
#include "G4GenericIon.hh"
#include "G4TransportationManager.hh"
#include "G4SafetyHelper.hh"
#include "G4ParticleTable.hh"
#include "G4ProcessVector.hh"
#include "G4ProcessManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType):
G4VMultipleScattering::G4VMultipleScattering(const G4String& name,
G4ProcessType):
G4VContinuousDiscreteProcess("msc", fElectromagnetic),
numberOfModels(0),
firstParticle(0),
@@ -99,8 +104,8 @@ G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType
SetProcessSubType(fMultipleScattering);
if("ionmsc" == name) { firstParticle = G4GenericIon::GenericIon(); }
geomMin = 1.e-6*CLHEP::mm;
lowestKinEnergy = 1*eV;
geomMin = 0.01*CLHEP::nm;
lowestKinEnergy = 10*eV;
// default limit on polar angle
polarAngleLimit = 0.0;
@@ -124,10 +129,12 @@ G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType
G4VMultipleScattering::~G4VMultipleScattering()
{
/*
if(1 < verboseLevel) {
G4cout << "G4VMultipleScattering destruct " << GetProcessName()
<< G4endl;
}
*/
delete modelManager;
emManager->DeRegister(this);
}
@@ -144,36 +151,6 @@ void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::SetModel(G4VMscModel* p, G4int index)
{
++warn;
if(warn < 10) {
G4cout << "### G4VMultipleScattering::SetModel is obsolete method "
<< "and will be removed for the next release." << G4endl;
G4cout << " Please, use SetEmModel" << G4endl;
}
G4int n = mscModels.size();
if(index >= n) { for(G4int i=n; i<=index; ++i) {mscModels.push_back(0);} }
mscModels[index] = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMscModel* G4VMultipleScattering::Model(G4int index)
{
++warn;
if(warn < 10) {
G4cout << "### G4VMultipleScattering::Model is obsolete method "
<< "and will be removed for the next release." << G4endl;
G4cout << " Please, use EmModel" << G4endl;
}
G4VMscModel* p = 0;
if(index >= 0 && index < G4int(mscModels.size())) { p = mscModels[index]; }
return p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::SetEmModel(G4VMscModel* p, G4int index)
{
G4int n = mscModels.size();
@@ -183,7 +160,7 @@ void G4VMultipleScattering::SetEmModel(G4VMscModel* p, G4int index)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VMscModel* G4VMultipleScattering::EmModel(G4int index)
G4VMscModel* G4VMultipleScattering::EmModel(G4int index) const
{
G4VMscModel* p = 0;
if(index >= 0 && index < G4int(mscModels.size())) { p = mscModels[index]; }
@@ -203,16 +180,39 @@ G4VMultipleScattering::GetModelByIndex(G4int idx, G4bool ver) const
void
G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
{
G4bool master = true;
if(GetMasterProcess() != this) { master = false; }
if(!firstParticle) { firstParticle = &part; }
if(part.GetParticleType() == "nucleus") {
SetStepLimitType(fMinimal);
SetLateralDisplasmentFlag(false);
SetRangeFactor(0.2);
if(&part == G4GenericIon::GenericIon()) { firstParticle = &part; }
isIon = true;
G4String pname = part.GetParticleName();
if(pname != "deuteron" && pname != "triton" &&
pname != "alpha+" && pname != "helium" &&
pname != "alpha" && pname != "He3" &&
pname != "hydrogen") {
const G4ParticleDefinition* theGenericIon =
G4ParticleTable::GetParticleTable()->FindParticle("GenericIon");
if(theGenericIon && firstParticle != theGenericIon) {
G4ProcessManager* pm = theGenericIon->GetProcessManager();
G4ProcessVector* v = pm->GetAlongStepProcessVector();
size_t n = v->size();
for(size_t j=0; j<n; ++j) {
if((*v)[j] == this) {
firstParticle = theGenericIon;
isIon = true;
break;
}
}
}
}
}
emManager->PreparePhysicsTable(&part, this);
emManager->PreparePhysicsTable(&part, this, master);
currParticle = 0;
if(1 < verboseLevel) {
@@ -233,6 +233,7 @@ G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
msc->SetIonisation(0, firstParticle);
msc->SetMasterThread(master);
if(0 == i) { currentModel = msc; }
if(isIon) {
msc->SetStepLimitType(fMinimal);
@@ -271,10 +272,46 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
<< GetProcessName()
<< " and particle " << num
<< " IsMaster= " << G4LossTableManager::Instance()->IsMaster()
<< G4endl;
}
G4bool master = true;
const G4VMultipleScattering* masterProcess =
static_cast<const G4VMultipleScattering*>(GetMasterProcess());
if(masterProcess != this) { master = false; }
emManager->BuildPhysicsTable(firstParticle);
if(firstParticle == &part) {
/*
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
<< GetProcessName()
<< " and particle " << num
<< " IsMaster= " << G4LossTableManager::Instance()->IsMaster()
<< " " << this
<< G4endl;
*/
emManager->BuildPhysicsTable(firstParticle);
if(!master) {
// initialisation of models
G4bool printing = true;
numberOfModels = modelManager->NumberOfModels();
/*
G4cout << "### G4VMultipleScattering::SlaveBuildPhysicsTable() for "
<< GetProcessName()
<< " and particle " << num
<< " Nmod= " << numberOfModels << " " << this
<< G4endl;
*/
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc =
static_cast<G4VMscModel*>(GetModelByIndex(i, printing));
G4VMscModel* msc0=
static_cast<G4VMscModel*>(masterProcess->GetModelByIndex(i,printing));
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
}
}
}
// explicitly defined printout by particle name
if(1 < verboseLevel ||
@@ -326,6 +363,14 @@ void G4VMultipleScattering::StartTracking(G4Track* track)
fIonisation = emManager->GetEnergyLossProcess(currParticle);
eloss = fIonisation;
}
/*
G4cout << "G4VMultipleScattering::StartTracking Nmod= " << numberOfModels
<< " " << currParticle->GetParticleName()
<< " E(MeV)= " << track->GetKineticEnergy()
<< " Ion= " << eloss << " " << fIonisation << " IsMaster= "
<< G4LossTableManager::Instance()->IsMaster()
<< G4endl;
*/
// one model
if(1 == numberOfModels) {
currentModel->StartTracking(track);
@@ -334,12 +379,12 @@ void G4VMultipleScattering::StartTracking(G4Track* track)
// many models
} else {
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
G4VMscModel* msc = static_cast<G4VMscModel*>(GetModelByIndex(i,true));
msc->StartTracking(track);
if(eloss) { msc->SetIonisation(fIonisation, currParticle); }
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -355,6 +400,12 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
physStepLimit = gPathLength = tPathLength = currentMinimalStep;
G4double ekin = track.GetKineticEnergy();
/*
G4cout << "MSC::AlongStepGPIL: Ekin= " << ekin
<< " " << currParticle->GetParticleName()
<< " currMod " << currentModel
<< G4endl;
*/
// isIon flag is used only to select a model
if(isIon) {
ekin *= proton_mass_c2/track.GetParticleDefinition()->GetPDGMass();
@@ -365,19 +416,22 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
currentModel = static_cast<G4VMscModel*>(
SelectModel(ekin,track.GetMaterialCutsCouple()->GetIndex()));
}
// step limit
if(currentModel->IsActive(ekin) && gPathLength >= geomMin
&& ekin >= lowestKinEnergy) {
isActive = true;
tPathLength = currentModel->ComputeTruePathLengthLimit(track, gPathLength);
tPathLength =
currentModel->ComputeTruePathLengthLimit(track, gPathLength);
if (tPathLength < physStepLimit) {
*selection = CandidateForSelection;
}
} else { isActive = false; }
/*
if(currParticle->GetPDGMass() > GeV)
//if(currParticle->GetPDGMass() > GeV)
/*
G4cout << "MSC::AlongStepGPIL: Ekin= " << ekin
<< " " << currParticle->GetParticleName()
<< " gPathLength= " << gPathLength
<< " tPathLength= " << tPathLength
<< " currentMinimalStep= " << currentMinimalStep
@@ -402,7 +456,8 @@ G4VMultipleScattering::PostStepGetPhysicalInteractionLength(
G4VParticleChange*
G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step)
{
fParticleChange.ProposeMomentumDirection(step.GetPostStepPoint()->GetMomentumDirection());
fParticleChange.ProposeMomentumDirection(
step.GetPostStepPoint()->GetMomentumDirection());
fNewPosition = step.GetPostStepPoint()->GetPosition();
fParticleChange.ProposePosition(fNewPosition);
fPositionChanged = false;
@@ -419,42 +474,40 @@ G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step)
currentModel->GetRange(currParticle,track.GetKineticEnergy(),
track.GetMaterialCutsCouple());
G4double trueLength = currentModel->ComputeTrueStepLength(geomLength);
tPathLength = currentModel->ComputeTrueStepLength(geomLength);
// protection against wrong t->g->t conversion
// if(trueLength > tPathLength)
/*
if(currParticle->GetPDGMass() > GeV)
G4cout << "G4VMsc::AlongStepDoIt: GeomLength= "
<< geomLength
<< " trueLenght= " << trueLength
<< " tPathLength= " << tPathLength
<< " physStepLimit= " << physStepLimit
<< " dr= " << range - trueLength
<< " ekin= " << track.GetKineticEnergy() << G4endl;
*/
if (trueLength <= physStepLimit) {
tPathLength = trueLength;
} else {
tPathLength = physStepLimit - 0.5*geomMin;
if (tPathLength > physStepLimit) {
tPathLength = physStepLimit;
}
// do not sample scattering at the last or at a small step
if(tPathLength + geomMin < range && tPathLength > geomMin) {
G4double preSafety = step.GetPreStepPoint()->GetSafety();
G4double postSafety= preSafety - geomLength;
G4double maxDisp = (tPathLength + geomLength)*0.5;
G4double postSafety= preSafety - maxDisp;
G4bool safetyRecomputed = false;
if( postSafety < geomMin ) {
if(postSafety < maxDisp) {
safetyRecomputed = true;
postSafety = currentModel->ComputeSafety(fNewPosition,0.0);
postSafety = safetyHelper->ComputeSafety(fNewPosition,maxDisp);
}
G4ThreeVector displacement =
currentModel->SampleScattering(track.GetDynamicParticle(),postSafety);
G4ThreeVector displacement = currentModel->SampleScattering(
step.GetPostStepPoint()->GetMomentumDirection(), postSafety);
G4double r2 = displacement.mag2();
//G4cout << "R= " << sqrt(r2) << " postSafety= " << postSafety << G4endl;
//G4cout << "R= " << sqrt(r2) << " postSafety= " << postSafety
// << G4endl;
// make correction for displacement
if(r2 > 0.0) {
@@ -464,11 +517,14 @@ G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step)
// displaced point is definitely within the volume
if(r2 > postSafety*postSafety) {
G4double dispR = std::sqrt(r2);
if(!safetyRecomputed) {
postSafety = currentModel->ComputeSafety(fNewPosition, 0.0);
postSafety = safetyHelper->ComputeSafety(fNewPosition, dispR);
}
// add a factor which ensure numerical stability
if(r2 > postSafety*postSafety) { fac = 0.99*postSafety/std::sqrt(r2); }
if(dispR > postSafety) {
fac = 0.99*postSafety/dispR;
}
}
// compute new endpoint of the Step
fNewPosition += fac*displacement;
@@ -487,10 +543,12 @@ G4VParticleChange*
G4VMultipleScattering::PostStepDoIt(const G4Track& track, const G4Step&)
{
fParticleChange.Initialize(track);
if(fPositionChanged) {
safetyHelper->ReLocateWithinVolume(fNewPosition);
fParticleChange.ProposePosition(fNewPosition);
}
return &fParticleChange;
}
@@ -505,7 +563,8 @@ G4double G4VMultipleScattering::GetContinuousStepLimit(
G4GPILSelection selection = NotCandidateForSelection;
G4double x = AlongStepGetPhysicalInteractionLength(track,previousStepSize,
currentMinimalStep,
currentSafety, &selection);
currentSafety,
&selection);
return x;
}
@@ -540,7 +599,7 @@ G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part,
G4bool yes = true;
if(part != firstParticle) { return yes; }
G4int nmod = modelManager->NumberOfModels();
const G4String ss[4] = {"1","2","3","4"};
static const G4String ss[4] = {"1","2","3","4"};
for(G4int i=0; i<nmod; ++i) {
G4VEmModel* msc = modelManager->GetModel(i);
yes = true;
@@ -553,12 +612,14 @@ G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part,
if ( yes ) {
if ( verboseLevel>0 ) {
G4cout << "Physics table are stored for " << part->GetParticleName()
G4cout << "Physics table are stored for "
<< part->GetParticleName()
<< " and process " << GetProcessName()
<< " with a name <" << name << "> " << G4endl;
}
} else {
G4cout << "Fail to store Physics Table for " << part->GetParticleName()
G4cout << "Fail to store Physics Table for "
<< part->GetParticleName()
<< " and process " << GetProcessName()
<< " in the directory <" << directory
<< "> " << G4endl;
@@ -583,7 +644,7 @@ G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition*,
void G4VMultipleScattering::SetIonisation(G4VEnergyLossProcess* p)
{
for(G4int i=0; i<numberOfModels; ++i) {
G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i));
G4VMscModel* msc = static_cast<G4VMscModel*>(GetModelByIndex(i, true));
msc->SetIonisation(p, firstParticle);
}
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
// $Id: G4ionEffectiveCharge.cc 74376 2013-10-04 08:25:47Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -56,6 +56,9 @@
#include "G4UnitsTable.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4Pow.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -71,7 +74,7 @@ G4ionEffectiveCharge::G4ionEffectiveCharge()
lastMat = 0;
lastKinEnergy = 0.0;
effCharge = eplus;
nist = G4NistManager::Instance();
g4pow = G4Pow::GetInstance();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -116,10 +119,9 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
// Helium ion case
if( Zi < 2.5 ) {
static G4double c[6] = {0.2865, 0.1266, -0.001429,
0.02402,-0.01135, 0.001475} ;
static const G4double c[6] = {0.2865,0.1266,-0.001429,0.02402,-0.01135,0.001475};
G4double Q = std::max(0.0,std::log(reducedEnergy*massFactor));
G4double Q = std::max(0.0,G4Log(reducedEnergy*massFactor));
G4double x = c[0];
G4double y = 1.0;
for (G4int i=1; i<6; i++) {
@@ -128,13 +130,13 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
}
G4double ex;
if(x < 0.2) ex = x * (1 - 0.5*x);
else ex = 1. - std::exp(-x);
else ex = 1. - G4Exp(-x);
G4double tq = 7.6 - Q;
G4double tq2= tq*tq;
G4double tt = ( 0.007 + 0.00005 * z );
if(tq2 < 0.2) tt *= (1.0 - tq2 + 0.5*tq2*tq2);
else tt *= std::exp(-tq2);
else tt *= G4Exp(-tq2);
effCharge = charge*(1.0 + tt) * std::sqrt(ex);
@@ -142,9 +144,9 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
} else {
G4double y;
// = nist->GetZ13(z);
// = g4pow->A13(Zi);
//G4double z23 = y*y;
G4double zi13 = nist->GetZ13(Zi);
G4double zi13 = g4pow->A13(Zi);
G4double zi23 = zi13*zi13;
// G4double e = std::max(reducedEnergy,energyBohr/z23);
//G4double e = reducedEnergy;
@@ -167,13 +169,13 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
G4double q;
G4double y3 = std::pow(y, 0.3) ;
// G4cout<<"y= "<<y<<" y3= "<<y3<<" v1= "<<v1<<" vF= "<<vF<<G4endl;
q = 1.0 - std::exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ;
q = 1.0 - G4Exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ;
//y *= 0.77;
//y *= (0.75 + 0.52/Zi);
//if( y < 0.2 ) q = y*(1.0 - 0.5*y);
//else q = 1.0 - std::exp(-y);
//else q = 1.0 - G4Exp(-y);
G4double qmin = minCharge/Zi;
if(q < qmin) q = qmin;
@@ -181,7 +183,7 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
effCharge = q*charge;
/*
G4double x1 = 1.0*effCharge*(1.0 - 0.132*std::log(y))/(y*std::sqrt(z));
G4double x1 = 1.0*effCharge*(1.0 - 0.132*G4Log(y))/(y*std::sqrt(z));
G4double x2 = 0.1*effCharge*effCharge*energyBohr/reducedEnergy;
chargeCorrection = 1.0 + x1 - x2;
@@ -189,27 +191,21 @@ G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
G4cout << "x1= "<<x1<<" x2= "<< x2<<" corr= "<<chargeCorrection<<G4endl;
*/
G4double tq = 7.6 - std::log(reducedEnergy/keV);
G4double tq = 7.6 - G4Log(reducedEnergy/keV);
G4double tq2= tq*tq;
G4double sq = ( 0.18 + 0.0015 * z ) / (Zi*Zi);
if(tq2 < 0.2) sq *= (1.0 - tq2 + 0.5*tq2*tq2);
else sq *= std::exp(-tq2);
sq += 1.0;
G4double sq = 1.0 + ( 0.18 + 0.0015 * z )*G4Exp(-tq2)/ (Zi*Zi);
// G4cout << "sq= " << sq << G4endl;
// Screen length according to
// J.F.Ziegler and J.M.Manoyan, The stopping of ions in compaunds,
// Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
G4double lambda = 10.0 * vF / (zi13 * (6.0 + q));
if(q < 0.2) lambda *= (1.0 - 0.66666667*q - q*q/9.0);
else lambda *= std::pow(1.0-q, 0.666666);
G4double lambda = 10.0 * vF *g4pow->A23(1.0 - q)/ (zi13 * (6.0 + q));
G4double lambda2 = lambda*lambda;
G4double xx = (0.5/q - 0.5)/vFsq;
if(lambda2 < 0.2) xx *= lambda2*(1.0 - 0.5*lambda2);
else xx *= std::log(1.0 + lambda2);
G4double xx = (0.5/q - 0.5)*G4Log(1.0 + lambda2)/vFsq;
chargeCorrection = sq * (1.0 + xx);