Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/utils/src/G4VEmProcess.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/utils/src/G4VEmProcess.cc (Version 11.3.0) and /processes/electromagnetic/utils/src/G4VEmProcess.cc (Version 9.2.p4)


  1 //                                             <<   1 //
  2 // ******************************************* <<   2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * License and Disclaimer                                           *
  4 // *                                           <<   4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License <<   7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.      <<   9 // * include a list of copyright holders.                             *
 10 // *                                           <<  10 // *                                                                  *
 11 // * Neither the authors of this software syst <<  11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin <<  12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran <<  13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum <<  14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio <<  16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                           <<  17 // *                                                                  *
 18 // * This  code  implementation is the result  <<  18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio <<  19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri <<  20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag <<  21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati <<  22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof <<  23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ******************************************* <<  24 // ********************************************************************
 25 //                                             <<  25 //
 26 // ------------------------------------------- <<  26 // $Id: G4VEmProcess.cc,v 1.60.2.1 2010/01/26 14:33:54 gcosmo Exp $
 27 //                                             <<  27 // GEANT4 tag $Name: geant4-09-02-patch-04 $
 28 // GEANT4 Class file                           <<  28 //
 29 //                                             <<  29 // -------------------------------------------------------------------
 30 //                                             <<  30 //
 31 // File name:     G4VEmProcess                 <<  31 // GEANT4 Class file
 32 //                                             <<  32 //
 33 // Author:        Vladimir Ivanchenko on base  <<  33 //
 34 //                                             <<  34 // File name:     G4VEmProcess
 35 // Creation date: 01.10.2003                   <<  35 //
 36 //                                             <<  36 // Author:        Vladimir Ivanchenko on base of Laszlo Urban code
 37 // Modifications: by V.Ivanchenko              <<  37 //
 38 //                                             <<  38 // Creation date: 01.10.2003
 39 // Class Description: based class for discrete <<  39 //
 40 //                                             <<  40 // Modifications:
 41                                                <<  41 // 30-06-04 make it to be pure discrete process (V.Ivanchenko)
 42 // ------------------------------------------- <<  42 // 30-09-08 optimise integral option (V.Ivanchenko)
 43 //                                             <<  43 // 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivanchenko)
 44 //....oooOO0OOooo........oooOO0OOooo........oo <<  44 // 11-03-05 Shift verbose level by 1, add applyCuts and killPrimary flags (VI)
 45 //....oooOO0OOooo........oooOO0OOooo........oo <<  45 // 14-03-05 Update logic PostStepDoIt (V.Ivanchenko)
 46                                                <<  46 // 08-04-05 Major optimisation of internal interfaces (V.Ivanchenko)
 47 #include "G4VEmProcess.hh"                     <<  47 // 18-04-05 Use G4ParticleChangeForGamma (V.Ivanchenko)
 48 #include "G4PhysicalConstants.hh"              <<  48 // 25-07-05 Add protection: integral mode only for charged particles (VI)
 49 #include "G4SystemOfUnits.hh"                  <<  49 // 04-09-05 default lambdaFactor 0.8 (V.Ivanchenko)
 50 #include "G4ProcessManager.hh"                 <<  50 // 11-01-06 add A to parameters of ComputeCrossSectionPerAtom (VI)
 51 #include "G4LossTableManager.hh"               <<  51 // 12-09-06 add SetModel() (mma)
 52 #include "G4LossTableBuilder.hh"               <<  52 // 12-04-07 remove double call to Clear model manager (V.Ivanchenko)
 53 #include "G4Step.hh"                           <<  53 // 27-10-07 Virtual functions moved to source (V.Ivanchenko)
 54 #include "G4ParticleDefinition.hh"             <<  54 //
 55 #include "G4VEmModel.hh"                       <<  55 // Class Description:
 56 #include "G4DataVector.hh"                     <<  56 //
 57 #include "G4PhysicsTable.hh"                   <<  57 
 58 #include "G4EmDataHandler.hh"                  <<  58 // -------------------------------------------------------------------
 59 #include "G4PhysicsLogVector.hh"               <<  59 //
 60 #include "G4VParticleChange.hh"                <<  60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 61 #include "G4ProductionCutsTable.hh"            <<  61 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 62 #include "G4Region.hh"                         <<  62 
 63 #include "G4Gamma.hh"                          <<  63 #include "G4VEmProcess.hh"
 64 #include "G4Electron.hh"                       <<  64 #include "G4LossTableManager.hh"
 65 #include "G4Positron.hh"                       <<  65 #include "G4Step.hh"
 66 #include "G4PhysicsTableHelper.hh"             <<  66 #include "G4ParticleDefinition.hh"
 67 #include "G4EmBiasingManager.hh"               <<  67 #include "G4VEmModel.hh"
 68 #include "G4EmParameters.hh"                   <<  68 #include "G4DataVector.hh"
 69 #include "G4EmProcessSubType.hh"               <<  69 #include "G4PhysicsTable.hh"
 70 #include "G4EmTableUtil.hh"                    <<  70 #include "G4PhysicsVector.hh"
 71 #include "G4EmUtility.hh"                      <<  71 #include "G4PhysicsLogVector.hh"
 72 #include "G4DNAModelSubType.hh"                <<  72 #include "G4VParticleChange.hh"
 73 #include "G4GenericIon.hh"                     <<  73 #include "G4ProductionCutsTable.hh"
 74 #include "G4Log.hh"                            <<  74 #include "G4Region.hh"
 75 #include <iostream>                            <<  75 #include "G4RegionStore.hh"
 76                                                <<  76 #include "G4Gamma.hh"
 77 //....oooOO0OOooo........oooOO0OOooo........oo <<  77 #include "G4Electron.hh"
 78                                                <<  78 #include "G4Positron.hh"
 79 G4VEmProcess::G4VEmProcess(const G4String& nam <<  79 #include "G4PhysicsTableHelper.hh"
 80   G4VDiscreteProcess(name, type)               <<  80 
 81 {                                              <<  81 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 82   theParameters = G4EmParameters::Instance();  <<  82 
 83   SetVerboseLevel(1);                          <<  83 G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
 84                                                <<  84   G4VDiscreteProcess(name, type),
 85   // Size of tables                            <<  85   secondaryParticle(0),
 86   minKinEnergy = 0.1*CLHEP::keV;               <<  86   buildLambdaTable(true),
 87   maxKinEnergy = 100.0*CLHEP::TeV;             <<  87   theLambdaTable(0),
 88                                                <<  88   theEnergyOfCrossSectionMax(0),
 89   // default lambda factor                     <<  89   theCrossSectionMax(0),
 90   invLambdaFactor = 1.0/lambdaFactor;          <<  90   integral(false),
 91                                                <<  91   applyCuts(false),
 92   // particle types                            <<  92   startFromNull(true),
 93   theGamma = G4Gamma::Gamma();                 <<  93   nRegions(0),
 94   theElectron = G4Electron::Electron();        <<  94   selectedModel(0),
 95   thePositron = G4Positron::Positron();        <<  95   particle(0),
 96                                                <<  96   currentCouple(0)
 97   pParticleChange = &fParticleChange;          <<  97 {
 98   fParticleChange.SetSecondaryWeightByProcess( <<  98   SetVerboseLevel(1);
 99   secParticles.reserve(5);                     <<  99 
100                                                << 100   // Size of tables assuming spline
101   modelManager = new G4EmModelManager();       << 101   minKinEnergy = 0.1*keV;
102   lManager = G4LossTableManager::Instance();   << 102   maxKinEnergy = 100.0*TeV;
103   lManager->Register(this);                    << 103   nLambdaBins  = 84;
104   isTheMaster = lManager->IsMaster();          << 104 
105   G4LossTableBuilder* bld = lManager->GetTable << 105   // default lambda factor
106   theDensityFactor = bld->GetDensityFactors(); << 106   lambdaFactor  = 0.8;
107   theDensityIdx = bld->GetCoupleIndexes();     << 107 
108 }                                              << 108   // default limit on polar angle
109                                                << 109   polarAngleLimit = 0.0;
110 //....oooOO0OOooo........oooOO0OOooo........oo << 110 
111                                                << 111   // particle types
112 G4VEmProcess::~G4VEmProcess()                  << 112   theGamma     = G4Gamma::Gamma();
113 {                                              << 113   theElectron  = G4Electron::Electron();
114   if(isTheMaster) {                            << 114   thePositron  = G4Positron::Positron();
115     delete theData;                            << 115 
116     delete theEnergyOfCrossSectionMax;         << 116   pParticleChange = &fParticleChange;
117   }                                            << 117   secParticles.reserve(5);
118   delete modelManager;                         << 118 
119   delete biasManager;                          << 119   modelManager = new G4EmModelManager();
120   lManager->DeRegister(this);                  << 120   (G4LossTableManager::Instance())->Register(this);
121 }                                              << 121 }
122                                                << 122 
123 //....oooOO0OOooo........oooOO0OOooo........oo << 123 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
124                                                << 124 
125 void G4VEmProcess::AddEmModel(G4int order, G4V << 125 G4VEmProcess::~G4VEmProcess()
126                               const G4Region*  << 126 {
127 {                                              << 127   if(1 < verboseLevel) 
128   if(nullptr == ptr) { return; }               << 128     G4cout << "G4VEmProcess destruct " << GetProcessName() 
129   G4VEmFluctuationModel* fm = nullptr;         << 129      << G4endl;
130   modelManager->AddEmModel(order, ptr, fm, reg << 130   Clear();
131   ptr->SetParticleChange(pParticleChange);     << 131   if(theLambdaTable) {
132 }                                              << 132     theLambdaTable->clearAndDestroy();
133                                                << 133     delete theLambdaTable;
134 //....oooOO0OOooo........oooOO0OOooo........oo << 134   }
135                                                << 135   delete modelManager;
136 void G4VEmProcess::SetEmModel(G4VEmModel* ptr, << 136   (G4LossTableManager::Instance())->DeRegister(this);
137 {                                              << 137 }
138   if(nullptr == ptr) { return; }               << 138 
139   if(!emModels.empty()) {                      << 139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
140     for(auto & em : emModels) { if(em == ptr)  << 140 
141   }                                            << 141 void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
142   emModels.push_back(ptr);                     << 142 {
143 }                                              << 143   if(!particle) particle = &part;
144                                                << 144   if(1 < verboseLevel) {
145 //....oooOO0OOooo........oooOO0OOooo........oo << 145     G4cout << "G4VEmProcess::PreparePhysicsTable() for "
146                                                << 146            << GetProcessName()
147 void G4VEmProcess::PreparePhysicsTable(const G << 147            << " and particle " << part.GetParticleName()
148 {                                              << 148      << " local particle " << particle->GetParticleName() 
149   if(nullptr == particle) { SetParticle(&part) << 149            << G4endl;
150                                                << 150   }
151   if(part.GetParticleType() == "nucleus" &&    << 151 
152      part.GetParticleSubType() == "generic") { << 152   if(particle == &part) {
153                                                << 153     Clear();
154     G4String pname = part.GetParticleName();   << 154     InitialiseProcess(particle);
155     if(pname != "deuteron" && pname != "triton << 155     theCuts = modelManager->Initialise(particle,secondaryParticle,2.,verboseLevel);
156        pname != "He3" && pname != "alpha" && p << 156     const G4ProductionCutsTable* theCoupleTable=
157        pname != "helium" && pname != "hydrogen << 157           G4ProductionCutsTable::GetProductionCutsTable();
158                                                << 158     theCutsGamma    = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
159       particle = G4GenericIon::GenericIon();   << 159     theCutsElectron = theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut);
160       isIon = true;                            << 160     theCutsPositron = theCoupleTable->GetEnergyCutsVector(idxG4PositronCut);
161     }                                          << 161     if(buildLambdaTable)
162   }                                            << 162       theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
163   if(particle != &part) { return; }            << 163   }
164                                                << 164 }
165   lManager->PreparePhysicsTable(&part, this);  << 165 
166                                                << 166 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
167   // for new run                               << 167 
168   currentCouple = nullptr;                     << 168 void G4VEmProcess::Clear()
169   preStepLambda = 0.0;                         << 169 {
170   fLambdaEnergy = 0.0;                         << 170   if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
171                                                << 171   if(theCrossSectionMax) delete [] theCrossSectionMax;
172   InitialiseProcess(particle);                 << 172   theEnergyOfCrossSectionMax = 0;
173                                                << 173   theCrossSectionMax = 0;
174   G4LossTableBuilder* bld = lManager->GetTable << 174   currentCouple = 0;
175   const G4ProductionCutsTable* theCoupleTable= << 175   preStepLambda = 0.0;
176     G4ProductionCutsTable::GetProductionCutsTa << 176   mfpKinEnergy  = DBL_MAX;
177   theCutsGamma    = theCoupleTable->GetEnergyC << 177 }
178   theCutsElectron = theCoupleTable->GetEnergyC << 178 
179   theCutsPositron = theCoupleTable->GetEnergyC << 179 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
180                                                << 180 
181   // initialisation of the process             << 181 void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
182   if(!actMinKinEnergy) { minKinEnergy = thePar << 182 {
183   if(!actMaxKinEnergy) { maxKinEnergy = thePar << 183   if(1 < verboseLevel) {
184                                                << 184     G4cout << "G4VEmProcess::BuildPhysicsTable() for "
185   applyCuts       = theParameters->ApplyCuts() << 185            << GetProcessName()
186   lambdaFactor    = theParameters->LambdaFacto << 186            << " and particle " << part.GetParticleName()
187   invLambdaFactor = 1.0/lambdaFactor;          << 187      << " buildLambdaTable= " << buildLambdaTable
188   theParameters->DefineRegParamForEM(this);    << 188            << G4endl;
189                                                << 189   }
190   // integral option may be disabled           << 190 
191   if(!theParameters->Integral()) { fXSType = f << 191   if(buildLambdaTable) {
192                                                << 192     BuildLambdaTable();
193   // prepare tables                            << 193     FindLambdaMax();
194   if(isTheMaster) {                            << 194   }
195     if(nullptr == theData) { theData = new G4E << 195   if(0 < verboseLevel) PrintInfoDefinition();
196                                                << 196 
197     if(buildLambdaTable) {                     << 197   if(1 < verboseLevel) {
198       theLambdaTable = theData->MakeTable(0);  << 198     G4cout << "G4VEmProcess::BuildPhysicsTable() done for "
199       bld->InitialiseBaseMaterials(theLambdaTa << 199            << GetProcessName()
200     }                                          << 200            << " and particle " << part.GetParticleName()
201     // high energy table                       << 201            << G4endl;
202     if(minKinEnergyPrim < maxKinEnergy) {      << 202   }
203       theLambdaTablePrim = theData->MakeTable( << 203 }
204       bld->InitialiseBaseMaterials(theLambdaTa << 204 
205     }                                          << 205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
206   }                                            << 206 
207   // models                                    << 207 void G4VEmProcess::BuildLambdaTable()
208   baseMat = bld->GetBaseMaterialFlag();        << 208 {
209   numberOfModels = modelManager->NumberOfModel << 209   if(1 < verboseLevel) {
210   currentModel = modelManager->GetModel(0);    << 210     G4cout << "G4EmProcess::BuildLambdaTable() for process "
211   if(nullptr != lManager->AtomDeexcitation())  << 211            << GetProcessName() << " and particle "
212     modelManager->SetFluoFlag(true);           << 212            << particle->GetParticleName()
213   }                                            << 213            << G4endl;
214   // forced biasing                            << 214   }
215   if(nullptr != biasManager) {                 << 215 
216     biasManager->Initialise(part, GetProcessNa << 216   // Access to materials
217     biasFlag = false;                          << 217   const G4ProductionCutsTable* theCoupleTable=
218   }                                            << 218         G4ProductionCutsTable::GetProductionCutsTable();
219                                                << 219   size_t numOfCouples = theCoupleTable->GetTableSize();
220   theCuts =                                    << 220   for(size_t i=0; i<numOfCouples; i++) {
221     G4EmTableUtil::PrepareEmProcess(this, part << 221 
222                                     modelManag << 222     if (theLambdaTable->GetFlag(i)) {
223                                     secID, tri << 223 
224                                     verboseLev << 224       // create physics vector and fill it
225 }                                              << 225       const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
226                                                << 226       G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
227 //....oooOO0OOooo........oooOO0OOooo........oo << 227       modelManager->FillLambdaVector(aVector, couple, startFromNull);
228                                                << 228       G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
229 void G4VEmProcess::BuildPhysicsTable(const G4P << 229     }
230 {                                              << 230   }
231   if(nullptr == masterProc) {                  << 231 
232     if(isTheMaster) { masterProc = this; }     << 232   if(1 < verboseLevel) {
233     else { masterProc = static_cast<const G4VE << 233     G4cout << "Lambda table is built for "
234   }                                            << 234            << particle->GetParticleName()
235   G4int nModels = modelManager->NumberOfModels << 235            << G4endl;
236   G4bool isLocked = theParameters->IsPrintLock << 236     if(2 < verboseLevel) {
237   G4bool toBuild = (buildLambdaTable || minKin << 237       G4cout << *theLambdaTable << G4endl;
238                                                << 238     }
239   G4EmTableUtil::BuildEmProcess(this, masterPr << 239   }
240                                 nModels, verbo << 240 }
241                                 isLocked, toBu << 241 
242 }                                              << 242 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
243                                                << 243 
244 //....oooOO0OOooo........oooOO0OOooo........oo << 244 G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
245                                                << 245                              const G4Track& track,
246 void G4VEmProcess::BuildLambdaTable()          << 246                              G4double   previousStepSize,
247 {                                              << 247                              G4ForceCondition* condition)
248   G4double scale = theParameters->MaxKinEnergy << 248 {
249   G4int nbin =                                 << 249   // condition is set to "Not Forced"
250     theParameters->NumberOfBinsPerDecade()*G4l << 250   *condition = NotForced;
251   if(actBinning) { nbin = std::max(nbin, nLamb << 251   G4double x = DBL_MAX;
252   scale = nbin/G4Log(scale);                   << 252   if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0;
253                                                << 253   InitialiseStep(track);
254   G4LossTableBuilder* bld = lManager->GetTable << 254 
255   G4EmTableUtil::BuildLambdaTable(this, partic << 255   if(preStepKinEnergy < mfpKinEnergy) {
256                                   bld, theLamb << 256     if (integral) ComputeIntegralLambda(preStepKinEnergy);
257                                   minKinEnergy << 257     else  preStepLambda = GetCurrentLambda(preStepKinEnergy);
258                                   maxKinEnergy << 258     if(preStepLambda <= DBL_MIN) mfpKinEnergy = 0.0;
259                                   startFromNul << 259   }
260 }                                              << 260 
261                                                << 261   // non-zero cross section
262 //....oooOO0OOooo........oooOO0OOooo........oo << 262   if(preStepLambda > DBL_MIN) { 
263                                                << 263     if (theNumberOfInteractionLengthLeft < 0.0) {
264 void G4VEmProcess::StreamInfo(std::ostream& ou << 264       // beggining of tracking (or just after DoIt of this process)
265                   const G4ParticleDefinition&  << 265       ResetNumberOfInteractionLengthLeft();
266 {                                              << 266     } else if(currentInteractionLength < DBL_MAX) {
267   G4String indent = (rst ? "  " : "");         << 267       // subtract NumberOfInteractionLengthLeft
268   out << std::setprecision(6);                 << 268       SubtractNumberOfInteractionLengthLeft(previousStepSize);
269   out << G4endl << indent << GetProcessName()  << 269       if(theNumberOfInteractionLengthLeft < 0.)
270   if (!rst) {                                  << 270   theNumberOfInteractionLengthLeft = perMillion;
271     out << " for " << part.GetParticleName();  << 271     }
272   }                                            << 272 
273   if(fXSType != fEmNoIntegral)  { out << " XSt << 273     // get mean free path and step limit
274   if(applyCuts) { out << " applyCuts:1 "; }    << 274     currentInteractionLength = 1.0/preStepLambda;
275   G4int subtype = GetProcessSubType();         << 275     x = theNumberOfInteractionLengthLeft * currentInteractionLength;
276   out << " SubType=" << subtype;               << 276 #ifdef G4VERBOSE
277   if (subtype == fAnnihilation) {              << 277     if (verboseLevel>2){
278     G4int mod = theParameters->PositronAtRestM << 278       G4cout << "G4VEmProcess::PostStepGetPhysicalInteractionLength ";
279     const G4String namp[2] = {"Simple", "Allis << 279       G4cout << "[ " << GetProcessName() << "]" << G4endl; 
280     out << " AtRestModel:" << namp[mod];       << 280       G4cout << " for " << particle->GetParticleName() 
281   }                                            << 281        << " in Material  " <<  currentMaterial->GetName()
282   if(biasFactor != 1.0) { out << "  BiasingFac << 282        << " Ekin(MeV)= " << preStepKinEnergy/MeV 
283   out << " BuildTable=" << buildLambdaTable << << 283        <<G4endl;
284   if(buildLambdaTable) {                       << 284       G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]" 
285     if(particle == &part) {                    << 285        << "InteractionLength= " << x/cm <<"[cm] " <<G4endl;
286       for(auto & v : *theLambdaTable) {        << 286     }
287         if(nullptr != v) {                     << 287 #endif
288           out << "      Lambda table from ";   << 288 
289           G4double emin = v->Energy(0);        << 289     // zero cross section case
290           G4double emax = v->GetMaxEnergy();   << 290   } else {
291           G4int nbin = G4int(v->GetVectorLengt << 291     if(theNumberOfInteractionLengthLeft > DBL_MIN && 
292           if(emin > minKinEnergy) { out << "th << 292        currentInteractionLength < DBL_MAX) {
293           else { out << G4BestUnit(emin,"Energ << 293 
294           out << " to "                        << 294       // subtract NumberOfInteractionLengthLeft
295               << G4BestUnit(emax,"Energy")     << 295       SubtractNumberOfInteractionLengthLeft(previousStepSize);
296               << ", " << G4lrint(nbin/std::log << 296       if(theNumberOfInteractionLengthLeft < 0.)
297               << " bins/decade, spline: "      << 297   theNumberOfInteractionLengthLeft = perMillion;
298               << splineFlag << G4endl;         << 298     }
299           break;                               << 299     currentInteractionLength = DBL_MAX;
300         }                                      << 300   }
301       }                                        << 301   return x;
302     } else {                                   << 302 }
303       out << "      Used Lambda table of "     << 303 
304       << particle->GetParticleName() << G4endl << 304 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
305     }                                          << 305 
306   }                                            << 306 G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
307   if(minKinEnergyPrim < maxKinEnergy) {        << 307                G4double,
308     if(particle == &part) {                    << 308                G4ForceCondition* condition)
309       for(auto & v : *theLambdaTablePrim) {    << 309 {
310         if(nullptr != v) {                     << 310   *condition = NotForced;
311           out << "      LambdaPrime table from << 311   return G4VEmProcess::MeanFreePath(track);
312               << G4BestUnit(v->Energy(0),"Ener << 312 }
313               << " to "                        << 313 
314               << G4BestUnit(v->GetMaxEnergy(), << 314 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
315               << " in " << v->GetVectorLength( << 315 
316               << " bins " << G4endl;           << 316 G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
317           break;                               << 317                                               const G4Step&)
318         }                                      << 318 {
319       }                                        << 319   fParticleChange.InitializeForPostStep(track);
320     } else {                                   << 320 
321       out << "      Used LambdaPrime table of  << 321   // Do not make anything if particle is stopped, the annihilation then
322                << particle->GetParticleName()  << 322   // should be performed by the AtRestDoIt!
323     }                                          << 323   if (track.GetTrackStatus() == fStopButAlive) return &fParticleChange;
324   }                                            << 324 
325   StreamProcessInfo(out);                      << 325   G4double finalT = track.GetKineticEnergy();
326   modelManager->DumpModelList(out, verboseLeve << 326 
327                                                << 327   // Integral approach
328   if(verboseLevel > 2 && buildLambdaTable) {   << 328   if (integral) {
329     out << "      LambdaTable address= " << th << 329     G4double lx = GetLambda(finalT, currentCouple);
330     if(theLambdaTable && particle == &part) {  << 330     if(preStepLambda<lx && 1 < verboseLevel) {
331       out << (*theLambdaTable) << G4endl;      << 331       G4cout << "WARING: for " << particle->GetParticleName() 
332     }                                          << 332              << " and " << GetProcessName()
333   }                                            << 333              << " E(MeV)= " << finalT/MeV
334 }                                              << 334              << " preLambda= " << preStepLambda << " < " << lx << " (postLambda) "
335                                                << 335        << G4endl;  
336 //....oooOO0OOooo........oooOO0OOooo........oo << 336     }
337                                                << 337 
338 void G4VEmProcess::StartTracking(G4Track* trac << 338     if(preStepLambda*G4UniformRand() > lx) {
339 {                                              << 339       ClearNumberOfInteractionLengthLeft();
340   // reset parameters for the new track        << 340       return &fParticleChange;
341   currentParticle = track->GetParticleDefiniti << 341     }
342   theNumberOfInteractionLengthLeft = -1.0;     << 342   }
343   mfpKinEnergy = DBL_MAX;                      << 343 
344   preStepLambda = 0.0;                         << 344   G4VEmModel* currentModel = SelectModel(finalT);
345                                                << 345 
346   if(isIon) { massRatio = proton_mass_c2/curre << 346   /*  
347                                                << 347   if(0 < verboseLevel) {
348   // forced biasing only for primary particles << 348     G4cout << "G4VEmProcess::PostStepDoIt: Sample secondary; E= "
349   if(biasManager) {                            << 349            << finalT/MeV
350     if(0 == track->GetParentID()) {            << 350            << " MeV; model= (" << currentModel->LowEnergyLimit()
351       // primary particle                      << 351            << ", " <<  currentModel->HighEnergyLimit() << ")"
352       biasFlag = true;                         << 352            << G4endl;
353       biasManager->ResetForcedInteraction();   << 353   }
354     }                                          << 354   */
355   }                                            << 355 
356 }                                              << 356   
357                                                << 357   // sample secondaries
358 //....oooOO0OOooo........oooOO0OOooo........oo << 358   secParticles.clear();
359                                                << 359   currentModel->SampleSecondaries(&secParticles, 
360 G4double G4VEmProcess::PostStepGetPhysicalInte << 360           currentCouple, 
361                              const G4Track& tr << 361           track.GetDynamicParticle(),
362                              G4double   previo << 362           (*theCuts)[currentMaterialIndex]);
363                              G4ForceCondition* << 363 
364 {                                              << 364   // save secondaries
365   *condition = NotForced;                      << 365   G4int num = secParticles.size();
366   G4double x = DBL_MAX;                        << 366   if(num > 0) {
367                                                << 367 
368   DefineMaterial(track.GetMaterialCutsCouple() << 368     fParticleChange.SetNumberOfSecondaries(num);
369   preStepKinEnergy = track.GetKineticEnergy(); << 369     G4double edep = fParticleChange.GetLocalEnergyDeposit();
370   const G4double scaledEnergy = preStepKinEner << 370      
371   SelectModel(scaledEnergy, currentCoupleIndex << 371     for (G4int i=0; i<num; i++) {
372   /*                                           << 372       G4DynamicParticle* dp = secParticles[i];
373   G4cout << "PostStepGetPhysicalInteractionLen << 373       const G4ParticleDefinition* p = dp->GetDefinition();
374          << "  couple: " << currentCouple << G << 374       G4double e = dp->GetKineticEnergy();
375   */                                           << 375       G4bool good = true;
376   if(!currentModel->IsActive(scaledEnergy)) {  << 376       if(applyCuts) {
377     theNumberOfInteractionLengthLeft = -1.0;   << 377   if (p == theGamma) {
378     currentInteractionLength = DBL_MAX;        << 378     if (e < (*theCutsGamma)[currentMaterialIndex]) good = false;
379     mfpKinEnergy = DBL_MAX;                    << 379 
380     preStepLambda = 0.0;                       << 380   } else if (p == theElectron) {
381     return x;                                  << 381     if (e < (*theCutsElectron)[currentMaterialIndex]) good = false;
382   }                                            << 382 
383                                                << 383   } else if (p == thePositron) {
384   // forced biasing only for primary particles << 384     if (electron_mass_c2 < (*theCutsGamma)[currentMaterialIndex] &&
385   if(biasManager) {                            << 385         e < (*theCutsPositron)[currentMaterialIndex]) {
386     if(0 == track.GetParentID()) {             << 386       good = false;
387       if(biasFlag &&                           << 387       e += 2.0*electron_mass_c2;
388          biasManager->ForcedInteractionRegion( << 388     }
389         return biasManager->GetStepLimit((G4in << 389   }
390       }                                        << 390         if(!good) {
391     }                                          << 391     delete dp;
392   }                                            << 392     edep += e;
393                                                << 393   }
394   // compute mean free path                    << 394       }
395                                                << 395       if (good) fParticleChange.AddSecondary(dp);
396   ComputeIntegralLambda(preStepKinEnergy, trac << 396     } 
397                                                << 397     fParticleChange.ProposeLocalEnergyDeposit(edep);
398   // zero cross section                        << 398   }
399   if(preStepLambda <= 0.0) {                   << 399 
400     theNumberOfInteractionLengthLeft = -1.0;   << 400   ClearNumberOfInteractionLengthLeft();
401     currentInteractionLength = DBL_MAX;        << 401   return &fParticleChange;
402                                                << 402 }
403   } else {                                     << 403 
404                                                << 404 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
405     // non-zero cross section                  << 405 
406     if (theNumberOfInteractionLengthLeft < 0.0 << 406 void G4VEmProcess::PrintInfoDefinition()
407                                                << 407 {
408       // beggining of tracking (or just after  << 408   if(verboseLevel > 0) {
409       theNumberOfInteractionLengthLeft = -G4Lo << 409     G4cout << G4endl << GetProcessName() << ":   for  "
410       theInitialNumberOfInteractionLength = th << 410            << particle->GetParticleName();
411                                                << 411     if(integral) G4cout << ", integral: 1 ";
412     } else {                                   << 412     if(applyCuts) G4cout << ", applyCuts: 1 ";
413                                                << 413     G4cout << "    SubType= " << GetProcessSubType() << G4endl;
414       theNumberOfInteractionLengthLeft -=      << 414     if(buildLambdaTable) {
415         previousStepSize/currentInteractionLen << 415       G4cout << "      Lambda tables from "
416       theNumberOfInteractionLengthLeft =       << 416        << G4BestUnit(minKinEnergy,"Energy") 
417         std::max(theNumberOfInteractionLengthL << 417        << " to "
418     }                                          << 418        << G4BestUnit(maxKinEnergy,"Energy")
419                                                << 419        << " in " << nLambdaBins << " bins, spline: " 
420     // new mean free path and step limit for t << 420        << (G4LossTableManager::Instance())->SplineFlag()
421     currentInteractionLength = 1.0/preStepLamb << 421        << G4endl;
422     x = theNumberOfInteractionLengthLeft * cur << 422     }
423   }                                            << 423     PrintInfo();
424   return x;                                    << 424     modelManager->DumpModelList(verboseLevel);
425 }                                              << 425   }
426                                                << 426 
427 //....oooOO0OOooo........oooOO0OOooo........oo << 427   if(verboseLevel > 2 && buildLambdaTable) {
428                                                << 428     G4cout << "      LambdaTable address= " << theLambdaTable << G4endl;
429 void G4VEmProcess::ComputeIntegralLambda(G4dou << 429     if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
430 {                                              << 430   }
431   if (fXSType == fEmNoIntegral) {              << 431 }
432     preStepLambda = GetCurrentLambda(e, LogEki << 432 
433                                                << 433 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
434   } else if (fXSType == fEmIncreasing) {       << 434 
435     if(e*invLambdaFactor < mfpKinEnergy) {     << 435 G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
436       preStepLambda = GetCurrentLambda(e, LogE << 436                const G4MaterialCutsCouple* couple)
437       mfpKinEnergy = (preStepLambda > 0.0) ? e << 437 {
438     }                                          << 438   // Cross section per atom is calculated
439                                                << 439   DefineMaterial(couple);
440   } else if(fXSType == fEmDecreasing) {        << 440   G4double cross = 0.0;
441     if(e < mfpKinEnergy) {                     << 441   G4bool b;
442       const G4double e1 = e*lambdaFactor;      << 442   if(theLambdaTable) {
443       preStepLambda = GetCurrentLambda(e1);    << 443     cross = (((*theLambdaTable)[currentMaterialIndex])->
444       mfpKinEnergy = e1;                       << 444                            GetValue(kineticEnergy, b));
445     }                                          << 445   } else {
446                                                << 446     G4VEmModel* model = SelectModel(kineticEnergy);
447   } else if(fXSType == fEmOnePeak) {           << 447     cross = 
448     const G4double epeak = (*theEnergyOfCrossS << 448       model->CrossSectionPerVolume(currentMaterial,particle,kineticEnergy);
449     if(e <= epeak) {                           << 449   }
450       if(e*invLambdaFactor < mfpKinEnergy) {   << 450   if(cross < 0.0) { cross = 0.0; }
451         preStepLambda = GetCurrentLambda(e, Lo << 451 
452         mfpKinEnergy = (preStepLambda > 0.0) ? << 452   return cross;
453       }                                        << 453 }
454     } else if(e < mfpKinEnergy) {              << 454 
455       const G4double e1 = std::max(epeak, e*la << 455 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
456       preStepLambda = GetCurrentLambda(e1);    << 456 
457       mfpKinEnergy = e1;                       << 457 G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
458     }                                          << 458                const G4String& directory,
459   } else {                                     << 459                      G4bool ascii)
460     preStepLambda = GetCurrentLambda(e, LogEki << 460 {
461   }                                            << 461   G4bool yes = true;
462 }                                              << 462 
463                                                << 463   if ( theLambdaTable && part == particle) {
464 //....oooOO0OOooo........oooOO0OOooo........oo << 464     const G4String name = 
465                                                << 465       GetPhysicsTableFileName(part,directory,"Lambda",ascii);
466 G4VParticleChange* G4VEmProcess::PostStepDoIt( << 466     yes = theLambdaTable->StorePhysicsTable(name,ascii);
467                                                << 467 
468 {                                              << 468     if ( yes ) {
469   // clear number of interaction lengths in an << 469       G4cout << "Physics tables are stored for " << particle->GetParticleName()
470   theNumberOfInteractionLengthLeft = -1.0;     << 470              << " and process " << GetProcessName()
471   mfpKinEnergy = DBL_MAX;                      << 471        << " in the directory <" << directory
472                                                << 472        << "> " << G4endl;
473   fParticleChange.InitializeForPostStep(track) << 473     } else {
474                                                << 474       G4cout << "Fail to store Physics Tables for " 
475   // Do not make anything if particle is stopp << 475        << particle->GetParticleName()
476   // should be performed by the AtRestDoIt!    << 476              << " and process " << GetProcessName()
477   if (track.GetTrackStatus() == fStopButAlive) << 477        << " in the directory <" << directory
478                                                << 478        << "> " << G4endl;
479   const G4double finalT = track.GetKineticEner << 479     }
480                                                << 480   }
481   // forced process - should happen only once  << 481   return yes;
482   if(biasFlag) {                               << 482 }
483     if(biasManager->ForcedInteractionRegion((G << 483 
484       biasFlag = false;                        << 484 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
485     }                                          << 485 
486   }                                            << 486 G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
487                                                << 487                     const G4String& directory,
488   // check active and select model             << 488                           G4bool ascii)
489   const G4double scaledEnergy = finalT*massRat << 489 {
490   SelectModel(scaledEnergy, currentCoupleIndex << 490   if(1 < verboseLevel) {
491   if(!currentModel->IsActive(scaledEnergy)) {  << 491     G4cout << "G4VEmProcess::RetrievePhysicsTable() for "
492                                                << 492            << part->GetParticleName() << " and process "
493   // Integral approach                         << 493      << GetProcessName() << G4endl;
494   if (fXSType != fEmNoIntegral) {              << 494   }
495     const G4double logFinalT =                 << 495   G4bool yes = true;
496       track.GetDynamicParticle()->GetLogKineti << 496 
497     const G4double lx = std::max(GetCurrentLam << 497   if(!buildLambdaTable || particle != part) return yes;
498 #ifdef G4VERBOSE                               << 498 
499     if(preStepLambda < lx && 1 < verboseLevel) << 499   const G4String particleName = part->GetParticleName();
500       G4cout << "WARNING: for " << currentPart << 500   G4String filename;
501              << " and " << GetProcessName() << << 501 
502              << " preLambda= " << preStepLambd << 502   filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
503              << " < " << lx << " (postLambda)  << 503   yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTable,
504     }                                          << 504                filename,ascii);
505 #endif                                         << 505   if ( yes ) {
506     // if false interaction then use new cross << 506     if (0 < verboseLevel) {
507     // if both values are zero - no interactio << 507       G4cout << "Lambda table for " << particleName << " is Retrieved from <"
508     if(preStepLambda*G4UniformRand() >= lx) {  << 508              << filename << ">"
509       return &fParticleChange;                 << 509              << G4endl;
510     }                                          << 510     }
511   }                                            << 511     if((G4LossTableManager::Instance())->SplineFlag()) {
512                                                << 512       size_t n = theLambdaTable->length();
513   // define new weight for primary and seconda << 513       for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
514   G4double weight = fParticleChange.GetParentW << 514     }
515   if(weightFlag) {                             << 515   } else {
516     weight /= biasFactor;                      << 516     if (1 < verboseLevel) {
517     fParticleChange.ProposeWeight(weight);     << 517       G4cout << "Lambda table for " << particleName << " in file <"
518   }                                            << 518              << filename << "> is not exist"
519                                                << 519              << G4endl;
520 #ifdef G4VERBOSE                               << 520     }
521   if(1 < verboseLevel) {                       << 521   }
522     G4cout << "G4VEmProcess::PostStepDoIt: Sam << 522 
523            << finalT/MeV                       << 523   return yes;
524            << " MeV; model= (" << currentModel << 524 }
525            << ", " <<  currentModel->HighEnerg << 525 
526            << G4endl;                          << 526 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
527   }                                            << 527 
528 #endif                                         << 528 void G4VEmProcess::FindLambdaMax()
529                                                << 529 {
530   // sample secondaries                        << 530   if(1 < verboseLevel) {
531   secParticles.clear();                        << 531     G4cout << "### G4VEmProcess::FindLambdaMax: " 
532   currentModel->SampleSecondaries(&secParticle << 532      << particle->GetParticleName() 
533                                   currentCoupl << 533            << " and process " << GetProcessName() << G4endl; 
534                                   track.GetDyn << 534   }
535                                   (*theCuts)[c << 535   size_t n = theLambdaTable->length();
536                                                << 536   G4PhysicsVector* pv = (*theLambdaTable)[0];
537   G4int num0 = (G4int)secParticles.size();     << 537   G4double e, s, emax, smax;
538                                                << 538   theEnergyOfCrossSectionMax = new G4double [n];
539   // splitting or Russian roulette             << 539   theCrossSectionMax = new G4double [n];
540   if(biasManager) {                            << 540   G4bool b;
541     if(biasManager->SecondaryBiasingRegion((G4 << 541 
542       G4double eloss = 0.0;                    << 542   for (size_t i=0; i<n; i++) {
543       weight *= biasManager->ApplySecondaryBia << 543     pv = (*theLambdaTable)[i];
544         secParticles, track, currentModel, &fP << 544     emax = DBL_MAX;
545         (G4int)currentCoupleIndex, (*theCuts)[ << 545     smax = 0.0;
546         step.GetPostStepPoint()->GetSafety()); << 546     if(pv) {
547       if(eloss > 0.0) {                        << 547       size_t nb = pv->GetVectorLength();
548         eloss += fParticleChange.GetLocalEnerg << 548       emax = pv->GetLowEdgeEnergy(nb);
549         fParticleChange.ProposeLocalEnergyDepo << 549       smax = 0.0;
550       }                                        << 550       for (size_t j=0; j<nb; j++) {
551     }                                          << 551   e = pv->GetLowEdgeEnergy(j);
552   }                                            << 552   s = pv->GetValue(e,b);
553                                                << 553   if(s > smax) {
554   // save secondaries                          << 554     smax = s;
555   G4int num = (G4int)secParticles.size();      << 555     emax = e;
556   if(num > 0) {                                << 556   }
557                                                << 557       }
558     fParticleChange.SetNumberOfSecondaries(num << 558     }
559     G4double edep = fParticleChange.GetLocalEn << 559     theEnergyOfCrossSectionMax[i] = emax;
560     G4double time = track.GetGlobalTime();     << 560     theCrossSectionMax[i] = smax;
561                                                << 561     if(2 < verboseLevel) {
562     G4int n1(0), n2(0);                        << 562       G4cout << "For " << particle->GetParticleName() 
563     if(num0 > mainSecondaries) {               << 563        << " Max CS at i= " << i << " emax(MeV)= " << emax/MeV
564       currentModel->FillNumberOfSecondaries(n1 << 564        << " lambda= " << smax << G4endl;
565     }                                          << 565     }
566                                                << 566   }
567     for (G4int i=0; i<num; ++i) {              << 567 }
568       G4DynamicParticle* dp = secParticles[i]; << 568 
569       if (nullptr != dp) {                     << 569 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
570         const G4ParticleDefinition* p = dp->Ge << 570 
571         G4double e = dp->GetKineticEnergy();   << 571 G4PhysicsVector* G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple*)
572         G4bool good = true;                    << 572 {
573         if(applyCuts) {                        << 573   G4PhysicsVector* v = 
574           if (p == theGamma) {                 << 574     new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
575             if (e < (*theCutsGamma)[currentCou << 575   v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
576                                                << 576   return v;
577           } else if (p == theElectron) {       << 577 }
578             if (e < (*theCutsElectron)[current << 578 
579                                                << 579 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
580           } else if (p == thePositron) {       << 
581             if (electron_mass_c2 < (*theCutsGa << 
582                 e < (*theCutsPositron)[current << 
583               good = false;                    << 
584               e += 2.0*electron_mass_c2;       << 
585             }                                  << 
586           }                                    << 
587           // added secondary if it is good     << 
588         }                                      << 
589         if (good) {                            << 
590           G4Track* t = new G4Track(dp, time, t << 
591           t->SetTouchableHandle(track.GetTouch << 
592           if (biasManager) {                   << 
593             t->SetWeight(weight * biasManager- << 
594           } else {                             << 
595             t->SetWeight(weight);              << 
596           }                                    << 
597           pParticleChange->AddSecondary(t);    << 
598                                                << 
599           // define type of secondary          << 
600           if(i < mainSecondaries) {            << 
601             t->SetCreatorModelID(secID);       << 
602             if(GetProcessSubType() == fCompton << 
603               t->SetCreatorModelID(_ComptonGam << 
604             }                                  << 
605           } else if(i < mainSecondaries + n1)  << 
606             t->SetCreatorModelID(tripletID);   << 
607           } else if(i < mainSecondaries + n1 + << 
608             t->SetCreatorModelID(_IonRecoil);  << 
609           } else {                             << 
610             if(i < num0) {                     << 
611               if(p == theGamma) {              << 
612                 t->SetCreatorModelID(fluoID);  << 
613               } else {                         << 
614                 t->SetCreatorModelID(augerID); << 
615               }                                << 
616             } else {                           << 
617               t->SetCreatorModelID(biasID);    << 
618             }                                  << 
619           }                                    << 
620           /*                                   << 
621           G4cout << "Secondary(post step) has  << 
622                  << ", Ekin= " << t->GetKineti << 
623                  << GetProcessName() << " fluo << 
624                  << " augerID= " << augerID << << 
625           */                                   << 
626         } else {                               << 
627           delete dp;                           << 
628           edep += e;                           << 
629         }                                      << 
630       }                                        << 
631     }                                          << 
632     fParticleChange.ProposeLocalEnergyDeposit( << 
633   }                                            << 
634                                                << 
635   if(0.0 == fParticleChange.GetProposedKinetic << 
636      fAlive == fParticleChange.GetTrackStatus( << 
637     if(particle->GetProcessManager()->GetAtRes << 
638          { fParticleChange.ProposeTrackStatus( << 
639     else { fParticleChange.ProposeTrackStatus( << 
640   }                                            << 
641                                                << 
642   return &fParticleChange;                     << 
643 }                                              << 
644                                                << 
645 //....oooOO0OOooo........oooOO0OOooo........oo << 
646                                                << 
647 G4bool G4VEmProcess::StorePhysicsTable(const G << 
648                                        const G << 
649                                        G4bool  << 
650 {                                              << 
651   if(!isTheMaster || part != particle) { retur << 
652   if(G4EmTableUtil::StoreTable(this, part, the << 
653              directory, "Lambda",              << 
654                                verboseLevel, a << 
655      G4EmTableUtil::StoreTable(this, part, the << 
656              directory, "LambdaPrim",          << 
657                                verboseLevel, a << 
658      return true;                              << 
659   }                                            << 
660   return false;                                << 
661 }                                              << 
662                                                << 
663 //....oooOO0OOooo........oooOO0OOooo........oo << 
664                                                << 
665 G4bool G4VEmProcess::RetrievePhysicsTable(cons << 
666                                           cons << 
667                                           G4bo << 
668 {                                              << 
669   if(!isTheMaster || part != particle) { retur << 
670   G4bool yes = true;                           << 
671   if(buildLambdaTable) {                       << 
672     yes = G4EmTableUtil::RetrieveTable(this, p << 
673                                        "Lambda << 
674                                        ascii,  << 
675   }                                            << 
676   if(yes && minKinEnergyPrim < maxKinEnergy) { << 
677     yes = G4EmTableUtil::RetrieveTable(this, p << 
678                                        "Lambda << 
679                                        ascii,  << 
680   }                                            << 
681   return yes;                                  << 
682 }                                              << 
683                                                << 
684 //....oooOO0OOooo........oooOO0OOooo........oo << 
685                                                << 
686 G4double G4VEmProcess::GetCrossSection(G4doubl << 
687                                        const G << 
688 {                                              << 
689   CurrentSetup(couple, kinEnergy);             << 
690   return GetCurrentLambda(kinEnergy, G4Log(kin << 
691 }                                              << 
692                                                << 
693 //....oooOO0OOooo........oooOO0OOooo........oo << 
694                                                << 
695 G4double G4VEmProcess::GetMeanFreePath(const G << 
696                                        G4doubl << 
697                                        G4Force << 
698 {                                              << 
699   *condition = NotForced;                      << 
700   return G4VEmProcess::MeanFreePath(track);    << 
701 }                                              << 
702                                                << 
703 //....oooOO0OOooo........oooOO0OOooo........oo << 
704                                                << 
705 G4double                                       << 
706 G4VEmProcess::ComputeCrossSectionPerAtom(G4dou << 
707                                          G4dou << 
708 {                                              << 
709   SelectModel(kinEnergy, currentCoupleIndex);  << 
710   return (currentModel) ?                      << 
711     currentModel->ComputeCrossSectionPerAtom(c << 
712                                              Z << 
713 }                                              << 
714                                                << 
715 //....oooOO0OOooo........oooOO0OOooo........oo << 
716                                                << 
717 G4PhysicsVector*                               << 
718 G4VEmProcess::LambdaPhysicsVector(const G4Mate << 
719 {                                              << 
720   DefineMaterial(couple);                      << 
721   G4PhysicsVector* newv = new G4PhysicsLogVect << 
722                                                << 
723   return newv;                                 << 
724 }                                              << 
725                                                << 
726 //....oooOO0OOooo........oooOO0OOooo........oo << 
727                                                << 
728 const G4Element* G4VEmProcess::GetCurrentEleme << 
729 {                                              << 
730   return (nullptr != currentModel) ?           << 
731     currentModel->GetCurrentElement(currentMat << 
732 }                                              << 
733                                                << 
734 //....oooOO0OOooo........oooOO0OOooo........oo << 
735                                                << 
736 const G4Element* G4VEmProcess::GetTargetElemen << 
737 {                                              << 
738   return (nullptr != currentModel) ?           << 
739     currentModel->GetCurrentElement(currentMat << 
740 }                                              << 
741                                                << 
742 //....oooOO0OOooo........oooOO0OOooo........oo << 
743                                                << 
744 const G4Isotope* G4VEmProcess::GetTargetIsotop << 
745 {                                              << 
746   return (nullptr != currentModel) ?           << 
747     currentModel->GetCurrentIsotope(GetCurrent << 
748 }                                              << 
749                                                << 
750 //....oooOO0OOooo........oooOO0OOooo........oo << 
751                                                << 
752 void G4VEmProcess::SetCrossSectionBiasingFacto << 
753 {                                              << 
754   if(f > 0.0) {                                << 
755     biasFactor = f;                            << 
756     weightFlag = flag;                         << 
757     if(1 < verboseLevel) {                     << 
758       G4cout << "### SetCrossSectionBiasingFac << 
759              << particle->GetParticleName()    << 
760              << " and process " << GetProcessN << 
761              << " biasFactor= " << f << " weig << 
762              << G4endl;                        << 
763     }                                          << 
764   }                                            << 
765 }                                              << 
766                                                << 
767 //....oooOO0OOooo........oooOO0OOooo........oo << 
768                                                << 
769 void                                           << 
770 G4VEmProcess::ActivateForcedInteraction(G4doub << 
771                                         G4bool << 
772 {                                              << 
773   if(nullptr == biasManager) { biasManager = n << 
774   if(1 < verboseLevel) {                       << 
775     G4cout << "### ActivateForcedInteraction:  << 
776            << particle->GetParticleName()      << 
777            << " and process " << GetProcessNam << 
778            << " length(mm)= " << length/mm     << 
779            << " in G4Region <" << r            << 
780            << "> weightFlag= " << flag         << 
781            << G4endl;                          << 
782   }                                            << 
783   weightFlag = flag;                           << 
784   biasManager->ActivateForcedInteraction(lengt << 
785 }                                              << 
786                                                << 
787 //....oooOO0OOooo........oooOO0OOooo........oo << 
788                                                << 
789 void                                           << 
790 G4VEmProcess::ActivateSecondaryBiasing(const G << 
791                  G4double factor,              << 
792                  G4double energyLimit)         << 
793 {                                              << 
794   if (0.0 <= factor) {                         << 
795                                                << 
796     // Range cut can be applied only for e-    << 
797     if(0.0 == factor && secondaryParticle != G << 
798       { return; }                              << 
799                                                << 
800     if(!biasManager) { biasManager = new G4EmB << 
801     biasManager->ActivateSecondaryBiasing(regi << 
802     if(1 < verboseLevel) {                     << 
803       G4cout << "### ActivateSecondaryBiasing: << 
804        << " process " << GetProcessName()      << 
805        << " factor= " << factor                << 
806        << " in G4Region <" << region           << 
807        << "> energyLimit(MeV)= " << energyLimi << 
808        << G4endl;                              << 
809     }                                          << 
810   }                                            << 
811 }                                              << 
812                                                << 
813 //....oooOO0OOooo........oooOO0OOooo........oo << 
814                                                << 
815 void G4VEmProcess::SetLambdaBinning(G4int n)   << 
816 {                                              << 
817   if(5 < n && n < 10000000) {                  << 
818     nLambdaBins = n;                           << 
819     actBinning = true;                         << 
820   } else {                                     << 
821     G4double e = (G4double)n;                  << 
822     PrintWarning("SetLambdaBinning", e);       << 
823   }                                            << 
824 }                                              << 
825                                                << 
826 //....oooOO0OOooo........oooOO0OOooo........oo << 
827                                                << 
828 void G4VEmProcess::SetMinKinEnergy(G4double e) << 
829 {                                              << 
830   if(1.e-3*eV < e && e < maxKinEnergy) {       << 
831     nLambdaBins = G4lrint(nLambdaBins*G4Log(ma << 
832                           /G4Log(maxKinEnergy/ << 
833     minKinEnergy = e;                          << 
834     actMinKinEnergy = true;                    << 
835   } else { PrintWarning("SetMinKinEnergy", e); << 
836 }                                              << 
837                                                << 
838 //....oooOO0OOooo........oooOO0OOooo........oo << 
839                                                << 
840 void G4VEmProcess::SetMaxKinEnergy(G4double e) << 
841 {                                              << 
842   if(minKinEnergy < e && e < 1.e+6*TeV) {      << 
843     nLambdaBins = G4lrint(nLambdaBins*G4Log(e/ << 
844                           /G4Log(maxKinEnergy/ << 
845     maxKinEnergy = e;                          << 
846     actMaxKinEnergy = true;                    << 
847   } else { PrintWarning("SetMaxKinEnergy", e); << 
848 }                                              << 
849                                                << 
850 //....oooOO0OOooo........oooOO0OOooo........oo << 
851                                                << 
852 void G4VEmProcess::SetMinKinEnergyPrim(G4doubl << 
853 {                                              << 
854   if(theParameters->MinKinEnergy() <= e &&     << 
855      e <= theParameters->MaxKinEnergy()) { min << 
856   else { PrintWarning("SetMinKinEnergyPrim", e << 
857 }                                              << 
858                                                << 
859 //....oooOO0OOooo........oooOO0OOooo........oo << 
860                                                << 
861 G4VEmProcess* G4VEmProcess::GetEmProcess(const << 
862 {                                              << 
863   return (nam == GetProcessName()) ? this : nu << 
864 }                                              << 
865                                                << 
866 //....oooOO0OOooo........oooOO0OOooo........oo << 
867                                                << 
868 G4double G4VEmProcess::PolarAngleLimit() const << 
869 {                                              << 
870   return theParameters->MscThetaLimit();       << 
871 }                                              << 
872                                                << 
873 //....oooOO0OOooo........oooOO0OOooo........oo << 
874                                                << 
875 void G4VEmProcess::PrintWarning(G4String tit,  << 
876 {                                              << 
877   G4String ss = "G4VEmProcess::" + tit;        << 
878   G4ExceptionDescription ed;                   << 
879   ed << "Parameter is out of range: " << val   << 
880      << " it will have no effect!\n" << "  Pro << 
881      << GetProcessName() << "  nbins= " << the << 
882      << " Emin(keV)= " << theParameters->MinKi << 
883      << " Emax(GeV)= " << theParameters->MaxKi << 
884   G4Exception(ss, "em0044", JustWarning, ed);  << 
885 }                                              << 
886                                                << 
887 //....oooOO0OOooo........oooOO0OOooo........oo << 
888                                                << 
889 void G4VEmProcess::ProcessDescription(std::ost << 
890 {                                              << 
891   if(nullptr != particle) {                    << 
892     StreamInfo(out, *particle, true);          << 
893   }                                            << 
894 }                                              << 
895                                                << 
896 //....oooOO0OOooo........oooOO0OOooo........oo << 
897                                                   580