Geant4 Cross Reference |
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 = ∂ 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