Ignore:
Timestamp:
Apr 6, 2009, 12:21:12 PM (17 years ago)
Author:
garnier
Message:

update processes

Location:
trunk/source/processes/electromagnetic/utils
Files:
37 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/processes/electromagnetic/utils/History

    r819 r961  
    1 $Id: History,v 1.308.2.1 2008/04/22 15:28:12 vnivanch Exp $
     1$Id: History,v 1.372 2009/02/26 11:33:33 vnivanch Exp $
    22-------------------------------------------------------------------
    33
     
    1818     ----------------------------------------------------------
    1919
    20 22 April 08: V.Ivant (emutils-V09-00-14)
    21 - G4EmCorrections - set finite size correction to zero (provides         
    22                     flat distribution of vertex detector response
    23                     for high energy hadrons)
    24 - G4ionEffectiveCharge - minor change of numerical constants to provide
    25                          a continuous change of charge versus energy
    26 
     2026 February 09: V.Ivant (emutils-V09-02-03)
     21G4EmConfigurator - fixed for the case if only fluctuation model is set
     22                   and main model is default
     23
     2422 February 09: V.Ivant (emutils-V09-02-02)
     25- G4VEmModel - make methods to access geometry protected, added new
     26               method SetSampleZ, added geommax private member
     27- G4EmCalculator - added possibility to be used by DNA processes:
     28                   take into account special DNA particles
     29
     3018 February 09: V.Ivant (emutils-V09-02-01)
     31G4VEmModel, G4VEmFluctuationModel, G4VEnegryLossProcess, G4VEmProcess,
     32G4VMultipleScattering - move all virtual methods to source, update comments
     33G4VEmModel - added flagDeexcitation and Get/Set methods
     34G4VEnegryLossProcess, G4VEmProcess - added calls to deexcitation PostStep
     35G4EmProcessOptions - added ActivateDeexcitation method
     36G4EnergyLossMessenger - added /process/em/deexcitation UI command
     37G4LossTableBuilder - added protection in BuildRangeTable against zero dedx
     38
     3927 January 09: V.Ivant (emutils-V09-02-00)
     40G4VEmModel - added method SampleDeexcitationAlongStep
     41G4VEnegryLossProcess - added deexcitation AlongStep per region
     42G4VMscModel - added methdos: InitialiseSafetyHelper, ComputeSafety,
     43              ComputeGeomLimit, ComputeDisplacement
     44G4VEmProcess - added possibility to set more than 1 model
     45
     4620 November 08: V.Ivant (emutils-V09-01-37)
     47G4EmConfigurator - fixed energy interval selection for a model
     48G4VMultipleScattering - set process sub-type 10 to distinguish with
     49                        single Coulomb scattering
     50
     5113 Novemver 08: A.Schaelicke (emutils-V09-01-36)
     52G4LossTableManager - changed default LPM effect to ON again
     53G4VEmModel - (VI) add LPM flag and Get/Set methods
     54
     5512 November 08: V.Ivant (emutils-V09-01-35)
     56G4VEmModel - fixed memory leak by destruction G4EmElementSelectors
     57G4EmSaturation - activate saturation for energy deposition due to
     58                 photo-electric effect
     59
     6024 October 08: V.Ivant (emutils-V09-01-34)
     61G4EmProcessSubType - moved optical processes enumeration to optical directory
     62
     6320 October 08: V.Ivant (emutils-V09-01-33)
     64G4EnergyLossMessenger - added /process/em/applyCuts command
     65
     6617 October 08: V.Ivant (emutils-V09-01-32)
     67G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering set number
     68   of bins for tables 7 per decade
     69
     7015 October 08: V.Ivant (emutils-V09-01-31)
     71G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering improved cout
     72
     7314 October 08: V.Ivant (emutils-V09-01-30)
     74G4VEmModel - add secondaryThreshold variable and Get/Set methods
     75G4EmCorrections - define the range of correction vector 25 keV - 2.5 MeV,
     76                  as it is in ICRU'73 table, use 20 bins
     77G4LossTableManager - set spline option "true" and flagLPM "false" by default
     78G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering set default
     79                  table size 0.1 keV - 100 TeV in 60 bins
     80G4EmModelManager - included G4EmProcessSubType.hh header
     81G4EmTableType.hh - changed enumeration names fIonisation -> fIsIonisation,
     82                   fSubIonisation -> fIsSubIonisation to avoid clash with
     83                   sub-type enumeration name
     84
     8521 September 08: V.Ivant (emutils-V09-01-29)
     86G4EmCorrections - do not compute ion corrections if for ions
     87                  G4hIonisation process is used
     88
     8921 September 08: V.Ivant (emutils-V09-01-28)
     90G4ionEffectiveCharge - remove chargeFactor - return to 01-25
     91G4VEnergyLossProcess - fixed initialisation;
     92
     9312 September 08: V.Ivant (emutils-V09-01-27)
     94G4VEmProcess - improved verbose output
     95G4VEnergyLossProcess - added pointer to current G4VEmModel;
     96                       removed method CorrectionsAlongStep, instead
     97                       corresponding method of a model are used;
     98                       improved verbose output
     99G4VEmFluctuationModel - added method SetParticleAndCharge
     100G4VEmModel - minor optimisations of SelectRandomAtom and SelectIsotope;
     101             added methods GetParticleCharge, GetChargeSquareRatio,
     102             CorrectionsAlongStep, ActivateNuclearStopping needed for
     103             simulation of ion transport
     104G4EmCorrections - added interfaces to effective charge
     105G4ionEffectiveCharge - added variable chargeFactor to be used for He ions
     106
     10729 August 08: V.Ivant (emutils-V09-01-26)
     108G4VEmProcess, G4VMultipleScattering, G4VEnergyLossProcess - use
     109                   new DumpModelList method from G4EmModelManager
     110                   in the verbosity output
     111G4EmModelManager - fixed crash in destructor when verbosity > 1;
     112                   fixed selection of models per energy;
     113                   update printout with DumpModelList method
     114
     11521 August 08: V.Ivant (emutils-V09-01-25)
     116G4VEmModel - add parameter kinEnergy to SetupMaterial method;
     117             set pointer currentElement in ComputeCrossSectionPerAtom
     118G4EmElementSelector - update usage of methods SetupMaterial and
     119             ComputeCrossSectionPerAtom
     120
     1213 August 08: V.Ivant (emutils-V09-01-24)
     122G4EmCorrections - dEdx data for ions are initialised at the start of a run for
     123                  materials used in geometry; search for ion/material pairs updated
     124G4EmCalculator - improved cout
     125
     12631 July 08: V.Ivant (emutils-V09-01-23)
     127G4VEmProcess, G4VMultipleScattering, G4VEnergyLossProcess - use verbosity flag
     128    for GetEmModel method
     129G4VEmModel - use stl vector for cross sections instead of array
     130
     13121 July 08: V.Ivant (emutils-V09-01-22)
     132G4VEmModel - added vector of G4ElementSelectors, in which vectors
     133             of relative cross sections per elements of a compound
     134             material are stored; added new methods:
     135             InitialisaElementSelectors and SelectRandomAtom,
     136G4LossTableBuilder - remove dependence on G4LossTableManager
     137G4LossTableManager - propagated spline flag to G4LossTableBuilder           
     138
     13915 July 08: V.Ivant (emutils-V09-01-21)
     140G4EmConfigurator - a new helper class to add model per particle type,
     141                   process, energy range and G4Region
     142G4VEmProcess, G4VEnergyLossProcess - renamed and improved method
     143                   "MicroscopicCrossSection" by "CrossSectionPerVolume"
     144G4VEmModel, G4VEmProcess, G4VMultipleScattering, G4VEnergyLossProcess
     145                   reodering of members of classes and improved comments:
     146                   - separated members fixed at construction, defined at
     147                     ininitialisation, and modified in run time
     148                   - improved comments in header files
     149G4LossTableManager - added register/deregister mechanism and deletion
     150                   at the end of job for G4VEmModel
     151G4EmModelManager - does not delete models anymore
     152
     1539 July 08: V.Ivant (emutils-V09-01-20)
     154G4ElectronIonPair - a new helper class to sample number of primary ionisations
     155                    in detectors
     156
     1578 July 08: V.Ivant (emutils-V09-01-19)
     158G4VEmModel - added inline method ComputeCrossSectionPerAtom
     159G4LossTableManager and G4EnergyLossTable - remove call to exit()
     160
     1619 June 08: V.Ivant (emutils-V09-01-18)
     162G4ionEffectiveCharge - return back Ziegler formula for effective charge of ions;
     163                       min effective charge is 1.0 (instead of 0.1)
     164G4EmCorrections - a minor change of the scale for external ion data
     165
     1662 June 08: V.Ivant (emutils-V09-01-17)
     167G4ionEffectiveCharge - use simplified formula for effective charge of ions
     168
     16928 May 08: V.Ivant (emutils-V09-01-16)
     170G4VEmModel - added virtual method SetupForMaterial
     171G4EmElementSelector - helper class to sample random G4Element in a
     172                      compound material
     173
     17428 May 08: V.Ivant (emutils-V09-01-15)
     175G4VEnergyLossProcess - fixed problem of subcutoff option for ions (ion
     176                       ranges were wrong)
     177G4LossableBuilder - use more precise algorith to compute range for the
     178                    case, when spline is used 
     179
     18020 May 08: V.Ivant (emutils-V09-01-14)
     181- G4EmCorrections - computation of the finite size correction is moved to
     182                    the Bethe-Bloch model
     183
     18411 May 08: V.Ivant (emutils-V09-01-13)
     185- G4VMultipleScattering - make AlongStepGetPhysicalInteractionLength
     186  method virtual allowing to overwrite it by a derived class -
     187  needed for ion simulation
     188- G4EmCalculator - fixed bug in computation for ions
     189
     19021 April 08: V.Ivant (emutils-V09-01-12)
     191- G4VEmModel, G4VEmProcess, G4VMultipleScattering, G4EnergyLossMessenger
     192  G4EmProcessOptions - introduced polarAngleLimit parameter and Get/Set
     193  methods for single and multiple scattering models
     194- G4ionEffectiveCharge - fixed initialisation at first event
     195- G4EmCorrections - review and fix computation of high order corrections
     196                    for ions
     197- G4EmCalculator - updated computations for ions
     198
     19908 April 08: V.Ivant (emutils-V09-01-11)
     200- G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering,
     201  G4LossTableBuilder - introduced spline
     202
     20325 March 08: V.Ivant (emutils-V09-01-10)
     204- G4EmCorrections - precompute EM formfactor for corrections
     205- G4VEnergyLossProcess - store bremsstrahlung cross sections
     206
     20725 March 08: V.Ivant (emutils-V09-01-09)
     208- G4EmCorrections - added cut dependence into finite size correction
     209- G4VEnergyLossProcess - added cout of linLossLimit
     210
     21117 March 08: V.Ivant (emutils-V09-01-08)
     212- G4EmSaturation - added interface with G4Step
     213     
     21414 March 08: mma (emutils-V09-01-07)
     215- modifs in G4EmSaturation
     216
     21714 March 08: V.Ivant (emutils-V09-01-06)
     218- G4EmSaturation - added computation of the average recoil mass,
     219                   use Birks coefficient from G4Material
     220- G4LossTableManager - fixed logic in compute dedx table for an
     221                       inactive process
     222
     22310 March 08: V.Ivant (emutils-V09-01-05)
     224- G4LossTableManager, G4EmProcessOptions - added Set/Get spline flag
     225- G4EnergyLossMessenger - added a command "/process/em/spline"
     226- G4VMultipleScattering - SetSkin method does not change
     227                          StepLimitType anymore
     228- G4VMscModel - new class to define general msc parameters
     229
     23021 February 08: V.Ivant (emutils-V09-01-04)
     231- G4EmSaturation - fixed initialisation problem
     232
     23321 February 08: V.Ivant (emutils-V09-01-03)
     234- G4EmCorrections - added correction on effective charge for NIST
     235  materials in the IonHighOrderCorrections method
     236- G4EmSaturation - new helper class
     237- G4LossTableManager - added GetEmSaturation method
     238
     23914 February 08: V.Ivant (emutils-V09-01-02)
     240- G4EmCorrections - added IonBarkasCorrection, IonHighOrderCorrections
     241  and ComputeIonCorrections methods in order to provide a smooth transition
     242  between low-energy parameterization and Bethe-Bloch model
     243- G4ionEffectiveCharge - use precomputed Z^1/3 values, use expantions
     244  of exp and pow functions, do not perform recomputation if arguments
     245  of methods unchanged
     246
     24704 February 08: V.Ivant (emutils-V09-01-01)
     248- G4VEnergyLossProcess - fixed computation of NIEL at the last step
     249  of a particle
     250 
    2725111 January 08: V.Ivant (emutils-V09-01-00)
    28252- G4EmCorrections - improve CPU by usage expansions and precalculated
     
    3325709 November 07: V.Ivant (emutils-V09-00-13)
    34258- G4VMultipleScattering - set at initialisation that scattering may be
    35                           off electrons (needed for single scattering)
     259                          off lectrons (needed for single scattering)
    36260- G4EmModelmanager - add pointers to G4Gamma and G4Positron at
    37261                     initialisation
     
    3926307 November 07: V.Ivant (emutils-V09-00-12)
    40264- G4VEnergyLossProcess - simplify logic to switch on/off fluctuations
    41 - G4EmProcessOptions - add forgotten initialisation of G4LossTableManager
     265- G4EmProcessOptions - add forgoten initialisation of G4LossTableManager
    42266                       parameters together with parameters of concrete
    43267                       processes (fixed initialisation when options
    44                        defined before processes are instantiated)
     268                       defined before proceeses are instantiated)
    45269
    4627029 October 07: V.Ivant (emutils-V09-00-11)
     
    75299- G4VEnergyLossProcess and G4VEmProcess - fixed handling zero cross
    76300  section in PostStepGetPhysicalInteractionLength method to avoid problem
    77   happens in FanoCavity example when cross section inside cavity is zero
     301  happans in FanoCavity example when cross section inside cavity is zero
    78302- G4VEmModel - compare cross section with DBL_MIN instead of zero
    79303
     
    124348  void, extra parameter std::vector<G4DynamicParticle*>*, this vector
    125349  is now a member of base class G4VEnergyLossProcess, G4VEmProcess,
    126   no new and delete of the vector in the run time. About 5% speedup
     350  no new and delete of the vector in the run time. About 5% speadup
    127351  of EM shower simulation
    128352- G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering modified
  • trunk/source/processes/electromagnetic/utils/include/G4DummyModel.hh

    r819 r961  
    2525//
    2626// $Id: G4DummyModel.hh,v 1.3 2007/05/22 17:31:57 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/include/G4EmCalculator.hh

    r819 r961  
    2525//
    2626// $Id: G4EmCalculator.hh,v 1.18 2007/03/15 12:34:46 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929//
  • trunk/source/processes/electromagnetic/utils/include/G4EmCorrections.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmCorrections.hh,v 1.10 2008/01/11 19:55:29 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmCorrections.hh,v 1.24 2008/09/12 14:44:48 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4141// 28.04.2006 General cleanup, add finite size corrections (V.Ivanchenko)
    4242// 13.05.2006 Add corrections for ion stopping (V.Ivanhcenko)
     43// 20.05.2008 Removed Finite Size correction (V.Ivanchenko)
     44// 12.09.2008 Added inlined interfaces to effective charge (V.Ivanchenko)
    4345//
    4446// Class Description:
     
    5860#include "G4Material.hh"
    5961#include "G4ParticleDefinition.hh"
     62#include "G4NistManager.hh"
    6063
    6164class G4VEmModel;
    6265class G4PhysicsVector;
    6366class G4IonTable;
    64 class G4NistManager;
     67class G4MaterialCutsCouple;
    6568
    6669class G4EmCorrections
     
    7376  virtual ~G4EmCorrections();
    7477
    75   G4double HighOrderCorrections(const G4ParticleDefinition* p,
    76                                 const G4Material* material,
    77                                       G4double kineticEnergy);
    78 
    79   G4double Bethe(const G4ParticleDefinition* p,
    80                  const G4Material* material,
     78  G4double HighOrderCorrections(const G4ParticleDefinition*,
     79                                const G4Material*,
     80                                G4double kineticEnergy,
     81                                G4double cutEnergy);
     82
     83  G4double IonHighOrderCorrections(const G4ParticleDefinition*,
     84                                   const G4MaterialCutsCouple*,
     85                                   G4double kineticEnergy);
     86
     87  G4double ComputeIonCorrections(const G4ParticleDefinition*,
     88                                 const G4Material*,
     89                                 G4double kineticEnergy);
     90
     91  G4double IonBarkasCorrection(const G4ParticleDefinition*,
     92                               const G4Material*,
     93                               G4double kineticEnergy);
     94
     95  G4double Bethe(const G4ParticleDefinition*,
     96                 const G4Material*,
    8197                 G4double kineticEnergy);
    8298
    83   G4double SpinCorrection(const G4ParticleDefinition* p,
    84                           const G4Material* material,
     99  G4double SpinCorrection(const G4ParticleDefinition*,
     100                          const G4Material*,
    85101                          G4double kineticEnergy);
    86102
    87   G4double KShellCorrection(const G4ParticleDefinition* p,
    88                             const G4Material* material,
     103  G4double KShellCorrection(const G4ParticleDefinition*,
     104                            const G4Material*,
    89105                            G4double kineticEnergy);
    90106
    91   G4double LShellCorrection(const G4ParticleDefinition* p,
    92                             const G4Material* material,
     107  G4double LShellCorrection(const G4ParticleDefinition*,
     108                            const G4Material*,
    93109                            G4double kineticEnergy);
    94110
    95   G4double ShellCorrection(const G4ParticleDefinition* p,
    96                            const G4Material* material,
     111  G4double ShellCorrection(const G4ParticleDefinition*,
     112                           const G4Material*,
    97113                           G4double kineticEnergy);
    98114
    99   G4double ShellCorrectionSTD(const G4ParticleDefinition* p,
    100                               const G4Material* material,
     115  G4double ShellCorrectionSTD(const G4ParticleDefinition*,
     116                              const G4Material*,
    101117                              G4double kineticEnergy);
    102118
    103   G4double DensityCorrection(const G4ParticleDefinition* p,
    104                              const G4Material* material,
     119  G4double DensityCorrection(const G4ParticleDefinition*,
     120                             const G4Material*,
    105121                             G4double kineticEnergy);
    106122
    107   G4double BarkasCorrection(const G4ParticleDefinition* p,
    108                             const G4Material* material,
     123  G4double BarkasCorrection(const G4ParticleDefinition*,
     124                            const G4Material*,
    109125                            G4double kineticEnergy);
    110126
    111   G4double BlochCorrection(const G4ParticleDefinition* p,
    112                            const G4Material* material,
     127  G4double BlochCorrection(const G4ParticleDefinition*,
     128                           const G4Material*,
    113129                           G4double kineticEnergy);
    114130
    115   G4double MottCorrection(const G4ParticleDefinition* p,
    116                           const G4Material* material,
     131  G4double MottCorrection(const G4ParticleDefinition*,
     132                          const G4Material*,
    117133                          G4double kineticEnergy);
    118134
    119   G4double FiniteSizeCorrection(const G4ParticleDefinition* p,
    120                                 const G4Material* material,
    121                                 G4double kineticEnergy);
    122 
    123   G4double NuclearDEDX(const G4ParticleDefinition* p,
    124                        const G4Material* material,
     135  G4double NuclearDEDX(const G4ParticleDefinition*,
     136                       const G4Material*,
    125137                       G4double kineticEnergy,
    126138                       G4bool fluct = true);
    127139
    128140  void AddStoppingData(G4int Z, G4int A, const G4String& materialName,
    129                        G4PhysicsVector& dVector);
    130 
     141                       G4PhysicsVector* dVector);
     142
     143  void InitialiseForNewRun();
     144
     145  // effective charge correction using stopping power data
    131146  G4double EffectiveChargeCorrection(const G4ParticleDefinition*,
    132147                                     const G4Material*,
    133                                      G4double);
    134 
    135   G4ionEffectiveCharge* GetIonEffectiveCharge(G4VEmModel* m = 0);
    136 
    137   G4int GetNumberOfStoppingVectors();
     148                                     G4double kineticEnergy);
     149
     150  // effective charge of an ion
     151  inline G4double GetParticleCharge(const G4ParticleDefinition*,
     152                                    const G4Material*,
     153                                    G4double kineticEnergy);
     154
     155  inline
     156  G4double EffectiveChargeSquareRatio(const G4ParticleDefinition*,
     157                                      const G4Material*,
     158                                      G4double kineticEnergy);
     159
     160  // ionisation models for ions
     161  inline void SetIonisationModels(G4VEmModel* m1 = 0, G4VEmModel* m2 = 0);
     162
     163  inline G4int GetNumberOfStoppingVectors();
    138164
    139165private:
     
    141167  void Initialise();
    142168
    143   G4PhysicsVector* InitialiseMaterial(const G4Material* mat);
    144 
    145   void SetupKinematics(const G4ParticleDefinition* p,
    146                        const G4Material* material,
     169  void BuildCorrectionVector();
     170
     171  void SetupKinematics(const G4ParticleDefinition*,
     172                       const G4Material*,
    147173                       G4double kineticEnergy);
    148174
     
    207233  G4double     Z23[100];
    208234
     235  std::vector<const G4Material*> currmat;
     236  std::vector<G4double>          thcorr[100];
     237  size_t        ncouples;
     238
    209239  const G4ParticleDefinition* particle;
    210240  const G4ParticleDefinition* curParticle;
     
    218248  G4double  mass;
    219249  G4double  massFactor;
     250  G4double  formfact;
     251  G4double  eth;
    220252  G4double  tau;
    221253  G4double  gamma;
     
    225257  G4double  ba2;
    226258  G4double  tmax;
    227   G4double  tmax0;
    228259  G4double  charge;
    229260  G4double  q2;
     261  G4double  eCorrMin;
     262  G4double  eCorrMax;
     263  G4int     nbinCorr;
    230264
    231265  G4AtomicShells        shells;
     
    234268  G4NistManager*        nist;
    235269  const G4IonTable*     ionTable;
    236   G4VEmModel*           ionModel;
     270  G4VEmModel*           ionLEModel;
     271  G4VEmModel*           ionHEModel;
    237272
    238273  // Ion stopping data
    239274  G4int                       nIons;
    240275  G4int                       idx;
     276  G4int                       currentZ;
    241277  std::vector<G4int>          Zion;
    242278  std::vector<G4int>          Aion;
    243279  std::vector<G4String>       materialName;
     280
     281  std::vector<const G4ParticleDefinition*> ionList;
    244282
    245283  std::vector<const G4Material*> materialList;
     
    271309               z21*((xv-x1)*(y2-yv)+(yv-y1)*(x2-xv))))
    272310         / ((x2-x1)*(y2-y1));
     311}
     312
     313inline
     314void G4EmCorrections::SetIonisationModels(G4VEmModel* m1, G4VEmModel* m2)
     315{
     316  if(m1) ionLEModel = m1;
     317  if(m2) ionHEModel = m2;
     318}
     319
     320inline G4int G4EmCorrections::GetNumberOfStoppingVectors()
     321{
     322  return nIons;
     323}
     324
     325inline G4double
     326G4EmCorrections::GetParticleCharge(const G4ParticleDefinition* p,
     327                                   const G4Material* mat,
     328                                   G4double kineticEnergy)
     329{
     330  return effCharge.EffectiveCharge(p,mat,kineticEnergy);
     331}
     332
     333inline G4double
     334G4EmCorrections::EffectiveChargeSquareRatio(const G4ParticleDefinition* p,
     335                                            const G4Material* mat,
     336                                            G4double kineticEnergy)
     337{
     338  return effCharge.EffectiveChargeSquareRatio(p,mat,kineticEnergy);
    273339}
    274340
     
    289355    G4double ratio = electron_mass_c2/mass;
    290356    tmax  = 2.0*electron_mass_c2*bg2 /(1. + 2.0*gamma*ratio + ratio*ratio);
    291     tmax0 = tmax;
    292357    charge  = p->GetPDGCharge()/eplus;
    293     if(charge < 1.5)  q2 = charge*charge;
     358    if(charge < 1.5)  {q2 = charge*charge;}
    294359    else {
    295360      q2 = effCharge.EffectiveChargeSquareRatio(p,mat,kinEnergy);
    296361      charge = std::sqrt(q2);
    297362    }
    298     if(mass > 120.*MeV)
    299       tmax = std::min(tmax,51200.*electron_mass_c2*std::pow(proton_mass_c2/mass,0.666667));
    300363  }
    301364  if(mat != material) {
  • trunk/source/processes/electromagnetic/utils/include/G4EmModelManager.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmModelManager.hh,v 1.22 2007/11/09 11:35:54 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4EmModelManager.hh,v 1.25 2008/10/13 14:56:56 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    7474#include "G4DataVector.hh"
    7575#include "G4EmTableType.hh"
     76#include "G4EmProcessSubType.hh"
     77#include "G4Region.hh"
    7678
    7779class G4RegionModels
     
    8486private:
    8587
    86   G4RegionModels(G4int nMod, std::vector<G4int>& list, G4DataVector& lowE);
     88  G4RegionModels(G4int nMod, std::vector<G4int>& indx,
     89                 G4DataVector& lowE, const G4Region* reg);
    8790
    8891  ~G4RegionModels();
     
    105108  };
    106109
     110  G4double LowEdgeEnergy(G4int n) const {
     111    return lowKineticEnergy[n];
     112  };
     113
     114  const G4Region* Region() const {
     115    return theRegion;
     116  };
     117
     118  const G4Region*    theRegion;
    107119  G4int              nModelsForRegion;
    108120  G4int*             theListOfModelIndexes;
     
    150162  G4VEmModel* SelectModel(G4double& energy, size_t& index);
    151163
    152   G4VEmModel* GetModel(G4int);
     164  G4VEmModel* GetModel(G4int, G4bool ver = false);
    153165
    154166  G4int NumberOfModels() const;
     
    157169 
    158170  void UpdateEmModel(const G4String&, G4double, G4double);
     171
     172  void DumpModelList(G4int verb);
    159173
    160174private:
     
    176190  std::vector<const G4Region*>            regions;
    177191  std::vector<G4int>                      orderOfModels;
    178   G4DataVector                            upperEkin;
    179192
    180193  G4int                       nEmModels;
  • trunk/source/processes/electromagnetic/utils/include/G4EmMultiModel.hh

    r819 r961  
    2525//
    2626// $Id: G4EmMultiModel.hh,v 1.6 2007/05/22 17:31:57 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/include/G4EmProcessOptions.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmProcessOptions.hh,v 1.12 2007/05/18 18:39:54 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmProcessOptions.hh,v 1.15 2009/02/18 14:40:10 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929//
     
    107107  void SetLinearLossLimit(G4double val);
    108108
    109   void ActivateDeexcitation(G4bool val, const G4Region* r = 0);
     109  void ActivateDeexcitation(const G4String& proc, G4bool val,
     110                            const G4String& reg = "");
    110111
    111112  void SetMscStepLimitation(G4MscStepLimitType val);
     
    121122  void SetLPMFlag(G4bool val);
    122123
     124  void SetSplineFlag(G4bool val);
     125
    123126  void SetBremsstrahlungTh(G4double val);
     127
     128  void SetPolarAngleLimit(G4double val);
    124129
    125130private:
  • trunk/source/processes/electromagnetic/utils/include/G4EmTableType.hh

    r819 r961  
    2525//
    2626//
    27 // $Id: G4EmTableType.hh,v 1.3 2007/01/15 17:27:40 vnivanch Exp $
    28 // GEANT4 tag $Name: $
     27// $Id: G4EmTableType.hh,v 1.4 2008/10/13 14:56:56 vnivanch Exp $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030//---------------------------------------------------------------
     
    5151  fRestricted,
    5252  fSubRestricted,
    53   fIonisation,
    54   fSubIonisation
     53  fIsIonisation,
     54  fIsSubIonisation
    5555};
    5656#endif
  • trunk/source/processes/electromagnetic/utils/include/G4EnergyLossMessenger.hh

    r819 r961  
    2525//
    2626//
    27 // $Id: G4EnergyLossMessenger.hh,v 1.18 2007/05/18 18:39:54 vnivanch Exp $
    28 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     27// $Id: G4EnergyLossMessenger.hh,v 1.23 2009/02/18 14:40:10 vnivanch Exp $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030// -------------------------------------------------------------------
     
    4545// 16-03-07 modify /process/eLoss/minsubsec command (V.Ivanchenko)
    4646// 18-05-07 add /process/msc directory and commands (V.Ivanchenko)
     47// 11-03-08 add /process/em directory and commands (V.Ivanchenko)
    4748//
    4849// -------------------------------------------------------------------
     
    100101  G4UIdirectory*             eLossDirectory;
    101102  G4UIdirectory*             mscDirectory;
     103  G4UIdirectory*             emDirectory;
    102104  G4UIcmdWithABool*          RndmStepCmd;
    103105  G4UIcmdWithABool*          EnlossFlucCmd;
     
    105107  G4UIcmdWithADouble*        MinSubSecCmd;
    106108  G4UIcommand*               StepFuncCmd;
     109  G4UIcommand*               deexCmd;
    107110  G4UIcmdWithAString*        mscCmd;
    108111  G4UIcmdWithADoubleAndUnit* MinEnCmd;
     
    112115  G4UIcmdWithABool*          lpmCmd;
    113116  G4UIcmdWithABool*          latCmd;
     117  G4UIcmdWithABool*          splCmd;
     118  G4UIcmdWithABool*          aplCmd;
    114119  G4UIcmdWithAnInteger*      verCmd;
     120  G4UIcmdWithAnInteger*      ver1Cmd;
    115121  G4UIcmdWithAnInteger*      dedxCmd;
    116122  G4UIcmdWithAnInteger*      lamCmd;
     
    120126  G4UIcmdWithADouble*        frCmd;
    121127  G4UIcmdWithADouble*        fgCmd;
     128  G4UIcmdWithADoubleAndUnit* angCmd;
    122129};
    123130
  • trunk/source/processes/electromagnetic/utils/include/G4EnergyLossTables.hh

    r819 r961  
    2626//
    2727// $Id: G4EnergyLossTables.hh,v 1.19 2006/06/29 19:54:35 gunter Exp $
    28 // GEANT4 tag $Name: $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030// $Id:
  • trunk/source/processes/electromagnetic/utils/include/G4LossTableBuilder.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4LossTableBuilder.hh,v 1.7 2006/06/29 19:54:37 gunter Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4LossTableBuilder.hh,v 1.8 2008/07/22 15:55:15 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929//
     
    4040//
    4141// Modifications:
    42 // 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
    43 //
     42// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivanchenko)
     43// 17-07-08 Added splineFlag (V.Ivanchenko)
    4444//
    4545// Class Description:
     
    5656#include "globals.hh"
    5757#include "G4PhysicsTable.hh"
    58 
    5958
    6059class G4LossTableBuilder
     
    7574                              G4PhysicsTable* invRangeTable,
    7675                              G4bool isIonisation = false);
     76
     77  inline void SetSplineFlag(G4bool flag);
    7778 
    7879private:
     
    8182  G4LossTableBuilder(const  G4LossTableBuilder&);
    8283
     84  G4bool splineFlag;
     85
    8386};
     87
     88inline void G4LossTableBuilder::SetSplineFlag(G4bool flag)
     89{
     90  splineFlag = flag;
     91}
    8492
    8593//....oooOO0OOooo.......oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
  • trunk/source/processes/electromagnetic/utils/include/G4LossTableManager.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4LossTableManager.hh,v 1.48 2007/11/07 18:38:49 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4LossTableManager.hh,v 1.53 2008/07/15 16:56:38 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929//
     
    7777#define G4LossTableManager_h 1
    7878
    79 
    8079#include <map>
    8180#include <vector>
     
    9190class G4VEmProcess;
    9291class G4EmCorrections;
     92class G4EmSaturation;
    9393class G4LossTableBuilder;
    9494
     
    152152
    153153  void DeRegister(G4VEmProcess* p);
     154
     155  void Register(G4VEmModel* p);
     156
     157  void DeRegister(G4VEmModel* p);
     158
     159  void Register(G4VEmFluctuationModel* p);
     160
     161  void DeRegister(G4VEmFluctuationModel* p);
    154162
    155163  void EnergyLossProcessIsInitialised(const G4ParticleDefinition* aParticle,
     
    195203  void SetLPMFlag(G4bool val);
    196204
     205  void SetSplineFlag(G4bool val);
     206
    197207  void SetLinearLossLimit(G4double val);
    198208
     
    207217  G4bool LPMFlag() const;
    208218
     219  G4bool SplineFlag() const;
     220
    209221  G4double BremsstrahlungTh() const;
    210222
     
    217229  inline G4VEnergyLossProcess* GetEnergyLossProcess(const G4ParticleDefinition*);
    218230
    219   inline G4EmCorrections* EmCorrections();
     231  G4EmCorrections* EmCorrections();
     232
     233  G4EmSaturation* EmSaturation();
    220234
    221235private:
     
    251265  std::vector<G4VMultipleScattering*> msc_vector;
    252266  std::vector<G4VEmProcess*> emp_vector;
     267  std::vector<G4VEmModel*> mod_vector;
     268  std::vector<G4VEmFluctuationModel*> fmod_vector;
    253269
    254270  // cash
     
    274290  G4bool stepFunctionActive;
    275291  G4bool flagLPM;
     292  G4bool splineFlag;
    276293
    277294  G4double minSubRange;
     
    286303  G4EnergyLossMessenger*      theMessenger;
    287304  G4EmCorrections*            emCorrections;
     305  G4EmSaturation*             emSaturation;
     306
    288307  const G4ParticleDefinition* firstParticle;
    289308  G4int verbose;
     
    418437//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    419438
    420 inline G4EmCorrections* G4LossTableManager::EmCorrections()
    421 {
    422   return emCorrections;
    423 }
    424 
    425 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    426 
    427439#endif
    428440
  • trunk/source/processes/electromagnetic/utils/include/G4MscStepLimitType.hh

    r819 r961  
    2626//
    2727// $Id: G4MscStepLimitType.hh,v 1.2 2007/06/11 14:56:51 vnivanch Exp $
    28 // GEANT4 tag $Name: $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030//---------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/include/G4VEmFluctuationModel.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmFluctuationModel.hh,v 1.10 2006/06/29 19:54:41 gunter Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4VEmFluctuationModel.hh,v 1.12 2009/02/19 11:25:50 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    9595  virtual void InitialiseMe(const G4ParticleDefinition*);
    9696
     97  virtual void SetParticleAndCharge(const G4ParticleDefinition*, G4double q2);
     98
    9799  //------------------------------------------------------------------------
    98100  // Generic methods common to all models
    99101  //------------------------------------------------------------------------
    100102
    101   G4String GetName() const;
     103  inline G4String GetName() const;
    102104
    103105private:
     
    113115//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    114116
    115 inline void G4VEmFluctuationModel::InitialiseMe(const G4ParticleDefinition*)
    116 {}
    117 
    118117inline G4String G4VEmFluctuationModel::GetName() const
    119118{
  • trunk/source/processes/electromagnetic/utils/include/G4VEmModel.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmModel.hh,v 1.48 2007/10/29 08:38:58 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEmModel.hh,v 1.66 2009/02/19 09:57:36 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    6161// 29-06-06 Add member currentElement and Get/Set methods (V.Ivanchenko)
    6262// 29-10-07 Added SampleScattering (V.Ivanchenko)
     63// 15-07-08 Reorder class members and improve comments (VI)
     64// 21-07-08 Added vector of G4ElementSelector and methods to use it (VI)
     65// 12-09-08 Added methods GetParticleCharge, GetChargeSquareRatio,
     66//          CorrectionsAlongStep, ActivateNuclearStopping (VI)
     67// 16-02-09 Move implementations of virtual methods to source (VI)
    6368//
    6469// Class Description:
     
    8186#include "G4DataVector.hh"
    8287#include "G4VEmFluctuationModel.hh"
     88#include "G4EmElementSelector.hh"
    8389#include "Randomize.hh"
     90#include <vector>
    8491
    8592class G4PhysicsTable;
     
    98105
    99106  //------------------------------------------------------------------------
    100   // Virtual methods to be implemented for the concrete model
    101   //------------------------------------------------------------------------
    102 
    103   virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&) = 0;
    104 
     107  // Virtual methods to be implemented for any concrete model
     108  //------------------------------------------------------------------------
     109
     110  virtual void Initialise(const G4ParticleDefinition*,
     111                          const G4DataVector&) = 0;
    105112
    106113  virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
     
    114121  //------------------------------------------------------------------------
    115122
    116   virtual G4double MinEnergyCut(const G4ParticleDefinition*,
    117                         const G4MaterialCutsCouple*);
    118 
    119   virtual G4double ComputeDEDX(const G4MaterialCutsCouple*,
    120                                const G4ParticleDefinition*,
    121                                G4double kineticEnergy,
    122                                G4double cutEnergy = DBL_MAX);
    123 
    124   virtual G4double CrossSection(const G4MaterialCutsCouple*,
    125                                 const G4ParticleDefinition*,
    126                                 G4double kineticEnergy,
    127                                 G4double cutEnergy = 0.0,
    128                                 G4double maxEnergy = DBL_MAX);
    129 
     123  // main method to compute dEdx
    130124  virtual G4double ComputeDEDXPerVolume(const G4Material*,
    131125                                        const G4ParticleDefinition*,
     
    133127                                        G4double cutEnergy = DBL_MAX);
    134128
    135 
    136   virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
    137                                               G4double kinEnergy,
    138                                               G4double Z,
    139                                               G4double A = 0.,
    140                                               G4double cutEnergy = 0.0,
    141                                               G4double maxEnergy = DBL_MAX);
    142                                      
    143   virtual G4double ComputeMeanFreePath(const G4ParticleDefinition*,
    144                                        G4double kineticEnergy,
    145                                        const G4Material*,   
    146                                        G4double cutEnergy = 0.0,
    147                                        G4double maxEnergy = DBL_MAX);
    148                                      
     129  // main method to compute cross section per Volume
    149130  virtual G4double CrossSectionPerVolume(const G4Material*,
    150131                                         const G4ParticleDefinition*,
     
    153134                                         G4double maxEnergy = DBL_MAX);
    154135
     136  // main method to compute cross section depending on atom
     137  virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
     138                                              G4double kinEnergy,
     139                                              G4double Z,
     140                                              G4double A = 0., /* amu */
     141                                              G4double cutEnergy = 0.0,
     142                                              G4double maxEnergy = DBL_MAX);
     143                                                                     
     144  // min cut in kinetic energy allowed by the model
     145  virtual G4double MinEnergyCut(const G4ParticleDefinition*,
     146                                const G4MaterialCutsCouple*);
     147
     148  // Compute effective ion charge square
     149  virtual G4double GetChargeSquareRatio(const G4ParticleDefinition*,
     150                                        const G4Material*,
     151                                        G4double kineticEnergy);
     152
     153  // Compute ion charge
     154  virtual G4double GetParticleCharge(const G4ParticleDefinition*,
     155                                     const G4Material*,
     156                                     G4double kineticEnergy);
     157
     158  // add correction to energy loss and ompute non-ionizing energy loss
     159  virtual void CorrectionsAlongStep(const G4MaterialCutsCouple*,
     160                                    const G4DynamicParticle*,
     161                                    G4double& eloss,
     162                                    G4double& niel,
     163                                    G4double length);
     164
     165  // sample PIXE deexcitation
     166  virtual void SampleDeexcitationAlongStep(const G4Material*,
     167                                           const G4Track&,
     168                                           G4double& eloss);
     169
    155170protected:
    156171
     172  // kinematically allowed max kinetic energy of a secondary
    157173  virtual G4double MaxSecondaryEnergy(const G4ParticleDefinition*,
    158174                                      G4double kineticEnergy); 
     
    177193  virtual void DefineForRegion(const G4Region*);
    178194
     195  virtual void SetupForMaterial(const G4ParticleDefinition*,
     196                                const G4Material*,
     197                                G4double kineticEnergy);
     198
    179199  //------------------------------------------------------------------------
    180200  // Generic methods common to all models
    181201  //------------------------------------------------------------------------
    182202
    183   void SetParticleChange(G4VParticleChange*, G4VEmFluctuationModel*);
    184 
    185   G4VEmFluctuationModel* GetModelOfFluctuations();
    186 
    187   G4double HighEnergyLimit();
    188 
    189   G4double LowEnergyLimit();
    190 
    191   void SetHighEnergyLimit(G4double);
    192 
    193   void SetLowEnergyLimit(G4double);
    194 
    195   G4double MaxSecondaryKinEnergy(const G4DynamicParticle* dynParticle);
    196 
    197   const G4Element* SelectRandomAtom(const G4Material*,
    198                                     const G4ParticleDefinition*,
    199                                     G4double kineticEnergy,
    200                                     G4double cutEnergy = 0.0,
    201                                     G4double maxEnergy = DBL_MAX);
    202 
    203   const G4String& GetName() const;
     203  // should be called at initialisation to build element selectors
     204  void InitialiseElementSelectors(const G4ParticleDefinition*,
     205                                  const G4DataVector&);
     206
     207  // dEdx per unit length
     208  inline G4double ComputeDEDX(const G4MaterialCutsCouple*,
     209                              const G4ParticleDefinition*,
     210                              G4double kineticEnergy,
     211                              G4double cutEnergy = DBL_MAX);
     212
     213  // cross section per volume
     214  inline G4double CrossSection(const G4MaterialCutsCouple*,
     215                                const G4ParticleDefinition*,
     216                                G4double kineticEnergy,
     217                                G4double cutEnergy = 0.0,
     218                                G4double maxEnergy = DBL_MAX);
     219
     220  // compute mean free path via cross section per volume
     221  inline G4double ComputeMeanFreePath(const G4ParticleDefinition*,
     222                                      G4double kineticEnergy,
     223                                      const G4Material*,   
     224                                      G4double cutEnergy = 0.0,
     225                                      G4double maxEnergy = DBL_MAX);
     226
     227  // generic cross section per element
     228  inline G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
     229                                             const G4Element*,
     230                                             G4double kinEnergy,
     231                                             G4double cutEnergy = 0.0,
     232                                             G4double maxEnergy = DBL_MAX);
     233
     234  // atom can be selected effitiantly if element selectors are initialised
     235  inline const G4Element* SelectRandomAtom(const G4MaterialCutsCouple*,
     236                                           const G4ParticleDefinition*,
     237                                           G4double kineticEnergy,
     238                                           G4double cutEnergy = 0.0,
     239                                           G4double maxEnergy = DBL_MAX);
     240
     241  // to select atom cross section per volume is recomputed for each element
     242  inline const G4Element* SelectRandomAtom(const G4Material*,
     243                                           const G4ParticleDefinition*,
     244                                           G4double kineticEnergy,
     245                                           G4double cutEnergy = 0.0,
     246                                           G4double maxEnergy = DBL_MAX);
     247
     248  // select isotope in order to have precise mass of the nucleus
     249  inline G4int SelectIsotopeNumber(const G4Element*);
     250
     251  //------------------------------------------------------------------------
     252  // Get/Set methods
     253  //------------------------------------------------------------------------
     254
     255  inline G4VEmFluctuationModel* GetModelOfFluctuations();
     256
     257  inline G4double HighEnergyLimit() const;
     258
     259  inline G4double LowEnergyLimit() const;
     260
     261  inline G4double PolarAngleLimit() const;
     262
     263  inline G4double SecondaryThreshold() const;
     264
     265  inline G4bool LPMFlag() const;
     266
     267  inline G4bool DeexcitationFlag() const;
     268
     269  inline void SetHighEnergyLimit(G4double);
     270
     271  inline void SetLowEnergyLimit(G4double);
     272
     273  inline void SetPolarAngleLimit(G4double);
     274
     275  inline void SetSecondaryThreshold(G4double);
     276
     277  inline void SetLPMFlag(G4bool val);
     278
     279  inline void SetDeexcitationFlag(G4bool val);
     280
     281  inline void ActivateNuclearStopping(G4bool);
     282
     283  inline G4double MaxSecondaryKinEnergy(const G4DynamicParticle* dynParticle);
     284
     285  inline const G4String& GetName() const;
     286
     287  inline void SetParticleChange(G4VParticleChange*, G4VEmFluctuationModel*);
     288
     289  inline void SetCurrentCouple(const G4MaterialCutsCouple*);
    204290
    205291protected:
    206292
    207   const G4Element* GetCurrentElement() const;
    208 
    209   void SetCurrentElement(const G4Element*);
     293  inline const G4MaterialCutsCouple* CurrentCouple() const;
     294
     295  inline void SetCurrentElement(const G4Element*);
     296
     297  inline const G4Element* GetCurrentElement() const;
    210298
    211299private:
     
    215303  G4VEmModel(const  G4VEmModel&);
    216304
     305  // ======== Parameters of the class fixed at construction =========
     306
     307  G4VEmFluctuationModel* fluc;
     308  const G4String   name;
     309
     310  // ======== Parameters of the class fixed at initialisation =======
     311
    217312  G4double        lowLimit;
    218313  G4double        highLimit;
    219   G4double        xsec[40];
    220 
    221   G4VEmFluctuationModel* fluc;
    222 
    223   const G4String   name;
    224   const G4Element* currentElement;
     314  G4double        polarAngleLimit;
     315  G4double        secondaryThreshold;
     316  G4bool          theLPMflag;
     317
     318  G4int           nSelectors;
     319  std::vector<G4EmElementSelector*> elmSelectors;
    225320
    226321protected:
    227322
    228323  G4VParticleChange*  pParticleChange;
     324  G4bool              nuclearStopping;
     325
     326  // ======== Cashed values - may be state dependent ================
     327
     328private:
     329
     330  const G4MaterialCutsCouple* currentCouple;
     331  const G4Element*            currentElement;
     332
     333  G4int                  nsec;
     334  G4bool                 flagDeexcitation;
     335  std::vector<G4double>  xsec;
     336
    229337};
    230338
    231339//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    232 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    233 
    234 inline G4double G4VEmModel::HighEnergyLimit()
    235 {
    236   return highLimit;
    237 }
    238 
    239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    240 
    241 inline G4double G4VEmModel::LowEnergyLimit()
    242 {
    243   return lowLimit;
    244 }
    245 
    246 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    247 
    248 inline void G4VEmModel::SetHighEnergyLimit(G4double val)
    249 {
    250   highLimit = val;
    251 }
    252 
    253 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    254 
    255 inline void G4VEmModel::SetLowEnergyLimit(G4double val)
    256 {
    257   lowLimit = val;
    258 }
    259 
    260 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    261 
    262 inline void G4VEmModel::SetParticleChange(G4VParticleChange* p, 
    263                                           G4VEmFluctuationModel* f = 0)
    264 {
    265   if(p && pParticleChange != p) pParticleChange = p;
    266   fluc = f;
    267 }
    268 
    269 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    270 
    271 
    272 inline G4VEmFluctuationModel* G4VEmModel::GetModelOfFluctuations()
    273 {
    274   return fluc;
    275 }
    276 
    277 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    278 
    279 inline G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*,
    280                                          const G4MaterialCutsCouple*)
    281 {
    282   return 0.0;
    283 }
    284 
    285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    286 
    287 inline G4double G4VEmModel::ComputeDEDXPerVolume(
    288                                         const G4Material*,
    289                                         const G4ParticleDefinition*,
    290                                         G4double,
    291                                         G4double)
    292 {
    293   return 0.0;
    294 }
    295 
    296340//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    297341
     
    301345                                        G4double cutEnergy)
    302346{
     347  currentCouple = c;
    303348  return ComputeDEDXPerVolume(c->GetMaterial(),p,kinEnergy,cutEnergy);
    304349}
     
    312357                                         G4double maxEnergy)
    313358{
    314   return
    315     CrossSectionPerVolume(c->GetMaterial(),p,kinEnergy,cutEnergy,maxEnergy);
     359  currentCouple = c;
     360  return CrossSectionPerVolume(c->GetMaterial(),p,kinEnergy,cutEnergy,maxEnergy);
     361}
     362
     363//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     364
     365inline G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
     366                                                G4double ekin,
     367                                                const G4Material* material,     
     368                                                G4double emin,
     369                                                G4double emax)
     370{
     371  G4double mfp = DBL_MAX;
     372  G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax);
     373  if (cross > DBL_MIN) mfp = 1./cross;
     374  return mfp;
    316375}
    317376
     
    319378
    320379inline G4double G4VEmModel::ComputeCrossSectionPerAtom(
    321                                          const G4ParticleDefinition*,
    322                                          G4double, G4double, G4double,
    323                                          G4double, G4double)
    324 {
    325   return 0.0;
    326 }
    327 
    328 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    329 
    330 inline const G4Element* G4VEmModel::SelectRandomAtom(
    331                                          const G4Material* material,
    332                                          const G4ParticleDefinition* pd,
    333                                          G4double kinEnergy,
    334                                          G4double tcut,
    335                                          G4double tmax)
     380                const G4ParticleDefinition* part,
     381                const G4Element* elm,
     382                G4double kinEnergy,
     383                G4double cutEnergy,
     384                G4double maxEnergy)
     385{
     386  currentElement = elm;
     387  return ComputeCrossSectionPerAtom(part,kinEnergy,elm->GetZ(),elm->GetN(),
     388                                    cutEnergy,maxEnergy);
     389}
     390
     391//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     392
     393inline
     394const G4Element* G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple,
     395                                              const G4ParticleDefinition* p,
     396                                              G4double kinEnergy,
     397                                              G4double cutEnergy,
     398                                              G4double maxEnergy)
     399{
     400  currentCouple = couple;
     401  if(nSelectors > 0) {
     402    currentElement =
     403      elmSelectors[couple->GetIndex()]->SelectRandomAtom(kinEnergy);
     404  } else {
     405    currentElement = SelectRandomAtom(couple->GetMaterial(),p,kinEnergy,
     406                                      cutEnergy,maxEnergy);
     407  }
     408  return currentElement;
     409}
     410
     411//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     412
     413inline
     414const G4Element* G4VEmModel::SelectRandomAtom(const G4Material* material,
     415                                              const G4ParticleDefinition* pd,
     416                                              G4double kinEnergy,
     417                                              G4double tcut,
     418                                              G4double tmax)
    336419{
    337420  const G4ElementVector* theElementVector = material->GetElementVector();
    338   G4int nelm = material->GetNumberOfElements();
    339   currentElement = (*theElementVector)[nelm-1];
    340   if (nelm > 1) {
     421  G4int n = material->GetNumberOfElements() - 1;
     422  currentElement = (*theElementVector)[n];
     423  if (n > 0) {
    341424    G4double x = G4UniformRand()*
    342                  CrossSectionPerVolume(material,pd,kinEnergy,tcut,tmax);
    343     for(G4int i=0; i<nelm; i++) {
     425                 G4VEmModel::CrossSectionPerVolume(material,pd,kinEnergy,tcut,tmax);
     426    for(G4int i=0; i<n; i++) {
    344427      if (x <= xsec[i]) {
    345428        currentElement = (*theElementVector)[i];
     
    353436//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    354437
     438inline G4int G4VEmModel::SelectIsotopeNumber(const G4Element* elm)
     439{
     440  G4int N = G4int(elm->GetN() + 0.5);
     441  G4int ni = elm->GetNumberOfIsotopes();
     442  if(ni > 0) {
     443    G4int idx = 0;
     444    if(ni > 1) {
     445      G4double* ab = currentElement->GetRelativeAbundanceVector();
     446      G4double x = G4UniformRand();
     447      for(; idx<ni; idx++) {
     448        x -= ab[idx];
     449        if (x <= 0.0) break;
     450      }
     451      if(idx >= ni) idx = ni - 1;
     452    }
     453    N = elm->GetIsotope(idx)->GetN();
     454  }
     455  return N;
     456}
     457
     458//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     459
     460inline G4VEmFluctuationModel* G4VEmModel::GetModelOfFluctuations()
     461{
     462  return fluc;
     463}
     464
     465//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     466
     467inline G4double G4VEmModel::HighEnergyLimit() const
     468{
     469  return highLimit;
     470}
     471
     472//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     473
     474inline G4double G4VEmModel::LowEnergyLimit() const
     475{
     476  return lowLimit;
     477}
     478
     479//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     480
     481inline G4double G4VEmModel::PolarAngleLimit() const
     482{
     483  return polarAngleLimit;
     484}
     485
     486//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     487
     488inline G4double G4VEmModel::SecondaryThreshold() const
     489{
     490  return secondaryThreshold;
     491}
     492
     493//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     494
     495inline G4bool G4VEmModel::LPMFlag() const
     496{
     497  return theLPMflag;
     498}
     499
     500//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     501
     502inline G4bool G4VEmModel::DeexcitationFlag() const
     503{
     504  return flagDeexcitation;
     505}
     506
     507//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     508
     509inline void G4VEmModel::SetHighEnergyLimit(G4double val)
     510{
     511  highLimit = val;
     512}
     513
     514//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     515
     516inline void G4VEmModel::SetLowEnergyLimit(G4double val)
     517{
     518  lowLimit = val;
     519}
     520
     521//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     522
     523inline void G4VEmModel::SetPolarAngleLimit(G4double val)
     524{
     525  polarAngleLimit = val;
     526}
     527
     528//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     529
     530inline void G4VEmModel::SetSecondaryThreshold(G4double val)
     531{
     532  secondaryThreshold = val;
     533}
     534
     535//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     536
     537inline void G4VEmModel::SetLPMFlag(G4bool val)
     538{
     539  theLPMflag = val;
     540}
     541
     542//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     543
     544inline void G4VEmModel::SetDeexcitationFlag(G4bool val)
     545{
     546  flagDeexcitation = val;
     547}
     548
     549//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     550
     551inline void G4VEmModel::ActivateNuclearStopping(G4bool val)
     552{
     553  nuclearStopping = val;
     554}
     555
     556//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     557
     558inline
     559G4double G4VEmModel::MaxSecondaryKinEnergy(const G4DynamicParticle* dynPart)
     560{
     561  return MaxSecondaryEnergy(dynPart->GetDefinition(),
     562                            dynPart->GetKineticEnergy());
     563}
     564
     565//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     566
     567inline const G4String& G4VEmModel::GetName() const
     568{
     569  return name;
     570}
     571
     572//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     573
     574inline void G4VEmModel::SetParticleChange(G4VParticleChange* p, 
     575                                          G4VEmFluctuationModel* f = 0)
     576{
     577  if(p && pParticleChange != p) pParticleChange = p;
     578  fluc = f;
     579}
     580
     581//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     582
     583inline void G4VEmModel::SetCurrentCouple(const G4MaterialCutsCouple* p)
     584{
     585  currentCouple = p;
     586}
     587
     588//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     589
     590inline const G4MaterialCutsCouple* G4VEmModel::CurrentCouple() const
     591{
     592  return currentCouple;
     593}
     594
     595//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     596
     597inline void G4VEmModel::SetCurrentElement(const G4Element* elm)
     598{
     599  currentElement = elm;
     600}
     601
     602//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     603
    355604inline const G4Element* G4VEmModel::GetCurrentElement() const
    356605{
     
    360609//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    361610
    362 inline void G4VEmModel::SetCurrentElement(const G4Element* elm)
    363 {
    364   currentElement = elm;
    365 }
    366 
    367 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    368 
    369 inline G4double G4VEmModel::MaxSecondaryKinEnergy(
    370                                           const G4DynamicParticle* dynParticle)
    371 {
    372   return MaxSecondaryEnergy(dynParticle->GetDefinition(),
    373                             dynParticle->GetKineticEnergy());
    374 }
    375 
    376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    377 
    378 inline G4double G4VEmModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
    379                                                G4double kineticEnergy)
    380 {
    381   return kineticEnergy;
    382 }
    383 
    384 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    385 
    386 inline const G4String& G4VEmModel::GetName() const
    387 {
    388   return name;
    389 }
    390 
    391 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    392 // Methods for msc simulation
    393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    394 
    395 inline void G4VEmModel::SampleScattering(const G4DynamicParticle*, G4double)
    396 {}
    397 
    398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    399 
    400 inline G4double G4VEmModel::ComputeTruePathLengthLimit(
    401                                 const G4Track&,
    402                                 G4PhysicsTable*,
    403                                 G4double)
    404 {
    405   return DBL_MAX;
    406 }
    407 
    408 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    409 
    410 inline G4double G4VEmModel::ComputeGeomPathLength(G4double truePathLength)
    411 {
    412   return truePathLength;
    413 }
    414 
    415 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    416 
    417 inline G4double G4VEmModel::ComputeTrueStepLength(G4double geomPathLength)
    418 {
    419   return geomPathLength;
    420 }
    421 
    422 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    423 
    424 inline void G4VEmModel::DefineForRegion(const G4Region*)
    425 {}
    426 
    427 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    428 
    429611#endif
    430612
  • trunk/source/processes/electromagnetic/utils/include/G4VEmProcess.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmProcess.hh,v 1.43 2007/10/29 08:38:58 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEmProcess.hh,v 1.50 2009/02/19 09:57:36 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5555//          PostStepGetPhysicalInteractionLength (V.Ivanchenko)
    5656// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
     57// 15-07-08 Reorder class members for further multi-thread development (VI)
    5758//
    5859// Class Description:
     
    9091
    9192  G4VEmProcess(const G4String& name,
    92                      G4ProcessType type = fElectromagnetic);
     93               G4ProcessType type = fElectromagnetic);
    9394
    9495  virtual ~G4VEmProcess();
     
    107108
    108109  //------------------------------------------------------------------------
    109   // Methods with standard implementation; may be overwritten if needed
    110   //------------------------------------------------------------------------
    111 
    112   inline G4double RecalculateLambda(G4double kinEnergy,
    113                                     const G4MaterialCutsCouple* couple);
    114 
    115   //------------------------------------------------------------------------
    116   // Generic methods common to all Discrete processes
     110  // Implementation of virtual methods common to all Discrete processes
    117111  //------------------------------------------------------------------------
    118112
    119113public:
    120114
     115  // Initialise for build of tables
     116  void PreparePhysicsTable(const G4ParticleDefinition&);
     117
     118  // Build physics table during initialisation
     119  void BuildPhysicsTable(const G4ParticleDefinition&);
     120
    121121  void PrintInfoDefinition();
    122122
    123   G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
    124 
    125   void PreparePhysicsTable(const G4ParticleDefinition&);
    126   // Initialise for build of tables
    127 
    128   void BuildPhysicsTable(const G4ParticleDefinition&);
    129   // Build physics table during initialisation
    130 
    131   G4bool StorePhysicsTable(const G4ParticleDefinition*,
    132                            const G4String& directory,
    133                            G4bool ascii = false);
    134   // Store PhysicsTable in a file.
    135   // Return false in case of failure at I/O
    136 
    137   G4bool RetrievePhysicsTable(const G4ParticleDefinition*,
    138                               const G4String& directory,
    139                               G4bool ascii);
    140     // Retrieve Physics from a file.
    141     // (return true if the Physics Table can be build by using file)
    142     // (return false if the process has no functionality or in case of failure)
    143     // File name should is constructed as processName+particleName and the
    144     // should be placed under the directory specifed by the argument.
    145 
    146   //------------------------------------------------------------------------
    147   // Specific methods for Discrete EM post step simulation
    148   //------------------------------------------------------------------------
    149 
    150   inline G4double MicroscopicCrossSection(G4double kineticEnergy,
    151                                           const G4MaterialCutsCouple* couple);
    152   // It returns the cross section of the process for energy/ material
    153 
    154   inline G4double ComputeCrossSectionPerAtom(G4double kineticEnergy,
    155                                              G4double Z, G4double A=0.,
    156                                              G4double cut=0.0);
    157   // It returns the cross section of the process per atom
    158 
    159   inline G4double MeanFreePath(const G4Track& track);
    160 
    161   virtual G4double PostStepGetPhysicalInteractionLength(
     123  // implementation of virtual method, specific for G4VEmProcess
     124  G4double PostStepGetPhysicalInteractionLength(
    162125                             const G4Track& track,
    163126                             G4double   previousStepSize,
     
    165128                            );
    166129
     130  // implementation of virtual method, specific for G4VEmProcess
     131  G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
     132
     133  // Store PhysicsTable in a file.
     134  // Return false in case of failure at I/O
     135  G4bool StorePhysicsTable(const G4ParticleDefinition*,
     136                           const G4String& directory,
     137                           G4bool ascii = false);
     138
     139  // Retrieve Physics from a file.
     140  // (return true if the Physics Table can be build by using file)
     141  // (return false if the process has no functionality or in case of failure)
     142  // File name should is constructed as processName+particleName and the
     143  // should be placed under the directory specifed by the argument.
     144  G4bool RetrievePhysicsTable(const G4ParticleDefinition*,
     145                              const G4String& directory,
     146                              G4bool ascii);
     147
     148  // deexcitation activated per G4Region
     149  void ActivateDeexcitation(G4bool, const G4Region* r = 0);
     150
     151  //------------------------------------------------------------------------
     152  // Specific methods for Discrete EM post step simulation
     153  //------------------------------------------------------------------------
     154
     155  // It returns the cross section per volume for energy/ material
     156  G4double CrossSectionPerVolume(G4double kineticEnergy,
     157                                 const G4MaterialCutsCouple* couple);
     158
     159  // It returns the cross section of the process per atom
     160  inline G4double ComputeCrossSectionPerAtom(G4double kineticEnergy,
     161                                             G4double Z, G4double A=0.,
     162                                             G4double cut=0.0);
     163
     164  inline G4double MeanFreePath(const G4Track& track);
     165
     166  // It returns cross section per volume
     167  inline G4double GetLambda(G4double& kinEnergy,
     168                            const G4MaterialCutsCouple* couple);
     169
     170  //------------------------------------------------------------------------
     171  // Specific methods to build and access Physics Tables
     172  //------------------------------------------------------------------------
     173
     174  // Binning for lambda table
     175  inline void SetLambdaBinning(G4int nbins);
     176  inline G4int LambdaBinning() const;
     177
     178  // Min kinetic energy for tables
     179  inline void SetMinKinEnergy(G4double e);
     180  inline G4double MinKinEnergy() const;
     181
     182  // Max kinetic energy for tables
     183  inline void SetMaxKinEnergy(G4double e);
     184  inline G4double MaxKinEnergy() const;
     185
     186  inline void SetPolarAngleLimit(G4double a);
     187  inline G4double PolarAngleLimit() const;
     188
     189  inline const G4PhysicsTable* LambdaTable() const;
     190
     191  //------------------------------------------------------------------------
     192  // Define and access particle type
     193  //------------------------------------------------------------------------
     194
     195  inline const G4ParticleDefinition* Particle() const;
     196  inline const G4ParticleDefinition* SecondaryParticle() const;
     197
     198  //------------------------------------------------------------------------
     199  // Specific methods to set, access, modify models and basic parameters
     200  //------------------------------------------------------------------------
     201
     202protected:
     203  // Select model in run time
     204  inline void SelectModel(G4double& kinEnergy);
     205
     206public:
     207  // Select model by energy and region index
    167208  inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy,
    168209                                            size_t& idxRegion) const;
    169 
    170   inline G4double GetLambda(G4double& kinEnergy,
    171                             const G4MaterialCutsCouple* couple);
    172   // It returns the Lambda of the process
    173 
    174   //------------------------------------------------------------------------
    175   // Specific methods to build and access Physics Tables
    176   //------------------------------------------------------------------------
    177 
    178   inline void SetLambdaBinning(G4int nbins);
    179   inline G4int LambdaBinning() const;
    180   // Binning for lambda table
    181 
    182   inline void SetMinKinEnergy(G4double e);
    183   inline G4double MinKinEnergy() const;
    184   // Min kinetic energy for tables
    185 
    186   inline void SetMaxKinEnergy(G4double e);
    187   inline G4double MaxKinEnergy() const;
    188   // Max kinetic energy for tables
    189 
    190   inline const G4PhysicsTable* LambdaTable() const;
    191 
    192   //------------------------------------------------------------------------
    193   // Define and access particle type
    194   //------------------------------------------------------------------------
    195 
    196   inline const G4ParticleDefinition* Particle() const;
    197   inline const G4ParticleDefinition* SecondaryParticle() const;
    198 
    199   //------------------------------------------------------------------------
    200   // Specific methods to set, access, modify models
    201   //------------------------------------------------------------------------
    202 
     210   
     211  // Add model for region, smaller value of order defines which
     212  // model will be selected for a given energy interval 
    203213  inline void AddEmModel(G4int, G4VEmModel*, const G4Region* region = 0);
    204   // Add EM model coupled for the region
    205    
    206   inline void SetModel(G4VEmModel*);
     214
    207215  // Assign a model to a process
     216  inline void SetModel(G4VEmModel*, G4int index = 1);
    208217 
    209   inline G4VEmModel* Model();
    210218  // return the assigned model
     219  inline G4VEmModel* Model(G4int index = 1);
    211220   
     221  // Define new energy range for the model identified by the name
    212222  inline void UpdateEmModel(const G4String&, G4double, G4double);
    213   // Define new energy range for the model identified by the name
    214223
    215224  // Access to models
    216   inline G4VEmModel* GetModelByIndex(G4int idx = 0);
    217 
    218   //------------------------------------------------------------------------
    219   // Get/set parameters used for simulation of energy loss
    220   //------------------------------------------------------------------------
    221 
    222   inline void ActivateDeexcitation(G4bool, const G4Region* r = 0);
     225  inline G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false);
    223226
    224227  inline void SetLambdaFactor(G4double val);
     
    228231
    229232  inline void SetApplyCuts(G4bool val);
     233
     234  //------------------------------------------------------------------------
     235  // Other generic methods
     236  //------------------------------------------------------------------------
    230237 
    231238protected:
     
    237244  G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*);
    238245
     246  inline G4double RecalculateLambda(G4double kinEnergy,
     247                                    const G4MaterialCutsCouple* couple);
     248
     249  inline G4ParticleChangeForGamma* GetParticleChange();
     250
    239251  inline void SetParticle(const G4ParticleDefinition* p);
    240252 
    241253  inline void SetSecondaryParticle(const G4ParticleDefinition* p);
    242254
    243   inline G4VEmModel* SelectModel(G4double& kinEnergy);
    244 
    245255  inline size_t CurrentMaterialCutsCoupleIndex() const;
    246256
     
    273283  inline G4double ComputeCurrentLambda(G4double kinEnergy);
    274284
    275   // hide  assignment operator
    276 
     285  // copy constructor and hide assignment operator
    277286  G4VEmProcess(G4VEmProcess &);
    278287  G4VEmProcess & operator=(const G4VEmProcess &right);
    279288
    280 // =====================================================================
    281 
    282 protected:
    283 
    284   G4ParticleChangeForGamma     fParticleChange;
    285 
    286 private:
    287 
    288   std::vector<G4DynamicParticle*> secParticles;
     289  // ======== Parameters of the class fixed at construction =========
    289290
    290291  G4EmModelManager*            modelManager;
    291   G4VEmModel*                  selectedModel; 
     292  const G4ParticleDefinition*  theGamma;
     293  const G4ParticleDefinition*  theElectron;
     294  const G4ParticleDefinition*  thePositron;
     295  const G4ParticleDefinition*  secondaryParticle;
     296
     297  G4bool                       buildLambdaTable;
     298
     299  // ======== Parameters of the class fixed at initialisation =======
     300
     301  std::vector<G4VEmModel*>     emModels;
    292302
    293303  // tables and vectors
     
    296306  G4double*                    theCrossSectionMax;
    297307
    298   const G4ParticleDefinition*  particle;
    299   const G4ParticleDefinition*  secondaryParticle;
    300   const G4ParticleDefinition*  theGamma;
    301   const G4ParticleDefinition*  theElectron;
    302   const G4ParticleDefinition*  thePositron;
    303 
    304308  const std::vector<G4double>* theCuts;
    305309  const std::vector<G4double>* theCutsGamma;
     
    312316  G4double                     maxKinEnergy;
    313317  G4double                     lambdaFactor;
     318  G4double                     polarAngleLimit;
     319
     320  G4bool                       integral;
     321  G4bool                       applyCuts;
     322  G4bool                       startFromNull;
     323  G4bool                       useDeexcitation;
     324
     325  G4int                        nDERegions;
     326  std::vector<const G4Region*> deRegions;
     327  G4bool*                      idxDERegions;
     328
     329  // ======== Cashed values - may be state dependent ================
     330
     331protected:
     332
     333  G4ParticleChangeForGamma     fParticleChange;
     334
     335private:
     336
     337  std::vector<G4DynamicParticle*> secParticles;
     338
     339  G4VEmModel*                  currentModel; 
     340
     341  const G4ParticleDefinition*  particle;
    314342
    315343  // cash
     
    322350  G4double                     preStepLambda;
    323351
    324   G4bool                       integral;
    325   G4bool                       buildLambdaTable;
    326   G4bool                       applyCuts;
    327   G4bool                       startFromNull;
    328 
    329   G4int                        nRegions;
    330   std::vector<G4Region*>       regions;
    331   std::vector<G4bool>          flagsDeexcitation;
    332 
    333352};
    334353
    335354//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     355//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     356
     357inline G4double G4VEmProcess::ComputeCrossSectionPerAtom(
     358                 G4double kineticEnergy, G4double Z, G4double A, G4double cut)
     359{
     360  SelectModel(kineticEnergy);
     361  G4double x = 0.0;
     362  if(currentModel) {
     363   x = currentModel->ComputeCrossSectionPerAtom(particle,kineticEnergy,
     364                                                 Z,A,cut);
     365  }
     366  return x;
     367}
     368
     369//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     370
     371inline G4double G4VEmProcess::MeanFreePath(const G4Track& track)
     372{
     373  DefineMaterial(track.GetMaterialCutsCouple());
     374  preStepLambda = GetCurrentLambda(track.GetKineticEnergy());
     375  G4double x = DBL_MAX;
     376  if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
     377  return x;
     378}
     379
     380//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     381
     382inline G4double G4VEmProcess::GetLambda(G4double& kineticEnergy,
     383                                        const G4MaterialCutsCouple* couple)
     384{
     385  DefineMaterial(couple);
     386  return GetCurrentLambda(kineticEnergy);
     387}
     388
     389//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     390
     391inline void G4VEmProcess::SetLambdaBinning(G4int nbins)
     392{
     393  nLambdaBins = nbins;
     394}
     395
     396//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     397
     398inline G4int G4VEmProcess::LambdaBinning() const
     399{
     400  return nLambdaBins;
     401}
     402
     403//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     404
     405inline void G4VEmProcess::SetMinKinEnergy(G4double e)
     406{
     407  minKinEnergy = e;
     408}
     409
     410//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     411
     412inline G4double G4VEmProcess::MinKinEnergy() const
     413{
     414  return minKinEnergy;
     415}
     416
     417//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     418
     419inline void G4VEmProcess::SetMaxKinEnergy(G4double e)
     420{
     421  maxKinEnergy = e;
     422}
     423
     424//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     425
     426inline G4double G4VEmProcess::MaxKinEnergy() const
     427{
     428  return maxKinEnergy;
     429}
     430
     431//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     432
     433inline void G4VEmProcess::SetPolarAngleLimit(G4double val)
     434{
     435  if(val < 0.0)     polarAngleLimit = 0.0;
     436  else if(val > pi) polarAngleLimit = pi;
     437  else              polarAngleLimit = val;
     438}
     439
     440//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     441
     442inline G4double G4VEmProcess::PolarAngleLimit() const
     443{
     444  return polarAngleLimit;
     445}
     446
     447//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     448
     449inline const G4PhysicsTable* G4VEmProcess::LambdaTable() const
     450{
     451  return theLambdaTable;
     452}
     453
     454//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     455
     456inline const G4ParticleDefinition* G4VEmProcess::Particle() const
     457{
     458  return particle;
     459}
     460
     461//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     462
     463inline const G4ParticleDefinition* G4VEmProcess::SecondaryParticle() const
     464{
     465  return secondaryParticle;
     466}
     467
     468//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     469
     470inline void G4VEmProcess::SelectModel(G4double& kinEnergy)
     471{
     472  currentModel = modelManager->SelectModel(kinEnergy, currentMaterialIndex);
     473  currentModel->SetCurrentCouple(currentCouple);
     474}
     475
     476//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     477
     478inline G4VEmModel* G4VEmProcess::SelectModelForMaterial(
     479                                   G4double kinEnergy, size_t& idxRegion) const
     480{
     481  return modelManager->SelectModel(kinEnergy, idxRegion);
     482}
     483
     484//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     485
     486inline void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* p,
     487                                     const G4Region* region)
     488{
     489  G4VEmFluctuationModel* fm = 0;
     490  modelManager->AddEmModel(order, p, fm, region);
     491  if(p) p->SetParticleChange(pParticleChange);
     492}
     493
     494//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     495
     496inline void G4VEmProcess::SetModel(G4VEmModel* p, G4int index)
     497{
     498  G4int n = emModels.size();
     499  if(index >= n) for(G4int i=n; i<index+1; i++) {emModels.push_back(0);}
     500  emModels[index] = p;
     501}
     502
     503//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     504
     505inline G4VEmModel* G4VEmProcess::Model(G4int index)
     506{
     507  G4VEmModel* p = 0;
     508  if(index >= 0 && index <  G4int(emModels.size())) p = emModels[index];
     509  return p;
     510}
     511
     512//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     513
     514inline void G4VEmProcess::UpdateEmModel(const G4String& nam,
     515                                        G4double emin, G4double emax)
     516{
     517  modelManager->UpdateEmModel(nam, emin, emax);
     518}
     519
     520//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     521
     522inline G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver)
     523{
     524  return modelManager->GetModel(idx, ver);
     525}
     526
     527//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     528
     529inline void G4VEmProcess::SetLambdaFactor(G4double val)
     530{
     531  if(val > 0.0 && val <= 1.0) lambdaFactor = val;
     532}
     533
     534//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     535
     536inline void G4VEmProcess::SetIntegral(G4bool val)
     537{
     538  if(particle && particle != theGamma) integral = val;
     539  if(integral) buildLambdaTable = true;
     540}
     541
     542//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     543
     544inline G4bool G4VEmProcess::IsIntegral() const
     545{
     546  return integral;
     547}
     548
     549//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     550
     551inline void G4VEmProcess::SetApplyCuts(G4bool val)
     552{
     553  applyCuts = val;
     554}
     555
     556//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     557
     558inline G4double G4VEmProcess::RecalculateLambda(G4double e,
     559                                                const G4MaterialCutsCouple* couple)
     560{
     561  DefineMaterial(couple);
     562  return ComputeCurrentLambda(e);
     563}
     564
     565//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     566
     567inline G4ParticleChangeForGamma* G4VEmProcess::GetParticleChange()
     568{
     569  return &fParticleChange;
     570}
     571
     572//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     573
     574inline void G4VEmProcess::SetParticle(const G4ParticleDefinition* p)
     575{
     576  particle = p;
     577}
     578
     579//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     580
     581inline void G4VEmProcess::SetSecondaryParticle(const G4ParticleDefinition* p)
     582{
     583  secondaryParticle = p;
     584}
     585
     586//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     587
     588inline size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
     589{
     590  return currentMaterialIndex;
     591}
     592
     593//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     594
     595inline G4double G4VEmProcess::GetGammaEnergyCut()
     596{
     597  return (*theCutsGamma)[currentMaterialIndex];
     598}
     599
     600//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     601
     602inline G4double G4VEmProcess::GetElectronEnergyCut()
     603{
     604  return (*theCutsElectron)[currentMaterialIndex];
     605}
     606
     607//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     608
     609inline void G4VEmProcess::SetBuildTableFlag(G4bool val)
     610{
     611  buildLambdaTable = val;
     612  if(!val) integral = false;
     613}
     614
     615//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     616
     617inline void G4VEmProcess::SetStartFromNullFlag(G4bool val)
     618{
     619  startFromNull = val;
     620}
     621
     622//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     623
     624inline void G4VEmProcess::InitialiseStep(const G4Track& track)
     625{
     626  preStepKinEnergy = track.GetKineticEnergy();
     627  DefineMaterial(track.GetMaterialCutsCouple());
     628  if (theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
     629}
     630
    336631//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    337632
     
    344639    mfpKinEnergy = DBL_MAX;
    345640  }
    346 }
    347 
    348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    349 
    350 inline void G4VEmProcess::InitialiseStep(const G4Track& track)
    351 {
    352   preStepKinEnergy = track.GetKineticEnergy();
    353   DefineMaterial(track.GetMaterialCutsCouple());
    354   if (theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
    355 }
    356 
    357 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    358 
    359 inline G4double G4VEmProcess::GetLambda(G4double& kineticEnergy,
    360                                   const G4MaterialCutsCouple* couple)
    361 {
    362   DefineMaterial(couple);
    363   return GetCurrentLambda(kineticEnergy);
    364 }
    365 
    366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    367 
    368 inline G4double G4VEmProcess::GetCurrentLambda(G4double e)
    369 {
    370   G4double x = 0.0;
    371   if(theLambdaTable) x = GetLambdaFromTable(e);
    372   else               x = ComputeCurrentLambda(e);
    373   return x;
    374 }
    375 
    376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    377 
    378 inline G4double G4VEmProcess::RecalculateLambda(G4double e,
    379                                                 const G4MaterialCutsCouple* couple)
    380 {
    381   DefineMaterial(couple);
    382   return ComputeCurrentLambda(e);
    383 }
    384 
    385 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    386 
    387 inline G4double G4VEmProcess::ComputeCurrentLambda(G4double e)
    388 {
    389   G4VEmModel* currentModel = SelectModel(e);
    390   G4double x = 0.0;
    391   if(currentModel)
    392     x = currentModel->CrossSectionPerVolume(currentMaterial,particle,
    393                                             e,(*theCuts)[currentMaterialIndex]);
    394   return x;
    395 }
    396 
    397 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    398 
    399 inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
    400 {
    401   G4bool b;
    402   return (((*theLambdaTable)[currentMaterialIndex])->GetValue(e, b));
    403641}
    404642
     
    428666//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    429667
    430 inline G4double G4VEmProcess::MeanFreePath(const G4Track& track)
    431 {
    432   DefineMaterial(track.GetMaterialCutsCouple());
    433   preStepLambda = GetCurrentLambda(track.GetKineticEnergy());
    434   G4double x = DBL_MAX;
    435   if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
     668inline G4double G4VEmProcess::GetLambdaFromTable(G4double e)
     669{
     670  G4bool b;
     671  return (((*theLambdaTable)[currentMaterialIndex])->GetValue(e, b));
     672}
     673
     674//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     675
     676inline G4double G4VEmProcess::GetCurrentLambda(G4double e)
     677{
     678  G4double x = 0.0;
     679  if(theLambdaTable) x = GetLambdaFromTable(e);
     680  else               x = ComputeCurrentLambda(e);
    436681  return x;
    437682}
     
    439684//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    440685
    441 inline G4VEmModel* G4VEmProcess::SelectModel(G4double& kinEnergy)
    442 {
    443   return modelManager->SelectModel(kinEnergy, currentMaterialIndex);
    444 }
    445 
    446 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    447 
    448 inline G4VEmModel* G4VEmProcess::SelectModelForMaterial(
    449                                    G4double kinEnergy, size_t& idxRegion) const
    450 {
    451   return modelManager->SelectModel(kinEnergy, idxRegion);
    452 }
    453 
    454 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    455 
    456 inline const G4ParticleDefinition* G4VEmProcess::Particle() const
    457 {
    458   return particle;
    459 }
    460 
    461 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    462 
    463 inline const G4ParticleDefinition* G4VEmProcess::SecondaryParticle() const
    464 {
    465   return secondaryParticle;
    466 }
    467 
    468 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    469 
    470 inline G4double G4VEmProcess::GetGammaEnergyCut()
    471 {
    472   return (*theCutsGamma)[currentMaterialIndex];
    473 }
    474 
    475 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    476 
    477 inline G4double G4VEmProcess::GetElectronEnergyCut()
    478 {
    479   return (*theCutsElectron)[currentMaterialIndex];
    480 }
    481 
    482 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    483 
    484 inline void G4VEmProcess::SetLambdaFactor(G4double val)
    485 {
    486   if(val > 0.0 && val <= 1.0) lambdaFactor = val;
    487 }
    488 
    489 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    490 
    491 inline G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx)
    492 {
    493   return modelManager->GetModel(idx);
    494 }
    495 
    496 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    497 
    498 inline void G4VEmProcess::SetParticle(const G4ParticleDefinition* p)
    499 {
    500   particle = p;
    501 }
    502 
    503 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    504 
    505 inline void G4VEmProcess::SetSecondaryParticle(const G4ParticleDefinition* p)
    506 {
    507   secondaryParticle = p;
    508 }
    509 
    510 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    511 
    512 inline void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* p,
    513                                      const G4Region* region)
    514 {
    515   G4VEmFluctuationModel* fm = 0;
    516   modelManager->AddEmModel(order, p, fm, region);
    517   if(p) p->SetParticleChange(pParticleChange);
    518 }
    519 
    520 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    521 
    522 inline void G4VEmProcess::SetModel(G4VEmModel* model)
    523 {
    524   selectedModel = model;
    525 }
    526 
    527 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    528 
    529 inline G4VEmModel* G4VEmProcess::Model()
    530 {
    531   return selectedModel;
    532 }
    533 
    534 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    535 
    536 inline void G4VEmProcess::UpdateEmModel(const G4String& nam,
    537                                         G4double emin, G4double emax)
    538 {
    539   modelManager->UpdateEmModel(nam, emin, emax);
    540 }
    541 
    542 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    543 
    544 inline G4double G4VEmProcess::ComputeCrossSectionPerAtom(
    545                  G4double kineticEnergy, G4double Z, G4double A, G4double cut)
    546 {
    547   G4VEmModel* model = SelectModel(kineticEnergy);
    548   return model->ComputeCrossSectionPerAtom(particle,kineticEnergy,Z,A,cut);
    549 }
    550 
    551 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    552 
    553 inline void G4VEmProcess::SetLambdaBinning(G4int nbins)
    554 {
    555   nLambdaBins = nbins;
    556 }
    557 
    558 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    559 
    560 inline G4int G4VEmProcess::LambdaBinning() const
    561 {
    562   return nLambdaBins;
    563 }
    564 
    565 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    566 
    567 inline void G4VEmProcess::SetMinKinEnergy(G4double e)
    568 {
    569   minKinEnergy = e;
    570 }
    571 
    572 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    573 
    574 inline G4double G4VEmProcess::MinKinEnergy() const
    575 {
    576   return minKinEnergy;
    577 }
    578 
    579 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    580 
    581 inline void G4VEmProcess::SetMaxKinEnergy(G4double e)
    582 {
    583   maxKinEnergy = e;
    584 }
    585 
    586 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    587 
    588 inline G4double G4VEmProcess::MaxKinEnergy() const
    589 {
    590   return maxKinEnergy;
    591 }
    592 
    593 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    594 
    595 inline void G4VEmProcess::ActivateDeexcitation(G4bool, const G4Region*)
    596 {}
    597 
    598 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    599 
    600 inline const G4PhysicsTable* G4VEmProcess::LambdaTable() const
    601 {
    602   return theLambdaTable;
    603 }
    604 
    605 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    606 
    607 inline void G4VEmProcess::SetIntegral(G4bool val)
    608 {
    609   if(particle && particle != theGamma) integral = val;
    610   if(integral) buildLambdaTable = true;
    611 }
    612 
    613 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    614 
    615 inline G4bool G4VEmProcess::IsIntegral() const
    616 {
    617   return integral;
    618 }
    619 
    620 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    621 
    622 inline void G4VEmProcess::SetBuildTableFlag(G4bool val)
    623 {
    624   buildLambdaTable = val;
    625   if(!val) integral = false;
    626 }
    627 
    628 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    629 
    630 inline void G4VEmProcess::SetStartFromNullFlag(G4bool val)
    631 {
    632   startFromNull = val;
    633 }
    634 
    635 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    636 
    637 inline void G4VEmProcess::SetApplyCuts(G4bool val)
    638 {
    639   applyCuts = val;
    640 }
    641 
    642 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    643 
    644 inline size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
    645 {
    646   return currentMaterialIndex;
     686inline G4double G4VEmProcess::ComputeCurrentLambda(G4double e)
     687{
     688  SelectModel(e);
     689  G4double x = 0.0;
     690  if(currentModel) {
     691    x = currentModel->CrossSectionPerVolume(currentMaterial,particle,
     692                                            e,(*theCuts)[currentMaterialIndex]);
     693  }
     694  return x;
    647695}
    648696
  • trunk/source/processes/electromagnetic/utils/include/G4VEnergyLoss.hh

    r819 r961  
    2626//
    2727// $Id: G4VEnergyLoss.hh,v 1.18 2006/06/29 19:54:47 gunter Exp $
    28 // GEANT4 tag $Name: $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030//
  • trunk/source/processes/electromagnetic/utils/include/G4VEnergyLossProcess.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEnergyLossProcess.hh,v 1.76 2007/11/07 18:38:49 vnivanch Exp $
     26// $Id: G4VEnergyLossProcess.hh,v 1.86 2009/02/19 09:57:36 vnivanch Exp $
    2727// GEANT4 tag $Name:
    2828//
     
    7979//          PostStepGetPhysicalInteractionLength (V.Ivanchenko)
    8080// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
     81// 15-07-08 Reorder class members for further multi-thread development (VI)
    8182//
    8283// Class Description:
     
    125126  virtual ~G4VEnergyLossProcess();
    126127
     128private:
     129  // clean vectors and arrays
     130  void Clean();
     131
    127132  //------------------------------------------------------------------------
    128133  // Virtual methods to be implemented in concrete processes
    129134  //------------------------------------------------------------------------
    130135
     136public:
    131137  virtual G4bool IsApplicable(const G4ParticleDefinition& p) = 0;
    132138 
     
    141147  // Methods with standard implementation; may be overwritten if needed
    142148  //------------------------------------------------------------------------
    143 protected:
    144149
    145150  virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*,
    146151                                    const G4Material*, G4double cut);
    147152
    148   virtual void CorrectionsAlongStep(const G4MaterialCutsCouple*,
    149                                     const G4DynamicParticle*,
    150                                     G4double& eloss,
    151                                     G4double& length);
    152 
    153   //------------------------------------------------------------------------
    154   // Generic methods common to all ContinuousDiscrete processes
    155   //------------------------------------------------------------------------
     153  //------------------------------------------------------------------------
     154  // Virtual methods implementation common to all EM ContinuousDiscrete
     155  // processes. Further inheritance is not assumed
     156  //------------------------------------------------------------------------
     157
    156158public:
    157159
     160  // prepare all tables
     161  void PreparePhysicsTable(const G4ParticleDefinition&);
     162
     163  // build all tables
     164  void BuildPhysicsTable(const G4ParticleDefinition&);
     165
     166  // build a table
     167  G4PhysicsTable* BuildDEDXTable(G4EmTableType tType = fRestricted);
     168
     169  // build a table
     170  G4PhysicsTable* BuildLambdaTable(G4EmTableType tType = fRestricted);
     171
     172  // summary printout after initialisation
    158173  void PrintInfoDefinition();
    159174
    160   void PreparePhysicsTable(const G4ParticleDefinition&);
    161 
    162   void BuildPhysicsTable(const G4ParticleDefinition&);
    163 
     175  // Add subcutoff option for the region
     176  void ActivateSubCutoff(G4bool val, const G4Region* region = 0);
     177
     178  // Activate deexcitation code for region
     179  void ActivateDeexcitation(G4bool, const G4Region* region = 0);
     180
     181  // Step limit from AlongStep
     182  G4double AlongStepGetPhysicalInteractionLength(const G4Track&,
     183                                                 G4double  previousStepSize,
     184                                                 G4double  currentMinimumStep,
     185                                                 G4double& currentSafety,
     186                                                 G4GPILSelection* selection);
     187
     188  // Step limit from cross section
     189  G4double PostStepGetPhysicalInteractionLength(const G4Track& track,
     190                                                G4double   previousStepSize,
     191                                                G4ForceCondition* condition);
     192
     193  // AlongStep computations
    164194  G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&);
    165195
     196  // Sampling of secondaries in vicinity of geometrical boundary
     197  void SampleSubCutSecondaries(std::vector<G4Track*>&, const G4Step&,
     198                               G4VEmModel* model, G4int matIdx,
     199                               G4double& extraEdep);
     200
     201  // PostStep sampling of secondaries
    166202  G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
    167203
    168   // Store PhysicsTable in a file.
    169   // Return false in case of failure at I/O
     204  // Store all PhysicsTable in files.
     205  // Return false in case of any fatal failure at I/O 
    170206  G4bool StorePhysicsTable(const G4ParticleDefinition*,
    171207                           const G4String& directory,
    172208                           G4bool ascii = false);
    173209
    174   // Retrieve Physics from a file.
    175   // (return true if the Physics Table can be build by using file)
    176   // (return false if the process has no functionality or in case of failure)
    177   // File name should is constructed as processName+particleName and the
    178   // should be placed under the directory specifed by the argument.
     210  // Retrieve all Physics from a files.
     211  // Return true if all the Physics Table are built.
     212  // Return false if any fatal failure.
    179213  G4bool RetrievePhysicsTable(const G4ParticleDefinition*,
    180214                              const G4String& directory,
    181215                              G4bool ascii);
    182216
     217private:
     218  // store a table
     219  G4bool StoreTable(const G4ParticleDefinition* p,
     220                    G4PhysicsTable*, G4bool ascii,
     221                    const G4String& directory,
     222                    const G4String& tname);
     223
     224  // retrieve a table
     225  G4bool RetrieveTable(const G4ParticleDefinition* p,
     226                       G4PhysicsTable*, G4bool ascii,
     227                       const G4String& directory,
     228                       const G4String& tname,
     229                       G4bool mandatory);
     230
     231  //------------------------------------------------------------------------
     232  // Public interface to cross section, mfp and sampling of fluctuations
     233  // These methods are not used in run time
     234  //------------------------------------------------------------------------
     235
     236public:
     237  // access to dispersion of restricted energy loss
     238  G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple,
     239                             const G4DynamicParticle* dp,
     240                             G4double length);
     241
     242  // Access to cross section table
     243  G4double CrossSectionPerVolume(G4double kineticEnergy,
     244                                 const G4MaterialCutsCouple* couple);
     245
     246  // access to cross section
     247  G4double MeanFreePath(const G4Track& track);
     248
     249  // access to step limit
     250  G4double ContinuousStepLimit(const G4Track& track,
     251                               G4double previousStepSize,
     252                               G4double currentMinimumStep,
     253                               G4double& currentSafety);
     254
    183255protected:
    184256
     257  // implementation of the pure virtual method
    185258  G4double GetMeanFreePath(const G4Track& track,
    186259                           G4double previousStepSize,
    187260                           G4ForceCondition* condition);
    188261
     262  // implementation of the pure virtual method
    189263  G4double GetContinuousStepLimit(const G4Track& track,
    190264                                  G4double previousStepSize,
     
    193267
    194268  //------------------------------------------------------------------------
    195   // Specific methods for along/post step EM processes
    196   //------------------------------------------------------------------------
     269  // Run time method which may be also used by derived processes
     270  //------------------------------------------------------------------------
     271
     272  // creeation of an empty vector for cross section
     273  G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*,
     274                                       G4double cut);
     275
     276  inline G4ParticleChangeForLoss* GetParticleChange();
     277
     278  inline size_t CurrentMaterialCutsCoupleIndex() const;
     279
     280  inline G4double GetCurrentRange() const;
     281
     282  //------------------------------------------------------------------------
     283  // Specific methods to set, access, modify models
     284  //------------------------------------------------------------------------
     285
     286  // Select model in run time
     287  inline void SelectModel(G4double kinEnergy);
    197288
    198289public:
    199 
     290  // Select model by energy and region index
     291  inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy,
     292                                            size_t& idx) const;
     293
     294  // Add EM model coupled with fluctuation model for region, smaller value
     295  // of order defines which pair of models will be selected for a given
     296  // energy interval 
     297  inline void AddEmModel(G4int, G4VEmModel*,
     298                         G4VEmFluctuationModel* fluc = 0,
     299                         const G4Region* region = 0);
     300
     301  // Define new energy range for the model identified by the name
     302  inline void UpdateEmModel(const G4String&, G4double, G4double);
     303
     304  // Assign a model to a process
     305  inline void SetEmModel(G4VEmModel*, G4int index=1);
     306 
     307  // return the assigned model
     308  inline G4VEmModel* EmModel(G4int index=1);
     309 
     310  // Access to models
     311  inline G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false);
     312
     313  inline G4int NumberOfModels();
     314
     315  // Assign a fluctuation model to a process
     316  inline void SetFluctModel(G4VEmFluctuationModel*);
     317 
     318  // return the assigned fluctuation model
     319  inline G4VEmFluctuationModel* FluctModel();
     320   
     321  //------------------------------------------------------------------------
     322  // Define and access particle type
     323  //------------------------------------------------------------------------
     324
     325protected:
     326  inline void SetParticle(const G4ParticleDefinition* p);
     327  inline void SetSecondaryParticle(const G4ParticleDefinition* p);
     328
     329public:
     330  inline void SetBaseParticle(const G4ParticleDefinition* p);
     331  inline const G4ParticleDefinition* Particle() const;
     332  inline const G4ParticleDefinition* BaseParticle() const;
     333  inline const G4ParticleDefinition* SecondaryParticle() const;
     334
     335  //------------------------------------------------------------------------
     336  // Get/set parameters to configure the process at initialisation time
     337  //------------------------------------------------------------------------
     338
     339  // Add subcutoff process (bremsstrahlung) to sample secondary
     340  // particle production in vicinity of the geometry boundary
    200341  void AddCollaborativeProcess(G4VEnergyLossProcess*);
    201342
    202   void SampleSubCutSecondaries(std::vector<G4Track*>&, const G4Step&,
    203                                G4VEmModel* model, G4int matIdx,
    204                                G4double& extraEdep);
    205 
    206   G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple,
    207                              const G4DynamicParticle* dp,
    208                              G4double length);
    209 
    210 
    211   virtual G4double AlongStepGetPhysicalInteractionLength(
    212                              const G4Track&,
    213                              G4double  previousStepSize,
    214                              G4double  currentMinimumStep,
    215                              G4double& currentSafety,
    216                              G4GPILSelection* selection
    217                             );
    218 
    219   virtual G4double PostStepGetPhysicalInteractionLength(
    220                              const G4Track& track,
    221                              G4double   previousStepSize,
    222                              G4ForceCondition* condition
    223                             );
    224 
    225   //------------------------------------------------------------------------
    226   // Specific methods to build and access Physics Tables
    227   //------------------------------------------------------------------------
    228 
    229   G4double MicroscopicCrossSection(G4double kineticEnergy,
    230                                    const G4MaterialCutsCouple* couple);
    231 
    232   G4PhysicsTable* BuildDEDXTable(G4EmTableType tType = fRestricted);
    233 
    234   G4PhysicsTable* BuildLambdaTable(G4EmTableType tType = fRestricted);
     343  inline void SetLossFluctuations(G4bool val);
     344  inline void SetRandomStep(G4bool val);
     345
     346  inline void SetIntegral(G4bool val);
     347  inline G4bool IsIntegral() const;
     348
     349  // Set/Get flag "isIonisation"
     350  inline void SetIonisation(G4bool val);
     351  inline G4bool IsIonisationProcess() const;
     352
     353  // Redefine parameteters for stepping control
     354  //
     355  inline void SetLinearLossLimit(G4double val);
     356  inline void SetMinSubRange(G4double val);
     357  inline void SetLambdaFactor(G4double val);
     358  inline void SetStepFunction(G4double v1, G4double v2);
     359
     360  inline G4int NumberOfSubCutoffRegions() const;
     361  inline G4int NumberOfDERegions() const;
     362
     363  //------------------------------------------------------------------------
     364  // Specific methods to path Physics Tables to the process
     365  //------------------------------------------------------------------------
    235366
    236367  void SetDEDXTable(G4PhysicsTable* p, G4EmTableType tType);
    237368  void SetCSDARangeTable(G4PhysicsTable* pRange);
    238369  void SetRangeTableForLoss(G4PhysicsTable* p);
     370  void SetSecondaryRangeTable(G4PhysicsTable* p);
    239371  void SetInverseRangeTable(G4PhysicsTable* p);
    240   void SetSecondaryRangeTable(G4PhysicsTable* p);
    241372
    242373  void SetLambdaTable(G4PhysicsTable* p);
     
    260391  // Max kinetic energy for tables
    261392  inline void SetMaxKinEnergyForCSDARange(G4double e);
     393
     394  // Return values for given G4MaterialCutsCouple
     395  inline G4double GetDEDX(G4double& kineticEnergy, const G4MaterialCutsCouple*);
     396  inline G4double GetDEDXForSubsec(G4double& kineticEnergy,
     397                                   const G4MaterialCutsCouple*);
     398  inline G4double GetRange(G4double& kineticEnergy, const G4MaterialCutsCouple*);
     399  inline G4double GetCSDARange(G4double& kineticEnergy, const G4MaterialCutsCouple*);
     400  inline G4double GetRangeForLoss(G4double& kineticEnergy, const G4MaterialCutsCouple*);
     401  inline G4double GetKineticEnergy(G4double& range, const G4MaterialCutsCouple*);
     402  inline G4double GetLambda(G4double& kineticEnergy, const G4MaterialCutsCouple*);
     403
     404  inline G4bool TablesAreBuilt() const;
    262405
    263406  // Access to specific tables
     
    273416  inline G4PhysicsTable* SubLambdaTable();
    274417
    275   // Return values for given G4MaterialCutsCouple
    276   inline G4double GetDEDX(G4double& kineticEnergy, const G4MaterialCutsCouple*);
    277   inline G4double GetDEDXForSubsec(G4double& kineticEnergy,
    278                                    const G4MaterialCutsCouple*);
    279   inline G4double GetRange(G4double& kineticEnergy, const G4MaterialCutsCouple*);
    280   inline G4double GetCSDARange(G4double& kineticEnergy, const G4MaterialCutsCouple*);
    281   inline G4double GetRangeForLoss(G4double& kineticEnergy, const G4MaterialCutsCouple*);
    282   inline G4double GetKineticEnergy(G4double& range, const G4MaterialCutsCouple*);
    283   inline G4double GetLambda(G4double& kineticEnergy, const G4MaterialCutsCouple*);
    284 
    285   inline G4bool TablesAreBuilt() const;
    286 
    287   //------------------------------------------------------------------------
    288   // Define and access particle type
    289   //------------------------------------------------------------------------
    290 
    291   inline void SetBaseParticle(const G4ParticleDefinition* p);
    292   inline const G4ParticleDefinition* Particle() const;
    293   inline const G4ParticleDefinition* BaseParticle() const;
    294   inline const G4ParticleDefinition* SecondaryParticle() const;
    295 
    296   //------------------------------------------------------------------------
    297   // Specific methods to set, access, modify models
    298   //------------------------------------------------------------------------
    299 
    300   // Add EM model coupled with fluctuation model for the region
    301   inline void AddEmModel(G4int, G4VEmModel*, G4VEmFluctuationModel* fluc = 0,
    302                                 const G4Region* region = 0);
    303 
    304   // Assign a model to a process
    305   inline void SetEmModel(G4VEmModel*, G4int index=1);
    306  
    307   // return the assigned model
    308   inline G4VEmModel* EmModel(G4int index=1);
    309  
    310   // Assign a fluctuation model to a process
    311   inline void SetFluctModel(G4VEmFluctuationModel*);
    312  
    313   // return the assigned fluctuation model
    314   inline G4VEmFluctuationModel* FluctModel();
    315    
    316   // Define new energy range for the model identified by the name
    317   inline void UpdateEmModel(const G4String&, G4double, G4double);
    318 
    319   // Access to models
    320   inline G4VEmModel* GetModelByIndex(G4int idx = 0);
    321 
    322   inline G4int NumberOfModels();
    323 
    324   //------------------------------------------------------------------------
    325   // Get/set parameters used for simulation of energy loss
    326   //------------------------------------------------------------------------
    327 
    328   inline void SetLossFluctuations(G4bool val);
    329   inline void SetRandomStep(G4bool val);
    330   inline void SetIntegral(G4bool val);
    331   inline G4bool IsIntegral() const;
    332 
    333   // Set/Get flag "isIonisation"
    334   inline void SetIonisation(G4bool val);
    335   inline G4bool IsIonisationProcess() const;
    336 
    337   // Redefine parameteters for stepping control
    338   //
    339   inline void SetLinearLossLimit(G4double val);
    340   inline void SetMinSubRange(G4double val);
    341   inline void SetStepFunction(G4double v1, G4double v2);
    342   inline void SetLambdaFactor(G4double val);
    343 
    344 
    345   // Add subcutoff option for the region
    346   void ActivateSubCutoff(G4bool val, const G4Region* region = 0);
    347 
    348   inline G4int NumberOfSubCutoffRegions() const;
    349 
    350   // Activate deexcitation code
    351   virtual void ActivateDeexcitation(G4bool, const G4Region* region = 0);
    352 
    353418  //------------------------------------------------------------------------
    354419  // Run time method for simulation of ionisation
    355420  //------------------------------------------------------------------------
    356421
     422  // sample range at the end of a step
    357423  inline G4double SampleRange();
    358424
    359   inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy, size_t& idx) const;
    360 
    361 
    362   // Set scaling parameters
     425  // Set scaling parameters for ions is needed to G4EmCalculator
    363426  inline void SetDynamicMassCharge(G4double massratio, G4double charge2ratio);
    364427
    365   // Helper functions
    366   inline G4double MeanFreePath(const G4Track& track);
    367 
    368   inline G4double ContinuousStepLimit(const G4Track& track,
    369                                       G4double previousStepSize,
    370                                       G4double currentMinimumStep,
    371                                       G4double& currentSafety);
    372 
    373 protected:
    374 
    375   G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*,
    376                                        G4double cut);
    377 
    378   inline virtual void InitialiseMassCharge(const G4Track&);
    379 
    380   inline void SetParticle(const G4ParticleDefinition* p);
    381 
    382   inline void SetSecondaryParticle(const G4ParticleDefinition* p);
    383 
    384   inline G4VEmModel* SelectModel(G4double kinEnergy);
    385 
    386   inline size_t CurrentMaterialCutsCoupleIndex() const;
    387 
    388   inline G4double GetCurrentRange() const;
    389 
    390428private:
    391429
    392   // Clear tables
    393   void Clear();
    394 
    395   inline void InitialiseStep(const G4Track&);
    396 
     430  // define material and indexes
    397431  inline void DefineMaterial(const G4MaterialCutsCouple* couple);
    398432
    399   // Returnd values for scaled energy and base particles mass
    400   //
     433  //------------------------------------------------------------------------
     434  // Compute values using scaling relation, mass and charge of based particle
     435  //------------------------------------------------------------------------
     436
    401437  inline G4double GetDEDXForScaledEnergy(G4double scaledKinEnergy);
    402438  inline G4double GetSubDEDXForScaledEnergy(G4double scaledKinEnergy);
     
    405441  inline G4double GetScaledRangeForScaledEnergy(G4double scaledKinEnergy);
    406442  inline G4double GetLimitScaledRangeForScaledEnergy(G4double scaledKinEnergy);
     443  inline G4double ScaledKinEnergyForLoss(G4double range);
    407444  inline G4double GetLambdaForScaledEnergy(G4double scaledKinEnergy);
    408   inline G4double ScaledKinEnergyForLoss(G4double range);
    409445  inline void ComputeLambdaForScaledEnergy(G4double scaledKinEnergy);
    410446
    411447  // hide  assignment operator
    412 
    413448  G4VEnergyLossProcess(G4VEnergyLossProcess &);
    414449  G4VEnergyLossProcess & operator=(const G4VEnergyLossProcess &right);
    415450
    416 // =====================================================================
    417 
    418 protected:
    419 
    420   G4ParticleChangeForLoss               fParticleChange;
    421 
    422 private:
    423 
    424   G4EmModelManager*                     modelManager;
     451  // ======== Parameters of the class fixed at construction =========
     452
     453  G4EmModelManager*           modelManager;
     454  G4SafetyHelper*             safetyHelper;
     455
     456  const G4ParticleDefinition* secondaryParticle;
     457  const G4ParticleDefinition* theElectron;
     458  const G4ParticleDefinition* thePositron;
     459  const G4ParticleDefinition* theGenericIon;
     460
     461  G4PhysicsVector*            vstrag;
     462
     463  // ======== Parameters of the class fixed at initialisation =======
     464
    425465  std::vector<G4VEmModel*>              emModels;
    426466  G4VEmFluctuationModel*                fluctModel;
    427467  std::vector<const G4Region*>          scoffRegions;
     468  std::vector<const G4Region*>          deRegions;
    428469  G4int                                 nSCoffRegions;
    429   G4int*                                idxSCoffRegions;
    430   std::vector<G4DynamicParticle*>       secParticles;
    431   std::vector<G4Track*>                 scTracks;
     470  G4int                                 nDERegions;
     471  G4bool*                               idxSCoffRegions;
     472  G4bool*                               idxDERegions;
     473
    432474  std::vector<G4VEnergyLossProcess*>    scProcesses;
    433475  G4int                                 nProcesses;
     
    453495  const G4DataVector*         theSubCuts;
    454496
    455   G4SafetyHelper*             safetyHelper;
    456 
    457   const G4ParticleDefinition* particle;
    458497  const G4ParticleDefinition* baseParticle;
    459   const G4ParticleDefinition* secondaryParticle;
    460   const G4ParticleDefinition* theElectron;
    461   const G4ParticleDefinition* thePositron;
    462 
    463   G4PhysicsVector*            vstrag;
    464 
    465   // cash
    466   const G4Material*           currentMaterial;
    467   const G4MaterialCutsCouple* currentCouple;
    468   size_t                      currentMaterialIndex;
    469498
    470499  G4int    nBins;
    471500  G4int    nBinsCSDA;
    472   G4int    nWarnings;
    473501
    474502  G4double lowestKinEnergy;
     
    477505  G4double maxKinEnergyCSDA;
    478506
    479   G4double massRatio;
    480   G4double reduceFactor;
    481   G4double chargeSquare;
    482   G4double chargeSqRatio;
    483 
    484   G4double preStepLambda;
    485   G4double fRange;
    486   G4double preStepKinEnergy;
    487   G4double preStepScaledEnergy;
    488507  G4double linLossLimit;
    489508  G4double minSubRange;
     
    491510  G4double finalRange;
    492511  G4double lambdaFactor;
    493   G4double mfpKinEnergy;
    494 
    495   G4GPILSelection  aGPILSelection;
    496512
    497513  G4bool   lossFluctuationFlag;
     
    499515  G4bool   tablesAreBuilt;
    500516  G4bool   integral;
     517  G4bool   isIon;
    501518  G4bool   isIonisation;
    502519  G4bool   useSubCutoff;
     520  G4bool   useDeexcitation;
     521
     522protected:
     523
     524  G4ParticleChangeForLoss          fParticleChange;
     525
     526  // ======== Cashed values - may be state dependent ================
     527
     528private:
     529
     530  std::vector<G4DynamicParticle*>  secParticles;
     531  std::vector<G4Track*>            scTracks;
     532
     533  const G4ParticleDefinition* particle;
     534
     535  G4VEmModel*                 currentModel;
     536  const G4Material*           currentMaterial;
     537  const G4MaterialCutsCouple* currentCouple;
     538  size_t                      currentMaterialIndex;
     539
     540  G4int    nWarnings;
     541
     542  G4double massRatio;
     543  G4double reduceFactor;
     544  G4double chargeSqRatio;
     545
     546  G4double preStepLambda;
     547  G4double fRange;
     548  G4double preStepKinEnergy;
     549  G4double preStepScaledEnergy;
     550  G4double mfpKinEnergy;
     551
     552  G4GPILSelection  aGPILSelection;
     553
    503554};
    504555
     
    506557//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    507558
    508 inline void G4VEnergyLossProcess::DefineMaterial(
    509             const G4MaterialCutsCouple* couple)
    510 {
    511   if(couple != currentCouple) {
    512     currentCouple   = couple;
    513     currentMaterial = couple->GetMaterial();
    514     currentMaterialIndex = couple->GetIndex();
    515     mfpKinEnergy = DBL_MAX;
    516   }
    517 }
    518 
    519 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    520 
    521 inline void G4VEnergyLossProcess::InitialiseStep(const G4Track& track)
    522 {
    523   InitialiseMassCharge(track);
    524   preStepKinEnergy = track.GetKineticEnergy();
    525   preStepScaledEnergy = preStepKinEnergy*massRatio;
    526   DefineMaterial(track.GetMaterialCutsCouple());
    527   if (theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
    528 }
    529 
    530 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    531 
    532 inline void G4VEnergyLossProcess::InitialiseMassCharge(const G4Track&)
    533 {}
     559inline G4ParticleChangeForLoss* G4VEnergyLossProcess::GetParticleChange()
     560{
     561  return &fParticleChange;
     562}
     563
     564//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     565
     566inline size_t G4VEnergyLossProcess::CurrentMaterialCutsCoupleIndex() const
     567{
     568  return currentMaterialIndex;
     569}
     570
     571//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     572 
     573inline G4double G4VEnergyLossProcess::GetCurrentRange() const
     574{
     575  return fRange;
     576}
     577
     578//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     579
     580inline void G4VEnergyLossProcess::SelectModel(G4double kinEnergy)
     581{
     582  currentModel = modelManager->SelectModel(kinEnergy, currentMaterialIndex);
     583  currentModel->SetCurrentCouple(currentCouple);
     584}
     585
     586//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     587
     588inline G4VEmModel* G4VEnergyLossProcess::SelectModelForMaterial(
     589                   G4double kinEnergy, size_t& idx) const
     590{
     591  return modelManager->SelectModel(kinEnergy, idx);
     592}
     593
     594//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     595
     596inline
     597void G4VEnergyLossProcess::AddEmModel(G4int order, G4VEmModel* p,
     598                                      G4VEmFluctuationModel* fluc,
     599                                      const G4Region* region)
     600{
     601  modelManager->AddEmModel(order, p, fluc, region);
     602  if(p) p->SetParticleChange(pParticleChange, fluc);
     603}
     604
     605//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     606
     607inline void G4VEnergyLossProcess::UpdateEmModel(const G4String& nam,
     608                                                G4double emin, G4double emax)
     609{
     610  modelManager->UpdateEmModel(nam, emin, emax);
     611}
     612
     613//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     614
     615inline void G4VEnergyLossProcess::SetEmModel(G4VEmModel* p, G4int index)
     616{
     617  G4int n = emModels.size();
     618  if(index >= n) for(G4int i=n; i<index+1; i++) {emModels.push_back(0);}
     619  emModels[index] = p;
     620}
     621
     622//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     623
     624inline G4VEmModel* G4VEnergyLossProcess::EmModel(G4int index)
     625{
     626  G4VEmModel* p = 0;
     627  if(index >= 0 && index <  G4int(emModels.size())) p = emModels[index];
     628  return p;
     629}
     630
     631//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     632
     633inline
     634G4VEmModel* G4VEnergyLossProcess::GetModelByIndex(G4int idx, G4bool ver)
     635{
     636  return modelManager->GetModel(idx, ver);
     637}
     638
     639//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     640
     641inline G4int G4VEnergyLossProcess::NumberOfModels()
     642{
     643  return modelManager->NumberOfModels();
     644}
     645
     646//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     647
     648inline void G4VEnergyLossProcess::SetFluctModel(G4VEmFluctuationModel* p)
     649{
     650  fluctModel = p;
     651}
     652
     653//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     654
     655inline G4VEmFluctuationModel* G4VEnergyLossProcess::FluctModel()
     656{
     657  return fluctModel;
     658}
     659
     660//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     661
     662inline void G4VEnergyLossProcess::SetParticle(const G4ParticleDefinition* p)
     663{
     664  particle = p;
     665}
     666
     667//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     668
     669inline void G4VEnergyLossProcess::SetSecondaryParticle(const G4ParticleDefinition* p)
     670{
     671  secondaryParticle = p;
     672}
     673
     674//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     675
     676inline void G4VEnergyLossProcess::SetBaseParticle(const G4ParticleDefinition* p)
     677{
     678  baseParticle = p;
     679}
     680
     681//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     682
     683inline const G4ParticleDefinition* G4VEnergyLossProcess::Particle() const
     684{
     685  return particle;
     686}
     687
     688//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     689
     690inline const G4ParticleDefinition* G4VEnergyLossProcess::BaseParticle() const
     691{
     692  return baseParticle;
     693}
     694
     695//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     696
     697inline const G4ParticleDefinition* G4VEnergyLossProcess::SecondaryParticle() const
     698{
     699  return secondaryParticle;
     700}
     701
     702//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     703
     704inline void G4VEnergyLossProcess::SetLossFluctuations(G4bool val)
     705{
     706  lossFluctuationFlag = val;
     707}
     708
     709//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     710
     711inline void G4VEnergyLossProcess::SetRandomStep(G4bool val)
     712{
     713  rndmStepFlag = val;
     714}
     715
     716//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     717
     718inline void G4VEnergyLossProcess::SetIntegral(G4bool val)
     719{
     720  integral = val;
     721}
     722
     723//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     724 
     725inline G4bool G4VEnergyLossProcess::IsIntegral() const
     726{
     727  return integral;
     728}
     729
     730//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     731
     732inline void G4VEnergyLossProcess::SetIonisation(G4bool val)
     733{
     734  isIonisation = val;
     735  if(val) aGPILSelection = CandidateForSelection;
     736  else    aGPILSelection = NotCandidateForSelection;
     737}
     738
     739//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     740
     741inline G4bool G4VEnergyLossProcess::IsIonisationProcess() const
     742{
     743  return isIonisation;
     744}
     745
     746//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     747
     748inline void G4VEnergyLossProcess::SetLinearLossLimit(G4double val)
     749{
     750  linLossLimit = val;
     751}
     752
     753//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     754
     755inline void G4VEnergyLossProcess::SetMinSubRange(G4double val)
     756{
     757  minSubRange = val;
     758}
     759
     760//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     761
     762inline void G4VEnergyLossProcess::SetLambdaFactor(G4double val)
     763{
     764  if(val > 0.0 && val <= 1.0) lambdaFactor = val;
     765}
     766
     767//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     768
     769void G4VEnergyLossProcess::SetStepFunction(G4double v1, G4double v2)
     770{
     771  dRoverRange = v1;
     772  finalRange = v2;
     773  if (dRoverRange > 0.999) dRoverRange = 1.0;
     774  currentCouple = 0;
     775  mfpKinEnergy  = DBL_MAX;
     776}
     777
     778//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     779
     780inline G4int G4VEnergyLossProcess::NumberOfSubCutoffRegions() const
     781{
     782  return nSCoffRegions;
     783}
     784
     785//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     786
     787inline G4int G4VEnergyLossProcess::NumberOfDERegions() const
     788{
     789  return nDERegions;
     790}
     791
     792//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     793
     794inline void G4VEnergyLossProcess::SetDEDXBinning(G4int nbins)
     795{
     796  nBins = nbins;
     797}
     798
     799//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     800
     801inline void G4VEnergyLossProcess::SetLambdaBinning(G4int nbins)
     802{
     803  nBins = nbins;
     804}
     805
     806//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     807
     808inline void G4VEnergyLossProcess::SetDEDXBinningForCSDARange(G4int nbins)
     809{
     810  nBinsCSDA = nbins;
     811}
     812
     813//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     814
     815inline void G4VEnergyLossProcess::SetMinKinEnergy(G4double e)
     816{
     817  minKinEnergy = e;
     818}
     819
     820//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     821
     822inline G4double G4VEnergyLossProcess::MinKinEnergy() const
     823{
     824  return minKinEnergy;
     825}
     826
     827//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     828
     829inline void G4VEnergyLossProcess::SetMaxKinEnergy(G4double e)
     830{
     831  maxKinEnergy = e;
     832  if(e < maxKinEnergyCSDA) maxKinEnergyCSDA = e;
     833}
     834
     835//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     836
     837inline G4double G4VEnergyLossProcess::MaxKinEnergy() const
     838{
     839  return maxKinEnergy;
     840}
     841
     842//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     843
     844inline void G4VEnergyLossProcess::SetMaxKinEnergyForCSDARange(G4double e)
     845{
     846  maxKinEnergyCSDA = e;
     847}
    534848
    535849//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    549863  DefineMaterial(couple);
    550864  return GetSubDEDXForScaledEnergy(kineticEnergy*massRatio);
    551 }
    552 
    553 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    554 
    555 inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
    556 {
    557   G4bool b;
    558   G4double x =
    559     ((*theDEDXTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio;
    560   if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
    561   return x;
    562 }
    563 
    564 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    565 
    566 inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e)
    567 {
    568   G4bool b;
    569   G4double x =
    570     ((*theDEDXSubTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio;
    571   if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
    572   return x;
    573 }
    574 
    575 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    576 
    577 inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
    578 {
    579   G4bool b;
    580   G4double x = 0.0;
    581   //  if(theIonisationTable) {
    582   x = ((*theIonisationTable)[currentMaterialIndex]->GetValue(e, b))
    583     *chargeSqRatio;
    584   if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
    585   //}
    586   return x;
    587 }
    588 
    589 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    590 
    591 inline
    592 G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
    593 {
    594   G4bool b;
    595   G4double x = 0.0;
    596   //if(theIonisationSubTable) {
    597   x = ((*theIonisationSubTable)[currentMaterialIndex]->GetValue(e, b))
    598     *chargeSqRatio;
    599   if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
    600   //}
    601   return x;
    602865}
    603866
     
    634897//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    635898
     899inline G4double G4VEnergyLossProcess::GetRangeForLoss(
     900                G4double& kineticEnergy,
     901                const G4MaterialCutsCouple* couple)
     902{
     903  DefineMaterial(couple);
     904  G4double x = DBL_MAX;
     905  if(theRangeTableForLoss)
     906    x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
     907  //  G4cout << "Range from " << GetProcessName()
     908  //         << "  e= " << kineticEnergy << " r= " << x << G4endl;
     909  return x;
     910}
     911
     912//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     913
     914inline G4double G4VEnergyLossProcess::GetKineticEnergy(
     915                G4double& range,
     916                const G4MaterialCutsCouple* couple)
     917{
     918  DefineMaterial(couple);
     919  G4double r = range/reduceFactor;
     920  G4double e = ScaledKinEnergyForLoss(r)/massRatio;
     921  return e;
     922}
     923
     924//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     925
     926inline G4double G4VEnergyLossProcess::GetLambda(G4double& kineticEnergy,
     927                                          const G4MaterialCutsCouple* couple)
     928{
     929  DefineMaterial(couple);
     930  G4double x = 0.0;
     931  if(theLambdaTable) x = GetLambdaForScaledEnergy(kineticEnergy*massRatio);
     932  return x;
     933}
     934
     935//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     936
     937inline G4bool G4VEnergyLossProcess::TablesAreBuilt() const
     938{
     939  return  tablesAreBuilt;
     940}
     941
     942//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     943
     944inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTable() const
     945{
     946  return theDEDXTable;
     947}
     948
     949//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     950
     951inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTableForSubsec() const
     952{
     953  return theDEDXSubTable;
     954}
     955
     956//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     957
     958inline G4PhysicsTable* G4VEnergyLossProcess::DEDXunRestrictedTable() const
     959{
     960  return theDEDXunRestrictedTable;
     961}
     962
     963//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     964
     965inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const
     966{
     967  G4PhysicsTable* t = theDEDXTable;
     968  if(theIonisationTable) t = theIonisationTable;
     969  return t;
     970}
     971
     972//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     973
     974inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTableForSubsec() const
     975{
     976  G4PhysicsTable* t = theDEDXSubTable;
     977  if(theIonisationSubTable) t = theIonisationSubTable;
     978  return t;
     979}
     980
     981//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     982
     983inline G4PhysicsTable* G4VEnergyLossProcess::CSDARangeTable() const
     984{
     985  return theCSDARangeTable;
     986}
     987
     988//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     989
     990inline G4PhysicsTable* G4VEnergyLossProcess::RangeTableForLoss() const
     991{
     992  return theRangeTableForLoss;
     993}
     994
     995//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     996
     997inline G4PhysicsTable* G4VEnergyLossProcess::InverseRangeTable() const
     998{
     999  return theInverseRangeTable;
     1000}
     1001
     1002//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1003
     1004inline G4PhysicsTable* G4VEnergyLossProcess::LambdaTable()
     1005{
     1006  return theLambdaTable;
     1007}
     1008
     1009//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1010
     1011inline G4PhysicsTable* G4VEnergyLossProcess::SubLambdaTable()
     1012{
     1013  return theSubLambdaTable;
     1014}
     1015
     1016//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1017
     1018inline G4double G4VEnergyLossProcess::SampleRange()
     1019{
     1020  G4double e = amu_c2*preStepKinEnergy/particle->GetPDGMass();
     1021  G4bool b;
     1022  G4double s = fRange*std::pow(10.,vstrag->GetValue(e,b));
     1023  G4double x = fRange + G4RandGauss::shoot(0.0,s);
     1024  if(x > 0.0) fRange = x;
     1025  return fRange;
     1026}
     1027
     1028//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1029
     1030inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
     1031                                                       G4double charge2ratio)
     1032{
     1033  massRatio     = massratio;
     1034  chargeSqRatio = charge2ratio;
     1035  reduceFactor  = 1.0/(chargeSqRatio*massRatio);
     1036}
     1037
     1038//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1039
     1040inline void G4VEnergyLossProcess::DefineMaterial(
     1041            const G4MaterialCutsCouple* couple)
     1042{
     1043  if(couple != currentCouple) {
     1044    currentCouple   = couple;
     1045    currentMaterial = couple->GetMaterial();
     1046    currentMaterialIndex = couple->GetIndex();
     1047    mfpKinEnergy = DBL_MAX;
     1048  }
     1049}
     1050
     1051//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1052
     1053inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
     1054{
     1055  G4bool b;
     1056  G4double x =
     1057    ((*theDEDXTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio;
     1058  if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
     1059  return x;
     1060}
     1061
     1062//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1063
     1064inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e)
     1065{
     1066  G4bool b;
     1067  G4double x =
     1068    ((*theDEDXSubTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio;
     1069  if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
     1070  return x;
     1071}
     1072
     1073//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1074
     1075inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
     1076{
     1077  G4bool b;
     1078  G4double x = 0.0;
     1079  //  if(theIonisationTable) {
     1080  x = ((*theIonisationTable)[currentMaterialIndex]->GetValue(e, b))
     1081    *chargeSqRatio;
     1082  if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
     1083  //}
     1084  return x;
     1085}
     1086
     1087//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1088
     1089inline
     1090G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e)
     1091{
     1092  G4bool b;
     1093  G4double x = 0.0;
     1094  //if(theIonisationSubTable) {
     1095  x = ((*theIonisationSubTable)[currentMaterialIndex]->GetValue(e, b))
     1096    *chargeSqRatio;
     1097  if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
     1098  //}
     1099  return x;
     1100}
     1101
     1102//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1103
     1104inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
     1105{
     1106  G4bool b;
     1107  G4double x = ((*theRangeTableForLoss)[currentMaterialIndex])->GetValue(e, b);
     1108  if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
     1109  return x;
     1110}
     1111
     1112//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1113
    6361114inline G4double G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(
    6371115                G4double e)
     
    6481126  }
    6491127  return x;
    650 }
    651 
    652 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    653 
    654 inline G4double G4VEnergyLossProcess::GetRangeForLoss(
    655                 G4double& kineticEnergy,
    656                 const G4MaterialCutsCouple* couple)
    657 {
    658   DefineMaterial(couple);
    659   G4double x = DBL_MAX;
    660   if(theRangeTableForLoss)
    661     x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
    662   //  G4cout << "Range from " << GetProcessName()
    663   //         << "  e= " << kineticEnergy << " r= " << x << G4endl;
    664   return x;
    665 }
    666 
    667 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    668 
    669 inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
    670 {
    671   G4bool b;
    672   G4double x = ((*theRangeTableForLoss)[currentMaterialIndex])->GetValue(e, b);
    673   if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy);
    674   return x;
    675 }
    676 
    677 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    678 
    679 inline G4double G4VEnergyLossProcess::GetKineticEnergy(
    680                 G4double& range,
    681                 const G4MaterialCutsCouple* couple)
    682 {
    683   DefineMaterial(couple);
    684   G4double r = range/reduceFactor;
    685   G4double e = ScaledKinEnergyForLoss(r)/massRatio;
    686   return e;
    6871128}
    6881129
     
    7021143  }
    7031144  return e;
    704 }
    705 
    706 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    707 
    708 inline G4double G4VEnergyLossProcess::GetLambda(G4double& kineticEnergy,
    709                                           const G4MaterialCutsCouple* couple)
    710 {
    711   DefineMaterial(couple);
    712   G4double x = 0.0;
    713   if(theLambdaTable) x = GetLambdaForScaledEnergy(kineticEnergy*massRatio);
    714   return x;
    7151145}
    7161146
     
    7491179//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    7501180
    751 inline G4double G4VEnergyLossProcess::ContinuousStepLimit(
    752          const G4Track& track, G4double x, G4double y, G4double& z)
    753 {
    754   G4GPILSelection sel;
    755   return AlongStepGetPhysicalInteractionLength(track, x, y, z, &sel);
    756 }
    757 
    758 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    759 
    760 inline G4double G4VEnergyLossProcess::SampleRange()
    761 {
    762   G4double e = amu_c2*preStepKinEnergy/particle->GetPDGMass();
    763   G4bool b;
    764   G4double s = fRange*std::pow(10.,vstrag->GetValue(e,b));
    765   G4double x = fRange + G4RandGauss::shoot(0.0,s);
    766   if(x > 0.0) fRange = x;
    767   return fRange;
    768 }
    769 
    770 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    771 
    772 inline G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track)
    773 {
    774   DefineMaterial(track.GetMaterialCutsCouple());
    775   preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio);
    776   G4double x = DBL_MAX;
    777   if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
    778   return x;
    779 }
    780 
    781 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    782 
    783 inline G4double G4VEnergyLossProcess::MinPrimaryEnergy(
    784                 const G4ParticleDefinition*, const G4Material*, G4double cut)
    785 {
    786   return cut;
    787 }
    788 
    789 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    790 
    791 inline G4VEmModel* G4VEnergyLossProcess::SelectModel(G4double kinEnergy)
    792 {
    793   return modelManager->SelectModel(kinEnergy, currentMaterialIndex);
    794 }
    795 
    796 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    797 
    798 inline G4VEmModel* G4VEnergyLossProcess::SelectModelForMaterial(
    799                    G4double kinEnergy, size_t& idx) const
    800 {
    801   return modelManager->SelectModel(kinEnergy, idx);
    802 }
    803 
    804 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    805 
    806 inline const G4ParticleDefinition* G4VEnergyLossProcess::Particle() const
    807 {
    808   return particle;
    809 }
    810 
    811 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    812 
    813 inline const G4ParticleDefinition* G4VEnergyLossProcess::BaseParticle() const
    814 {
    815   return baseParticle;
    816 }
    817 
    818 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    819 
    820 inline const G4ParticleDefinition* G4VEnergyLossProcess::SecondaryParticle() const
    821 {
    822   return secondaryParticle;
    823 }
    824 
    825 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    826 
    827 inline void G4VEnergyLossProcess::CorrectionsAlongStep(
    828                              const G4MaterialCutsCouple*,
    829                              const G4DynamicParticle*,
    830                              G4double&,
    831                              G4double&)
    832 {}
    833 
    834 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    835 
    836 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTable() const
    837 {
    838   return theDEDXTable;
    839 }
    840 
    841 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    842 
    843 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTableForSubsec() const
    844 {
    845   return theDEDXSubTable;
    846 }
    847 
    848 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    849 
    850 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXunRestrictedTable() const
    851 {
    852   return theDEDXunRestrictedTable;
    853 }
    854 
    855 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    856 
    857 inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const
    858 {
    859   G4PhysicsTable* t = theDEDXTable;
    860   if(theIonisationTable) t = theIonisationTable;
    861   return t;
    862 }
    863 
    864 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    865 
    866 inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTableForSubsec() const
    867 {
    868   G4PhysicsTable* t = theDEDXSubTable;
    869   if(theIonisationSubTable) t = theIonisationSubTable;
    870   return t;
    871 }
    872 
    873 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    874 
    875 inline G4PhysicsTable* G4VEnergyLossProcess::CSDARangeTable() const
    876 {
    877   return theCSDARangeTable;
    878 }
    879 
    880 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    881 
    882 inline G4PhysicsTable* G4VEnergyLossProcess::RangeTableForLoss() const
    883 {
    884   return theRangeTableForLoss;
    885 }
    886 
    887 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    888 
    889 inline G4PhysicsTable* G4VEnergyLossProcess::InverseRangeTable() const
    890 {
    891   return theInverseRangeTable;
    892 }
    893 
    894 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    895 
    896 inline G4PhysicsTable* G4VEnergyLossProcess::LambdaTable()
    897 {
    898   return theLambdaTable;
    899 }
    900 
    901 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    902 
    903 inline G4PhysicsTable* G4VEnergyLossProcess::SubLambdaTable()
    904 {
    905   return theSubLambdaTable;
    906 }
    907 
    908 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    909  
    910 inline G4bool G4VEnergyLossProcess::IsIntegral() const
    911 {
    912   return integral;
    913 }
    914 
    915 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    916 
    917 inline size_t G4VEnergyLossProcess::CurrentMaterialCutsCoupleIndex() const
    918 {
    919   return currentMaterialIndex;
    920 }
    921 
    922 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    923 
    924 inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio,
    925                                                        G4double charge2ratio)
    926 {
    927   massRatio     = massratio;
    928   chargeSqRatio = charge2ratio;
    929   chargeSquare  = charge2ratio*eplus*eplus;
    930   if(chargeSqRatio > 0.0) reduceFactor  = 1.0/(chargeSqRatio*massRatio);
    931 }
    932  
    933 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    934  
    935 inline G4double G4VEnergyLossProcess::GetCurrentRange() const
    936 {
    937   return fRange;
    938 }
    939 
    940 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    941 
    942 void G4VEnergyLossProcess::AddEmModel(G4int order, G4VEmModel* p,
    943                                       G4VEmFluctuationModel* fluc,
    944                                       const G4Region* region)
    945 {
    946   modelManager->AddEmModel(order, p, fluc, region);
    947   if(p) p->SetParticleChange(pParticleChange, fluc);
    948 }
    949 
    950 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    951 
    952 inline G4VEmModel* G4VEnergyLossProcess::GetModelByIndex(G4int idx)
    953 {
    954   return modelManager->GetModel(idx);
    955 }
    956 
    957 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    958 
    959 inline G4int G4VEnergyLossProcess::NumberOfModels()
    960 {
    961   return modelManager->NumberOfModels();
    962 }
    963 
    964 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    965 
    966 inline void G4VEnergyLossProcess::SetEmModel(G4VEmModel* p, G4int index)
    967 {
    968   G4int n = emModels.size();
    969   if(index >= n) for(G4int i=n; i<index+1; i++) {emModels.push_back(0);}
    970   emModels[index] = p;
    971 }
    972 
    973 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    974 
    975 inline G4VEmModel* G4VEnergyLossProcess::EmModel(G4int index)
    976 {
    977   G4VEmModel* p = 0;
    978   if(index >= 0 && index <  G4int(emModels.size())) p = emModels[index];
    979   return p;
    980 }
    981 
    982 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    983 
    984 inline void G4VEnergyLossProcess::SetFluctModel(G4VEmFluctuationModel* p)
    985 {
    986   fluctModel = p;
    987 }
    988 
    989 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    990 
    991 inline G4VEmFluctuationModel* G4VEnergyLossProcess::FluctModel()
    992 {
    993   return fluctModel;
    994 }
    995 
    996 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    997 
    998 inline void G4VEnergyLossProcess::UpdateEmModel(const G4String& nam,
    999                                                 G4double emin, G4double emax)
    1000 {
    1001   modelManager->UpdateEmModel(nam, emin, emax);
    1002 }
    1003 
    1004 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1005 
    1006 inline void G4VEnergyLossProcess::SetIntegral(G4bool val)
    1007 {
    1008   integral = val;
    1009 }
    1010 
    1011 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1012 
    1013 inline void G4VEnergyLossProcess::SetParticle(const G4ParticleDefinition* p)
    1014 {
    1015   particle = p;
    1016 }
    1017 
    1018 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1019 
    1020 inline void G4VEnergyLossProcess::SetBaseParticle(const G4ParticleDefinition* p)
    1021 {
    1022   baseParticle = p;
    1023 }
    1024 
    1025 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1026 
    1027 inline void G4VEnergyLossProcess::SetSecondaryParticle(const G4ParticleDefinition* p)
    1028 {
    1029   secondaryParticle = p;
    1030 }
    1031 
    1032 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1033 
    1034 inline void G4VEnergyLossProcess::SetLinearLossLimit(G4double val)
    1035 {
    1036   linLossLimit = val;
    1037 }
    1038 
    1039 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1040 
    1041 inline void G4VEnergyLossProcess::SetLossFluctuations(G4bool val)
    1042 {
    1043   lossFluctuationFlag = val;
    1044 }
    1045 
    1046 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1047 
    1048 inline void G4VEnergyLossProcess::SetRandomStep(G4bool val)
    1049 {
    1050   rndmStepFlag = val;
    1051 }
    1052 
    1053 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1054 
    1055 inline void G4VEnergyLossProcess::SetMinSubRange(G4double val)
    1056 {
    1057   minSubRange = val;
    1058 }
    1059 
    1060 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1061 
    1062 inline G4bool G4VEnergyLossProcess::TablesAreBuilt() const
    1063 {
    1064   return  tablesAreBuilt;
    1065 }
    1066 
    1067 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1068 
    1069 inline G4int G4VEnergyLossProcess::NumberOfSubCutoffRegions() const
    1070 {
    1071   return nSCoffRegions;
    1072 }
    1073 
    1074 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1075 
    1076 inline void G4VEnergyLossProcess::SetDEDXBinning(G4int nbins)
    1077 {
    1078   nBins = nbins;
    1079 }
    1080 
    1081 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1082 
    1083 inline void G4VEnergyLossProcess::SetLambdaBinning(G4int nbins)
    1084 {
    1085   nBins = nbins;
    1086 }
    1087 
    1088 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1089 
    1090 inline void G4VEnergyLossProcess::SetDEDXBinningForCSDARange(G4int nbins)
    1091 {
    1092   nBinsCSDA = nbins;
    1093 }
    1094 
    1095 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1096 
    1097 inline G4double G4VEnergyLossProcess::MinKinEnergy() const
    1098 {
    1099   return minKinEnergy;
    1100 }
    1101 
    1102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1103 
    1104 inline void G4VEnergyLossProcess::SetMinKinEnergy(G4double e)
    1105 {
    1106   minKinEnergy = e;
    1107 }
    1108 
    1109 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1110 
    1111 inline void G4VEnergyLossProcess::SetMaxKinEnergy(G4double e)
    1112 {
    1113   maxKinEnergy = e;
    1114   if(e < maxKinEnergyCSDA) maxKinEnergyCSDA = e;
    1115 }
    1116 
    1117 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1118 
    1119 inline void G4VEnergyLossProcess::SetMaxKinEnergyForCSDARange(G4double e)
    1120 {
    1121   maxKinEnergyCSDA = e;
    1122 }
    1123 
    1124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1125 
    1126 inline G4double G4VEnergyLossProcess::MaxKinEnergy() const
    1127 {
    1128   return maxKinEnergy;
    1129 }
    1130 
    1131 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1132 
    1133 inline void G4VEnergyLossProcess::SetLambdaFactor(G4double val)
    1134 {
    1135   if(val > 0.0 && val <= 1.0) lambdaFactor = val;
    1136 }
    1137 
    1138 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1139 
    1140 inline void G4VEnergyLossProcess::SetIonisation(G4bool val)
    1141 {
    1142   isIonisation = val;
    1143   if(val) aGPILSelection = CandidateForSelection;
    1144   else    aGPILSelection = NotCandidateForSelection;
    1145 }
    1146 
    1147 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1148 
    1149 inline G4bool G4VEnergyLossProcess::IsIonisationProcess() const
    1150 {
    1151   return isIonisation;
    1152 }
    1153 
    1154 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1155 
    1156 void G4VEnergyLossProcess::SetStepFunction(G4double v1, G4double v2)
    1157 {
    1158   dRoverRange = v1;
    1159   finalRange = v2;
    1160   if (dRoverRange > 0.999) dRoverRange = 1.0;
    1161   currentCouple = 0;
    1162   mfpKinEnergy  = DBL_MAX;
    1163 }
    1164 
    1165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1166 
    11671181#endif
  • trunk/source/processes/electromagnetic/utils/include/G4VMultipleScattering.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VMultipleScattering.hh,v 1.48 2007/10/29 08:38:58 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VMultipleScattering.hh,v 1.55 2009/02/18 12:19:33 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    6363// 12-02-07 Add get/set skin (V.Ivanchenko)
    6464// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
     65// 15-07-08 Reorder class members for further multi-thread development (VI)
    6566//
    6667
     
    7273
    7374#include "G4VContinuousDiscreteProcess.hh"
    74 #include "G4LossTableManager.hh"
    7575#include "globals.hh"
    7676#include "G4Material.hh"
     
    9595
    9696  G4VMultipleScattering(const G4String& name = "msc",
    97                               G4ProcessType type = fElectromagnetic);
     97                        G4ProcessType type = fElectromagnetic);
    9898
    9999  virtual ~G4VMultipleScattering();
     
    104104
    105105  virtual G4bool IsApplicable(const G4ParticleDefinition& p) = 0;
    106     // True for all charged particles
    107106
    108107  virtual void PrintInfo() = 0;
     
    112111  virtual void InitialiseProcess(const G4ParticleDefinition*) = 0;
    113112
    114   //------------------------------------------------------------------------
    115   // Methods with standard implementation; may be overwritten if needed
    116   //------------------------------------------------------------------------
    117113public:
    118114
     
    138134  G4bool StorePhysicsTable(const G4ParticleDefinition*,
    139135                           const G4String& directory,
    140                                  G4bool ascii = false);
     136                           G4bool ascii = false);
    141137
    142138  // Retrieve Physics from a file.
     
    147143  G4bool RetrievePhysicsTable(const G4ParticleDefinition*,
    148144                              const G4String& directory,
    149                                     G4bool ascii);
    150 
    151   //------------------------------------------------------------------------
    152   // Specific methods for msc processes
    153   //------------------------------------------------------------------------
     145                              G4bool ascii);
    154146
    155147  // The function overloads the corresponding function of the base
     
    158150  G4double AlongStepGetPhysicalInteractionLength(
    159151                                            const G4Track&,
    160                                                   G4double  previousStepSize,
    161                                                   G4double  currentMinimalStep,
    162                                                   G4double& currentSafety,
    163                                                   G4GPILSelection* selection);
     152                                            G4double  previousStepSize,
     153                                            G4double  currentMinimalStep,
     154                                            G4double& currentSafety,
     155                                            G4GPILSelection* selection);
    164156
    165157  // The function overloads the corresponding function of the base
     
    188180  inline void SetMinKinEnergy(G4double e);
    189181  inline G4double MinKinEnergy() const;
    190     // Print out of the class parameters
    191182
    192183  inline void SetMaxKinEnergy(G4double e);
     
    197188  inline G4PhysicsTable* LambdaTable() const;
    198189
    199   //------------------------------------------------------------------------
    200   // Define and access particle type
    201   //------------------------------------------------------------------------
    202 
     190  // access particle type
    203191  inline const G4ParticleDefinition* Particle() const;
    204   inline void SetParticle(const G4ParticleDefinition*);
    205192
    206193  //------------------------------------------------------------------------
     
    208195  //------------------------------------------------------------------------
    209196
    210   inline void AddEmModel(G4int, G4VEmModel*, const G4Region* region = 0);
    211 
     197protected:
     198  // Select model in run time
     199  inline G4VEmModel* SelectModel(G4double kinEnergy);
     200
     201public:
     202  // Select model in run time
    212203  inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy,
    213204                                            size_t& idxRegion) const;
    214205
    215   // Access to models
    216   inline G4VEmModel* GetModelByIndex(G4int idx = 0);
    217 
    218   //------------------------------------------------------------------------
    219   // Parameters for simulation of multiple scattering
    220   //------------------------------------------------------------------------
    221 
     206  // Add model for region, smaller value of order defines which
     207  // model will be selected for a given energy interval 
     208  inline void AddEmModel(G4int order, G4VEmModel*, const G4Region* region = 0);
     209
     210  // Access to models by index
     211  inline G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false);
     212
     213  //------------------------------------------------------------------------
     214  // Get/Set parameters for simulation of multiple scattering
     215  //------------------------------------------------------------------------
     216
     217  inline G4bool LateralDisplasmentFlag() const;
    222218  inline void SetLateralDisplasmentFlag(G4bool val);
    223      // lateral displacement to be/not to be computed
    224 
     219
     220  inline G4double Skin() const;
    225221  inline void SetSkin(G4double val);
    226      // skin parameter
    227 
     222
     223  inline G4double RangeFactor() const;
    228224  inline void SetRangeFactor(G4double val);
    229      // FactorRange parameter
    230 
     225
     226  inline G4double GeomFactor() const;
    231227  inline void SetGeomFactor(G4double val);
    232      // FactorRange parameter
    233 
     228
     229  inline G4double PolarAngleLimit() const;
     230  inline void SetPolarAngleLimit(G4double val);
     231
     232  inline G4MscStepLimitType StepLimitType() const;
    234233  inline void SetStepLimitType(G4MscStepLimitType val);
    235      // FactorRange parameter
     234
     235  //------------------------------------------------------------------------
     236  // Run time methods
     237  //------------------------------------------------------------------------
    236238
    237239protected:
     
    241243                           G4double,
    242244                           G4ForceCondition* condition);
    243 
    244   //------------------------------------------------------------------------
    245   // Run time methods
    246   //------------------------------------------------------------------------
    247245
    248246  // This method is not used for tracking, it returns step limit
     
    252250                                  G4double& currentSafety);
    253251
    254   inline G4double GetLambda(const G4ParticleDefinition* p, G4double& kineticEnergy);
     252  inline G4double GetLambda(const G4ParticleDefinition* p,
     253                            G4double& kineticEnergy);
    255254
    256255  // This method is used for tracking, it returns step limit
    257256  inline G4double GetMscContinuousStepLimit(const G4Track& track,
    258                                             G4double previousStepSize,
     257                                            G4double scaledKinEnergy,
    259258                                            G4double currentMinimalStep,
    260259                                            G4double& currentSafety);
    261260
    262   inline G4VEmModel* SelectModel(G4double kinEnergy);
    263   // Select concrete model
     261  // define current material
     262  inline void DefineMaterial(const G4MaterialCutsCouple* couple);
    264263
    265264  inline const G4MaterialCutsCouple* CurrentMaterialCutsCouple() const;
    266   // Return current G4MaterialCutsCouple
    267 
    268   inline void DefineMaterial(const G4MaterialCutsCouple* couple);
    269   // define current material
    270 
    271   //------------------------------------------------------------------------
    272   // Parameters for simulation of multiple scattering
    273   //------------------------------------------------------------------------
    274 
    275   inline G4double Skin() const;
    276 
    277   inline G4double RangeFactor() const;
    278 
    279   inline G4double GeomFactor() const;
    280 
    281   inline G4MscStepLimitType StepLimitType() const;
    282 
    283   inline G4bool LateralDisplasmentFlag() const;
     265
     266  inline G4ParticleChangeForMSC* GetParticleChange();
     267
    284268
    285269private:
    286270
    287271  // hide  assignment operator
    288 
    289272  G4VMultipleScattering(G4VMultipleScattering &);
    290273  G4VMultipleScattering & operator=(const G4VMultipleScattering &right);
    291274
    292   // =====================================================================
    293 
    294 protected:
    295 
    296   G4GPILSelection             valueGPILSelectionMSC;
    297   G4ParticleChangeForMSC      fParticleChange;
    298 
    299 private:
     275  // ======== Parameters of the class fixed at construction =========
    300276
    301277  G4EmModelManager*           modelManager;
    302   G4VEmModel*                 currentModel;
     278  G4bool                      buildLambdaTable;
     279
     280  // ======== Parameters of the class fixed at initialisation =======
     281
    303282  G4PhysicsTable*             theLambdaTable;
    304 
    305   // cache
    306283  const G4ParticleDefinition* firstParticle;
    307   const G4ParticleDefinition* currentParticle;
    308   const G4MaterialCutsCouple* currentCouple;
    309   size_t                      currentMaterialIndex;
    310 
    311   G4int                       nBins;
    312284
    313285  G4MscStepLimitType          stepLimit;
     
    318290  G4double                    facrange;
    319291  G4double                    facgeom;
     292  G4double                    polarAngleLimit;
     293
     294  G4int                       nBins;
    320295
    321296  G4bool                      latDisplasment;
    322   G4bool                      buildLambdaTable;
     297
     298  // ======== Cashed values - may be state dependent ================
     299
     300protected:
     301
     302  G4GPILSelection             valueGPILSelectionMSC;
     303  G4ParticleChangeForMSC      fParticleChange;
     304
     305private:
     306
     307  G4VEmModel*                 currentModel;
     308
     309  // cache
     310  const G4ParticleDefinition* currentParticle;
     311  const G4MaterialCutsCouple* currentCouple;
     312  size_t                      currentMaterialIndex;
     313
    323314};
    324315
    325316//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    327 
    328 inline void G4VMultipleScattering::DefineMaterial(const G4MaterialCutsCouple* couple)
    329 {
    330   if(couple != currentCouple) {
    331     currentCouple   = couple;
    332     currentMaterialIndex = couple->GetIndex();
    333   }
    334 }
    335 
    336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    337 
    338 inline G4double G4VMultipleScattering::GetMscContinuousStepLimit(
    339                                           const G4Track& track,
    340                                                 G4double,
    341                                                 G4double currentMinimalStep,
    342                                                 G4double&)
    343 {
    344   G4double x = currentMinimalStep;
    345   G4double e = track.GetKineticEnergy();
    346   DefineMaterial(track.GetMaterialCutsCouple());
    347   currentModel = SelectModel(e);
    348   if(x > 0.0 && e > 0.0) {
    349     G4double tPathLength =
    350       currentModel->ComputeTruePathLengthLimit(track, theLambdaTable, x);
    351     if (tPathLength < x) valueGPILSelectionMSC = CandidateForSelection;
    352     x = currentModel->ComputeGeomPathLength(tPathLength); 
    353     //  G4cout << "tPathLength= " << tPathLength
    354     //         << " stepLimit= " << x
    355     //        << " currentMinimalStep= " << currentMinimalStep<< G4endl;
    356   }
    357   return x;
    358 }
    359 
    360317//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    361318
     
    367324{
    368325  return GetMscContinuousStepLimit(track,previousStepSize,currentMinimalStep,
    369                                       currentSafety);
    370 }
    371 
    372 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    373 
    374 inline G4double G4VMultipleScattering::GetLambda(const G4ParticleDefinition* p, G4double& e)
     326                                   currentSafety);
     327}
     328
     329//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     330
     331inline void G4VMultipleScattering::SetBinning(G4int nbins)
     332{
     333  nBins = nbins;
     334}
     335
     336//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     337
     338inline G4int G4VMultipleScattering::Binning() const
     339{
     340  return nBins;
     341}
     342
     343//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     344
     345inline void G4VMultipleScattering::SetMinKinEnergy(G4double e)
     346{
     347  minKinEnergy = e;
     348}
     349
     350//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     351
     352inline G4double G4VMultipleScattering::MinKinEnergy() const
     353{
     354  return minKinEnergy;
     355}
     356
     357//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     358
     359inline void G4VMultipleScattering::SetMaxKinEnergy(G4double e)
     360{
     361  maxKinEnergy = e;
     362}
     363
     364//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     365
     366inline G4double G4VMultipleScattering::MaxKinEnergy() const
     367{
     368  return maxKinEnergy;
     369}
     370
     371//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     372
     373inline  void G4VMultipleScattering::SetBuildLambdaTable(G4bool val)
     374{
     375  buildLambdaTable = val;
     376}
     377
     378//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     379
     380inline G4PhysicsTable* G4VMultipleScattering::LambdaTable() const
     381{
     382  return theLambdaTable;
     383}
     384
     385//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     386
     387inline  const G4ParticleDefinition* G4VMultipleScattering::Particle() const
     388{
     389  return currentParticle;
     390}
     391
     392//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     393
     394inline void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p,
     395                                              const G4Region* region)
     396{
     397  G4VEmFluctuationModel* fm = 0;
     398  modelManager->AddEmModel(order, p, fm, region);
     399  if(p) p->SetParticleChange(pParticleChange);
     400}
     401
     402//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     403
     404inline G4VEmModel* G4VMultipleScattering::SelectModel(G4double kinEnergy)
     405{
     406  return modelManager->SelectModel(kinEnergy, currentMaterialIndex);
     407}
     408
     409//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     410
     411inline G4VEmModel* G4VMultipleScattering::SelectModelForMaterial(
     412                   G4double kinEnergy, size_t& idxRegion) const
     413{
     414  return modelManager->SelectModel(kinEnergy, idxRegion);
     415}
     416
     417//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     418
     419inline
     420G4VEmModel* G4VMultipleScattering::GetModelByIndex(G4int idx, G4bool ver)
     421{
     422  return modelManager->GetModel(idx, ver);
     423}
     424
     425//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     426
     427inline  G4bool G4VMultipleScattering::LateralDisplasmentFlag() const
     428{
     429  return latDisplasment;
     430}
     431
     432//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     433
     434inline  void G4VMultipleScattering::SetLateralDisplasmentFlag(G4bool val)
     435{
     436  latDisplasment = val;
     437}
     438
     439//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     440
     441inline  G4double G4VMultipleScattering::Skin() const
     442{
     443  return skin;
     444}
     445
     446//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     447
     448inline  void G4VMultipleScattering::SetSkin(G4double val)
     449{
     450  if(val < 1.0) skin = 0.0;
     451  else          skin = val;
     452}
     453
     454//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     455
     456inline  G4double G4VMultipleScattering::RangeFactor() const
     457{
     458  return facrange;
     459}
     460
     461//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     462
     463inline  void G4VMultipleScattering::SetRangeFactor(G4double val)
     464{
     465  if(val > 0.0) facrange = val;
     466}
     467
     468//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     469
     470inline  G4double G4VMultipleScattering::GeomFactor() const
     471{
     472  return facgeom;
     473}
     474
     475//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     476
     477inline  void G4VMultipleScattering::SetGeomFactor(G4double val)
     478{
     479  if(val > 0.0) facgeom = val;
     480}
     481
     482//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     483
     484inline  G4double G4VMultipleScattering::PolarAngleLimit() const
     485{
     486  return polarAngleLimit;
     487}
     488
     489//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     490
     491inline  void G4VMultipleScattering::SetPolarAngleLimit(G4double val)
     492{
     493  if(val < 0.0)     polarAngleLimit = 0.0;
     494  else if(val > pi) polarAngleLimit = pi;
     495  else              polarAngleLimit = val;
     496}
     497
     498//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     499
     500inline G4MscStepLimitType G4VMultipleScattering::StepLimitType() const
     501{
     502  return stepLimit;
     503}
     504
     505//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     506
     507inline void G4VMultipleScattering::SetStepLimitType(G4MscStepLimitType val)
     508{
     509  stepLimit = val;
     510  if(val == fMinimal) facrange = 0.2;
     511}
     512
     513//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     514
     515inline
     516G4double G4VMultipleScattering::GetLambda(const G4ParticleDefinition* p,
     517                                          G4double& e)
    375518{
    376519  G4double x;
     
    388531//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    389532
    390 inline G4VEmModel* G4VMultipleScattering::SelectModel(G4double kinEnergy)
    391 {
    392   return modelManager->SelectModel(kinEnergy, currentMaterialIndex);
    393 }
    394 
    395 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    396 
    397 inline G4VEmModel* G4VMultipleScattering::SelectModelForMaterial(
    398                                            G4double kinEnergy, size_t& idxRegion) const
    399 {
    400   return modelManager->SelectModel(kinEnergy, idxRegion);
    401 }
    402 
    403 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    404 
    405 inline void G4VMultipleScattering::SetBinning(G4int nbins)
    406 {
    407   nBins = nbins;
    408 }
    409 
    410 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    411 
    412 inline G4int G4VMultipleScattering::Binning() const
    413 {
    414   return nBins;
    415 }
    416 
    417 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    418 
    419 inline void G4VMultipleScattering::SetMinKinEnergy(G4double e)
    420 {
    421   minKinEnergy = e;
    422 }
    423 
    424 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    425 
    426 inline G4double G4VMultipleScattering::MinKinEnergy() const
    427 {
    428   return minKinEnergy;
    429 }
    430 
    431 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    432 
    433 inline void G4VMultipleScattering::SetMaxKinEnergy(G4double e)
    434 {
    435   maxKinEnergy = e;
    436 }
    437 
    438 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    439 
    440 inline G4double G4VMultipleScattering::MaxKinEnergy() const
    441 {
    442   return maxKinEnergy;
    443 }
    444 
    445 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    446 
    447 inline  G4bool G4VMultipleScattering::LateralDisplasmentFlag() const
    448 {
    449   return latDisplasment;
    450 }
    451 
    452 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    453 
    454 inline  void G4VMultipleScattering::SetLateralDisplasmentFlag(G4bool val)
    455 {
    456   latDisplasment = val;
    457 }
    458 
    459 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    460 
    461 inline  G4double G4VMultipleScattering::Skin() const
    462 {
    463   return skin;
    464 }
    465 
    466 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    467 
    468 inline  void G4VMultipleScattering::SetSkin(G4double val)
    469 {
    470   if(val <= 0.99999) {
    471     skin = 0.0;
    472     stepLimit = fUseSafety;
    473   } else {
    474     skin = val;
    475     stepLimit = fUseDistanceToBoundary;
     533inline G4double G4VMultipleScattering::GetMscContinuousStepLimit(
     534                                          const G4Track& track,
     535                                          G4double scaledKinEnergy,
     536                                          G4double currentMinimalStep,
     537                                          G4double&)
     538{
     539  G4double x = currentMinimalStep;
     540  DefineMaterial(track.GetMaterialCutsCouple());
     541  currentModel = SelectModel(scaledKinEnergy);
     542  if(x > 0.0 && scaledKinEnergy > 0.0) {
     543    G4double tPathLength =
     544      currentModel->ComputeTruePathLengthLimit(track, theLambdaTable, x);
     545    if (tPathLength < x) valueGPILSelectionMSC = CandidateForSelection;
     546    x = currentModel->ComputeGeomPathLength(tPathLength); 
     547    //  G4cout << "tPathLength= " << tPathLength
     548    //         << " stepLimit= " << x
     549    //        << " currentMinimalStep= " << currentMinimalStep<< G4endl;
    476550  }
    477 }
    478 
    479 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    480 
    481 inline  G4double G4VMultipleScattering::RangeFactor() const
    482 {
    483   return facrange;
    484 }
    485 
    486 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    487 
    488 inline  void G4VMultipleScattering::SetRangeFactor(G4double val)
    489 {
    490   if(val > 0.0) facrange = val;
    491 }
    492 
    493 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    494 
    495 inline  G4double G4VMultipleScattering::GeomFactor() const
    496 {
    497   return facgeom;
    498 }
    499 
    500 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    501 
    502 inline  void G4VMultipleScattering::SetGeomFactor(G4double val)
    503 {
    504   if(val > 0.0) facgeom = val;
    505 }
    506 
    507 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    508 
    509 inline G4MscStepLimitType G4VMultipleScattering::StepLimitType() const
    510 {
    511   return stepLimit;
    512 }
    513 
    514 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    515 
    516 inline void G4VMultipleScattering::SetStepLimitType(G4MscStepLimitType val)
    517 {
    518   stepLimit = val;
    519   if(val == fMinimal) {
    520     skin = 0;
    521     facrange = 0.2;
    522   } else if(val == fUseSafety) {
    523     skin = 0;
     551  return x;
     552}
     553
     554//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     555
     556inline
     557void G4VMultipleScattering::DefineMaterial(const G4MaterialCutsCouple* couple)
     558{
     559  if(couple != currentCouple) {
     560    currentCouple   = couple;
     561    currentMaterialIndex = couple->GetIndex();
    524562  }
    525563}
     
    527565//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    528566
    529 inline  void G4VMultipleScattering::SetBuildLambdaTable(G4bool val)
    530 {
    531    buildLambdaTable = val;
    532 }
    533 
    534 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    535 
    536 inline  const G4ParticleDefinition* G4VMultipleScattering::Particle() const
    537 {
    538   return currentParticle;
    539 }
    540 
    541 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    542 
    543 inline G4PhysicsTable* G4VMultipleScattering::LambdaTable() const
    544 {
    545   return theLambdaTable;
    546 }
    547 
    548 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    549 
    550 inline
    551 const G4MaterialCutsCouple* G4VMultipleScattering::CurrentMaterialCutsCouple() const
     567inline const G4MaterialCutsCouple*
     568G4VMultipleScattering::CurrentMaterialCutsCouple() const
    552569{
    553570  return currentCouple;
     
    556573//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    557574
    558 inline void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p,
    559                                               const G4Region* region)
    560 {
    561   G4VEmFluctuationModel* fm = 0;
    562   modelManager->AddEmModel(order, p, fm, region);
    563   if(p)p->SetParticleChange(pParticleChange);
    564 }
    565 
    566 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    567 
    568 inline G4VEmModel* G4VMultipleScattering::GetModelByIndex(G4int idx)
    569 {
    570   return modelManager->GetModel(idx);
     575inline G4ParticleChangeForMSC* G4VMultipleScattering::GetParticleChange()
     576{
     577  return &fParticleChange;
    571578}
    572579
  • trunk/source/processes/electromagnetic/utils/include/G4ionEffectiveCharge.hh

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4ionEffectiveCharge.hh,v 1.8 2006/08/15 16:21:39 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4ionEffectiveCharge.hh,v 1.12 2008/09/20 19:39:34 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5656
    5757#include "globals.hh"
     58#include "G4ParticleDefinition.hh"
    5859
    5960class G4Material;
    60 class G4ParticleDefinition;
     61class G4NistManager;
    6162
    6263class G4ionEffectiveCharge
     
    8485  G4ionEffectiveCharge(const G4ionEffectiveCharge&);
    8586
     87  G4NistManager*              nist;
     88
     89  const G4ParticleDefinition* lastPart;
     90  const G4Material*           lastMat;
     91  G4double                    lastKinEnergy;
     92
    8693  G4double                    chargeCorrection;
     94  G4double                    effCharge;
     95
    8796  G4double                    energyHighLimit;
    8897  G4double                    energyLowLimit;
     
    100109                                 G4double kineticEnergy)
    101110{
    102   G4double charge = EffectiveCharge(p,material,kineticEnergy)/eplus;
    103   charge *= chargeCorrection;
     111  G4double charge = effCharge;
     112  if( kineticEnergy != lastKinEnergy || material != lastMat || p != lastPart) {
     113    charge = EffectiveCharge(p,material,kineticEnergy);
     114  }
     115  charge *= chargeCorrection/CLHEP::eplus;
    104116
    105117  return charge*charge;
  • trunk/source/processes/electromagnetic/utils/src/G4DummyModel.cc

    r819 r961  
    2525//
    2626// $Id: G4DummyModel.cc,v 1.3 2007/05/22 17:31:58 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/src/G4EmCalculator.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmCalculator.cc,v 1.37 2007/08/16 15:55:42 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmCalculator.cc,v 1.46 2009/02/24 09:56:03 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5555//            10 keV to 1 keV (V. Ivanchenko)
    5656// 15.03.2007 Add ComputeEnergyCutFromRangeCut methods (V.Ivanchenko)
     57// 21.04.2008 Updated computations for ions (V.Ivanchenko)
    5758//
    5859// Class Description:
     
    126127  if(couple && UpdateParticle(p, kinEnergy) ) {
    127128    res = manager->GetDEDX(p, kinEnergy, couple);
     129    if(isIon) {
     130      G4double eth = 2.0*MeV/massRatio;
     131      if(kinEnergy > eth) {
     132        G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy);
     133        G4double x2 = corr->ComputeIonCorrections(p,mat,eth);
     134        res += x1 - x2*eth/kinEnergy;
     135        /*     
     136        G4cout << "### GetDEDX: E= " << kinEnergy << " res= " << res
     137               << " x1= " << x1 << " x2= " << x2
     138               << " del= " << x1 - x2*eth/kinEnergy << G4endl;;
     139        */
     140      }
     141    }
     142
    128143    if(verbose>0) {
    129144      G4cout << "G4EmCalculator::GetDEDX: E(MeV)= " << kinEnergy/MeV
     
    406421        res = currentModel->ComputeDEDXPerVolume(
    407422              mat, baseParticle, escaled, cut) * chargeSquare;
    408         if(verbose > 1)
     423        if(verbose > 1) {
    409424          G4cout <<  baseParticle->GetParticleName()
    410425                 << " Escaled(MeV)= " << escaled;
     426        }
    411427      } else {
    412428        res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
    413429        if(verbose > 1) G4cout <<  " no basePart E(MeV)= " << kinEnergy;
    414430      }
    415       if(verbose > 1)
     431      if(verbose > 1) {
    416432        G4cout << " DEDX(MeV/mm)= " << res*mm/MeV
    417433               << " DEDX(MeV*cm^2/g)= "
    418434               << res*gram/(MeV*cm2*mat->GetDensity())
    419435               << G4endl;
    420 
    421       if(isIon) {
    422         if(currentModel->HighEnergyLimit() > 100.*MeV)
    423           res += corr->HighOrderCorrections(p,mat,kinEnergy);
    424         else
    425           res *= corr->EffectiveChargeCorrection(p,mat,kinEnergy);
    426         if(verbose > 1)
    427           G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
    428                  << " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
    429                  << G4endl;
    430       }
    431 
    432      
     436      }
     437
    433438      // emulate boundary region for different parameterisations
    434439      G4double eth = currentModel->LowEnergyLimit();
     
    447452          res0 = loweModel->ComputeDEDXPerVolume(mat, p, eth, cut);
    448453        }
    449         if(verbose > 1)
     454        if(verbose > 1) {
    450455          G4cout << "At boundary energy(MeV)= " << eth/MeV
    451456                 << " DEDX(MeV/mm)= " << res1*mm/MeV
    452457                 << G4endl;
    453         if(isIon) res1 += corr->HighOrderCorrections(p,mat,eth/massRatio);
    454         //G4cout << "eth= " << eth << " escaled= " << escaled
    455         //  << " res0= " << res0 << " res1= "
    456         //       << res1 <<  "  q2= " << chargeSquare << G4endl;
     458        }
     459        /*
     460        G4cout << "eth= " << eth << " escaled= " << escaled
     461               << " res0= " << res0 << " res1= "
     462               << res1 <<  "  q2= " << chargeSquare << G4endl;
     463        */
    457464        res *= (1.0 + (res0/res1 - 1.0)*eth/escaled);
     465
     466        if(isIon) {
     467          G4double ethscaled = eth/massRatio;
     468          if(kinEnergy > ethscaled) {
     469            G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy);
     470            G4double x2 = corr->ComputeIonCorrections(p,mat,ethscaled);
     471            res += x1 - x2*ethscaled/kinEnergy;
     472          }
     473       
     474          if(verbose > 1) {
     475            G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
     476                   << " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
     477                   << G4endl;
     478          }
     479        }
    458480      }
    459481     
     
    507529//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    508530
    509 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4ParticleDefinition* part,
    510                                           const G4Material* mat, G4double cut)
     531G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
     532                                          const G4ParticleDefinition* part,
     533                                          const G4Material* mat,
     534                                          G4double cut)
    511535{
    512536  G4double dedx = ComputeElectronicDEDX(kinEnergy,part,mat,cut);
     
    517541//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    518542
    519 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4String& part,
    520                                           const G4String& mat, G4double cut)
     543G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
     544                                          const G4String& part,
     545                                          const G4String& mat,
     546                                          G4double cut)
    521547{
    522548  return ComputeTotalDEDX(kinEnergy,FindParticle(part),FindMaterial(mat),cut);
     
    729755    if(currentProcess) currentProcessName = currentProcess->GetProcessName();
    730756
    731     if(p->GetParticleType() == "nucleus" &&
    732        currentParticleName  != "deuteron" && currentParticleName != "triton") {
     757    if(p->GetParticleType() == "nucleus"
     758       && currentParticleName != "deuteron" 
     759       && currentParticleName != "triton"
     760       && currentParticleName != "alpha+"
     761       && currentParticleName != "helium"
     762       && currentParticleName != "hydrogen"
     763      ) {
    733764      baseParticle = theGenericIon;
    734765      massRatio = baseParticle->GetPDGMass()/p->GetPDGMass();
     
    755786  if(isIon) {
    756787    chargeSquare =
    757      ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy);
    758     if(currentProcess)
     788     ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy)
     789      * corr->EffectiveChargeCorrection(p,currentMaterial,kinEnergy);
     790    if(currentProcess) {
    759791      currentProcess->SetDynamicMassCharge(massRatio,chargeSquare);
    760     // G4cout << "massR= " << massRatio << "   q2= " << chargeSquare << G4endl;
     792      //G4cout << "NewP: massR= " << massRatio << "   q2= " << chargeSquare << G4endl;
     793    }
    761794  }
    762795  return true;
  • trunk/source/processes/electromagnetic/utils/src/G4EmCorrections.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmCorrections.cc,v 1.23.2.1 2008/04/22 15:28:13 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmCorrections.cc,v 1.51 2008/12/18 13:01:44 gunter Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4444// 08.05.2007 V.Ivanchenko Use G4IonTable for ion mass instead of NistTable to avoid
    4545//                         division by zero
     46// 29.02.2008 V.Ivanchenko use expantions for log and power function
     47// 21.04.2008 Updated computations for ions (V.Ivanchenko)
     48// 20.05.2008 Removed Finite Size correction (V.Ivanchenko)
    4649//
    4750//
     
    5659#include "G4EmCorrections.hh"
    5760#include "Randomize.hh"
    58 #include "G4NistManager.hh"
    5961#include "G4ParticleTable.hh"
    6062#include "G4IonTable.hh"
    6163#include "G4VEmModel.hh"
    6264#include "G4Proton.hh"
     65#include "G4GenericIon.hh"
    6366#include "G4LPhysicsFreeVector.hh"
     67#include "G4PhysicsLogVector.hh"
     68#include "G4ProductionCutsTable.hh"
     69#include "G4MaterialCutsCouple.hh"
    6470
    6571//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    6773G4EmCorrections::G4EmCorrections()
    6874{
    69   Initialise();
    7075  particle   = 0;
    7176  curParticle= 0;
     
    7479  curVector  = 0;
    7580  kinEnergy  = 0.0;
    76   ionModel   = 0;
     81  ionLEModel = 0;
     82  ionHEModel = 0;
    7783  nIons      = 0;
    7884  verbose    = 1;
     85  ncouples   = 0;
    7986  massFactor = 1.0;
     87  eth        = 2.0*MeV;
     88  nbinCorr   = 20;
     89  eCorrMin   = 25.*keV;
     90  eCorrMax   = 250.*MeV;
    8091  nist = G4NistManager::Instance();
    8192  ionTable = G4ParticleTable::GetParticleTable()->GetIonTable();
     93  Initialise();
    8294}
    8395
     
    93105G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
    94106                                               const G4Material* mat,
    95                                                G4double e)
     107                                               G4double e, G4double)
    96108{
    97109// . Z^3 Barkas effect in the stopping power of matter for charged particles
     
    108120  G4double Bloch  = BlochCorrection (p, mat, e);
    109121  G4double Mott   = MottCorrection (p, mat, e);
    110   G4double FSize  = FiniteSizeCorrection (p, mat, e);
    111 
    112   G4double sum = (2.0*(Barkas + Bloch) + FSize + Mott);
     122
     123  G4double sum = (2.0*(Barkas + Bloch) + Mott);
    113124
    114125  if(verbose > 1)
    115126    G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
    116            << " Bloch= " << Bloch << " Mott= " << Mott << " Fsize= " << FSize
     127           << " Bloch= " << Bloch << " Mott= " << Mott
    117128           << " Sum= " << sum << G4endl;
    118129
    119130  sum *= material->GetElectronDensity() * q2 *  twopi_mc2_rcl2 /beta2;
     131  return sum;
     132}
     133
     134//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     135
     136G4double G4EmCorrections::IonBarkasCorrection(const G4ParticleDefinition* p,
     137                                              const G4Material* mat,
     138                                              G4double e)
     139{
     140// . Z^3 Barkas effect in the stopping power of matter for charged particles
     141//   J.C Ashley and R.H.Ritchie
     142//   Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
     143//   and ICRU49 report
     144//   valid for kineticEnergy < 0.5 MeV
     145
     146  SetupKinematics(p, mat, e);
     147  G4double res = 0.0;
     148  if(tau > 0.0)
     149    res = 2.0*BarkasCorrection(p, mat, e)*
     150      material->GetElectronDensity() * q2 *  twopi_mc2_rcl2 /beta2;
     151  return res;
     152}
     153
     154//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     155
     156G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
     157                                                const G4Material* mat,
     158                                                G4double e)
     159{
     160// . Z^3 Barkas effect in the stopping power of matter for charged particles
     161//   J.C Ashley and R.H.Ritchie
     162//   Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
     163//   and ICRU49 report
     164//   valid for kineticEnergy < 0.5 MeV
     165//   Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
     166  SetupKinematics(p, mat, e);
     167  if(tau <= 0.0) return 0.0;
     168
     169  G4double Barkas = BarkasCorrection (p, mat, e);
     170  G4double Bloch  = BlochCorrection (p, mat, e);
     171  G4double Mott   = MottCorrection (p, mat, e);
     172
     173  G4double sum = 2.0*(Barkas*(charge - 1.0)/charge + Bloch) + Mott;
     174
     175  if(verbose > 1) {
     176    G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
     177           << " Bloch= " << Bloch << " Mott= " << Mott
     178           << " Sum= " << sum << G4endl;
     179  }
     180  sum *= material->GetElectronDensity() * q2 *  twopi_mc2_rcl2 /beta2;
     181
     182  if(verbose > 1) G4cout << " Sum= " << sum << G4endl;
     183  return sum;
     184}
     185
     186//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     187
     188G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
     189                                                  const G4MaterialCutsCouple* couple,
     190                                                  G4double e)
     191{
     192// . Z^3 Barkas effect in the stopping power of matter for charged particles
     193//   J.C Ashley and R.H.Ritchie
     194//   Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
     195//   and ICRU49 report
     196//   valid for kineticEnergy < 0.5 MeV
     197//   Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
     198
     199  G4double sum = 0.0;
     200
     201  if(ionHEModel) {
     202    G4int Z = G4int(p->GetPDGCharge()/eplus + 0.5);
     203    if(Z >= 100)   Z = 99;
     204    else if(Z < 1) Z = 1;
     205
     206    // fill vector
     207    if(thcorr[Z].size() == 0) {
     208      thcorr[Z].resize(ncouples);
     209      G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
     210
     211      for(size_t i=0; i<ncouples; i++) {
     212        (thcorr[Z])[i] = ethscaled*ComputeIonCorrections(p, currmat[i], ethscaled);
     213        //G4cout << i << ". ethscaled= " << ethscaled
     214        //<< " corr= " << (thcorr[Z])[i]/ethscaled << G4endl;
     215      }
     216    }
     217    G4double rest = (thcorr[Z])[couple->GetIndex()];
     218
     219    sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e;
     220
     221    if(verbose > 1) G4cout << " Sum= " << sum << " dSum= " << rest/e << G4endl;
     222  }
    120223  return sum;
    121224}
     
    226329    G4int ieta = Index(y, Eta, nEtaK);
    227330    corr = Value2(x, y, TheK[itet], TheK[itet+1], Eta[ieta], Eta[ieta+1],
    228                   CK[itet][ieta], CK[itet+1][ieta], CK[itet][ieta+1], CK[itet+1][ieta+1]);
     331                  CK[itet][ieta], CK[itet+1][ieta],
     332                  CK[itet][ieta+1], CK[itet+1][ieta+1]);
    229333    //G4cout << "   x= " <<x<<" y= "<<y<<" tet= " <<TheK[itet]
    230334    //<<" "<< TheK[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
     
    439543    else {
    440544      G4int iw = Index(W, engBarkas, 47);
    441       val = Value(W, engBarkas[iw], engBarkas[iw+1], corBarkas[iw], corBarkas[iw+1]);
     545      val = Value(W, engBarkas[iw], engBarkas[iw+1],
     546                  corBarkas[iw], corBarkas[iw+1]);
    442547    }
    443548    //    G4cout << "i= " << i << " b= " << b << " W= " << W
     
    479584{
    480585  SetupKinematics(p, mat, e);
    481   G4double mterm = pi*fine_structure_const*beta*charge;
    482   /*
    483   G4double mterm = 0.0;
    484   if(beta > 0.0) {
    485 
    486     // Estimation of mean square root of the ionisation potential
    487     G4double Zeff = 0.0;
    488     G4double norm = 0.0;
    489 
    490     for (G4int i = 0; i<numberOfElements; i++) {
    491       G4double Z = (*theElementVector)[i]->GetZ();
    492       Zeff += Z*atomDensity[i];
    493       norm += atomDensity[i];
    494     }
    495     Zeff *= (2.0/norm);
    496     G4double ze1 = std::log(Zeff);
    497     G4double eexc= material->GetIonisation()->GetMeanExcitationEnergy()*ze1*ze1/Zeff;
    498 
    499     G4double invbeta = 1.0/beta;
    500     G4double invbeta2= invbeta*invbeta;
    501     G4double za  = charge*fine_structure_const;
    502     G4double za2 = za*za;
    503     G4double za3 = za2*za;
    504     G4double x   = za*invbeta;
    505     G4double cosx;
    506     if(x < COSEB[13]) {
    507       G4int i = Index(x,COSEB,14);
    508       cosx    = Value(x,COSEB[i], COSEB[i+1],COSXI[i],COSXI[i+1]);
    509     } else {
    510       cosx = COSXI[13]*COSEB[13]/x;
    511     }
    512 
    513     mterm =
    514       za*beta*(1.725 + pi*cosx*(0.52 - 2.0*std::sqrt(eexc/(2.0*electron_mass_c2*bg2))));
    515       + za2*(3.246 - 0.451*beta2)
    516       + za3*(1.522*beta + 0.987*invbeta)
    517       + za2*za2*(4.569 - 0.494*beta2 - 2.696*invbeta2)
    518       + za3*za2*(1.254*beta + 0.222*invbeta - 1.17*invbeta*invbeta2);
    519   }
    520 */ 
     586  G4double mterm = CLHEP::pi*fine_structure_const*beta*charge;
    521587  return mterm;
    522 }
    523 
    524 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    525 
    526 G4double G4EmCorrections::FiniteSizeCorrection(const G4ParticleDefinition* p,
    527                                                const G4Material* mat,
    528                                                G4double e)
    529   // Finite size corrections are parameterized according to
    530   // J.D.Jackson Phys. Rev. D59 (1998) 017301
    531 {
    532   if(p) return 0.0;
    533   SetupKinematics(p, mat, e);
    534   G4double term = 0.0;
    535   G4double numlim = 0.2;
    536 
    537   //Leptons
    538   if(p->GetLeptonNumber() != 0) {
    539     G4double x =  tmax/(e + mass);
    540     term = x*x;
    541 
    542     // Pions and Kaons
    543   } else if(p->GetPDGSpin() == 0.0 && q2 < 1.5) {
    544     G4double xpi = 0.736*GeV;
    545     G4double x   = 2.0*electron_mass_c2*tmax0/(xpi*xpi);
    546     if(x <= numlim) term = -x*(1.0 - 0.5*x);
    547     else            term = -std::log(1.0 + x);
    548 
    549     // Protons and baryons
    550   } else if(q2 < 1.5) {
    551     G4double xp = 0.8426*GeV;
    552     G4double x  = 2.0*electron_mass_c2*tmax0/(xp*xp);
    553     G4double ksi2 = 2.79285*2.79285;
    554     if(x <= numlim) term = -x*((1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) + 0.5*x);
    555     else term = -x*(1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) - std::log(1.0 + x);
    556     G4double b  = xp*0.5/mass;
    557     G4double c  = xp*mass/(electron_mass_c2*(mass + e));
    558     G4double lb = b*b;
    559     G4double lb2= lb*lb;
    560     G4double nu = 0.5*c*c;
    561     G4double x1 = 1.0 + x;
    562     G4double x2 = x1*x1;
    563     G4double l1 = 1.0 - lb;
    564     G4double l2 = l1*l1;
    565     G4double lx = 1.0 + lb*x;
    566     G4double ia = lb2*(lx*std::log(lx/x1)/x + l1 -
    567                        0.5*x*l2/(lb*x1) +
    568                        x*(3.0 + 2.0*x)*l2*l1/(6.0*x2*lb2))/(l2*l2);
    569     G4double ib = x*x*(3.0 + x)/(6.0*x2*x1);
    570     term += lb*((ksi2 - 1.0)*ia + nu*ksi2*ib);
    571     // G4cout << "Proton F= " << term << " ia= " << ia << " ib= " << ib << " lb= " << lb<< G4endl;
    572    
    573     //ions
    574   } else {
    575     G4double xp = 0.8426*GeV/std::pow(mass/proton_mass_c2,-0.33333333);
    576     G4double x  = 2.0*electron_mass_c2*tmax0/(xp*xp);
    577     if(x <= numlim) term = -x*(1.0 - 0.5*x);
    578     else            term = -std::log(1.0 + x);
    579     //G4cout << "Ion F= " << term << G4endl;
    580   }
    581 
    582   return term;
    583588}
    584589
     
    629634  if (er >= ed[0])       nloss = a[0];
    630635  else {
     636    // the table is inverse in energy
    631637    for (G4int i=102; i>=0; i--)
    632638    {
     
    657663//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    658664
    659 G4ionEffectiveCharge* G4EmCorrections::GetIonEffectiveCharge(G4VEmModel* m)
    660 {
    661   if(m) ionModel = m;
    662   return &effCharge;
    663 }
    664 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    665 
    666 G4int G4EmCorrections::GetNumberOfStoppingVectors()
    667 {
    668   return nIons;
    669 }
    670 
    671 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    672 
    673665G4double G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition* p,
    674666                                                    const G4Material* mat,
     
    676668{
    677669  G4double factor = 1.0;
    678   if(p->GetPDGCharge() <= 2.5*eplus) return factor;
    679   if(verbose > 1)
    680     G4cout << "EffectiveChargeCorrection: " << p->GetParticleName() << " in " << mat->GetName()
     670  if(p->GetPDGCharge() <= 2.5*eplus || nIons <= 0) return factor;
     671  /*
     672  if(verbose > 1) {
     673    G4cout << "EffectiveChargeCorrection: " << p->GetParticleName()
     674           << " in " << mat->GetName()
    681675           << " ekin(MeV)= " << ekin/MeV << G4endl;
     676  }
     677  */
    682678  if(p != curParticle || mat != curMaterial) {
    683679    curParticle = p;
    684     curMaterial = 0;
     680    curMaterial = mat;
    685681    curVector   = 0;
    686     G4int Z = p->GetAtomicNumber();
    687     G4int A = p->GetAtomicMass();
    688     if(verbose > 1) G4cout << "Zion= " << Z << " Aion= " << A << G4endl;
    689     massFactor = proton_mass_c2/ionTable->GetIonMass(Z,A);
    690     idx = 0;
    691     for(; idx<nIons; idx++) {
    692       if(Z == Zion[idx] && A == Aion[idx]) {
    693         if(materialList[idx] == mat) {
    694           curMaterial = mat;
    695           curVector = stopData[idx];
    696           break;
    697         } else if(materialList[idx] == 0) {
    698           if(materialName[idx] == mat->GetName())
    699             curVector = InitialiseMaterial(mat);
    700         }
     682    currentZ = p->GetAtomicNumber();
     683    if(verbose > 1) {
     684      G4cout << "G4EmCorrections::EffectiveChargeCorrection: Zion= "
     685             << currentZ << " Aion= " << p->GetPDGMass()/amu_c2 << G4endl;
     686    }
     687    massFactor = proton_mass_c2/p->GetPDGMass();
     688    idx = -1;
     689    G4int dz = 1000;
     690
     691    for(G4int i=0; i<nIons; i++) {
     692      if(materialList[i] == mat) {
     693        G4int delz = currentZ - Zion[i];
     694        if(delz < 0) delz = -delz;
     695        if(delz < dz) {
     696          idx = i;
     697          dz = delz;
     698          if(0 == delz) break;
     699        }
    701700      }
     701    }
     702    //    G4cout << " idx= " << idx << " dz= " << dz << G4endl;
     703    if(idx > 0) {
     704      if(!ionList[idx]) BuildCorrectionVector();
     705      if(ionList[idx])  curVector = stopData[idx];
    702706    }
    703707  }
     
    705709    G4bool b;
    706710    factor = curVector->GetValue(ekin*massFactor,b);
    707   }
    708   if(verbose > 1) G4cout << "  factor= " << factor << G4endl;
     711    if(verbose > 1) {
     712      G4cout << "E= " << ekin << " factor= " << factor << " massfactor= "
     713             << massFactor << G4endl;
     714    }
     715  }
    709716  return factor;
    710717}
     
    714721void G4EmCorrections::AddStoppingData(G4int Z, G4int A,
    715722                                      const G4String& mname,
    716                                       G4PhysicsVector& dVector)
    717 {
    718   idx = 0;
    719   for(; idx<nIons; idx++) {
    720     if(Z == Zion[idx] && A == Aion[idx] && mname == materialName[idx])
    721       break;
    722   }
    723   if(idx == nIons) {
     723                                      G4PhysicsVector* dVector)
     724{
     725  G4int i = 0;
     726  for(; i<nIons; i++) {
     727    if(Z == Zion[i] && A == Aion[i] && mname == materialName[i]) break;
     728  }
     729  if(i == nIons) {
    724730    Zion.push_back(Z);
    725731    Aion.push_back(A);
    726732    materialName.push_back(mname);
    727733    materialList.push_back(0);
    728     stopData.push_back(0);
     734    ionList.push_back(0);
     735    stopData.push_back(dVector);
    729736    nIons++;
    730   } else {
    731     if(stopData[idx]) delete stopData[idx];
    732   }
    733   size_t nbins = dVector.GetVectorLength();
    734   size_t n = 0;
    735   for(; n<nbins; n++) {
    736     if(dVector.GetLowEdgeEnergy(n) > 2.0*MeV) break;
    737   }
    738   if(n < nbins) nbins = n + 1;
    739   G4LPhysicsFreeVector* v =
    740     new G4LPhysicsFreeVector(nbins,
    741                              dVector.GetLowEdgeEnergy(0),
    742                              dVector.GetLowEdgeEnergy(nbins-1));
     737    if(verbose>1) {
     738      G4cout << "AddStoppingData Z= " << Z << " A= " << A << " " << mname
     739             << "  idx= " << i << G4endl;
     740    }
     741  }
     742}
     743
     744//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     745
     746void G4EmCorrections::BuildCorrectionVector()
     747{
     748  if(!ionLEModel || !ionHEModel) {
     749    return;
     750  }
     751
     752  const G4ParticleDefinition* ion = curParticle;
     753  G4int Z = Zion[idx];
     754  if(currentZ != Z) {
     755    ion = G4ParticleTable::GetParticleTable()->FindIon(Z, Aion[idx], 0, Z);
     756  }
     757  //G4cout << "BuildCorrectionVector: idx= " << idx << " Z= " << Z
     758  //     << " curZ= " << currentZ << G4endl;
     759
     760  // G4double A = nist->GetAtomicMassAmu(Z);
     761  G4double A = G4double(ion->GetBaryonNumber());
     762  G4PhysicsVector* v = stopData[idx];
     763   
     764  const G4ParticleDefinition* p = G4GenericIon::GenericIon();
     765  G4double massRatio = proton_mass_c2/ion->GetPDGMass();
     766
     767  if(verbose>1) {
     768    G4cout << "BuildCorrectionVector: Stopping for "
     769           << curParticle->GetParticleName() << " in "
     770           << materialName[idx] << " Ion Z= " << Z << " A= " << A
     771           << " massRatio= " << massRatio << G4endl;
     772  }
    743773  G4bool b;
    744   for(size_t i=0; i<nbins; i++) {
    745     G4double e = dVector.GetLowEdgeEnergy(i);
    746     G4double dedx = dVector.GetValue(e, b);
    747     v->PutValues(i, e, dedx);
    748   }
    749   //  G4cout << *v << G4endl;
    750   stopData[idx] = v;
    751 }
    752 
    753 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    754 
    755 G4PhysicsVector* G4EmCorrections::InitialiseMaterial(const G4Material* mat)
    756 {
    757   G4PhysicsVector* v = 0;
    758   const G4Material* m = nist->FindOrBuildMaterial(materialName[idx],false);
    759   if(m) {
    760     materialList[idx] = m;
    761     curMaterial = mat;
    762     v = stopData[idx];
    763     size_t nbins = v->GetVectorLength();
    764     const G4ParticleDefinition* p = G4Proton::Proton();
    765     if(verbose>1) G4cout << "G4ionIonisation::InitialiseMaterial Stooping data for "
    766                          << materialName[idx] << G4endl;
    767     G4bool b;
    768     for(size_t i=0; i<nbins; i++) {
    769       G4double e = v->GetLowEdgeEnergy(i);
    770       G4double dedx = v->GetValue(e, b);
    771       G4double dedx1= ionModel->ComputeDEDXPerVolume(mat, p, e, e)*
    772         effCharge.EffectiveChargeSquareRatio(curParticle,mat,e/massFactor);
    773       v->PutValue(i, dedx/dedx1);
    774       if(verbose>1) G4cout << "  E(meV)= " << e/MeV << "   Correction= " << dedx/dedx1
    775                            << "   "  << dedx << " " << dedx1 << G4endl;
    776     }
    777   }
    778   return v;
     774
     775  G4PhysicsLogVector* vv =
     776    new G4PhysicsLogVector(eCorrMin,eCorrMax,nbinCorr);
     777  vv->SetSpline(true);
     778  G4double e, eion, dedx, dedx1;
     779  G4double eth0 = v->GetLowEdgeEnergy(0);
     780  G4double escal = eth/massRatio;
     781  G4double qe =
     782    effCharge.EffectiveChargeSquareRatio(ion, curMaterial, escal);
     783  G4double dedxt =
     784    ionLEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe;
     785  G4double dedx1t =
     786    ionHEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe
     787    + ComputeIonCorrections(curParticle, curMaterial, escal);
     788  G4double rest = escal*(dedxt - dedx1t);
     789  //G4cout << "Escal(MeV)= "<<escal<<" dedxt0= " <<dedxt
     790  //     << " dedxt1= " << dedx1t << G4endl;   
     791
     792  for(G4int i=0; i<nbinCorr; i++) {
     793    e = vv->GetLowEdgeEnergy(i);
     794    escal = e/massRatio;
     795    eion  = escal/A;
     796    if(eion <= eth0) {
     797      dedx = v->GetValue(eth0, b)*std::sqrt(eion/eth0);
     798    } else {
     799      dedx = v->GetValue(eion, b);
     800    }
     801    qe = effCharge.EffectiveChargeSquareRatio(curParticle,curMaterial,escal);
     802    if(e <= eth) {
     803      dedx1 = ionLEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe;
     804    } else {
     805      dedx1 = ionHEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe +
     806        ComputeIonCorrections(curParticle, curMaterial, escal) + rest/escal;
     807    }
     808    vv->PutValue(i, dedx/dedx1);
     809    if(verbose>1) {
     810      G4cout << "  E(meV)= " << e/MeV << "   Correction= " << dedx/dedx1
     811             << "   "  << dedx << " " << dedx1
     812             << "  massF= " << massFactor << G4endl;
     813    }
     814  }
     815  delete v;
     816  ionList[idx]  = ion;
     817  stopData[idx] = vv;
     818  if(verbose>1) G4cout << "End data set " << G4endl;
     819}
     820
     821//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     822
     823void G4EmCorrections::InitialiseForNewRun()
     824{
     825  G4ProductionCutsTable* tb = G4ProductionCutsTable::GetProductionCutsTable();
     826  ncouples = tb->GetTableSize();
     827  if(currmat.size() != ncouples) {
     828    currmat.resize(ncouples);
     829    size_t i;
     830    for(i=0; i<100; i++) {thcorr[i].clear();}
     831    for(i=0; i<ncouples; i++) {
     832      currmat[i] = tb->GetMaterialCutsCouple(i)->GetMaterial();
     833      G4String nam = currmat[i]->GetName();
     834      for(G4int j=0; j<nIons; j++) {
     835        if(nam == materialName[j]) { materialList[j] = currmat[i]; }
     836      }
     837    }
     838  }
    779839}
    780840
  • trunk/source/processes/electromagnetic/utils/src/G4EmModelManager.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmModelManager.cc,v 1.40 2007/11/09 11:35:54 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4EmModelManager.cc,v 1.46 2008/10/13 14:56:56 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    7878//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    7979
    80 G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& list, G4DataVector& lowE)
     80G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& indx,
     81                               G4DataVector& lowE, const G4Region* reg)
    8182{
    8283  nModelsForRegion      = nMod;
    8384  theListOfModelIndexes = new G4int [nModelsForRegion];
    84   lowKineticEnergy      = new G4double [nModelsForRegion];
     85  lowKineticEnergy      = new G4double [nModelsForRegion+1];
    8586  for (G4int i=0; i<nModelsForRegion; i++) {
    86     theListOfModelIndexes[i] = list[i];
     87    theListOfModelIndexes[i] = indx[i];
    8788    lowKineticEnergy[i] = lowE[i];
    8889  }
     90  lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion];
     91  theRegion = reg;
    8992}
    9093
     
    99102//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    100103
    101 #include "G4LossTableManager.hh"
    102104#include "G4Step.hh"
    103105#include "G4ParticleDefinition.hh"
     
    107109#include "G4MaterialCutsCouple.hh"
    108110#include "G4ProductionCutsTable.hh"
    109 #include "G4Region.hh"
    110111#include "G4RegionStore.hh"
    111112#include "G4Gamma.hh"
    112113#include "G4Positron.hh"
     114#include "G4UnitsTable.hh"
    113115
    114116//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    128130  regions.clear();
    129131  orderOfModels.clear();
    130   upperEkin.clear();
    131132  maxCutInRange    = 12.*cm;
    132133  maxSubCutInRange = 0.7*mm;
     
    139140G4EmModelManager::~G4EmModelManager()
    140141{
    141   G4int i,j;
    142142  Clear();
     143}
     144
     145//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     146
     147void G4EmModelManager::Clear()
     148{
    143149  if(1 < verboseLevel) {
    144     G4cout << "G4EmModelManager:: delete models ";
    145     if(particle) G4cout << " for " << particle->GetParticleName();
    146     G4cout << " nModels=" << nEmModels <<G4endl;
    147   }
    148 
    149   for(i = 0; i<nEmModels; i++) {
    150     orderOfModels[i] = 1;
    151   }
    152   for(i = 0; i<nEmModels; i++) {
    153     if (orderOfModels[i]) {
    154       orderOfModels[i] = 0;
    155       for(j = i+1; j<nEmModels; j++) {
    156         if(models[i] == models[j]) orderOfModels[j] = 0;
    157       }
    158       G4String nam = models[i]->GetName();
    159       if(nam != "PAI" && nam != "PAIModel" ) delete models[i];
    160     }
    161   }
    162   for(i = 0; i<nEmModels; i++) {
    163     orderOfModels[i] = 1;
    164   }
    165   for(i = 0; i<nEmModels; i++) {
    166     if (orderOfModels[i]) {
    167       orderOfModels[i] = 0;
    168       for(j = i+1; j<nEmModels; j++) {
    169         if(flucModels[i] == flucModels[j]) orderOfModels[j] = 0;
    170       }
    171       delete flucModels[i];
    172     }
    173   }
    174   if(1 < verboseLevel)
    175     G4cout << "G4EmModelManager:: models are deleted!" << G4endl;
    176 }
    177 
    178 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    179 
    180 void G4EmModelManager::Clear()
    181 {
    182   if(1 < verboseLevel) {
    183     G4cout << "G4EmModelManager::Clear()";
    184     if(particle) G4cout << " for " << particle->GetParticleName();
    185     G4cout << G4endl;
     150    G4cout << "G4EmModelManager::Clear()" << G4endl;
    186151  }
    187152
    188153  theCuts.clear();
    189154  theSubCuts.clear();
    190   upperEkin.clear();
    191155  if(idxOfRegionModels) delete [] idxOfRegionModels;
    192156  if(setOfRegionModels && nRegions) {
     
    215179  orderOfModels.push_back(num);
    216180  p->DefineForRegion(r);
    217   if (nEmModels>0) {
    218     G4int idx = nEmModels;
    219     do {idx--;} while (idx && num < orderOfModels[idx]);
    220     if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;
    221     if (idx < nEmModels) {
    222       models[nEmModels] = models[idx];
    223       flucModels[nEmModels] = flucModels[idx];
    224       regions[nEmModels] = regions[idx];
    225       orderOfModels[nEmModels] = orderOfModels[idx];
    226       models[idx] = p;
    227       flucModels[idx] = fm;
    228       regions[idx] = r;
    229       orderOfModels[idx] = num;
    230     }
    231   }
    232181  nEmModels++;
    233182}
     
    254203//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    255204
    256 G4VEmModel* G4EmModelManager::GetModel(G4int i)
     205G4VEmModel* G4EmModelManager::GetModel(G4int i, G4bool ver)
    257206{
    258207  G4VEmModel* m = 0;
    259   if(i >= 0 && i < nEmModels) m = models[i];
    260   else if(verboseLevel > 0)
     208  if(i >= 0 && i < nEmModels) {m = models[i];}
     209  else if(verboseLevel > 0 && ver) {
    261210    G4cout << "G4EmModelManager::GetModel WARNING: "
    262211           << "index " << i << " is wrong Nmodels= "
    263            << nEmModels << G4endl;
     212           << nEmModels;
     213    if(particle) G4cout << " for " << particle->GetParticleName();
     214    G4cout<< G4endl;
     215  }
    264216  return m;
    265217}
     
    269221const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
    270222                                                 const G4ParticleDefinition* sp,
    271                                                        G4double theMinSubRange,
    272                                                       G4int val)
     223                                                 G4double theMinSubRange,
     224                                                G4int val)
    273225{
    274226  verboseLevel = val;
     
    293245  // Identify the list of regions with different set of models
    294246  nRegions = 1;
    295   std::vector<const G4Region*> set;
    296   set.push_back(world);
     247  std::vector<const G4Region*> setr;
     248  setr.push_back(world);
    297249  G4bool isWorld = false;
    298250
     
    306258      if (nRegions>1) {
    307259        for (G4int j=1; j<nRegions; j++) {
    308           if ( r == set[j] ) newRegion = false;
     260          if ( r == setr[j] ) newRegion = false;
    309261        }
    310262      }
    311263      if (newRegion) {
    312         set.push_back(r);
     264        setr.push_back(r);
    313265        nRegions++;
    314266      }
     
    322274  idxOfRegionModels[numOfCouples] = 0;
    323275  setOfRegionModels = new G4RegionModels*[nRegions];
    324   upperEkin.resize(nEmModels);
     276
     277  std::vector<G4int>    modelAtRegion(nEmModels);
     278  std::vector<G4int>    modelOrd(nEmModels);
     279  G4DataVector          eLow(nEmModels);
     280  G4DataVector          eHigh(nEmModels);
     281  G4int nmax = nEmModels;
    325282
    326283  // Order models for regions
    327284  for (G4int reg=0; reg<nRegions; reg++) {
    328     const G4Region* region = set[reg];
    329 
     285    const G4Region* region = setr[reg];
    330286    G4int n = 0;
    331 
    332     std::vector<G4int>    modelAtRegion;
    333     G4DataVector            eLow;
    334     G4DataVector            eHigh;
    335     modelAtRegion.clear();
    336     eLow.clear();
    337     eHigh.clear();
    338287
    339288    if(isWorld || 0 < reg) {
     
    346295          G4double tmin = model->LowEnergyLimit();
    347296          G4double tmax = model->HighEnergyLimit();
    348           if (n>0) tmin = std::max(tmin, eHigh[n-1]);
     297          G4int  ord    = orderOfModels[ii];
     298          G4bool push   = true;
     299          G4bool insert = false;
     300          G4int  idx    = n;
    349301
    350302          if(1 < verboseLevel) {
     
    355307                 << " tmin(MeV)= " << tmin/MeV
    356308                 << "; tmax(MeV)= " << tmax/MeV
    357                  << "; order= " << orderOfModels[ii]
     309                 << "; order= " << ord
    358310                 << G4endl;
    359311          }
    360 
    361           if (tmin < tmax) {
    362             modelAtRegion.push_back(ii);
    363             eLow.push_back(tmin);
    364             eHigh.push_back(tmax);
    365             upperEkin[ii] = tmax;
    366             n++;
     312       
     313          if (n == 0) n++;
     314          else {
     315            tmin = std::min(tmin, eHigh[n-1]);
     316            if(tmin >= tmax) push = false;
     317            else {
     318
     319              // high energy model
     320              if(tmin == eHigh[n-1] && tmax > eHigh[n-1]) n++;
     321              else if (tmax > eHigh[n-1]) {
     322
     323                // compare order of models
     324                for(G4int k = n-1; k>=0; k--) {
     325       
     326                  if (ord >= modelOrd[k]) {
     327                    tmin = std::max(tmin, eHigh[k]);           
     328                    if(k < n-1) n = k + 2;
     329                    break;
     330                  } else if (tmin > eLow[k]) {
     331                    eHigh[k] = tmin;
     332                    n = k + 2;
     333                    break;
     334                  } else if (tmin == eLow[k]) {
     335                    n = k + 1;
     336                    break;
     337                  }
     338                }
     339                if(tmin < eLow[0]) n = 1;
     340                idx = n - 1;
     341
     342                // low energy model
     343              } else {
     344
     345                tmax = std::max(tmax, eLow[0]);
     346                insert = true;
     347                push = false;
     348                idx = 0;
     349                if(tmax <= eLow[0]) tmax = eLow[0];
     350                else {
     351
     352                  for(G4int k=0; k<n; k++) {
     353       
     354                    if (ord >= modelOrd[k]) {
     355                      if(k == 0) {
     356                        if(tmin < eLow[0]) tmax = eLow[0];
     357                        else insert = false;
     358                        break;
     359                      } else {
     360                        insert = false;
     361                        break;
     362                      }
     363                    } else if(tmax < eHigh[k]) {
     364                      idx = k;
     365                      if(k > 0) tmin = eLow[k];
     366                      eLow[k] = tmax;               
     367                      break;
     368                    } else if(tmax == eHigh[k]) {           
     369                      insert = false;
     370                      push = true;
     371                      idx = k;
     372                      if(k > 0) tmin = eLow[k];
     373                      else tmin = std::min(tmin,eLow[0]);
     374                      break;
     375                    } else {
     376                      modelAtRegion[k] = ii;
     377                      modelOrd[k] = ord;
     378                      if(k == 0) eLow[idx] = std::min(tmin,eLow[0]);
     379                    }
     380                  }
     381                }
     382                if(insert && idx < n) n++;
     383                else insert = false;
     384              }
     385            }
     386          }
     387          if(n > nmax) {
     388            nmax = n;
     389            modelAtRegion.resize(nmax);
     390            modelOrd.resize(nmax);
     391            eLow.resize(nmax);
     392            eHigh.resize(nmax);
     393          }
     394          if(insert) {
     395            for(G4int k=n-2; k>=idx; k--) {           
     396              modelAtRegion[k+1] = modelAtRegion[k];
     397              modelOrd[k+1] = modelOrd[k];
     398              eLow[k+1]  = eLow[k];
     399              eHigh[k+1] = eHigh[k];
     400            }
     401          }
     402          if (push || insert) {
     403            modelAtRegion[idx] = ii;
     404            modelOrd[idx] = ord;
     405            eLow[idx]  = tmin;
     406            eHigh[idx] = tmax;
    367407          }
    368408        }
     
    374414      eLow.push_back(0.0);
    375415      eHigh.push_back(DBL_MAX);
    376       upperEkin.push_back(DBL_MAX);
    377416    }
    378417    eLow[0] = 0.0;
     418    if(n >= nmax) eLow.resize(nmax+1);
     419    eLow[n] = eHigh[n-1];
    379420
    380421    if(1 < verboseLevel) {
     
    382423      if (region) G4cout << region->GetName();
    383424      G4cout << ">  Elow(MeV)= ";
    384       for(G4int ii=0; ii<n; ii++) {G4cout << eLow[ii]/MeV << " ";}
     425      for(G4int ii=0; ii<=n; ii++) {G4cout << eLow[ii]/MeV << " ";}
    385426      G4cout << G4endl;
    386427    }
    387     G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow);
     428    G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow, region);
    388429    setOfRegionModels[reg] = rm;
    389430  }
     
    399440 
    400441    G4int reg = nRegions;
    401     do {reg--;} while (reg>0 && pcuts != (set[reg]->GetProductionCuts()));
     442    do {reg--;} while (reg>0 && pcuts != (setr[reg]->GetProductionCuts()));
    402443    idxOfRegionModels[i] = reg;
    403444
     
    474515{
    475516
    476   // vectors to provide continues dE/dx
    477   G4DataVector factor;
    478   G4DataVector dedxLow;
    479   G4DataVector dedxHigh;
    480 
    481517  G4double e;
    482518
     
    491527    G4cout << "G4EmModelManager::FillDEDXVector() for "
    492528           << couple->GetMaterial()->GetName()
    493            << "  Ecut(MeV)= " << cut
    494            << "  Esubcut(MeV)= " << subcut
     529           << "  cut(MeV)= " << cut
     530           << "  subcut(MeV)= " << subcut
    495531           << "  Type " << tType
    496532           << "  for " << particle->GetParticleName()
     
    501537  const G4RegionModels* regModels = setOfRegionModels[reg];
    502538  G4int nmod = regModels->NumberOfModels();
    503   factor.resize(nmod);
    504   dedxLow.resize(nmod);
    505   dedxHigh.resize(nmod);
     539
     540  // vectors to provide continues dE/dx
     541  G4DataVector factor(nmod);
     542  G4DataVector eLow(nmod+1);
     543  G4DataVector dedxLow(nmod);
     544  G4DataVector dedxHigh(nmod);
    506545
    507546  if(1 < verboseLevel) {
     
    512551  }
    513552
    514 
    515553  // calculate factors to provide continuity of energy loss
     554
     555
    516556  factor[0] = 1.0;
    517557  G4int j;
     
    519559  G4int totBinsLoss = aVector->GetVectorLength();
    520560
    521   dedxLow[0]  = 0.0;
    522 
    523   e = upperEkin[regModels->ModelIndex(0)];
     561  dedxLow[0] = 0.0;
     562  eLow[0]    = 0.0;
     563
     564  e = regModels->LowEdgeEnergy(1);
     565  eLow[1]    = e;
    524566  G4VEmModel* model = models[regModels->ModelIndex(0)];
    525567  dedxHigh[0] = 0.0;
    526568  if(model && cut > subcut) {
    527569    dedxHigh[0] = model->ComputeDEDX(couple,particle,e,cut);
    528     if(subcut > 0.0)
     570    if(subcut > 0.0) {
    529571      dedxHigh[0] -= model->ComputeDEDX(couple,particle,e,subcut);
     572    }
    530573  }
    531574  if(nmod > 1) {
    532575    for(j=1; j<nmod; j++) {
    533576
    534       e = upperEkin[regModels->ModelIndex(j-1)];
     577      e = regModels->LowEdgeEnergy(j);
     578      eLow[j]   = e;
    535579      G4int idx = regModels->ModelIndex(j);
    536580
    537581      dedxLow[j] = models[idx]->ComputeDEDX(couple,particle,e,cut);
    538       if(subcut > 0.0)
     582      if(subcut > 0.0) {
    539583        dedxLow[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut);
     584      }
    540585      if(subcut == cut) dedxLow[j] = 0.0;
    541586
    542       e = upperEkin[idx];
     587      e = regModels->LowEdgeEnergy(j+1);
     588      eLow[j+1] = e;
    543589      dedxHigh[j] = models[idx]->ComputeDEDX(couple,particle,e,cut);
    544       if(subcut > 0.0)
     590      if(subcut > 0.0) {
    545591        dedxHigh[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut);
     592      }
    546593      if(subcut == cut) dedxHigh[j] = 0.0;
    547594    }
     595    if(1 < verboseLevel) {
     596      G4cout << " model #0" 
     597             << "  dedx(" << eLow[0] << ")=  " << dedxLow[0]
     598             << "  dedx(" << eLow[1] << ")=  " << dedxHigh[0]
     599             << G4endl;
     600    }
    548601
    549602    for(j=1; j<nmod; j++) {
    550       if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
    551       else                 factor[j] = 0.0;
     603      if(dedxLow[j] > 0.0) {
     604        factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0)*eLow[j];
     605      } else  factor[j] = 0.0;
     606      if(1 < verboseLevel) {
     607        G4cout << " model #" << j
     608               << "  dedx(" << eLow[j] << ")=  " << dedxLow[j]
     609               << "  dedx(" << eLow[j+1] << ")=  " << dedxHigh[j]
     610               << "  factor= " << factor[j]/eLow[j]
     611               << G4endl;
     612      }
    552613    }
    553614
     
    565626      // Choose a model of energy losses
    566627    G4int k = 0;
    567     if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
     628    if (nmod > 1 && e > eLow[1]) {
    568629      do {
    569630        k++;
    570         fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
    571       } while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
     631        fac *= (1.0 + factor[k]/e);
     632      } while (k+1 < nmod && e > eLow[k+1]);
    572633    }
    573634
     
    602663                                        G4EmTableType tType)
    603664{
    604   // vectors to provide continues cross section
    605   G4DataVector factor;
    606   G4DataVector sigmaLow;
    607   G4DataVector sigmaHigh;
    608 
    609665  G4double e;
    610666
     
    630686  const G4RegionModels* regModels = setOfRegionModels[reg];
    631687  G4int nmod = regModels->NumberOfModels();
    632   factor.resize(nmod);
    633   sigmaLow.resize(nmod);
    634   sigmaHigh.resize(nmod);
     688
     689  // vectors to provide continues dE/dx
     690  G4DataVector factor(nmod);
     691  G4DataVector eLow(nmod+1);
     692  G4DataVector sigmaLow(nmod);
     693  G4DataVector sigmaHigh(nmod);
    635694
    636695  if(2 < verboseLevel) {
     
    644703  G4int totBinsLambda = aVector->GetVectorLength();
    645704
    646   sigmaLow[0]  = 0.0;
    647 
    648   e = upperEkin[regModels->ModelIndex(0)];
     705  sigmaLow[0] = 0.0;
     706  eLow[0]     = 0.0;
     707
     708  e = regModels->LowEdgeEnergy(1);
     709  eLow[1]     = e;
    649710  G4VEmModel* model = models[regModels->ModelIndex(0)];
    650711  sigmaHigh[0] = 0.0;
     
    668729    for(j=1; j<nmod; j++) {
    669730
    670       e  = upperEkin[regModels->ModelIndex(j-1)];
    671       sigmaLow[j] =
    672         models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax);
    673       e  = upperEkin[regModels->ModelIndex(j)];
    674       sigmaHigh[j] =
    675         models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax);
     731      e  = regModels->LowEdgeEnergy(j);
     732      eLow[j]   = e;
     733      G4int idx = regModels->ModelIndex(j);
     734
     735      sigmaLow[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax);
     736      e  = regModels->LowEdgeEnergy(j+1);
     737      eLow[j+1] = e;
     738      sigmaHigh[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax);
     739    }
     740    if(1 < verboseLevel) {
     741      G4cout << " model #0" 
     742             << "  sigma(" << eLow[0] << ")=  " << sigmaLow[0]
     743             << "  sigma(" << eLow[1] << ")=  " << sigmaHigh[0]
     744             << G4endl;
     745    }
     746    for(j=1; j<nmod; j++) {
     747      if(sigmaLow[j] > 0.0) {
     748        factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0)*eLow[j];
     749      } else  factor[j] = 0.0;
    676750      if(1 < verboseLevel) {
    677         G4cout << " model #" << j << "   eUp= " << e
    678                << "  sigmaUp= " << sigmaHigh[j]
    679                << "  sigmaDown= " << sigmaLow[j]
     751        G4cout << " model #" << j
     752               << "  sigma(" << eLow[j] << ")=  " << sigmaLow[j]
     753               << "  sigma(" << eLow[j+1] << ")=  " << sigmaHigh[j]
     754               << "  factor= " << factor[j]/eLow[j]
    680755               << G4endl;
    681756      }
    682     }
    683     for(j=1; j<nmod; j++) {
    684       if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
    685       else                  factor[j] = 0.0;
    686757    }
    687758  }
     
    695766    G4int k = 0;
    696767    G4double fac = 1.0;
    697     if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
     768    if (nmod > 1 && e > eLow[1]) {
    698769      do {
    699770        k++;
    700         fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
    701       } while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
     771        fac *= (1.0 + factor[k]/e);
     772      } while ( k+1 < nmod && e > eLow[k+1] );
    702773    }
    703774
     
    721792
    722793//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     794
     795void G4EmModelManager::DumpModelList(G4int verb)
     796{
     797  if(verb == 0) return;
     798  for(G4int i=0; i<nRegions; i++) {
     799    G4RegionModels* r = setOfRegionModels[i];
     800    const G4Region* reg = r->Region();
     801    if(verb > 1 || nRegions > 1) {
     802    }
     803    G4int n = r->NumberOfModels(); 
     804    if(verb > 1 || n > 0) {
     805      G4cout << "      ===== EM models for the G4Region  " << reg->GetName()
     806             << " ======" << G4endl;;
     807      for(G4int j=0; j<n; j++) {
     808        const G4VEmModel* m = models[r->ModelIndex(j)];
     809        G4cout << std::setw(20);
     810        G4cout << m->GetName() << " :     Emin= "
     811               << std::setw(10) << G4BestUnit(r->LowEdgeEnergy(j),"Energy")
     812               << "        Emax=   "
     813               << G4BestUnit(r->LowEdgeEnergy(j+1),"Energy")
     814               << G4endl;
     815      } 
     816    }
     817  }
     818}
     819
     820//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
  • trunk/source/processes/electromagnetic/utils/src/G4EmMultiModel.cc

    r819 r961  
    2525//
    2626// $Id: G4EmMultiModel.cc,v 1.6 2007/05/22 17:31:58 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/src/G4EmProcessOptions.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmProcessOptions.cc,v 1.22 2007/11/07 18:38:49 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmProcessOptions.cc,v 1.26 2009/02/18 14:43:27 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5959#include "G4VMultipleScattering.hh"
    6060#include "G4Region.hh"
     61#include "G4RegionStore.hh"
    6162
    6263//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    392393//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    393394
    394 void G4EmProcessOptions::ActivateDeexcitation(G4bool val, const G4Region* r)
    395 {
    396   const std::vector<G4VEnergyLossProcess*>& v =
    397         theManager->GetEnergyLossProcessVector();
    398   std::vector<G4VEnergyLossProcess*>::const_iterator itr;
    399   for(itr = v.begin(); itr != v.end(); itr++) {
    400     G4VEnergyLossProcess* p = *itr;
    401     if(p) p->ActivateDeexcitation(val,r);
    402   }
    403   const std::vector<G4VEmProcess*>& w =
    404         theManager->GetEmProcessVector();
    405   std::vector<G4VEmProcess*>::const_iterator itp;
    406   for(itp = w.begin(); itp != w.end(); itp++) {
    407     G4VEmProcess* q = *itp;
    408     if(q) q->ActivateDeexcitation(val,r);
     395void G4EmProcessOptions::ActivateDeexcitation(const G4String& pname,
     396                                              G4bool val,
     397                                              const G4String& reg)
     398{
     399  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     400  const G4Region* r = 0;
     401  if(reg == "" || reg == "World") {
     402    r = regionStore->GetRegion("DefaultRegionForTheWorld", false);
     403  } else {
     404    r = regionStore->GetRegion(reg, false);
     405  }
     406  if(!r) {
     407    G4cout << "G4EmProcessOptions::ActivateDeexcitation ERROR: G4Region <"
     408           << reg << "> not found, the command ignored" << G4endl;
     409    return;
     410  }
     411
     412  const std::vector<G4VEnergyLossProcess*>& v =
     413        theManager->GetEnergyLossProcessVector();
     414  std::vector<G4VEnergyLossProcess*>::const_iterator itr;
     415  for(itr = v.begin(); itr != v.end(); itr++) {
     416    G4VEnergyLossProcess* p = *itr;
     417    if(p) {
     418      if(pname == p->GetProcessName()) p->ActivateDeexcitation(val,r);
     419    }
     420  }
     421  const std::vector<G4VEmProcess*>& w =
     422        theManager->GetEmProcessVector();
     423  std::vector<G4VEmProcess*>::const_iterator itp;
     424  for(itp = w.begin(); itp != w.end(); itp++) {
     425    G4VEmProcess* q = *itp;
     426    if(q) {
     427      if(pname == q->GetProcessName()) q->ActivateDeexcitation(val,r);
     428    }
    409429  }
    410430}
     
    477497//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    478498
     499void G4EmProcessOptions::SetPolarAngleLimit(G4double val)
     500{
     501  const std::vector<G4VMultipleScattering*>& u =
     502        theManager->GetMultipleScatteringVector();
     503  std::vector<G4VMultipleScattering*>::const_iterator itm;
     504  for(itm = u.begin(); itm != u.end(); itm++) {
     505    if(*itm) (*itm)->SetPolarAngleLimit(val);
     506  }
     507  const std::vector<G4VEmProcess*>& w =
     508        theManager->GetEmProcessVector();
     509  std::vector<G4VEmProcess*>::const_iterator itp;
     510  for(itp = w.begin(); itp != w.end(); itp++) {
     511    G4VEmProcess* q = *itp;
     512    if(q) q->SetPolarAngleLimit(val);
     513  }
     514}
     515
     516//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     517
    479518void G4EmProcessOptions::SetLPMFlag(G4bool val)
    480519{
     
    484523//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    485524
     525void G4EmProcessOptions::SetSplineFlag(G4bool val)
     526{
     527  theManager->SetSplineFlag(val);
     528}
     529
     530//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     531
    486532void G4EmProcessOptions::SetLinearLossLimit(G4double val)
    487533{
  • trunk/source/processes/electromagnetic/utils/src/G4EnergyLossMessenger.cc

    r819 r961  
    2525//
    2626//
    27 // $Id: G4EnergyLossMessenger.cc,v 1.29 2007/06/11 14:56:51 vnivanch Exp $
    28 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     27// $Id: G4EnergyLossMessenger.cc,v 1.37 2009/02/18 14:43:27 vnivanch Exp $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030// -------------------------------------------------------------------
     
    4949// 16-03-07 modify /process/eLoss/minsubsec command (V.Ivanchenko)
    5050// 18-05-07 add /process/msc directory and commands (V.Ivanchenko)
     51// 11-03-08 add /process/em directory and commands (V.Ivanchenko)
    5152//
    5253// -------------------------------------------------------------------
     
    8485  mscDirectory = new G4UIdirectory("/process/msc/");
    8586  mscDirectory->SetGuidance("Commands for EM scattering processes.");
     87  emDirectory = new G4UIdirectory("/process/em/");
     88  emDirectory->SetGuidance("General commands for EM processes.");
    8689
    8790  RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/rndmStep",this);
     
    146149
    147150  IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this);
    148   IntegCmd->SetGuidance("Switch true/false the integration of cross section over step.");
     151  IntegCmd->SetGuidance("Switch true/false the integral option");
    149152  IntegCmd->SetParameterName("integ",true);
    150153  IntegCmd->SetDefaultValue(true);
     
    152155
    153156  rangeCmd = new G4UIcmdWithABool("/process/eLoss/CSDARange",this);
    154   rangeCmd->SetGuidance("Switch true/false the precise range calculation.");
     157  rangeCmd->SetGuidance("Switch true/false the CSDA range calculation");
    155158  rangeCmd->SetParameterName("range",true);
    156159  rangeCmd->SetDefaultValue(true);
     
    158161
    159162  lpmCmd = new G4UIcmdWithABool("/process/eLoss/LPM",this);
    160   lpmCmd->SetGuidance("Switch true/false the LPM effect calculation.");
     163  lpmCmd->SetGuidance("The flag of the LPM effect calculation");
    161164  lpmCmd->SetParameterName("lpm",true);
    162165  lpmCmd->SetDefaultValue(true);
    163166  lpmCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    164167
     168  splCmd = new G4UIcmdWithABool("/process/em/spline",this);
     169  splCmd->SetGuidance("The flag of usage spline for Physics Vectors");
     170  splCmd->SetParameterName("spl",true);
     171  splCmd->SetDefaultValue(false);
     172  splCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
     173
     174  aplCmd = new G4UIcmdWithABool("/process/em/applyCuts",this);
     175  aplCmd->SetGuidance("The flag to Apply Cuts for gamma processes");
     176  aplCmd->SetParameterName("apl",true);
     177  aplCmd->SetDefaultValue(false);
     178  aplCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
     179
     180  deexCmd = new G4UIcommand("/process/em/deexcitation",this);
     181  deexCmd->SetGuidance("Set deexcitation flag per process and G4Region.");
     182  deexCmd->SetGuidance("  procName  : process name");
     183  deexCmd->SetGuidance("  flag      : flag");
     184  deexCmd->SetGuidance("  regName   : G4Region name");
     185
     186  G4UIparameter* pName = new G4UIparameter("pName",'s',false);
     187  deexCmd->SetParameter(pName);
     188
     189  G4UIparameter* flag = new G4UIparameter("flag",'s',false);
     190  deexCmd->SetParameter(flag);
     191
     192  G4UIparameter* regName = new G4UIparameter("regName",'s',false);
     193  deexCmd->SetParameter(regName);
     194
    165195  dedxCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsDEDX",this);
    166   dedxCmd->SetGuidance("Set number of bins for DEDX tables.");
     196  dedxCmd->SetGuidance("Set number of bins for DEDX tables");
    167197  dedxCmd->SetParameterName("binsDEDX",true);
    168198  dedxCmd->SetDefaultValue(120);
     
    170200
    171201  lamCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsLambda",this);
    172   lamCmd->SetGuidance("Set number of bins for Lambda tables.");
     202  lamCmd->SetGuidance("Set number of bins for Lambda tables");
    173203  lamCmd->SetParameterName("binsL",true);
    174204  lamCmd->SetDefaultValue(120);
     
    176206
    177207  verCmd = new G4UIcmdWithAnInteger("/process/eLoss/verbose",this);
    178   verCmd->SetGuidance("Set verbose level for EM physics.");
     208  verCmd->SetGuidance("Set verbose level for EM physics");
    179209  verCmd->SetParameterName("verb",true);
    180210  verCmd->SetDefaultValue(1);
    181211  verCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    182212
     213  ver1Cmd = new G4UIcmdWithAnInteger("/process/em/verbose",this);
     214  ver1Cmd->SetGuidance("Set verbose level for EM physics");
     215  ver1Cmd->SetParameterName("verb1",true);
     216  ver1Cmd->SetDefaultValue(1);
     217  ver1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
     218
    183219  lllCmd = new G4UIcmdWithADouble("/process/eLoss/linLossLimit",this);
    184   lllCmd->SetGuidance("Set linearLossLimit parameter.");
     220  lllCmd->SetGuidance("Set linearLossLimit parameter");
    185221  lllCmd->SetParameterName("linlim",true);
    186222  lllCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    187223
    188   labCmd = new G4UIcmdWithADouble("/process/eLoss/lambdaFactor",this);
    189   labCmd->SetGuidance("Set lambdaFactor parameter.");
     224  labCmd = new G4UIcmdWithADouble("/process/eLoss/LambdaFactor",this);
     225  labCmd->SetGuidance("Set lambdaFactor parameter for integral option");
    190226  labCmd->SetParameterName("Fl",true);
    191227  labCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    192228
    193229  mscCmd = new G4UIcmdWithAString("/process/msc/StepLimit",this);
    194   mscCmd->SetGuidance("Set msc step limitation type.");
     230  mscCmd->SetGuidance("Set msc step limitation type");
    195231  mscCmd->SetParameterName("StepLim",true);
    196232  mscCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    197233
    198234  latCmd = new G4UIcmdWithABool("/process/msc/LateralDisplacement",this);
    199   latCmd->SetGuidance("Switch true/false sampling of latra dislacent.");
     235  latCmd->SetGuidance("Set flag of sampling of lateral displacement");
    200236  latCmd->SetParameterName("lat",true);
    201237  latCmd->SetDefaultValue(true);
     
    203239
    204240  frCmd = new G4UIcmdWithADouble("/process/msc/RangeFactor",this);
    205   frCmd->SetGuidance("Set RangeFactor parameter for msc process.");
     241  frCmd->SetGuidance("Set RangeFactor parameter for msc processes");
    206242  frCmd->SetParameterName("Fr",true);
    207243  frCmd->SetRange("Fr>0");
     
    210246
    211247  fgCmd = new G4UIcmdWithADouble("/process/msc/GeomFactor",this);
    212   fgCmd->SetGuidance("Set GeomFactor parameter for msc process.");
     248  fgCmd->SetGuidance("Set GeomFactor parameter for msc processes");
    213249  fgCmd->SetParameterName("Fg",true);
    214250  fgCmd->SetRange("Fg>0");
     
    217253
    218254  skinCmd = new G4UIcmdWithADouble("/process/msc/Skin",this);
    219   skinCmd->SetGuidance("Set skin parameter for multiple scattering.");
     255  skinCmd->SetGuidance("Set skin parameter for msc processes");
    220256  skinCmd->SetParameterName("skin",true);
    221257  skinCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    222258
     259  angCmd = new G4UIcmdWithADoubleAndUnit("/process/msc/ThetaLimit",this);
     260  angCmd->SetGuidance("Set the limit on the polar angle");
     261  angCmd->SetParameterName("theta",true);
     262  angCmd->SetUnitCategory("Angle");
     263  angCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    223264}
    224265
     
    233274  delete MinSubSecCmd;
    234275  delete StepFuncCmd;
     276  delete deexCmd;
    235277  delete eLossDirectory;
    236278  delete mscDirectory;
     279  delete emDirectory;
    237280  delete MinEnCmd;
    238281  delete MaxEnCmd;
     
    240283  delete rangeCmd;
    241284  delete lpmCmd;
     285  delete splCmd;
     286  delete aplCmd;
    242287  delete latCmd;
    243288  delete verCmd;
     289  delete ver1Cmd;
    244290  delete mscCmd;
    245291  delete dedxCmd;
     
    250296  delete labCmd;
    251297  delete skinCmd;
     298  delete angCmd;
    252299}
    253300
     
    289336  }
    290337
     338  if (command == deexCmd) {
     339    G4String s1 (""), s2(""), s3("");
     340    G4bool b = false;
     341    std::istringstream is(newValue);
     342    is >> s1 >> s2 >> s3;
     343    if(s2 == "true") b = true;
     344    opt->ActivateDeexcitation(s1,b,s3);
     345  }
     346
    291347  if (command == mscCmd) {
    292348    if(newValue == "Minimal")
     
    317373  } 
    318374
    319   if (command == IntegCmd)
     375  if (command == IntegCmd) {
    320376    opt->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
    321  
     377  }
    322378  if (command == rangeCmd) {
    323379    opt->SetBuildCSDARange(rangeCmd->GetNewBoolValue(newValue));
     
    330386  }
    331387
     388  if (command == splCmd) {
     389    opt->SetSplineFlag(splCmd->GetNewBoolValue(newValue));
     390    G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
     391  }
     392
     393  if (command == aplCmd) {
     394    opt->SetApplyCuts(aplCmd->GetNewBoolValue(newValue));
     395  }
     396
    332397  if (command == latCmd) {
    333398    opt->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue));
     
    335400  }
    336401
    337   if (command == verCmd)
     402  if (command == verCmd) {
    338403    opt->SetVerbose(verCmd->GetNewIntValue(newValue));
    339 
    340   if (command == lllCmd)
     404  }
     405  if (command == ver1Cmd) {
     406    opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
     407  }
     408  if (command == lllCmd) {
    341409    opt->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue));
    342 
    343   if (command == labCmd)
     410  }
     411  if (command == labCmd) {
    344412    opt->SetLambdaFactor(labCmd->GetNewDoubleValue(newValue));
    345  
     413  }
    346414  if (command == skinCmd) {
    347415    opt->SetSkin(skinCmd->GetNewDoubleValue(newValue));
     
    364432    G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
    365433  }
     434  if (command == angCmd) {
     435    opt->SetPolarAngleLimit(angCmd->GetNewDoubleValue(newValue));
     436    G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
     437  } 
    366438}
    367439
  • trunk/source/processes/electromagnetic/utils/src/G4EnergyLossTables.cc

    r819 r961  
    2525//
    2626//
    27 // $Id: G4EnergyLossTables.cc,v 1.33 2006/06/29 19:55:09 gunter Exp $
    28 // GEANT4 tag $Name: $
     27// $Id: G4EnergyLossTables.cc,v 1.34 2008/07/08 10:57:22 vnivanch Exp $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030// -------------------------------------------------------------------
     
    998998//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    999999
    1000 void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle, const G4String& q)
    1001 {
    1002   G4String s = "G4EnergyLossTables:: " + q + " table not found for "
    1003              + aParticle->GetParticleName() + "!";
    1004   G4Exception(s);
    1005   exit(1);
    1006 }
    1007 
    1008 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     1000void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle,
     1001                                            const G4String& q)
     1002{
     1003  G4String s = " " + q + " table not found for "
     1004             + aParticle->GetParticleName() + " !";
     1005  G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01",
     1006              FatalException, s);
     1007}
     1008
     1009//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
  • trunk/source/processes/electromagnetic/utils/src/G4LossTableBuilder.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4LossTableBuilder.cc,v 1.24 2007/02/16 11:59:35 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4LossTableBuilder.cc,v 1.28 2009/02/18 16:24:47 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    6464
    6565G4LossTableBuilder::G4LossTableBuilder()
    66 {}
     66{
     67  splineFlag = true;
     68}
    6769
    6870//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    7375//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    7476
    75 void G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
    76                                   const std::vector<G4PhysicsTable*>& list)
     77void
     78G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
     79                                   const std::vector<G4PhysicsTable*>& list)
    7780{
    7881  size_t n_processes = list.size();
     
    9194
    9295    pv = new G4PhysicsLogVector(elow, ehigh, nbins);
     96    pv->SetSpline(splineFlag);
    9397    for (size_t j=0; j<nbins; j++) {
    9498      G4double dedx = 0.0;
     
    128132      G4double dedx1  = pv->GetValue(elow, b);
    129133
     134      //G4cout << "nbins= " << nbins << " dedx1= " << dedx1 << G4endl;
     135
     136      // protection for specific cases dedx=0
    130137      if(dedx1 == 0.0) {
    131         for (size_t k=1; k<nbins; k++) {
     138        for (size_t k=1; k<nbins-1; k++) {
    132139          bin0++;
    133140          elow  = pv->GetLowEdgeEnergy(k);
     
    138145      }
    139146
     147      //G4cout << "nbins= " << nbins << " elow= " << elow << " ehigh= " << ehigh << G4endl;
     148      // initialisation of a new vector
    140149      G4PhysicsLogVector* v = new G4PhysicsLogVector(elow, ehigh, nbins);
    141 
     150      // dedx is exect zero
     151      if(nbins <= 2) {
     152        v->PutValue(0,1000.);
     153        v->PutValue(1,2000.);
     154        G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v);
     155        return;
     156      }
     157      v->SetSpline(splineFlag);
     158
     159      // assumed dedx proportional to beta
    142160      G4double range  = 2.*elow/dedx1;
    143       //G4double range  = elow/dedx1;
    144161      v->PutValue(0,range);
    145162      G4double energy1 = elow;
     
    148165
    149166        G4double energy2 = pv->GetLowEdgeEnergy(j+bin0);
    150         G4double dedx2   = pv->GetValue(energy2, b);
    151167        G4double de      = (energy2 - energy1) * del;
    152         G4double energy  = energy1 - de*0.5;
    153 
    154         G4bool   yes     = true;
    155         //G4bool   yes     = false;
    156         if(dedx1 < DBL_MIN || dedx2 < DBL_MIN) yes = false;   
    157 
    158         G4double fac, f;
    159 
    160         if(yes) fac = std::log(dedx2/dedx1)/std::log(energy2/energy1);
    161         else    fac = (dedx2 - dedx1)/(energy2 - energy1);
    162 
     168        G4double energy  = energy2 + de*0.5;
    163169        for (size_t k=0; k<n; k++) {
    164           energy += de;
    165           if(yes) f = dedx1*std::exp(fac*std::log(energy/energy1));
    166           else    f = dedx1 + fac*(energy - energy1);
    167           if(f > DBL_MIN) range  += de/f;
    168         }
     170          energy -= de;
     171          dedx1 = pv->GetValue(energy, b);
     172          if(dedx1 > 0.0) range += de/dedx1;
     173        }
     174
    169175        //      G4cout << "Range i= " <<i << " j= " << j << G4endl;
    170176        v->PutValue(j,range);
    171177        energy1 = energy2;
    172         dedx1   = dedx2;
    173178      }
    174179      G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v);
     
    197202      G4double rlow  = pv->GetValue(elow, b);
    198203      G4double rhigh = pv->GetValue(ehigh, b);
    199 
    200       rhigh *= std::exp(std::log(rhigh/rlow)/((G4double)(nbins-1)));
    201 
    202204     
    203205      G4LPhysicsFreeVector* v = new G4LPhysicsFreeVector(nbins,rlow,rhigh);
     206      v->SetSpline(splineFlag);
     207
    204208      for (size_t j=0; j<nbins; j++) {
    205209        G4double e  = pv->GetLowEdgeEnergy(j);
     
    207211        v->PutValues(j,r,e);
    208212      }
     213      v->PutValues(nbins,rhigh+rlow,ehigh);
    209214
    210215      G4PhysicsTableHelper::SetPhysicsVector(invRangeTable, i, v);
  • trunk/source/processes/electromagnetic/utils/src/G4LossTableManager.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4LossTableManager.cc,v 1.84 2007/06/14 07:28:48 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4LossTableManager.cc,v 1.95 2008/11/13 18:23:39 schaelic Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    7070// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
    7171// 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
     72// 21-02-08 Add G4EmSaturation (V.Ivanchenko)
    7273//
    7374// Class Description:
     
    9192#include "G4PhysicsTableHelper.hh"
    9293#include "G4EmCorrections.hh"
     94#include "G4EmSaturation.hh"
    9395#include "G4EmTableType.hh"
    9496#include "G4LossTableBuilder.hh"
     
    116118  size_t msc = msc_vector.size();
    117119  for (size_t j=0; j<msc; j++) {
    118     if(msc_vector[j] ) delete msc_vector[j];
     120    if( msc_vector[j] ) delete msc_vector[j];
    119121  }
    120122  size_t emp = emp_vector.size();
    121123  for (size_t k=0; k<emp; k++) {
    122     if(emp_vector[k] ) delete emp_vector[k];
     124    if( emp_vector[k] ) delete emp_vector[k];
     125  }
     126  size_t mod = mod_vector.size();
     127  for (size_t a=0; a<mod; a++) {
     128    if( mod_vector[a] ) delete mod_vector[a];
     129  }
     130  size_t fmod = fmod_vector.size();
     131  for (size_t b=0; b<fmod; b++) {
     132    if( fmod_vector[b] ) delete fmod_vector[b];
    123133  }
    124134  Clear();
     
    126136  delete tableBuilder;
    127137  delete emCorrections;
     138  delete emSaturation;
    128139}
    129140
     
    152163  tableBuilder = new G4LossTableBuilder();
    153164  emCorrections= new G4EmCorrections();
     165  emSaturation = new G4EmSaturation();
    154166  integral = true;
    155167  integralActive = false;
     
    160172  stepFunctionActive = false;
    161173  flagLPM = true;
     174  splineFlag = true;
    162175  bremsTh = DBL_MAX;
    163176  verbose = 1;
     177  tableBuilder->SetSplineFlag(splineFlag);
    164178}
    165179
     
    226240{
    227241  msc_vector.push_back(p);
    228   if(verbose > 1)
     242  if(verbose > 1) {
    229243    G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
    230244           << p->GetProcessName() << G4endl;
     245  }
    231246}
    232247
     
    246261{
    247262  emp_vector.push_back(p);
    248   if(verbose > 1)
     263  if(verbose > 1) {
    249264    G4cout << "G4LossTableManager::Register G4VEmProcess : "
    250265           << p->GetProcessName() << G4endl;
     266  }
    251267}
    252268
     
    258274  for (size_t i=0; i<emp; i++) {
    259275    if(emp_vector[i] == p) emp_vector[i] = 0;
     276  }
     277}
     278
     279//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     280
     281void G4LossTableManager::Register(G4VEmModel* p)
     282{
     283  mod_vector.push_back(p);
     284  if(verbose > 1) {
     285    G4cout << "G4LossTableManager::Register G4VEmModel : "
     286           << p->GetName() << G4endl;
     287  }
     288}
     289
     290//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     291
     292void G4LossTableManager::DeRegister(G4VEmModel* p)
     293{
     294  size_t n = mod_vector.size();
     295  for (size_t i=0; i<n; i++) {
     296    if(mod_vector[i] == p) mod_vector[i] = 0;
     297  }
     298}
     299
     300//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     301
     302void G4LossTableManager::Register(G4VEmFluctuationModel* p)
     303{
     304  fmod_vector.push_back(p);
     305  if(verbose > 1) {
     306    G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
     307           << p->GetName() << G4endl;
     308  }
     309}
     310
     311//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     312
     313void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p)
     314{
     315  size_t n = fmod_vector.size();
     316  for (size_t i=0; i<n; i++) {
     317    if(fmod_vector[i] == p) fmod_vector[i] = 0;
    260318  }
    261319}
     
    364422     const G4ParticleDefinition* aParticle)
    365423{
    366   G4String s = "G4LossTableManager:: dE/dx table not found for "
    367              + aParticle->GetParticleName() + "!";
    368   G4Exception(s);
    369   exit(1);
     424  G4String s = " dE/dx table not found for "
     425             + aParticle->GetParticleName() + " !";
     426  G4Exception("G4LossTableManager::ParticleHaveNoLoss", "EM01",
     427              FatalException, s);
     428
    370429}
    371430
     
    476535    p = loss_vector[i];
    477536    if (p && aParticle == part_vector[i] && !tables_are_built[i]) {
    478       if (p->IsIonisationProcess() && isActive[i] || !em || (em && !isActive[iem]) ) {
     537      if ((p->IsIonisationProcess() && isActive[i]) ||
     538          !em || (em && !isActive[iem]) ) {
    479539        em = p;
    480540        iem= i;
     
    509569  dedx = em->IonisationTable();
    510570  if (1 < n_dedx) {
    511     em->SetDEDXTable(dedx, fIonisation);
     571    em->SetDEDXTable(dedx, fIsIonisation);
    512572    dedx = 0;
    513573    dedx  = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
     
    560620    G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
    561621    if (1 < listSub.size()) {
    562       em->SetDEDXTable(dedxSub, fSubIonisation);
     622      em->SetDEDXTable(dedxSub, fIsSubIonisation);
    563623      dedxSub = 0;
    564624      dedxSub = G4PhysicsTableHelper::PreparePhysicsTable(dedxSub);
     
    829889}
    830890
     891//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     892
     893void G4LossTableManager::SetSplineFlag(G4bool val)
     894{
     895  splineFlag = val;
     896  tableBuilder->SetSplineFlag(splineFlag);
     897}
     898
     899//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     900
     901G4bool G4LossTableManager::SplineFlag() const
     902{
     903  return splineFlag;
     904}
     905
    831906//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    832907
     
    843918}
    844919
     920//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     921
     922G4EmCorrections* G4LossTableManager::EmCorrections()
     923{
     924  return emCorrections;
     925}
     926
     927//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     928
     929G4EmSaturation* G4LossTableManager::EmSaturation()
     930{
     931  return emSaturation;
     932}
     933
    845934//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
  • trunk/source/processes/electromagnetic/utils/src/G4VEmFluctuationModel.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmFluctuationModel.cc,v 1.2 2006/06/29 19:55:15 gunter Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4VEmFluctuationModel.cc,v 1.4 2009/02/19 11:25:50 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4949
    5050#include "G4VEmFluctuationModel.hh"
    51 
     51#include "G4LossTableManager.hh"
    5252
    5353//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    5656G4VEmFluctuationModel::G4VEmFluctuationModel(const G4String& nam)
    5757  : name(nam)
     58{
     59  G4LossTableManager::Instance()->Register(this);
     60}
     61
     62G4VEmFluctuationModel::~G4VEmFluctuationModel()
     63{
     64  G4LossTableManager::Instance()->DeRegister(this);
     65}
     66
     67void G4VEmFluctuationModel::InitialiseMe(const G4ParticleDefinition*)
    5868{}
    5969
    60 G4VEmFluctuationModel::~G4VEmFluctuationModel()
     70void G4VEmFluctuationModel::SetParticleAndCharge(const G4ParticleDefinition*,
     71                                                 G4double)
    6172{}
    6273
  • trunk/source/processes/electromagnetic/utils/src/G4VEmModel.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmModel.cc,v 1.8 2007/09/25 10:19:07 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEmModel.cc,v 1.25 2009/02/19 09:57:36 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4141// 25.10.2005 Set default highLimit=100.TeV (V.Ivanchenko)
    4242// 06.02.2006 add method ComputeMeanFreePath() (mma)
     43// 16.02.2009 Move implementations of virtual methods to source (VI)
    4344//
    4445//
     
    5152
    5253#include "G4VEmModel.hh"
     54#include "G4LossTableManager.hh"
     55#include "G4ProductionCutsTable.hh"
    5356
    5457//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     
    5659
    5760G4VEmModel::G4VEmModel(const G4String& nam):
    58  lowLimit(0.1*keV), highLimit(100.0*TeV), fluc(0), name(nam), pParticleChange(0)
    59 {}
     61  fluc(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV),
     62  polarAngleLimit(0.0),secondaryThreshold(DBL_MAX),theLPMflag(false),
     63  pParticleChange(0),nuclearStopping(false),
     64  currentCouple(0),currentElement(0),
     65  nsec(5),flagDeexcitation(false)
     66{
     67  xsec.resize(nsec);
     68  nSelectors = 0;
     69  G4LossTableManager::Instance()->Register(this);
     70}
    6071
    6172//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    6273
    6374G4VEmModel::~G4VEmModel()
    64 {}
     75{
     76  G4LossTableManager::Instance()->DeRegister(this);
     77  G4int n = elmSelectors.size();
     78  if(n > 0) {
     79    for(G4int i=0; i<n; i++) {
     80      delete elmSelectors[i];
     81    }
     82  }
     83}
     84
     85//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     86
     87void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p,
     88                                            const G4DataVector& cuts)
     89{
     90  // initialise before run
     91  flagDeexcitation = false;
     92
     93  G4int nbins = G4int(std::log10(highLimit/lowLimit) + 0.5);
     94  if(nbins < 3) nbins = 3;
     95  G4bool spline = G4LossTableManager::Instance()->SplineFlag();
     96
     97  G4ProductionCutsTable* theCoupleTable=
     98    G4ProductionCutsTable::GetProductionCutsTable();
     99  G4int numOfCouples = theCoupleTable->GetTableSize();
     100
     101  // prepare vector
     102  if(numOfCouples > nSelectors) {
     103    elmSelectors.resize(numOfCouples);
     104    nSelectors = numOfCouples;
     105  }
     106
     107  // initialise vector
     108  for(G4int i=0; i<numOfCouples; i++) {
     109    const G4MaterialCutsCouple* couple =
     110      theCoupleTable->GetMaterialCutsCouple(i);
     111    const G4Material* material = couple->GetMaterial();
     112    G4int idx = couple->GetIndex();
     113
     114    // selector already exist check if should be deleted
     115    G4bool create = true;
     116    if(elmSelectors[i]) {
     117      if(material == elmSelectors[i]->GetMaterial()) create = false;
     118      else delete elmSelectors[i];
     119    }
     120    if(create) {
     121      elmSelectors[i] = new G4EmElementSelector(this,material,nbins,
     122                                                lowLimit,highLimit,spline);
     123    }
     124    elmSelectors[i]->Initialise(p, cuts[idx]);
     125    //elmSelectors[i]->Dump(p);
     126  }
     127}
     128
     129//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     130
     131G4double G4VEmModel::ComputeDEDXPerVolume(const G4Material*,
     132                                          const G4ParticleDefinition*,
     133                                          G4double,G4double)
     134{
     135  return 0.0;
     136}
    65137
    66138//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     
    68140G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
    69141                                           const G4ParticleDefinition* p,
    70                                                  G4double ekin,
    71                                                  G4double emin,
    72                                                  G4double emax)
    73 {
     142                                           G4double ekin,
     143                                           G4double emin,
     144                                           G4double emax)
     145{
     146  SetupForMaterial(p, material, ekin);
    74147  G4double cross = 0.0;
    75148  const G4ElementVector* theElementVector = material->GetElementVector();
    76149  const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
    77   size_t nelm = material->GetNumberOfElements();
    78   for (size_t i=0; i<nelm; i++) {
    79     const G4Element* elm = (*theElementVector)[i];
     150  G4int nelm = material->GetNumberOfElements();
     151  if(nelm > nsec) {
     152    xsec.resize(nelm);
     153    nsec = nelm;
     154  }
     155  for (G4int i=0; i<nelm; i++) {
    80156    cross += theAtomNumDensityVector[i]*
    81       ComputeCrossSectionPerAtom(p,ekin,elm->GetZ(),elm->GetN(),emin,emax);
     157      ComputeCrossSectionPerAtom(p,(*theElementVector)[i],ekin,emin,emax);
    82158    xsec[i] = cross;
    83159  }
     
    87163//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    88164
    89 G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
    90                                                G4double ekin,
    91                                          const G4Material* material,     
    92                                                G4double emin,
    93                                                G4double emax)
    94 {
    95   G4double mfp = DBL_MAX;
    96   G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax);
    97   if (cross > DBL_MIN) mfp = 1./cross;
    98   return mfp;
    99 }
    100 
    101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    102 
    103 
     165G4double G4VEmModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
     166                                                G4double, G4double, G4double,
     167                                                G4double, G4double)
     168{
     169  return 0.0;
     170}
     171
     172//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     173
     174G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*,
     175                                  const G4MaterialCutsCouple*)
     176{
     177  return 0.0;
     178}
     179
     180//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     181
     182G4double G4VEmModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
     183                                          const G4Material*, G4double)
     184{
     185  G4double q = p->GetPDGCharge()/CLHEP::eplus;
     186  return q*q;
     187}
     188
     189//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     190
     191G4double G4VEmModel::GetParticleCharge(const G4ParticleDefinition* p,
     192                                       const G4Material*, G4double)
     193{
     194  return p->GetPDGCharge();
     195}
     196
     197//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     198
     199void G4VEmModel::CorrectionsAlongStep(const G4MaterialCutsCouple*,
     200                                      const G4DynamicParticle*,
     201                                      G4double&,G4double&,G4double)
     202{}
     203
     204//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     205
     206void G4VEmModel::SampleDeexcitationAlongStep(const G4Material*,
     207                                             const G4Track&,
     208                                             G4double& )
     209{}
     210
     211//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     212
     213G4double G4VEmModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
     214                                        G4double kineticEnergy)
     215{
     216  return kineticEnergy;
     217}
     218
     219//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     220
     221void G4VEmModel::SampleScattering(const G4DynamicParticle*, G4double)
     222{}
     223
     224//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     225
     226G4double G4VEmModel::ComputeTruePathLengthLimit(const G4Track&,
     227                                                G4PhysicsTable*,
     228                                                G4double)
     229{
     230  return DBL_MAX;
     231}
     232
     233//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     234
     235G4double G4VEmModel::ComputeGeomPathLength(G4double truePathLength)
     236{
     237  return truePathLength;
     238}
     239
     240//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     241
     242G4double G4VEmModel::ComputeTrueStepLength(G4double geomPathLength)
     243{
     244  return geomPathLength;
     245}
     246
     247//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     248
     249void G4VEmModel::DefineForRegion(const G4Region*)
     250{}
     251
     252//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     253
     254void G4VEmModel::SetupForMaterial(const G4ParticleDefinition*,
     255                                  const G4Material*, G4double)
     256{}
     257
     258//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
  • trunk/source/processes/electromagnetic/utils/src/G4VEmProcess.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmProcess.cc,v 1.48 2007/10/29 08:38:58 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEmProcess.cc,v 1.62 2009/02/19 09:57:36 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    8282
    8383G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
    84                       G4VDiscreteProcess(name, type),
    85   selectedModel(0),                   
     84  G4VDiscreteProcess(name, type),
     85  secondaryParticle(0),
     86  buildLambdaTable(true),
    8687  theLambdaTable(0),
    8788  theEnergyOfCrossSectionMax(0),
    8889  theCrossSectionMax(0),
    89   particle(0),
    90   secondaryParticle(0),
    91   nLambdaBins(90),
    92   lambdaFactor(0.8),
    93   currentCouple(0),
    9490  integral(false),
    95   buildLambdaTable(true),
    9691  applyCuts(false),
    9792  startFromNull(true),
    98   nRegions(0)
     93  useDeexcitation(false),
     94  nDERegions(0),
     95  idxDERegions(0),
     96  currentModel(0),
     97  particle(0),
     98  currentCouple(0)
    9999{
    100100  SetVerboseLevel(1);
     101
     102  // Size of tables assuming spline
    101103  minKinEnergy = 0.1*keV;
    102   maxKinEnergy = 100.0*GeV;
     104  maxKinEnergy = 100.0*TeV;
     105  nLambdaBins  = 84;
     106
     107  // default lambda factor
     108  lambdaFactor  = 0.8;
     109
     110  // default limit on polar angle
     111  polarAngleLimit = 0.0;
     112
     113  // particle types
    103114  theGamma     = G4Gamma::Gamma();
    104115  theElectron  = G4Electron::Electron();
     
    126137  delete modelManager;
    127138  (G4LossTableManager::Instance())->DeRegister(this);
     139}
     140
     141//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     142
     143void G4VEmProcess::Clear()
     144{
     145  delete [] theEnergyOfCrossSectionMax;
     146  delete [] theCrossSectionMax;
     147  delete [] idxDERegions;
     148  theEnergyOfCrossSectionMax = 0;
     149  theCrossSectionMax = 0;
     150  idxDERegions = 0;
     151  currentCouple = 0;
     152  preStepLambda = 0.0;
     153  mfpKinEnergy  = DBL_MAX;
     154  deRegions.clear();
     155  nDERegions = 0;
    128156}
    129157
     
    153181      theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
    154182  }
    155 }
    156 
    157 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    158 
    159 void G4VEmProcess::Clear()
    160 {
    161   if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
    162   if(theCrossSectionMax) delete [] theCrossSectionMax;
    163   theEnergyOfCrossSectionMax = 0;
    164   theCrossSectionMax = 0;
    165   currentCouple = 0;
    166   preStepLambda = 0.0;
    167   mfpKinEnergy  = DBL_MAX;
     183  // Sub Cutoff and Deexcitation
     184  if (nDERegions>0) {
     185
     186    const G4ProductionCutsTable* theCoupleTable=
     187          G4ProductionCutsTable::GetProductionCutsTable();
     188    size_t numOfCouples = theCoupleTable->GetTableSize();
     189
     190    idxDERegions = new G4bool[numOfCouples];
     191
     192    for (size_t j=0; j<numOfCouples; j++) {
     193
     194      const G4MaterialCutsCouple* couple =
     195        theCoupleTable->GetMaterialCutsCouple(j);
     196      const G4ProductionCuts* pcuts = couple->GetProductionCuts();
     197      G4bool reg = false;
     198      for(G4int i=0; i<nDERegions; i++) {
     199        if(deRegions[i]) {
     200          if(pcuts == deRegions[i]->GetProductionCuts()) reg = true;
     201        }
     202      }
     203      idxDERegions[j] = reg;
     204    }
     205  }
     206  if (1 < verboseLevel && nDERegions>0) {
     207    G4cout << " Deexcitation is activated for regions: " << G4endl;
     208    for (G4int i=0; i<nDERegions; i++) {
     209      const G4Region* r = deRegions[i];
     210      G4cout << "           " << r->GetName() << G4endl;
     211    }
     212  }
    168213}
    169214
     
    228273      G4cout << *theLambdaTable << G4endl;
    229274    }
     275  }
     276}
     277
     278//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     279
     280void G4VEmProcess::PrintInfoDefinition()
     281{
     282  if(verboseLevel > 0) {
     283    G4cout << G4endl << GetProcessName() << ":   for  "
     284           << particle->GetParticleName();
     285    if(integral) G4cout << ", integral: 1 ";
     286    if(applyCuts) G4cout << ", applyCuts: 1 ";
     287    G4cout << "    SubType= " << GetProcessSubType() << G4endl;
     288    if(buildLambdaTable) {
     289      G4cout << "      Lambda tables from "
     290             << G4BestUnit(minKinEnergy,"Energy")
     291             << " to "
     292             << G4BestUnit(maxKinEnergy,"Energy")
     293             << " in " << nLambdaBins << " bins, spline: "
     294             << (G4LossTableManager::Instance())->SplineFlag()
     295             << G4endl;
     296    }
     297    PrintInfo();
     298    modelManager->DumpModelList(verboseLevel);
     299  }
     300
     301  if(verboseLevel > 2 && buildLambdaTable) {
     302    G4cout << "      LambdaTable address= " << theLambdaTable << G4endl;
     303    if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
    230304  }
    231305}
     
    295369//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    296370
    297 G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
    298                                        G4double,
    299                                        G4ForceCondition* condition)
    300 {
    301   *condition = NotForced;
    302   return G4VEmProcess::MeanFreePath(track);
    303 }
    304 
    305 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    306 
    307371G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
    308372                                              const G4Step&)
     
    333397  }
    334398
    335   G4VEmModel* currentModel = SelectModel(finalT);
    336 
     399  SelectModel(finalT);
     400  if(useDeexcitation) {
     401    currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]);
     402  }
    337403  /* 
    338404  if(0 < verboseLevel) {
     
    373439
    374440        } else if (p == thePositron) {
    375           if (e < (*theCutsPositron)[currentMaterialIndex]) {
     441          if (electron_mass_c2 < (*theCutsGamma)[currentMaterialIndex] &&
     442              e < (*theCutsPositron)[currentMaterialIndex]) {
    376443            good = false;
    377444            e += 2.0*electron_mass_c2;
     
    394461//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    395462
    396 void G4VEmProcess::PrintInfoDefinition()
    397 {
    398   if(verboseLevel > 0) {
    399     G4cout << G4endl << GetProcessName() << ": " ;
    400     PrintInfo();
    401     if(integral) {
    402       G4cout << "      Integral mode is used  "<< G4endl;
    403     }
    404   }
    405 
    406   if (!buildLambdaTable)  return;
    407  
    408   if(verboseLevel > 0) {
    409     G4cout << "      tables are built for  "
    410            << particle->GetParticleName()
    411            << G4endl
    412            << "      Lambda tables from "
    413            << G4BestUnit(minKinEnergy,"Energy")
    414            << " to "
    415            << G4BestUnit(maxKinEnergy,"Energy")
    416            << " in " << nLambdaBins << " bins."
    417            << G4endl;
    418   }
    419 
    420   if(verboseLevel > 1) {
    421     G4cout << "Tables are built for " << particle->GetParticleName()
    422            << G4endl;
    423 
    424   if(verboseLevel > 2) {
    425     G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
    426     if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
    427     }
    428   }
    429 }
    430 
    431 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    432 
    433 G4double G4VEmProcess::MicroscopicCrossSection(G4double kineticEnergy,
    434                                          const G4MaterialCutsCouple* couple)
    435 {
    436   // Cross section per atom is calculated
    437   DefineMaterial(couple);
    438   G4double cross = 0.0;
    439   G4bool b;
    440   if(theLambdaTable) {
    441     cross = (((*theLambdaTable)[currentMaterialIndex])->
    442                            GetValue(kineticEnergy, b));
    443 
    444     cross /= currentMaterial->GetTotNbOfAtomsPerVolume();
    445   } else {
    446     G4VEmModel* model = SelectModel(kineticEnergy);
    447     cross =
    448       model->CrossSectionPerVolume(currentMaterial,particle,kineticEnergy);
    449   }
    450 
    451   return cross;
    452 }
    453 
    454 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    455 
    456463G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
    457464                                       const G4String& directory,
     
    508515             << G4endl;
    509516    }
     517    if((G4LossTableManager::Instance())->SplineFlag()) {
     518      size_t n = theLambdaTable->length();
     519      for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
     520    }
    510521  } else {
    511522    if (1 < verboseLevel) {
     
    517528
    518529  return yes;
     530}
     531
     532//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     533
     534void G4VEmProcess::ActivateDeexcitation(G4bool val, const G4Region* r)
     535{
     536  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     537  const G4Region* reg = r;
     538  if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
     539
     540  // the region is in the list
     541  if (nDERegions) {
     542    for (G4int i=0; i<nDERegions; i++) {
     543      if (reg == deRegions[i]) {
     544        if(!val) deRegions[i] = 0;
     545        return;
     546      }
     547    }
     548  }
     549
     550  // new region
     551  if(val) {
     552    useDeexcitation = true;
     553    deRegions.push_back(reg);
     554    nDERegions++;
     555  } else {
     556    useDeexcitation = false;
     557  }
     558}
     559
     560//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     561
     562G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
     563                                             const G4MaterialCutsCouple* couple)
     564{
     565  // Cross section per atom is calculated
     566  DefineMaterial(couple);
     567  G4double cross = 0.0;
     568  G4bool b;
     569  if(theLambdaTable) {
     570    cross = (((*theLambdaTable)[currentMaterialIndex])->
     571                           GetValue(kineticEnergy, b));
     572  } else {
     573    SelectModel(kineticEnergy);
     574    cross = currentModel->CrossSectionPerVolume(currentMaterial,
     575                                                particle,kineticEnergy);
     576  }
     577
     578  return cross;
     579}
     580
     581//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     582
     583G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
     584                                       G4double,
     585                                       G4ForceCondition* condition)
     586{
     587  *condition = NotForced;
     588  return G4VEmProcess::MeanFreePath(track);
    519589}
    520590
     
    568638  G4PhysicsVector* v =
    569639    new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
     640  v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
    570641  return v;
    571642}
  • trunk/source/processes/electromagnetic/utils/src/G4VEnergyLoss.cc

    r819 r961  
    2626//
    2727// $Id: G4VEnergyLoss.cc,v 1.46 2006/06/29 19:55:21 gunter Exp $
    28 // GEANT4 tag $Name: $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030
  • trunk/source/processes/electromagnetic/utils/src/G4VEnergyLossProcess.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEnergyLossProcess.cc,v 1.123 2008/01/11 19:55:29 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEnergyLossProcess.cc,v 1.146 2009/02/19 11:25:50 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    146146
    147147G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name,
    148   G4ProcessType type): G4VContinuousDiscreteProcess(name, type),
     148                                           G4ProcessType type):
     149  G4VContinuousDiscreteProcess(name, type),
     150  secondaryParticle(0),
    149151  nSCoffRegions(0),
     152  nDERegions(0),
    150153  idxSCoffRegions(0),
     154  idxDERegions(0),
    151155  nProcesses(0),
    152156  theDEDXTable(0),
     
    165169  theEnergyOfCrossSectionMax(0),
    166170  theCrossSectionMax(0),
    167   particle(0),
    168171  baseParticle(0),
    169   secondaryParticle(0),
    170   currentCouple(0),
    171   nBins(120),
    172   nBinsCSDA(70),
    173   nWarnings(0),
    174   linLossLimit(0.05),
    175172  minSubRange(0.1),
    176   lambdaFactor(0.8),
    177   mfpKinEnergy(0.0),
    178173  lossFluctuationFlag(true),
    179174  rndmStepFlag(false),
    180175  tablesAreBuilt(false),
    181176  integral(true),
     177  isIon(false),
    182178  isIonisation(true),
    183   useSubCutoff(false)
     179  useSubCutoff(false),
     180  useDeexcitation(false),
     181  particle(0),
     182  currentCouple(0),
     183  nWarnings(0),
     184  mfpKinEnergy(0.0)
    184185{
    185186  SetVerboseLevel(1);
    186187
    187   // Size of tables
     188  // low energy limit
    188189  lowestKinEnergy  = 1.*eV;
     190
     191  // Size of tables assuming spline
    189192  minKinEnergy     = 0.1*keV;
    190193  maxKinEnergy     = 100.0*TeV;
     194  nBins            = 84;
    191195  maxKinEnergyCSDA = 1.0*GeV;
     196  nBinsCSDA        = 35;
     197
     198  // default linear loss limit for spline
     199  linLossLimit  = 0.01;
    192200
    193201  // default dRoverRange and finalRange
    194202  SetStepFunction(0.2, 1.0*mm);
    195203
    196   theElectron = G4Electron::Electron();
    197   thePositron = G4Positron::Positron();
     204  // default lambda factor
     205  lambdaFactor  = 0.8;
     206
     207  // particle types
     208  theElectron   = G4Electron::Electron();
     209  thePositron   = G4Positron::Positron();
     210  theGenericIon = 0;
    198211
    199212  // run time objects
     
    208221  fluctModel = 0;
    209222
    210   scoffRegions.clear();
    211   scProcesses.clear();
    212223  scTracks.reserve(5);
    213224  secParticles.reserve(5);
     
    215226  // Data for stragling of ranges from ICRU'37 report
    216227  const G4int nrbins = 7;
    217   vstrag = new G4PhysicsLogVector(keV, GeV, nrbins);
     228  vstrag = new G4PhysicsLogVector(keV, GeV, nrbins-1);
     229  vstrag->SetSpline(true);
    218230  G4double s[nrbins] = {-0.2, -0.85, -1.3, -1.578, -1.76, -1.85, -1.9};
    219231  for(G4int i=0; i<nrbins; i++) {vstrag->PutValue(i, s[i]);}
     
    228240           << G4endl;
    229241  delete vstrag;
    230   Clear();
     242  Clean();
    231243
    232244  if ( !baseParticle ) {
     
    282294//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    283295
    284 void G4VEnergyLossProcess::Clear()
    285 {
    286   if(1 < verboseLevel)
     296void G4VEnergyLossProcess::Clean()
     297{
     298  if(1 < verboseLevel) {
    287299    G4cout << "G4VEnergyLossProcess::Clear() for " << GetProcessName()
    288     << G4endl;
    289 
     300           << G4endl;
     301  }
    290302  delete [] theDEDXAtMaxEnergy;
    291303  delete [] theRangeAtMaxEnergy;
     
    293305  delete [] theCrossSectionMax;
    294306  delete [] idxSCoffRegions;
     307  delete [] idxDERegions;
    295308
    296309  theDEDXAtMaxEnergy = 0;
     
    300313  tablesAreBuilt = false;
    301314
    302   scTracks.clear();
     315  //scTracks.clear();
    303316  scProcesses.clear();
    304 }
    305 
    306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    307 
    308 void G4VEnergyLossProcess::PreparePhysicsTable(
    309      const G4ParticleDefinition& part)
    310 {
    311 
    312   // Are particle defined?
    313   if( !particle ) {
    314     if(part.GetParticleType() == "nucleus" &&
    315        part.GetParticleSubType() == "generic")
    316          particle = G4GenericIon::GenericIon();
    317     else particle = &part;
    318   }
    319 
     317  nProcesses = 0;
     318}
     319
     320//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     321
     322G4double G4VEnergyLossProcess::MinPrimaryEnergy(const G4ParticleDefinition*,
     323                                                const G4Material*,
     324                                                G4double cut)
     325{
     326  return cut;
     327}
     328
     329//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     330
     331void
     332G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
     333{
    320334  if(1 < verboseLevel) {
    321335    G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
    322336           << GetProcessName()
    323337           << " for " << part.GetParticleName()
    324            << " local: " << particle->GetParticleName()
    325338           << G4endl;
    326339  }
    327 
    328   G4LossTableManager* lManager = G4LossTableManager::Instance();
    329 
    330   if(&part != particle) {
    331     if(part.GetParticleType() == "nucleus") lManager->RegisterIon(&part, this);
    332     else                          lManager->RegisterExtraParticle(&part, this);
    333     return;
    334   }
    335 
    336   Clear();
    337340
    338341  currentCouple = 0;
     
    341344  fRange        = DBL_MAX;
    342345  preStepKinEnergy = 0.0;
     346  chargeSqRatio = 1.0;
     347  massRatio = 1.0;
     348  reduceFactor = 1.0;
     349
     350  G4LossTableManager* lManager = G4LossTableManager::Instance();
     351
     352  // Are particle defined?
     353  if( !particle ) {
     354    particle = &part;
     355    if(part.GetParticleType() == "nucleus") {
     356      if(!theGenericIon) theGenericIon = G4GenericIon::GenericIon();
     357      if(particle == theGenericIon) { isIon = true; }
     358      else if(part.GetPDGCharge() > eplus) {
     359        isIon = true;
     360
     361        // generic ions created on-fly
     362        if(part.GetPDGCharge() > 2.5*eplus) {
     363          particle = theGenericIon;
     364        }
     365      }
     366    }
     367  }
     368
     369  if( particle != &part) {
     370    if(part.GetParticleType() == "nucleus") {
     371      isIon = true;
     372      lManager->RegisterIon(&part, this);
     373    } else {
     374      lManager->RegisterExtraParticle(&part, this);
     375    }
     376    return;
     377  }
     378
     379  Clean();
    343380
    344381  // Base particle and set of models can be defined here
     
    372409  G4double initialCharge = particle->GetPDGCharge();
    373410  G4double initialMass   = particle->GetPDGMass();
    374   chargeSquare = initialCharge*initialCharge/(eplus*eplus);
    375   chargeSqRatio = 1.0;
    376   massRatio = 1.0;
    377   reduceFactor = 1.0;
    378411
    379412  if (baseParticle) {
     
    387420                                     minSubRange, verboseLevel);
    388421
    389   // Sub Cutoff Regime
    390   scProcesses.clear();
    391   nProcesses = 0;
    392  
    393   if (nSCoffRegions>0) {
     422  // Sub Cutoff and Deexcitation
     423  if (nSCoffRegions>0 || nDERegions>0) {
    394424    theSubCuts = modelManager->SubCutoff();
    395425
     
    397427          G4ProductionCutsTable::GetProductionCutsTable();
    398428    size_t numOfCouples = theCoupleTable->GetTableSize();
    399     idxSCoffRegions = new G4int[numOfCouples];
     429
     430    if(nSCoffRegions>0) idxSCoffRegions = new G4bool[numOfCouples];
     431    if(nDERegions>0) idxDERegions = new G4bool[numOfCouples];
    400432 
    401433    for (size_t j=0; j<numOfCouples; j++) {
     
    404436        theCoupleTable->GetMaterialCutsCouple(j);
    405437      const G4ProductionCuts* pcuts = couple->GetProductionCuts();
    406       G4int reg = 0;
    407       for(G4int i=0; i<nSCoffRegions; i++) {
    408         if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = 1;
    409       }
    410       idxSCoffRegions[j] = reg;
     438     
     439      if(nSCoffRegions>0) {
     440        G4bool reg = false;
     441        for(G4int i=0; i<nSCoffRegions; i++) {
     442          if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = true;
     443        }
     444        idxSCoffRegions[j] = reg;
     445      }
     446      if(nDERegions>0) {
     447        G4bool reg = false;
     448        for(G4int i=0; i<nDERegions; i++) {
     449          if( pcuts == deRegions[i]->GetProductionCuts()) reg = true;
     450        }
     451        idxDERegions[j] = reg;
     452      }
    411453    }
    412454  }
     
    416458  if (1 < verboseLevel) {
    417459    G4cout << "G4VEnergyLossProcess::Initialise() is done "
     460           << " for local " << particle->GetParticleName()
     461           << " isIon= " << isIon
    418462           << " chargeSqRatio= " << chargeSqRatio
    419463           << " massRatio= " << massRatio
     
    426470      }
    427471    }
     472    if (nDERegions) {
     473      G4cout << " Deexcitation is ON for regions: " << G4endl;
     474      for (G4int i=0; i<nDERegions; i++) {
     475        const G4Region* r = deRegions[i];
     476        G4cout << "           " << r->GetName() << G4endl;
     477      }
     478    }
    428479  }
    429480}
     
    442493  }
    443494
    444   if(!tablesAreBuilt && &part == particle)
    445     G4LossTableManager::Instance()->BuildPhysicsTable(particle, this);
    446 
    447   if(0 < verboseLevel && (&part == particle) && !baseParticle) {
    448     PrintInfoDefinition();
    449     safetyHelper->InitialiseHelper();
     495  if(&part == particle) {
     496    if(!tablesAreBuilt) {
     497      G4LossTableManager::Instance()->BuildPhysicsTable(particle, this);
     498    }
     499    if(!baseParticle) {
     500      if(0 < verboseLevel) PrintInfoDefinition();
     501   
     502      // needs to be done only once
     503      safetyHelper->InitialiseHelper();
     504    }
    450505  }
    451506
     
    456511    if(isIonisation) G4cout << "  isIonisation  flag = 1";
    457512    G4cout << G4endl;
    458   }
    459 }
    460 
    461 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    462 
    463 void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
    464 {
    465   G4RegionStore* regionStore = G4RegionStore::GetInstance();
    466   if(val) {
    467     useSubCutoff = true;
    468     if (!r) r = regionStore->GetRegion("DefaultRegionForTheWorld", false);
    469     if (nSCoffRegions) {
    470       for (G4int i=0; i<nSCoffRegions; i++) {
    471         if (r == scoffRegions[i]) return;
    472       }
    473     }
    474     scoffRegions.push_back(r);
    475     nSCoffRegions++;
    476   } else {
    477     useSubCutoff = false;
    478513  }
    479514}
     
    528563  for(size_t i=0; i<numOfCouples; i++) {
    529564
    530     if(1 < verboseLevel)
     565    if(1 < verboseLevel) {
    531566      G4cout << "G4VEnergyLossProcess::BuildDEDXVector flag=  "
    532567             << table->GetFlag(i) << G4endl;
    533 
     568    }
    534569    if (table->GetFlag(i)) {
    535570
     
    538573        theCoupleTable->GetMaterialCutsCouple(i);
    539574      G4PhysicsVector* aVector = new G4PhysicsLogVector(emin, emax, bin);
     575      aVector->SetSpline((G4LossTableManager::Instance())->SplineFlag());
     576
    540577      modelManager->FillDEDXVector(aVector, couple, tType);
    541578
     
    580617           << G4endl;
    581618  }
    582   if(!table) return table;
     619  if(!table) {return table;}
    583620
    584621  // Access to materials
     
    615652//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    616653
    617 G4double G4VEnergyLossProcess::GetContinuousStepLimit(
    618                 const G4Track&,
    619                 G4double, G4double, G4double&)
    620 {
    621   return DBL_MAX;
     654void G4VEnergyLossProcess::PrintInfoDefinition()
     655{
     656  if(0 < verboseLevel) {
     657    G4cout << G4endl << GetProcessName() << ":   for  "
     658           << particle->GetParticleName()
     659           << "    SubType= " << GetProcessSubType()
     660           << G4endl
     661           << "      dE/dx and range tables from "
     662           << G4BestUnit(minKinEnergy,"Energy")
     663           << " to " << G4BestUnit(maxKinEnergy,"Energy")
     664           << " in " << nBins << " bins" << G4endl
     665           << "      Lambda tables from threshold to "
     666           << G4BestUnit(maxKinEnergy,"Energy")
     667           << " in " << nBins << " bins, spline: "
     668           << (G4LossTableManager::Instance())->SplineFlag()
     669           << G4endl;
     670    if(theRangeTableForLoss && isIonisation) {
     671      G4cout << "      finalRange(mm)= " << finalRange/mm
     672             << ", dRoverRange= " << dRoverRange
     673             << ", integral: " << integral
     674             << ", fluct: " << lossFluctuationFlag
     675             << ", linLossLimit= " << linLossLimit
     676             << G4endl;
     677    }
     678    PrintInfo();
     679    modelManager->DumpModelList(verboseLevel);
     680    if(theCSDARangeTable && isIonisation) {
     681      G4cout << "      CSDA range table up"
     682             << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy")
     683             << " in " << nBinsCSDA << " bins" << G4endl;
     684    }
     685    if(nSCoffRegions>0 && isIonisation) {
     686      G4cout << "      Subcutoff sampling in " << nSCoffRegions
     687             << " regions" << G4endl;
     688    }
     689    if(2 < verboseLevel) {
     690      G4cout << "      DEDXTable address= " << theDEDXTable << G4endl;
     691      if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl;
     692      G4cout << "non restricted DEDXTable address= "
     693             << theDEDXunRestrictedTable << G4endl;
     694      if(theDEDXunRestrictedTable && isIonisation) {
     695           G4cout << (*theDEDXunRestrictedTable) << G4endl;
     696      }
     697      if(theDEDXSubTable && isIonisation) {
     698        G4cout << (*theDEDXSubTable) << G4endl;
     699      }
     700      G4cout << "      CSDARangeTable address= " << theCSDARangeTable
     701             << G4endl;
     702      if(theCSDARangeTable && isIonisation) {
     703        G4cout << (*theCSDARangeTable) << G4endl;
     704      }
     705      G4cout << "      RangeTableForLoss address= " << theRangeTableForLoss
     706             << G4endl;
     707      if(theRangeTableForLoss && isIonisation) {
     708             G4cout << (*theRangeTableForLoss) << G4endl;
     709      }
     710      G4cout << "      InverseRangeTable address= " << theInverseRangeTable
     711             << G4endl;
     712      if(theInverseRangeTable && isIonisation) {
     713             G4cout << (*theInverseRangeTable) << G4endl;
     714      }
     715      G4cout << "      LambdaTable address= " << theLambdaTable << G4endl;
     716      if(theLambdaTable && isIonisation) {
     717        G4cout << (*theLambdaTable) << G4endl;
     718      }
     719      G4cout << "      SubLambdaTable address= " << theSubLambdaTable << G4endl;
     720      if(theSubLambdaTable && isIonisation) {
     721        G4cout << (*theSubLambdaTable) << G4endl;
     722      }
     723    }
     724  }
     725}
     726
     727//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     728
     729void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
     730{
     731  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     732  const G4Region* reg = r;
     733  if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
     734
     735  // the region is in the list
     736  if (nSCoffRegions) {
     737    for (G4int i=0; i<nSCoffRegions; i++) {
     738      if (reg == scoffRegions[i]) {
     739        if(!val) deRegions[i] = 0;
     740        return;
     741      }
     742    }
     743  }
     744
     745  // new region
     746  if(val) {
     747    useSubCutoff = true;
     748    scoffRegions.push_back(reg);
     749    nSCoffRegions++;
     750  } else {
     751    useSubCutoff = false;
     752  }
     753}
     754
     755//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     756
     757void G4VEnergyLossProcess::ActivateDeexcitation(G4bool val, const G4Region* r)
     758{
     759  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     760  const G4Region* reg = r;
     761  if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
     762
     763  // the region is in the list
     764  if (nDERegions) {
     765    for (G4int i=0; i<nDERegions; i++) {
     766      if (reg == deRegions[i]) {
     767        if(!val) deRegions[i] = 0;
     768        return;
     769      }
     770    }
     771  }
     772
     773  // new region
     774  if(val) {
     775    useDeexcitation = true;
     776    deRegions.push_back(reg);
     777    nDERegions++;
     778  } else {
     779    useDeexcitation = false;
     780  }
    622781}
    623782
     
    641800    if(x > finalRange && y < currentMinStep) {
    642801      x = y + finalRange*(1.0 - dRoverRange)*(2.0 - finalRange/fRange);
    643     } else if (rndmStepFlag) x = SampleRange();
    644     //    G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
    645     //    <<" range= "<<fRange <<" cMinSt="<<currentMinStep
    646     //    <<" safety= " << safety<< " limit= " << x <<G4endl;
    647   }
    648   //  G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
     802    } else if (rndmStepFlag) {x = SampleRange();}
     803    //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
     804    //  <<" range= "<<fRange <<" cMinSt="<<currentMinStep
     805    //  << " limit= " << x <<G4endl;
     806  }
     807  //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
    649808  //  <<" stepLimit= "<<x<<G4endl;
    650809  return x;
    651 }
    652 
    653 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    654 
    655 G4double G4VEnergyLossProcess::GetMeanFreePath(
    656                              const G4Track& track,
    657                              G4double,
    658                              G4ForceCondition* condition)
    659 
    660 {
    661   *condition = NotForced;
    662   return MeanFreePath(track);
    663810}
    664811
     
    673820  *condition = NotForced;
    674821  G4double x = DBL_MAX;
     822
     823  // initialisation of material, mass, charge, model at the beginning of the step
     824  DefineMaterial(track.GetMaterialCutsCouple());
     825
     826  const G4ParticleDefinition* currPart = track.GetDefinition();
     827  if(theGenericIon == particle) {
     828    massRatio = proton_mass_c2/currPart->GetPDGMass();
     829  } 
     830  preStepKinEnergy    = track.GetKineticEnergy();
     831  preStepScaledEnergy = preStepKinEnergy*massRatio;
     832  SelectModel(preStepScaledEnergy);
     833
     834  if(isIon) {
     835    chargeSqRatio =
     836      currentModel->GetChargeSquareRatio(currPart,currentMaterial,preStepKinEnergy);
     837    reduceFactor  = 1.0/(chargeSqRatio*massRatio);
     838  }
     839  //G4cout << "q2= " << chargeSqRatio << " massRatio= " << massRatio << G4endl;
     840  // initialisation for sampling of the interaction length
    675841  if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0;
    676   InitialiseStep(track);
    677 
     842  if(theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
     843
     844  // compute mean free path
    678845  if(preStepScaledEnergy < mfpKinEnergy) {
    679846    if (integral) ComputeLambdaForScaledEnergy(preStepScaledEnergy);
     
    686853    if (theNumberOfInteractionLengthLeft < 0.0) {
    687854      // beggining of tracking (or just after DoIt of this process)
     855      //G4cout<<"G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength Reset"<<G4endl;
    688856      ResetNumberOfInteractionLengthLeft();
    689857    } else if(currentInteractionLength < DBL_MAX) {
     
    702870      G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength ";
    703871      G4cout << "[ " << GetProcessName() << "]" << G4endl;
    704       G4cout << " for " << particle->GetParticleName()
     872      G4cout << " for " << currPart->GetParticleName()
    705873             << " in Material  " <<  currentMaterial->GetName()
    706874             << " Ekin(MeV)= " << preStepKinEnergy/MeV
     
    710878    }
    711879#endif
    712 
    713880    // zero cross section case
    714881  } else {
     
    738905  if(length <= DBL_MIN) return &fParticleChange;
    739906  G4double eloss  = 0.0;
    740 
    741   /*
     907  G4double esecdep = 0.0;
     908 
     909  /* 
    742910  if(-1 < verboseLevel) {
    743911    const G4ParticleDefinition* d = track.GetDefinition();
     
    755923  */
    756924
     925  const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
     926
    757927  // stopping
    758928  if (length >= fRange) {
     929    eloss = preStepKinEnergy;
     930    if (useDeexcitation) {
     931      if(idxDERegions[currentMaterialIndex]) {
     932        currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss);
     933        if(eloss < 0.0) eloss = 0.0;
     934      }
     935    }
    759936    fParticleChange.SetProposedKineticEnergy(0.0);
    760     fParticleChange.ProposeLocalEnergyDeposit(preStepKinEnergy);
     937    fParticleChange.ProposeLocalEnergyDeposit(eloss);
    761938    return &fParticleChange;
    762939  }
     
    772949      GetScaledRangeForScaledEnergy(preStepScaledEnergy) - length/reduceFactor;
    773950    eloss = preStepKinEnergy - ScaledKinEnergyForLoss(x)/massRatio;
     951   
    774952    /*
    775953    if(-1 < verboseLevel)
     
    781959             << " eloss0(MeV)= "
    782960             << GetDEDXForScaledEnergy(preStepScaledEnergy)*length/MeV
     961             << " lim(MeV)= " << preStepKinEnergy*linLossLimit/MeV
    783962             << G4endl;
    784963    */
    785964  }
    786965
    787   const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
    788   G4VEmModel* currentModel = SelectModel(preStepScaledEnergy);
    789   /*   
     966  /*   
    790967  G4double eloss0 = eloss;
    791968  if(-1 < verboseLevel ) {
     
    801978  G4double cut  = (*theCuts)[currentMaterialIndex];
    802979  G4double esec = 0.0;
    803   G4double esecdep = 0.0;
    804980
    805981  // SubCutOff
     
    807983    if(idxSCoffRegions[currentMaterialIndex]) {
    808984
    809       G4double currentMinSafety = 0.0;
     985      G4bool yes = false;
    810986      G4StepPoint* prePoint  = step.GetPreStepPoint();
    811       G4StepPoint* postPoint = step.GetPostStepPoint();
    812       G4double preSafety  = prePoint->GetSafety();
    813       G4double postSafety = preSafety - length;
    814       G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1);
    815 
    816       // recompute safety
    817       if(prePoint->GetStepStatus() != fGeomBoundary &&
    818          postPoint->GetStepStatus() != fGeomBoundary) {
    819 
    820         /*
    821         //      G4bool yes = (track.GetTrackID() == 5512);
    822         G4bool yes = false;
    823         if(yes)
    824           G4cout << "G4VEnergyLoss: presafety= " << preSafety
    825                  << " rcut= " << rcut << "  length= " << length
    826                  << " dir " << track.GetMomentumDirection()
    827                  << G4endl;
    828         */
    829 
    830         if(preSafety < rcut)
     987
     988      // Check boundary
     989      if(prePoint->GetStepStatus() == fGeomBoundary) yes = true;
     990
     991      // Check PrePoint
     992      else {
     993        G4double preSafety  = prePoint->GetSafety();
     994        G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1);
     995
     996        // recompute presafety
     997        if(preSafety < rcut) {
    831998          preSafety = safetyHelper->ComputeSafety(prePoint->GetPosition());
    832 
    833         //if(yes) {
    834         //  G4cout << "G4VEnergyLoss: newsafety= " << preSafety << G4endl;
    835           //       if(preSafety==0.0 && track.GetTrackID() == 5512 ) exit(1);
    836         //}
    837         if(postSafety < rcut)
    838           postSafety = safetyHelper->ComputeSafety(postPoint->GetPosition());
    839         /*     
    840           if(-1 < verboseLevel)
    841           G4cout << "Subcutoff: presafety(mm)= " << preSafety/mm
    842                  << " postsafety(mm)= " << postSafety/mm
    843                  << " rcut(mm)= " << rcut/mm
    844                  << G4endl;
    845         */
    846         currentMinSafety = std::min(preSafety,postSafety);
    847       }
    848 
     999        }
     1000
     1001        if(preSafety < rcut) yes = true;
     1002
     1003        // Check PostPoint
     1004        else {
     1005          G4double postSafety = preSafety - length;
     1006          if(postSafety < rcut) {
     1007            postSafety =
     1008              safetyHelper->ComputeSafety(step.GetPostStepPoint()->GetPosition());
     1009            if(postSafety < rcut) yes = true;
     1010          }
     1011        }
     1012      }
     1013 
    8491014      // Decide to start subcut sampling
    850       if(currentMinSafety < rcut) {
     1015      if(yes) {
    8511016
    8521017        cut = (*theSubCuts)[currentMaterialIndex];
     
    8561021                                currentModel,currentMaterialIndex,
    8571022                                esecdep);
     1023        // add bremsstrahlung sampling
    8581024        /*
    8591025        if(nProcesses > 0) {
     
    8761042            esec += e;
    8771043            pParticleChange->AddSecondary(t);
    878             //  mom -= t->GetMomentum();
    8791044          }     
    880           //        fParticleChange.SetProposedMomentum(mom);           
    8811045        }
    8821046      }
     
    8851049
    8861050  // Corrections, which cannot be tabulated
    887   CorrectionsAlongStep(currentCouple, dynParticle, eloss, length);
     1051  currentModel->CorrectionsAlongStep(currentCouple, dynParticle,
     1052                                     eloss, esecdep, length);
    8881053
    8891054  // Sample fluctuations
     
    8951060      G4double tmax =
    8961061        std::min(currentModel->MaxSecondaryKinEnergy(dynParticle),cut);
     1062      G4double emean = eloss;
    8971063      eloss = fluc->SampleFluctuations(currentMaterial,dynParticle,
    898                                        tmax,length,eloss);
    899       /*           
     1064                                       tmax,length,emean);
     1065      /*                            
    9001066      if(-1 < verboseLevel)
    9011067      G4cout << "After fluct: eloss(MeV)= " << eloss/MeV
    9021068             << " fluc= " << (eloss-eloss0)/MeV
    903              << " currentChargeSquare= " << chargeSquare
     1069             << " ChargeSqRatio= " << chargeSqRatio
    9041070             << " massRatio= " << massRatio
    9051071             << " tmax= " << tmax
     
    9111077  eloss += esecdep;
    9121078  if(eloss < 0.0) eloss = 0.0;
     1079
     1080  // deexcitation
     1081  else if (useDeexcitation) {
     1082    if(idxDERegions[currentMaterialIndex]) {
     1083      currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss);
     1084      if(eloss < 0.0) eloss = 0.0;
     1085    }
     1086  }
    9131087
    9141088  // Energy balanse
     
    9171091    eloss  = preStepKinEnergy - esec;
    9181092    finalT = 0.0;
     1093  } else if(isIon) {
     1094    fParticleChange.SetProposedCharge(
     1095      currentModel->GetParticleCharge(track.GetDefinition(),currentMaterial,finalT));
    9191096  }
    9201097
     
    9221099  fParticleChange.ProposeLocalEnergyDeposit(eloss);
    9231100
    924   /*
     1101  /* 
    9251102  if(-1 < verboseLevel) {
    9261103    G4cout << "Final value eloss(MeV)= " << eloss/MeV
     
    9311108           << G4endl;
    9321109  }
    933   */
     1110  */ 
    9341111
    9351112  return &fParticleChange;
     
    9431120       G4VEmModel* model,
    9441121       G4int idx,
    945        G4double& extraEdep)
     1122       G4double& /*extraEdep*/)
    9461123{
    9471124  // Fast check weather subcutoff can work
     
    9521129  const G4Track* track = step.GetTrack();
    9531130  const G4DynamicParticle* dp = track->GetDynamicParticle();
     1131  G4double e = dp->GetKineticEnergy()*massRatio;
    9541132  G4bool b;
    955   G4double cross =
    956     chargeSqRatio*(((*theSubLambdaTable)[idx])->GetValue(dp->GetKineticEnergy(),b));
     1133  G4double cross = chargeSqRatio*(((*theSubLambdaTable)[idx])->GetValue(e,b));
    9571134  G4double length = step.GetStepLength();
    9581135
    9591136  // negligible probability to get any interaction
    9601137  if(length*cross < perMillion) return;
    961   /*   
     1138  /*     
    9621139  if(-1 < verboseLevel)
    9631140    G4cout << "<<< Subcutoff for " << GetProcessName()
     
    9701147  // Sample subcutoff secondaries
    9711148  G4StepPoint* preStepPoint = step.GetPreStepPoint();
     1149  G4StepPoint* postStepPoint = step.GetPostStepPoint();
    9721150  G4ThreeVector prepoint = preStepPoint->GetPosition();
    973   G4ThreeVector dr = step.GetPostStepPoint()->GetPosition() - prepoint;
     1151  G4ThreeVector dr = postStepPoint->GetPosition() - prepoint;
    9741152  G4double pretime = preStepPoint->GetGlobalTime();
    975   //  G4double dt = length/preStepPoint->GetVelocity();
     1153  G4double dt = postStepPoint->GetGlobalTime() - pretime;
     1154  //G4double dt = length/preStepPoint->GetVelocity();
    9761155  G4double fragment = 0.0;
    9771156
     
    9921171
    9931172      G4bool addSec = true;
     1173      /*
    9941174      // do not track very low-energy delta-electrons
    9951175      if(theSecondaryRangeTable && (*it)->GetDefinition() == theElectron) {
     
    10041184        }
    10051185      }
     1186      */
    10061187      if(addSec) {
    1007         //      G4Track* t = new G4Track((*it), pretime + fragment*dt, r);
    1008         G4Track* t = new G4Track((*it), pretime, r);
     1188        G4Track* t = new G4Track((*it), pretime + fragment*dt, r);
     1189        //G4Track* t = new G4Track((*it), pretime, r);
    10091190        t->SetTouchableHandle(track->GetTouchableHandle());
    10101191        tracks.push_back(t);
    10111192
    1012         /*
    1013           if(-1 < verboseLevel)
    1014           G4cout << "New track " << p->GetDefinition()->GetParticleName()
    1015           << " e(keV)= " << p->GetKineticEnergy()/keV
    1016           << " fragment= " << fragment
    1017           << G4endl;
     1193        /*     
     1194        if(-1 < verboseLevel)
     1195          G4cout << "New track " << t->GetDefinition()->GetParticleName()
     1196                 << " e(keV)= " << t->GetKineticEnergy()/keV
     1197                << " fragment= " << fragment
     1198                << G4endl;
    10181199        */
    10191200      }
     
    10591240  }
    10601241
    1061   G4VEmModel* currentModel = SelectModel(postStepScaledEnergy);
     1242  SelectModel(postStepScaledEnergy);
     1243  if(useDeexcitation) {
     1244    currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]);
     1245  }
     1246
    10621247  const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
    10631248  G4double tcut = (*theCuts)[currentMaterialIndex];
     
    10941279//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    10951280
    1096 void G4VEnergyLossProcess::PrintInfoDefinition()
    1097 {
    1098   if(0 < verboseLevel) {
    1099     G4cout << G4endl << GetProcessName() << ":   tables are built for  "
    1100            << particle->GetParticleName()
    1101            << G4endl
    1102            << "      dE/dx and range tables from "
    1103            << G4BestUnit(minKinEnergy,"Energy")
    1104            << " to " << G4BestUnit(maxKinEnergy,"Energy")
    1105            << " in " << nBins << " bins." << G4endl
    1106            << "      Lambda tables from threshold to "
    1107            << G4BestUnit(maxKinEnergy,"Energy")
    1108            << " in " << nBins << " bins."
     1281G4bool G4VEnergyLossProcess::StorePhysicsTable(
     1282       const G4ParticleDefinition* part, const G4String& directory,
     1283       G4bool ascii)
     1284{
     1285  G4bool res = true;
     1286  if ( baseParticle || part != particle ) return res;
     1287
     1288  if(!StoreTable(part,theDEDXTable,ascii,directory,"DEDX"))
     1289    {res = false;}
     1290
     1291  if(!StoreTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr"))
     1292    {res = false;}
     1293
     1294  if(!StoreTable(part,theDEDXSubTable,ascii,directory,"SubDEDX"))
     1295    {res = false;}
     1296
     1297  if(!StoreTable(part,theIonisationTable,ascii,directory,"Ionisation"))
     1298    {res = false;}
     1299
     1300  if(!StoreTable(part,theIonisationSubTable,ascii,directory,"SubIonisation"))
     1301    {res = false;}
     1302
     1303  if(isIonisation &&
     1304     !StoreTable(part,theCSDARangeTable,ascii,directory,"CSDARange"))
     1305    {res = false;}
     1306
     1307  if(isIonisation &&
     1308     !StoreTable(part,theRangeTableForLoss,ascii,directory,"Range"))
     1309    {res = false;}
     1310 
     1311  if(isIonisation &&
     1312     !StoreTable(part,theInverseRangeTable,ascii,directory,"InverseRange"))
     1313    {res = false;}
     1314 
     1315  if(!StoreTable(part,theLambdaTable,ascii,directory,"Lambda"))
     1316    {res = false;}
     1317
     1318  if(!StoreTable(part,theSubLambdaTable,ascii,directory,"SubLambda"))
     1319    {res = false;}
     1320
     1321  if ( res ) {
     1322    if(0 < verboseLevel) {
     1323      G4cout << "Physics tables are stored for " << particle->GetParticleName()
     1324             << " and process " << GetProcessName()
     1325             << " in the directory <" << directory
     1326             << "> " << G4endl;
     1327    }
     1328  } else {
     1329    G4cout << "Fail to store Physics Tables for "
     1330           << particle->GetParticleName()
     1331           << " and process " << GetProcessName()
     1332           << " in the directory <" << directory
     1333           << "> " << G4endl;
     1334  }
     1335  return res;
     1336}
     1337
     1338//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     1339
     1340G4bool G4VEnergyLossProcess::RetrievePhysicsTable(
     1341       const G4ParticleDefinition* part, const G4String& directory,
     1342       G4bool ascii)
     1343{
     1344  G4bool res = true;
     1345  const G4String particleName = part->GetParticleName();
     1346
     1347  if(1 < verboseLevel) {
     1348    G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for "
     1349           << particleName << " and process " << GetProcessName()
     1350           << "; tables_are_built= " << tablesAreBuilt
    11091351           << G4endl;
    1110     PrintInfo();
    1111     if(theRangeTableForLoss && isIonisation)
    1112       G4cout << "      Step function: finalRange(mm)= " << finalRange/mm
    1113              << ", dRoverRange= " << dRoverRange
    1114              << ", integral: " << integral
    1115              << ", fluct: " << lossFluctuationFlag
    1116              << G4endl;
    1117    
    1118     if(theCSDARangeTable && isIonisation)
    1119       G4cout << "      CSDA range table up"
    1120              << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy")
    1121              << " in " << nBinsCSDA << " bins." << G4endl;
    1122    
    1123     if(nSCoffRegions>0)
    1124       G4cout << "      Subcutoff sampling in " << nSCoffRegions
    1125              << " regions" << G4endl;
    1126 
    1127     if(2 < verboseLevel) {
    1128       G4cout << "DEDXTable address= " << theDEDXTable << G4endl;
    1129       if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl;
    1130       G4cout << "non restricted DEDXTable address= "
    1131              << theDEDXunRestrictedTable << G4endl;
    1132       if(theDEDXunRestrictedTable && isIonisation)
    1133            G4cout << (*theDEDXunRestrictedTable) << G4endl;
    1134       if(theDEDXSubTable && isIonisation) G4cout << (*theDEDXSubTable)
    1135                                                  << G4endl;
    1136       G4cout << "CSDARangeTable address= " << theCSDARangeTable
     1352  }
     1353  if(particle == part) {
     1354
     1355    //    G4bool yes = true;
     1356    if ( !baseParticle ) {
     1357
     1358      G4bool fpi = true;
     1359      if(!RetrieveTable(part,theDEDXTable,ascii,directory,"DEDX",fpi))
     1360        {fpi = false;}
     1361
     1362      if(!RetrieveTable(part,theIonisationTable,ascii,directory,"Ionisation",false))
     1363        {fpi = false;}
     1364
     1365      if(!RetrieveTable(part,theRangeTableForLoss,ascii,directory,"Range",fpi))
     1366        {res = false;}
     1367
     1368      if(!RetrieveTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr",false))
     1369        {res = false;}
     1370
     1371      if(!RetrieveTable(part,theCSDARangeTable,ascii,directory,"CSDARange",false))
     1372        {res = false;}
     1373
     1374      if(!RetrieveTable(part,theInverseRangeTable,ascii,directory,"InverseRange",fpi))
     1375        {res = false;}
     1376
     1377      if(!RetrieveTable(part,theLambdaTable,ascii,directory,"Lambda",true))
     1378        {res = false;}
     1379
     1380      G4bool yes = false;
     1381      if(nSCoffRegions > 0) {yes = true;}
     1382
     1383      if(!RetrieveTable(part,theDEDXSubTable,ascii,directory,"SubDEDX",yes))
     1384        {res = false;}
     1385
     1386      if(!RetrieveTable(part,theSubLambdaTable,ascii,directory,"SubLambda",yes))
     1387        {res = false;}
     1388
     1389      if(!fpi) yes = false;
     1390      if(!RetrieveTable(part,theIonisationSubTable,ascii,directory,"SubIonisation",yes))
     1391        {res = false;}
     1392    }
     1393  }
     1394
     1395  return res;
     1396}
     1397
     1398//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     1399
     1400G4bool G4VEnergyLossProcess::StoreTable(const G4ParticleDefinition* part,
     1401                                        G4PhysicsTable* aTable, G4bool ascii,
     1402                                        const G4String& directory,
     1403                                        const G4String& tname)
     1404{
     1405  G4bool res = true;
     1406  if ( aTable ) {
     1407    const G4String name = GetPhysicsTableFileName(part,directory,tname,ascii);
     1408    if( !aTable->StorePhysicsTable(name,ascii)) res = false;
     1409  }
     1410  return res;
     1411}
     1412
     1413//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     1414
     1415G4bool G4VEnergyLossProcess::RetrieveTable(const G4ParticleDefinition* part,
     1416                                           G4PhysicsTable* aTable, G4bool ascii,
     1417                                           const G4String& directory,
     1418                                           const G4String& tname,
     1419                                           G4bool mandatory)
     1420{
     1421  G4bool res = true;
     1422  G4String filename = GetPhysicsTableFileName(part,directory,tname,ascii);
     1423  G4bool yes = aTable->ExistPhysicsTable(filename);
     1424  if(yes) {
     1425    yes = G4PhysicsTableHelper::RetrievePhysicsTable(aTable,filename,ascii);
     1426    if((G4LossTableManager::Instance())->SplineFlag()) {
     1427      size_t n = aTable->length();
     1428      for(size_t i=0; i<n; i++) {(*aTable)[i]->SetSpline(true);}
     1429    }
     1430  }
     1431  if(yes) {
     1432    if (0 < verboseLevel) {
     1433      G4cout << tname << " table for " << part->GetParticleName()
     1434             << " is Retrieved from <" << filename << ">"
    11371435             << G4endl;
    1138       if(theCSDARangeTable && isIonisation) G4cout << (*theCSDARangeTable)
    1139             << G4endl;
    1140       G4cout << "RangeTableForLoss address= " << theRangeTableForLoss
     1436    }
     1437  } else {
     1438    if(mandatory) res = false;
     1439    if(mandatory || 1 < verboseLevel) {
     1440      G4cout << tname << " table for " << part->GetParticleName()
     1441             << " from file <"
     1442             << filename << "> is not Retrieved"
    11411443             << G4endl;
    1142       if(theRangeTableForLoss && isIonisation)
    1143              G4cout << (*theRangeTableForLoss) << G4endl;
    1144       G4cout << "InverseRangeTable address= " << theInverseRangeTable
    1145              << G4endl;
    1146       if(theInverseRangeTable && isIonisation)
    1147              G4cout << (*theInverseRangeTable) << G4endl;
    1148       G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
    1149       if(theLambdaTable && isIonisation) G4cout << (*theLambdaTable) << G4endl;
    1150       G4cout << "SubLambdaTable address= " << theSubLambdaTable << G4endl;
    1151       if(theSubLambdaTable && isIonisation) G4cout << (*theSubLambdaTable)
    1152              << G4endl;
     1444    }
     1445  }
     1446  return res;
     1447}
     1448
     1449//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1450
     1451G4double G4VEnergyLossProcess::GetDEDXDispersion(
     1452                                  const G4MaterialCutsCouple *couple,
     1453                                  const G4DynamicParticle* dp,
     1454                                        G4double length)
     1455{
     1456  DefineMaterial(couple);
     1457  G4double ekin = dp->GetKineticEnergy();
     1458  SelectModel(ekin*massRatio);
     1459  G4double tmax = currentModel->MaxSecondaryKinEnergy(dp);
     1460  tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]);
     1461  G4double d = 0.0;
     1462  G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations();
     1463  if(fm) d = fm->Dispersion(currentMaterial,dp,tmax,length);
     1464  return d;
     1465}
     1466
     1467//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1468
     1469G4double G4VEnergyLossProcess::CrossSectionPerVolume(
     1470         G4double kineticEnergy, const G4MaterialCutsCouple* couple)
     1471{
     1472  // Cross section per volume is calculated
     1473  DefineMaterial(couple);
     1474  G4double cross = 0.0;
     1475  G4bool b;
     1476  if(theLambdaTable) {
     1477    cross =
     1478      ((*theLambdaTable)[currentMaterialIndex])->GetValue(kineticEnergy, b);
     1479  } else {
     1480    SelectModel(kineticEnergy);
     1481    cross =
     1482      currentModel->CrossSectionPerVolume(currentMaterial,
     1483                                          particle, kineticEnergy,
     1484                                          (*theCuts)[currentMaterialIndex]);
     1485  }
     1486
     1487  return cross;
     1488}
     1489
     1490//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1491
     1492G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track)
     1493{
     1494  DefineMaterial(track.GetMaterialCutsCouple());
     1495  preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio);
     1496  G4double x = DBL_MAX;
     1497  if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
     1498  return x;
     1499}
     1500
     1501//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1502
     1503G4double G4VEnergyLossProcess::ContinuousStepLimit(const G4Track& track,
     1504                                                   G4double x, G4double y,
     1505                                                   G4double& z)
     1506{
     1507  G4GPILSelection sel;
     1508  return AlongStepGetPhysicalInteractionLength(track, x, y, z, &sel);
     1509}
     1510
     1511//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1512
     1513G4double G4VEnergyLossProcess::GetMeanFreePath(
     1514                             const G4Track& track,
     1515                             G4double,
     1516                             G4ForceCondition* condition)
     1517
     1518{
     1519  *condition = NotForced;
     1520  return MeanFreePath(track);
     1521}
     1522
     1523//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1524
     1525G4double G4VEnergyLossProcess::GetContinuousStepLimit(
     1526                const G4Track&,
     1527                G4double, G4double, G4double&)
     1528{
     1529  return DBL_MAX;
     1530}
     1531
     1532//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1533
     1534G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(
     1535                 const G4MaterialCutsCouple* couple, G4double cut)
     1536{
     1537  //  G4double cut  = (*theCuts)[couple->GetIndex()];
     1538  //  G4int nbins = nLambdaBins;
     1539  G4double tmin =
     1540    std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),
     1541             minKinEnergy);
     1542  if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;
     1543  G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins);
     1544  v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
     1545
     1546  return v;
     1547}
     1548
     1549//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1550 
     1551void G4VEnergyLossProcess::AddCollaborativeProcess(
     1552            G4VEnergyLossProcess* p)
     1553{
     1554  G4bool add = true;
     1555  if(p->GetProcessName() != "eBrem") add = false;
     1556  if(add && nProcesses > 0) {
     1557    for(G4int i=0; i<nProcesses; i++) {
     1558      if(p == scProcesses[i]) {
     1559        add = false;
     1560        break;
     1561      }
     1562    }
     1563  }
     1564  if(add) {
     1565    scProcesses.push_back(p);
     1566    nProcesses++;
     1567    if (1 < verboseLevel) {
     1568      G4cout << "### The process " << p->GetProcessName()
     1569             << " is added to the list of collaborative processes of "
     1570             << GetProcessName() << G4endl;
    11531571    }
    11541572  }
     
    11821600  } else if(fSubRestricted == tType) {   
    11831601    theDEDXSubTable = p;
    1184   } else if(fIonisation == tType && theIonisationTable != p) {   
     1602  } else if(fIsIonisation == tType && theIonisationTable != p) {   
    11851603    if(theIonisationTable) theIonisationTable->clearAndDestroy();
    11861604    theIonisationTable = p;
    1187   } else if(fSubIonisation == tType && theIonisationSubTable != p) {   
     1605  } else if(fIsSubIonisation == tType && theIonisationSubTable != p) {   
    11881606    if(theIonisationSubTable) theIonisationSubTable->clearAndDestroy();
    11891607    theIonisationSubTable = p;
     
    13191737//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    13201738
    1321 G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(
    1322                  const G4MaterialCutsCouple* couple, G4double cut)
    1323 {
    1324   //  G4double cut  = (*theCuts)[couple->GetIndex()];
    1325   //  G4int nbins = nLambdaBins;
    1326   G4double tmin =
    1327     std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),
    1328              minKinEnergy);
    1329   if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;
    1330   G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins);
    1331   return v;
    1332 }
    1333 
    1334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1335 
    1336 G4double G4VEnergyLossProcess::MicroscopicCrossSection(
    1337          G4double kineticEnergy, const G4MaterialCutsCouple* couple)
    1338 {
    1339   // Cross section per atom is calculated
    1340   DefineMaterial(couple);
    1341   G4double cross = 0.0;
    1342   G4bool b;
    1343   if(theLambdaTable)
    1344     cross =
    1345       ((*theLambdaTable)[currentMaterialIndex])->GetValue(kineticEnergy, b)/
    1346       currentMaterial->GetTotNbOfAtomsPerVolume();
    1347 
    1348   return cross;
    1349 }
    1350 
    1351 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1352 
    1353 G4bool G4VEnergyLossProcess::StorePhysicsTable(
    1354        const G4ParticleDefinition* part, const G4String& directory,
    1355        G4bool ascii)
    1356 {
    1357   G4bool res = true;
    1358   if ( baseParticle || part != particle ) return res;
    1359 
    1360   if ( theDEDXTable ) {
    1361     const G4String name = GetPhysicsTableFileName(part,directory,"DEDX",ascii);
    1362     if( !theDEDXTable->StorePhysicsTable(name,ascii)) res = false;
    1363   }
    1364 
    1365   if ( theDEDXunRestrictedTable ) {
    1366     const G4String name =
    1367       GetPhysicsTableFileName(part,directory,"DEDXnr",ascii);
    1368     if( !theDEDXTable->StorePhysicsTable(name,ascii)) res = false;
    1369   }
    1370 
    1371   if ( theDEDXSubTable ) {
    1372     const G4String name =
    1373       GetPhysicsTableFileName(part,directory,"SubDEDX",ascii);
    1374     if( !theDEDXSubTable->StorePhysicsTable(name,ascii)) res = false;
    1375   }
    1376 
    1377   if ( theIonisationTable ) {
    1378     const G4String name =
    1379       GetPhysicsTableFileName(part,directory,"Ionisation",ascii);
    1380     if( !theIonisationTable->StorePhysicsTable(name,ascii)) res = false;
    1381   }
    1382 
    1383   if ( theIonisationSubTable ) {
    1384     const G4String name =
    1385       GetPhysicsTableFileName(part,directory,"SubIonisation",ascii);
    1386     if( !theIonisationSubTable->StorePhysicsTable(name,ascii)) res = false;
    1387   }
    1388 
    1389   if ( theCSDARangeTable && isIonisation ) {
    1390     const G4String name =
    1391       GetPhysicsTableFileName(part,directory,"CSDARange",ascii);
    1392     if( !theCSDARangeTable->StorePhysicsTable(name,ascii)) res = false;
    1393   }
    1394 
    1395   if ( theRangeTableForLoss && isIonisation ) {
    1396     const G4String name =
    1397       GetPhysicsTableFileName(part,directory,"Range",ascii);
    1398     if( !theRangeTableForLoss->StorePhysicsTable(name,ascii)) res = false;
    1399   }
    1400 
    1401   if ( theInverseRangeTable && isIonisation ) {
    1402     const G4String name =
    1403       GetPhysicsTableFileName(part,directory,"InverseRange",ascii);
    1404     if( !theInverseRangeTable->StorePhysicsTable(name,ascii)) res = false;
    1405   }
    1406 
    1407   if ( theLambdaTable  && isIonisation) {
    1408     const G4String name =
    1409       GetPhysicsTableFileName(part,directory,"Lambda",ascii);
    1410     if( !theLambdaTable->StorePhysicsTable(name,ascii)) res = false;
    1411   }
    1412 
    1413   if ( theSubLambdaTable  && isIonisation) {
    1414     const G4String name =
    1415       GetPhysicsTableFileName(part,directory,"SubLambda",ascii);
    1416     if( !theSubLambdaTable->StorePhysicsTable(name,ascii)) res = false;
    1417   }
    1418   if ( res ) {
    1419     if(0 < verboseLevel) {
    1420       G4cout << "Physics tables are stored for " << particle->GetParticleName()
    1421              << " and process " << GetProcessName()
    1422              << " in the directory <" << directory
    1423              << "> " << G4endl;
    1424     }
    1425   } else {
    1426     G4cout << "Fail to store Physics Tables for "
    1427            << particle->GetParticleName()
    1428            << " and process " << GetProcessName()
    1429            << " in the directory <" << directory
    1430            << "> " << G4endl;
    1431   }
    1432   return res;
    1433 }
    1434 
    1435 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
    1436 
    1437 G4bool G4VEnergyLossProcess::RetrievePhysicsTable(
    1438        const G4ParticleDefinition* part, const G4String& directory,
    1439        G4bool ascii)
    1440 {
    1441   G4bool res = true;
    1442   const G4String particleName = part->GetParticleName();
    1443 
    1444   if(1 < verboseLevel) {
    1445     G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for "
    1446            << particleName << " and process " << GetProcessName()
    1447            << "; tables_are_built= " << tablesAreBuilt
    1448            << G4endl;
    1449   }
    1450   if(particle == part) {
    1451 
    1452     G4bool yes = true;
    1453     G4bool fpi = true;
    1454     if ( !baseParticle ) {
    1455       G4String filename;
    1456 
    1457       filename = GetPhysicsTableFileName(part,directory,"DEDX",ascii);
    1458       yes = theDEDXTable->ExistPhysicsTable(filename);
    1459       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1460                     theDEDXTable,filename,ascii);
    1461       if(yes) {
    1462         if (0 < verboseLevel) {
    1463           G4cout << "DEDX table for " << particleName
    1464                  << " is Retrieved from <"
    1465                  << filename << ">"
    1466                  << G4endl;
    1467         }
    1468       } else {
    1469         fpi = false;
    1470         if (1 < verboseLevel) {
    1471           G4cout << "DEDX table for " << particleName << " from file <"
    1472                  << filename << "> is not Retrieved"
    1473                  << G4endl;
    1474         }
    1475       }
    1476 
    1477       filename = GetPhysicsTableFileName(part,directory,"Range",ascii);
    1478       yes = theRangeTableForLoss->ExistPhysicsTable(filename);
    1479       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1480                     theRangeTableForLoss,filename,ascii);
    1481       if(yes) {
    1482         if (0 < verboseLevel) {
    1483           G4cout << "Range table for loss for " << particleName
    1484                  << " is Retrieved from <"
    1485                  << filename << ">"
    1486                  << G4endl;
    1487         }
    1488       } else {
    1489         if(fpi) {
    1490           res = false;
    1491           G4cout << "Range table for loss for " << particleName
    1492                  << " from file <"
    1493                  << filename << "> is not Retrieved"
    1494                  << G4endl;
    1495         }
    1496       }
    1497 
    1498       filename = GetPhysicsTableFileName(part,directory,"DEDXnr",ascii);
    1499       yes = theDEDXunRestrictedTable->ExistPhysicsTable(filename);
    1500       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1501                     theDEDXunRestrictedTable,filename,ascii);
    1502       if(yes) {
    1503         if (0 < verboseLevel) {
    1504           G4cout << "Non-restricted DEDX table for " << particleName
    1505                  << " is Retrieved from <"
    1506                  << filename << ">"
    1507                  << G4endl;
    1508         }
    1509       } else {
    1510         if (1 < verboseLevel) {
    1511           G4cout << "Non-restricted DEDX table for " << particleName
    1512                  << " from file <"
    1513                  << filename << "> is not Retrieved"
    1514                  << G4endl;
    1515         }
    1516       }
    1517 
    1518       filename = GetPhysicsTableFileName(part,directory,"CSDARange",ascii);
    1519       yes = theCSDARangeTable->ExistPhysicsTable(filename);
    1520       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1521                     theCSDARangeTable,filename,ascii);
    1522       if(yes) {
    1523         if (0 < verboseLevel) {
    1524           G4cout << "CSDA Range table for " << particleName
    1525                  << " is Retrieved from <"
    1526                  << filename << ">"
    1527                  << G4endl;
    1528         }
    1529       } else {
    1530         G4cout << "CSDA Range table for loss for " << particleName
    1531                << " does not exist"
    1532                << G4endl;
    1533       }
    1534 
    1535       filename = GetPhysicsTableFileName(part,directory,"InverseRange",ascii);
    1536       yes = theInverseRangeTable->ExistPhysicsTable(filename);
    1537       if(yes)  yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1538                      theInverseRangeTable,filename,ascii);
    1539       if(yes) {
    1540         if (0 < verboseLevel) {
    1541           G4cout << "InverseRange table for " << particleName
    1542                  << " is Retrieved from <"
    1543                  << filename << ">"
    1544                  << G4endl;
    1545         }
    1546       } else {
    1547         if(fpi) {
    1548           res = false;
    1549           G4cout << "InverseRange table for " << particleName
    1550                  << " from file <"
    1551                  << filename << "> is not Retrieved"
    1552                  << G4endl;
    1553 
    1554         }
    1555       }
    1556 
    1557       filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
    1558       yes = theLambdaTable->ExistPhysicsTable(filename);
    1559       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1560                     theLambdaTable,filename,ascii);
    1561       if(yes) {
    1562         if (0 < verboseLevel) {
    1563           G4cout << "Lambda table for " << particleName
    1564                  << " is Retrieved from <"
    1565                  << filename << ">"
    1566                  << G4endl;
    1567         }
    1568       } else {
    1569         if(fpi) {
    1570           res = false;
    1571           G4cout << "Lambda table for " << particleName << " from file <"
    1572                  << filename << "> is not Retrieved"
    1573                  << G4endl;
    1574         }
    1575       }
    1576 
    1577       filename = GetPhysicsTableFileName(part,directory,"SubDEDX",ascii);
    1578       yes = theDEDXSubTable->ExistPhysicsTable(filename);
    1579       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1580                     theDEDXSubTable,filename,ascii);
    1581       if(yes) {
    1582         if (0 < verboseLevel) {
    1583           G4cout << "SubDEDX table for " << particleName
    1584                  << " is Retrieved from <"
    1585                  << filename << ">"
    1586                  << G4endl;
    1587         }
    1588       } else {
    1589         if(nSCoffRegions) {
    1590           res=false;
    1591           G4cout << "SubDEDX table for " << particleName << " from file <"
    1592                  << filename << "> is not Retrieved"
    1593                  << G4endl;
    1594         }
    1595       }
    1596 
    1597       filename = GetPhysicsTableFileName(part,directory,"SubLambda",ascii);
    1598       yes = theSubLambdaTable->ExistPhysicsTable(filename);
    1599       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1600                     theSubLambdaTable,filename,ascii);
    1601       if(yes) {
    1602         if (0 < verboseLevel) {
    1603           G4cout << "SubLambda table for " << particleName
    1604                  << " is Retrieved from <"
    1605                  << filename << ">"
    1606                  << G4endl;
    1607         }
    1608       } else {
    1609         if(nSCoffRegions) {
    1610           res=false;
    1611           G4cout << "SubLambda table for " << particleName << " from file <"
    1612                  << filename << "> is not Retrieved"
    1613                  << G4endl;
    1614         }
    1615       }
    1616 
    1617       filename = GetPhysicsTableFileName(part,directory,"Ionisation",ascii);
    1618       yes = theIonisationTable->ExistPhysicsTable(filename);
    1619       if(yes) {
    1620         theIonisationTable =
    1621           G4PhysicsTableHelper::PreparePhysicsTable(theIonisationTable);
    1622        
    1623         yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1624                     theIonisationTable,filename,ascii);
    1625       }
    1626       if(yes) {
    1627         if (0 < verboseLevel) {
    1628           G4cout << "Ionisation table for " << particleName
    1629                  << " is Retrieved from <"
    1630                  << filename << ">"
    1631                  << G4endl;
    1632         }
    1633       }
    1634 
    1635       filename = GetPhysicsTableFileName(part,directory,"SubIonisation",ascii);
    1636       yes = theIonisationSubTable->ExistPhysicsTable(filename);
    1637       if(yes) {
    1638         theIonisationSubTable =
    1639           G4PhysicsTableHelper::PreparePhysicsTable(theIonisationSubTable);
    1640         yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1641                     theIonisationSubTable,filename,ascii);
    1642       }
    1643       if(yes) {
    1644         if (0 < verboseLevel) {
    1645           G4cout << "SubIonisation table for " << particleName
    1646                  << " is Retrieved from <"
    1647                  << filename << ">"
    1648                  << G4endl;
    1649         }
    1650       }
    1651     }
    1652   }
    1653 
    1654   return res;
    1655 }
    1656 
    1657 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1658  
    1659 void G4VEnergyLossProcess::AddCollaborativeProcess(
    1660             G4VEnergyLossProcess* p)
    1661 {
    1662   G4bool add = true;
    1663   if(nProcesses > 0) {
    1664     for(G4int i=0; i<nProcesses; i++) {
    1665       if(p == scProcesses[i]) {
    1666         add = false;
    1667         break;
    1668       }
    1669     }
    1670   }
    1671   if(add) {
    1672     scProcesses.push_back(p);
    1673     nProcesses++;
    1674     if (0 < verboseLevel)
    1675       G4cout << "### The process " << p->GetProcessName()
    1676              << " is added to the list of collaborative processes of "
    1677              << GetProcessName() << G4endl;
    1678   }
    1679 }
    1680 
    1681 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1682 
    1683 G4double G4VEnergyLossProcess::GetDEDXDispersion(
    1684                                   const G4MaterialCutsCouple *couple,
    1685                                   const G4DynamicParticle* dp,
    1686                                         G4double length)
    1687 {
    1688   DefineMaterial(couple);
    1689   G4double ekin = dp->GetKineticEnergy();
    1690   G4VEmModel* currentModel = SelectModel(ekin*massRatio);
    1691   G4double tmax = currentModel->MaxSecondaryKinEnergy(dp);
    1692   tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]);
    1693   G4double d = 0.0;
    1694   G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations();
    1695   if(fm) d = fm->Dispersion(currentMaterial,dp,tmax,length);
    1696   return d;
    1697 }
    1698 
    1699 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1700 
    1701 void G4VEnergyLossProcess::ActivateDeexcitation(G4bool, const G4Region*)
    1702 {}
    1703 
    1704 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1705 
  • trunk/source/processes/electromagnetic/utils/src/G4VMultipleScattering.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VMultipleScattering.cc,v 1.47 2007/11/09 11:35:54 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VMultipleScattering.cc,v 1.60 2008/11/20 20:32:40 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5555// 12-04-07 Add verbosity at destruction (V.Ivanchenko)
    5656// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
     57// 11-03-08 Set skin value does not effect step limit type (V.Ivanchenko)
    5758//
    5859// Class Description:
     
    8586//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    8687
    87 G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType type):
    88                  G4VContinuousDiscreteProcess(name, type),
     88G4VMultipleScattering::G4VMultipleScattering(const G4String& name,
     89                                             G4ProcessType type):
     90  G4VContinuousDiscreteProcess(name, type),
     91  buildLambdaTable(true),
    8992  theLambdaTable(0),
    9093  firstParticle(0),
    91   currentParticle(0),
    92   currentCouple(0),
    93   nBins(120),
    9494  stepLimit(fUseSafety),
    95   skin(0.0),
     95  skin(3.0),
    9696  facrange(0.02),
    9797  facgeom(2.5),
    9898  latDisplasment(true),
    99   buildLambdaTable(true)
    100 {
     99  currentParticle(0),
     100  currentCouple(0)
     101{
     102  SetVerboseLevel(1);
     103  SetProcessSubType(fMultipleScattering);
     104
     105  // Size of tables assuming spline
    101106  minKinEnergy = 0.1*keV;
    102107  maxKinEnergy = 100.0*TeV;
    103   SetVerboseLevel(1);
     108  nBins        = 84;
     109
     110  // default limit on polar angle
     111  polarAngleLimit = 0.0;
    104112
    105113  pParticleChange = &fParticleChange;
     
    114122G4VMultipleScattering::~G4VMultipleScattering()
    115123{
    116   if(1 < verboseLevel)
     124  if(1 < verboseLevel) {
    117125    G4cout << "G4VMultipleScattering destruct " << GetProcessName()
    118126           << G4endl;
     127  }
    119128  delete modelManager;
    120129  if (theLambdaTable) {
     
    131140  G4String num = part.GetParticleName();
    132141  if(1 < verboseLevel) {
    133     //    G4cout << "========================================================" << G4endl;
    134142    G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
    135143           << GetProcessName()
     
    148156      if (theLambdaTable->GetFlag(i)) {
    149157        // create physics vector and fill it
    150         const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
     158        const G4MaterialCutsCouple* couple =
     159          theCoupleTable->GetMaterialCutsCouple(i);
    151160        G4PhysicsVector* aVector = PhysicsVector(couple);
    152161        modelManager->FillLambdaVector(aVector, couple, false);
     
    162171  }
    163172  if(verboseLevel>0 && ( num == "e-" || num == "mu+" || 
    164                          num == "proton" || num == "pi-" || num == "GenericIon")) {
     173                         num == "proton" || num == "pi-" ||
     174                         num == "GenericIon")) {
    165175    PrintInfoDefinition();
    166176    if(2 < verboseLevel && theLambdaTable) G4cout << *theLambdaTable << G4endl;
     
    182192    currentCouple = 0;
    183193    if(part.GetParticleType() == "nucleus" &&
    184        part.GetParticleSubType() == "generic")
    185          firstParticle = G4GenericIon::GenericIon();
    186     else firstParticle = &part;
     194       part.GetParticleSubType() == "generic") {
     195      firstParticle = G4GenericIon::GenericIon();
     196    } else {
     197      firstParticle = &part;
     198    }
     199
    187200    currentParticle = &part;
    188201  }
    189202
    190203  if(1 < verboseLevel) {
    191     //    G4cout << "========================================================" << G4endl;
    192204    G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
    193205           << GetProcessName()
     
    217229{
    218230  if (0 < verboseLevel) {
    219     G4cout << G4endl << GetProcessName() << ":  Model variant of multiple scattering "
    220            << "for " << firstParticle->GetParticleName()
     231    G4cout << G4endl << GetProcessName()
     232           << ":   for " << firstParticle->GetParticleName()
     233           << "    SubType= " << GetProcessSubType()
    221234           << G4endl;
    222235    if (theLambdaTable) {
     
    225238             << " to "
    226239             << G4BestUnit(MaxKinEnergy(),"Energy")
    227              << " in " << nBins << " bins."
     240             << " in " << nBins << " bins, spline: "
     241             << (G4LossTableManager::Instance())->SplineFlag()
    228242             << G4endl;
    229243    }
    230     G4cout << "      LateralDisplacementFlag=  " << latDisplasment
    231            << "   Skin= " << skin << G4endl;
    232244    PrintInfo();
     245    modelManager->DumpModelList(verboseLevel);
    233246    if (2 < verboseLevel) {
    234247      G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
     
    242255G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
    243256                             const G4Track& track,
    244                              G4double previousStepSize,
     257                             G4double,
    245258                             G4double currentMinimalStep,
    246259                             G4double& currentSafety,
     
    249262  // get Step limit proposed by the process
    250263  valueGPILSelectionMSC = NotCandidateForSelection;
    251   G4double steplength = GetMscContinuousStepLimit(track,previousStepSize,
    252                                               currentMinimalStep,currentSafety);
     264  G4double steplength = GetMscContinuousStepLimit(track,
     265                                                  track.GetKineticEnergy(),
     266                                                  currentMinimalStep,
     267                                                  currentSafety);
    253268  // G4cout << "StepLimit= " << steplength << G4endl;
    254269  // set return value for G4GPILSelection
     
    315330  if( couple->IsUsed() ) nbins = nBins;
    316331  G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nbins);
     332  v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
    317333  return v;
    318334}
     
    372388               << G4endl;
    373389    }
     390    if((G4LossTableManager::Instance())->SplineFlag()) {
     391      size_t n = theLambdaTable->length();
     392      for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
     393    }
    374394  } else {
    375395    if (1 < verboseLevel) {
  • trunk/source/processes/electromagnetic/utils/src/G4ionEffectiveCharge.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4ionEffectiveCharge.cc,v 1.17.2.1 2008/04/22 15:28:13 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4ionEffectiveCharge.cc,v 1.24 2008/12/18 13:01:46 gunter Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5454#include "G4ionEffectiveCharge.hh"
    5555#include "G4UnitsTable.hh"
    56 #include "G4ParticleDefinition.hh"
    5756#include "G4Material.hh"
     57#include "G4NistManager.hh"
    5858
    5959//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    6262{
    6363  chargeCorrection = 1.0;
    64   energyHighLimit  = 10.0*MeV;
     64  energyHighLimit  = 20.0*MeV;
    6565  energyLowLimit   = 1.0*keV;
    6666  energyBohr       = 25.*keV;
    6767  massFactor       = amu_c2/(proton_mass_c2*keV);
    68   minCharge        = 0.1;
     68  minCharge        = 1.0;
     69  lastPart         = 0;
     70  lastMat          = 0;
     71  lastKinEnergy    = 0.0;
     72  effCharge        = eplus;
     73  nist = G4NistManager::Instance();
    6974}
    7075
     
    7883G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
    7984                                               const G4Material* material,
    80                                                      G4double kineticEnergy)
     85                                               G4double kineticEnergy)
    8186{
     87  if(p == lastPart && material == lastMat && kineticEnergy == lastKinEnergy)
     88    return effCharge;
     89
     90  lastPart      = p;
     91  lastMat       = material;
     92  lastKinEnergy = kineticEnergy;
     93
    8294  G4double mass   = p->GetPDGMass();
    8395  G4double charge = p->GetPDGCharge();
     
    8597
    8698  chargeCorrection = 1.0;
     99  effCharge = charge;
    87100
    88101  // The aproximation of ion effective charge from:
     
    94107  if( reducedEnergy > Zi*energyHighLimit || Zi < 1.5 || !material) return charge;
    95108
    96   static G4double c[6] = {0.2865,  0.1266, -0.001429,
    97                           0.02402,-0.01135, 0.001475} ;
    98 
    99109  G4double z    = material->GetIonisation()->GetZeffective();
    100   reducedEnergy = std::max(reducedEnergy,energyLowLimit);
    101   G4double q;
     110  //  reducedEnergy = std::max(reducedEnergy,energyLowLimit);
    102111
    103112  // Helium ion case
    104113  if( Zi < 2.5 ) {
     114
     115    static G4double c[6] = {0.2865,  0.1266, -0.001429,
     116                            0.02402,-0.01135, 0.001475} ;
    105117
    106118    G4double Q = std::max(0.0,std::log(reducedEnergy*massFactor));
     
    120132    if(tq2 < 0.2) tt *= (1.0 - tq2 + 0.5*tq2*tq2);
    121133    else          tt *= std::exp(-tq2);
    122     q = (1.0 + tt) * std::sqrt(ex);
     134
     135    effCharge = charge*(1.0 + tt) * std::sqrt(ex);
    123136
    124137    // Heavy ion case
    125138  } else {
    126139   
    127     G4double z23  = std::pow(z, 0.666666);
    128     G4double zi13 = std::pow(Zi, 0.333333);
     140    G4double y;
     141    //    = nist->GetZ13(z);
     142    //G4double z23  = y*y;
     143    G4double zi13 = nist->GetZ13(Zi);
    129144    G4double zi23 = zi13*zi13;
    130     G4double e = std::max(reducedEnergy,energyBohr/z23);
     145    //    G4double e = std::max(reducedEnergy,energyBohr/z23);
     146    //G4double e = reducedEnergy;
    131147
    132148    // v1 is ion velocity in vF unit
    133149    G4double eF   = material->GetIonisation()->GetFermiEnergy();
    134     G4double v1sq = e/eF;
     150    G4double v1sq = reducedEnergy/eF;
    135151    G4double vFsq = eF/energyBohr;
    136     G4double vF   = std::sqrt(vFsq);
    137 
    138     G4double y ;
     152    G4double vF   = std::sqrt(eF/energyBohr);
    139153
    140154    // Faster than Fermi velocity
     
    147161    }
    148162
     163    G4double q;
    149164    G4double y3 = std::pow(y, 0.3) ;
    150     //    G4cout << "y= " << y << " y3= " << y3 << " v1= " << v1 << " vF= " << vF << G4endl;
     165    // G4cout<<"y= "<<y<<" y3= "<<y3<<" v1= "<<v1<<" vF= "<<vF<<G4endl;
    151166    q = 1.0 - std::exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ;
    152 
    153     //    q = 1.0 - std::exp(-0.95*std::sqrt(reducedEnergy/energyBohr)/zi23);
     167   
     168    //y *= 0.77;
     169    //y *= (0.75 + 0.52/Zi);
     170
     171    //if( y < 0.2 ) q = y*(1.0 - 0.5*y);
     172    //else          q = 1.0 - std::exp(-y);
    154173
    155174    G4double qmin = minCharge/Zi;
    156 
    157175    if(q < qmin) q = qmin;
     176 
     177    effCharge = q*charge;
     178
     179    /*
     180    G4double x1 = 1.0*effCharge*(1.0 - 0.132*std::log(y))/(y*std::sqrt(z));
     181    G4double x2 = 0.1*effCharge*effCharge*energyBohr/reducedEnergy;
     182
     183    chargeCorrection = 1.0 + x1 - x2;
     184
     185    G4cout << "x1= "<<x1<<" x2= "<< x2<<" corr= "<<chargeCorrection<<G4endl;
     186    */
    158187   
    159188    G4double tq = 7.6 - std::log(reducedEnergy/keV);
     
    170199
    171200    G4double lambda = 10.0 * vF / (zi13 * (6.0 + q));
    172     if(q < 0.2) lambda *= (1.0 - 0.666666*q - q*q/9.0);
     201    if(q < 0.2) lambda *= (1.0 - 0.66666667*q - q*q/9.0);
    173202    else        lambda *= std::pow(1.0-q, 0.666666);
    174203
     
    180209
    181210    chargeCorrection = sq * (1.0 + xx);
     211   
    182212  }
    183213  //  G4cout << "G4ionEffectiveCharge: charge= " << charge << " q= " << q
    184214  //         << " chargeCor= " << chargeCorrection
    185215  //       << " e(MeV)= " << kineticEnergy/MeV << G4endl;
    186   return q*charge;
     216  return effCharge;
    187217}
    188218
Note: See TracChangeset for help on using the changeset viewer.