Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 // 28 // Author: A. Forti 29 // Maria Grazia Pia (Maria.Grazia.Pia@ 30 // 31 // History: 32 // -------- 33 // October 1998 - low energy modifications by 34 // Added Livermore data table construction met 35 // Modified BuildMeanFreePath to read new data 36 // Added EnergySampling method A. Forti 37 // Modified PostStepDoIt to insert sampling wi 38 // Added SelectRandomAtom A. Forti 39 // Added map of the elements A. Forti 40 // 10.04.2000 VL 41 // - Correcting Fluorescence transition probab 42 // non-radiative transitions. No Auger elect 43 // 17.02.2000 Veronique Lefebure 44 // - bugs corrected in fluorescence simulation 45 // . when final use of binding energy: no ph 46 // . no Fluorescence was simulated when the 47 // was below production threshold. 48 // 49 // 07-09-99, if no e- emitted: edep=photon en 50 // 24.04.01 V.Ivanchenko remove RogueWav 51 // 12.08.2001 MGP Revised accordi 52 // 16.09.2001 E. Guardincerri Added fluoresce 53 // 06.10.2001 MGP Added protectio 54 // when binding en 55 // 18.04.2001 V.Ivanchenko Fix problem wit 56 // MeanFreePath is 57 // 31.05.2002 V.Ivanchenko Add path of Flu 58 // 14.06.2002 V.Ivanchenko By default do n 59 // 21.01.2003 V.Ivanchenko Cut per region 60 // 10.05.2004 P.Rodrigues Changes to acco 61 // 20.01.2006 A.Trindade Changes to acco 62 // 63 // ------------------------------------------- 64 65 #include "G4LowEnergyPhotoElectric.hh" 66 67 #include "G4RDVPhotoElectricAngularDistributio 68 #include "G4RDPhotoElectricAngularGeneratorSim 69 #include "G4RDPhotoElectricAngularGeneratorSau 70 #include "G4RDPhotoElectricAngularGeneratorPol 71 72 #include "G4PhysicalConstants.hh" 73 #include "G4SystemOfUnits.hh" 74 #include "G4ParticleDefinition.hh" 75 #include "G4Track.hh" 76 #include "G4Step.hh" 77 #include "G4ForceCondition.hh" 78 #include "G4Gamma.hh" 79 #include "G4Electron.hh" 80 #include "G4DynamicParticle.hh" 81 #include "G4VParticleChange.hh" 82 #include "G4ThreeVector.hh" 83 #include "G4RDVCrossSectionHandler.hh" 84 #include "G4RDCrossSectionHandler.hh" 85 #include "G4RDVEMDataSet.hh" 86 #include "G4RDCompositeEMDataSet.hh" 87 #include "G4RDVDataSetAlgorithm.hh" 88 #include "G4RDLogLogInterpolation.hh" 89 #include "G4RDVRangeTest.hh" 90 #include "G4RDRangeNoTest.hh" 91 #include "G4RDAtomicTransitionManager.hh" 92 #include "G4RDAtomicShell.hh" 93 #include "G4ProductionCutsTable.hh" 94 95 G4LowEnergyPhotoElectric::G4LowEnergyPhotoElec 96 : G4VDiscreteProcess(processName), lowEnergy 97 intrinsicLowEnergyLimit(10*eV), 98 intrinsicHighEnergyLimit(100*GeV), 99 cutForLowEnergySecondaryPhotons(250.*eV), 100 cutForLowEnergySecondaryElectrons(250.*eV) 101 { 102 if (lowEnergyLimit < intrinsicLowEnergyLimit 103 highEnergyLimit > intrinsicHighEnergyLim 104 { 105 G4Exception("G4LowEnergyPhotoElectric::G 106 "OutOfRange", FatalException 107 "Energy limit outside intrin 108 } 109 110 crossSectionHandler = new G4RDCrossSectionHa 111 shellCrossSectionHandler = new G4RDCrossSect 112 meanFreePathTable = 0; 113 rangeTest = new G4RDRangeNoTest; 114 generatorName = "geant4.6.2"; 115 ElectronAngularGenerator = new G4RDPhotoElec 116 117 118 if (verboseLevel > 0) 119 { 120 G4cout << GetProcessName() << " is creat 121 << "Energy range: " 122 << lowEnergyLimit / keV << " keV - " 123 << highEnergyLimit / GeV << " GeV" 124 << G4endl; 125 } 126 } 127 128 G4LowEnergyPhotoElectric::~G4LowEnergyPhotoEle 129 { 130 delete crossSectionHandler; 131 delete shellCrossSectionHandler; 132 delete meanFreePathTable; 133 delete rangeTest; 134 delete ElectronAngularGenerator; 135 } 136 137 void G4LowEnergyPhotoElectric::BuildPhysicsTab 138 { 139 140 crossSectionHandler->Clear(); 141 G4String crossSectionFile = "phot/pe-cs-"; 142 crossSectionHandler->LoadData(crossSectionFi 143 144 shellCrossSectionHandler->Clear(); 145 G4String shellCrossSectionFile = "phot/pe-ss 146 shellCrossSectionHandler->LoadShellData(shel 147 148 delete meanFreePathTable; 149 meanFreePathTable = crossSectionHandler->Bui 150 } 151 152 G4VParticleChange* G4LowEnergyPhotoElectric::P 153 const G4Step& aStep) 154 { 155 // Fluorescence generated according to: 156 // J. Stepanek ,"A program to determine the 157 // subshell ionisation by a particle or due 158 // Comp. Phys. Comm. 1206 pp 1-1-9 (1997) 159 160 aParticleChange.Initialize(aTrack); 161 162 const G4DynamicParticle* incidentPhoton = aT 163 G4double photonEnergy = incidentPhoton->GetK 164 if (photonEnergy <= lowEnergyLimit) 165 { 166 aParticleChange.ProposeTrackStatus(fStop 167 aParticleChange.ProposeEnergy(0.); 168 aParticleChange.ProposeLocalEnergyDeposi 169 return G4VDiscreteProcess::PostStepDoIt( 170 } 171 172 G4ThreeVector photonDirection = incidentPhot 173 174 // Select randomly one element in the curren 175 const G4MaterialCutsCouple* couple = aTrack. 176 G4int Z = crossSectionHandler->SelectRandomA 177 178 // Select the ionised shell in the current a 179 size_t shellIndex = shellCrossSectionHandler 180 181 // Retrieve the corresponding identifier and 182 const G4RDAtomicTransitionManager* transitio 183 const G4RDAtomicShell* shell = transitionMan 184 G4double bindingEnergy = shell->BindingEnerg 185 G4int shellId = shell->ShellId(); 186 187 // Create lists of pointers to DynamicPartic 188 // (Is the electron vector necessary? To be 189 std::vector<G4DynamicParticle*>* photonVecto 190 std::vector<G4DynamicParticle*> electronVect 191 192 G4double energyDeposit = 0.0; 193 194 // Primary outcoming electron 195 G4double eKineticEnergy = photonEnergy - bin 196 197 // There may be cases where the binding ener 198 // In such cases do not generate secondaries 199 if (eKineticEnergy > 0.) 200 { 201 // Generate the electron only if with la 202 G4double safety = aStep.GetPostStepPoint 203 204 if (rangeTest->Escape(G4Electron::Electr 205 { 206 207 // Calculate direction of the photoelectro 208 G4ThreeVector gammaPolarization = incident 209 G4ThreeVector electronDirection = Electron 210 211 // The electron is created ... 212 G4DynamicParticle* electron = new G4Dynami 213 electronDirection, 214 eKineticEnergy); 215 electronVector.push_back(electron); 216 } 217 else 218 { 219 energyDeposit += eKineticEnergy; 220 } 221 } 222 else 223 { 224 bindingEnergy = photonEnergy; 225 } 226 227 G4int nElectrons = electronVector.size(); 228 size_t nTotPhotons = 0; 229 G4int nPhotons=0; 230 const G4ProductionCutsTable* theCoupleTable= 231 G4ProductionCutsTable::GetProductionCu 232 233 size_t index = couple->GetIndex(); 234 G4double cutg = (*(theCoupleTable->GetEnergy 235 cutg = std::min(cutForLowEnergySecondaryPhot 236 237 G4double cute = (*(theCoupleTable->GetEnergy 238 cute = std::min(cutForLowEnergySecondaryPhot 239 240 G4DynamicParticle* aPhoton; 241 242 // Generation of fluorescence 243 // Data in EADL are available only for Z > 5 244 // Protection to avoid generating photons in 245 // shell binding energy > photon energy 246 if (Z > 5 && (bindingEnergy > cutg || bindi 247 { 248 photonVector = deexcitationManager.Gener 249 nTotPhotons = photonVector->size(); 250 for (size_t k=0; k<nTotPhotons; k++) 251 { 252 aPhoton = (*photonVector)[k]; 253 if (aPhoton) 254 { 255 G4double itsCut = cutg; 256 if(aPhoton->GetDefinition() == G 257 G4double itsEnergy = aPhoton->GetKinet 258 259 if (itsEnergy > itsCut && itsEnergy <= 260 { 261 nPhotons++; 262 // Local energy deposit is given as the 263 // energies of incident photons minus th 264 // of the outcoming fluorescence photons 265 bindingEnergy -= itsEnergy; 266 267 } 268 else 269 { 270 delete aPhoton; 271 (*photonVector)[k] = 0; 272 } 273 } 274 } 275 } 276 277 energyDeposit += bindingEnergy; 278 279 G4int nSecondaries = nElectrons + nPhotons; 280 aParticleChange.SetNumberOfSecondaries(nSeco 281 282 for (G4int l = 0; l<nElectrons; l++ ) 283 { 284 aPhoton = electronVector[l]; 285 if(aPhoton) { 286 aParticleChange.AddSecondary(aPhoton); 287 } 288 } 289 for ( size_t ll = 0; ll < nTotPhotons; ll++) 290 { 291 aPhoton = (*photonVector)[ll]; 292 if(aPhoton) { 293 aParticleChange.AddSecondary(aPhoton); 294 } 295 } 296 297 delete photonVector; 298 299 if (energyDeposit < 0) 300 { 301 G4cout << "WARNING - " 302 << "G4LowEnergyPhotoElectric::PostStepD 303 << G4endl; 304 energyDeposit = 0; 305 } 306 307 // Kill the incident photon 308 aParticleChange.ProposeMomentumDirection( 0. 309 aParticleChange.ProposeEnergy( 0. ); 310 311 aParticleChange.ProposeLocalEnergyDeposit(en 312 aParticleChange.ProposeTrackStatus( fStopAnd 313 314 // Reset NbOfInteractionLengthLeft and retur 315 return G4VDiscreteProcess::PostStepDoIt( aTr 316 } 317 318 G4bool G4LowEnergyPhotoElectric::IsApplicable( 319 { 320 return ( &particle == G4Gamma::Gamma() ); 321 } 322 323 G4double G4LowEnergyPhotoElectric::GetMeanFree 324 G4double, // previousStepSize 325 G4ForceCondition*) 326 { 327 const G4DynamicParticle* photon = track.GetD 328 G4double energy = photon->GetKineticEnergy() 329 G4Material* material = track.GetMaterial(); 330 // size_t materialIndex = material->GetInde 331 332 G4double meanFreePath = DBL_MAX; 333 334 // if (energy > highEnergyLimit) 335 // meanFreePath = meanFreePathTable->Find 336 // else if (energy < lowEnergyLimit) meanFr 337 // else meanFreePath = meanFreePathTable->F 338 339 G4double cross = shellCrossSectionHandler->V 340 if(cross > 0.0) meanFreePath = 1.0/cross; 341 342 return meanFreePath; 343 } 344 345 void G4LowEnergyPhotoElectric::SetCutForLowEnS 346 { 347 cutForLowEnergySecondaryPhotons = cut; 348 deexcitationManager.SetCutForSecondaryPhoton 349 } 350 351 void G4LowEnergyPhotoElectric::SetCutForLowEnS 352 { 353 cutForLowEnergySecondaryElectrons = cut; 354 deexcitationManager.SetCutForAugerElectrons( 355 } 356 357 void G4LowEnergyPhotoElectric::ActivateAuger(G 358 { 359 deexcitationManager.ActivateAugerElectronPro 360 } 361 362 void G4LowEnergyPhotoElectric::SetAngularGener 363 { 364 ElectronAngularGenerator = distribution; 365 ElectronAngularGenerator->PrintGeneratorInfo 366 } 367 368 void G4LowEnergyPhotoElectric::SetAngularGener 369 { 370 if (name == "default") 371 { 372 delete ElectronAngularGenerator; 373 ElectronAngularGenerator = new G4RDPhoto 374 generatorName = name; 375 } 376 else if (name == "standard") 377 { 378 delete ElectronAngularGenerator; 379 ElectronAngularGenerator = new G4RDPhoto 380 generatorName = name; 381 } 382 else if (name == "polarized") 383 { 384 delete ElectronAngularGenerator; 385 ElectronAngularGenerator = new G4RDPhoto 386 generatorName = name; 387 } 388 else 389 { 390 G4Exception("G4LowEnergyPhotoElectric::S 391 "InvalidSetup", FatalExcepti 392 "Generator does not exist!") 393 } 394 395 ElectronAngularGenerator->PrintGeneratorInfo 396 } 397