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 // 27 // ------------------------------------------- 27 // ------------------------------------------------------------------- 28 // 28 // 29 // Geant4 Class file 29 // Geant4 Class file 30 // 30 // 31 // Authors: Alfonso Mantero (Alfonso.Mantero@g 31 // Authors: Alfonso Mantero (Alfonso.Mantero@ge.infn.it) 32 // 32 // 33 // Created 22 April 2010 from old G4UAtomicDee 33 // Created 22 April 2010 from old G4UAtomicDeexcitation class 34 // 34 // 35 // Modified: 35 // Modified: 36 // --------- 36 // --------- 37 // 20 Oct 2011 Alf modified to take into acc 37 // 20 Oct 2011 Alf modified to take into account ECPSSR form Form Factor 38 // 03 Nov 2011 Alf Extended Empirical and Fo 38 // 03 Nov 2011 Alf Extended Empirical and Form Factor ionisation XS models 39 // out thei ranges with Anal 39 // out thei ranges with Analytical one. 40 // 07 Nov 2011 Alf Restored original ioniati 40 // 07 Nov 2011 Alf Restored original ioniation XS for alphas, 41 // letting scaled ones for o 41 // letting scaled ones for other ions. 42 // 20 Mar 2012 LP Register G4PenelopeIonisa 42 // 20 Mar 2012 LP Register G4PenelopeIonisationCrossSection 43 // 43 // 44 // ------------------------------------------- 44 // ------------------------------------------------------------------- 45 // 45 // 46 // Class description: 46 // Class description: 47 // Implementation of atomic deexcitation 47 // Implementation of atomic deexcitation 48 // 48 // 49 // ------------------------------------------- 49 // ------------------------------------------------------------------- 50 50 51 #include "G4UAtomicDeexcitation.hh" 51 #include "G4UAtomicDeexcitation.hh" 52 #include "G4PhysicalConstants.hh" 52 #include "G4PhysicalConstants.hh" 53 #include "G4SystemOfUnits.hh" 53 #include "G4SystemOfUnits.hh" 54 #include "Randomize.hh" 54 #include "Randomize.hh" 55 #include "G4Gamma.hh" 55 #include "G4Gamma.hh" 56 #include "G4AtomicTransitionManager.hh" 56 #include "G4AtomicTransitionManager.hh" 57 #include "G4FluoTransition.hh" 57 #include "G4FluoTransition.hh" 58 #include "G4Electron.hh" 58 #include "G4Electron.hh" 59 #include "G4Positron.hh" 59 #include "G4Positron.hh" 60 #include "G4Proton.hh" 60 #include "G4Proton.hh" 61 #include "G4Alpha.hh" 61 #include "G4Alpha.hh" 62 62 63 #include "G4teoCrossSection.hh" 63 #include "G4teoCrossSection.hh" 64 #include "G4empCrossSection.hh" 64 #include "G4empCrossSection.hh" 65 #include "G4PenelopeIonisationCrossSection.hh" 65 #include "G4PenelopeIonisationCrossSection.hh" 66 #include "G4LivermoreIonisationCrossSection.hh 66 #include "G4LivermoreIonisationCrossSection.hh" 67 #include "G4EmCorrections.hh" 67 #include "G4EmCorrections.hh" 68 #include "G4LossTableManager.hh" 68 #include "G4LossTableManager.hh" 69 #include "G4EmParameters.hh" 69 #include "G4EmParameters.hh" 70 #include "G4Material.hh" 70 #include "G4Material.hh" 71 #include "G4AtomicShells.hh" 71 #include "G4AtomicShells.hh" 72 72 73 using namespace std; 73 using namespace std; 74 74 75 //....oooOO0OOooo........oooOO0OOooo........oo 75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 76 76 77 G4UAtomicDeexcitation::G4UAtomicDeexcitation() 77 G4UAtomicDeexcitation::G4UAtomicDeexcitation(): 78 G4VAtomDeexcitation("UAtomDeexcitation"), 78 G4VAtomDeexcitation("UAtomDeexcitation"), 79 minGammaEnergy(DBL_MAX), 79 minGammaEnergy(DBL_MAX), 80 minElectronEnergy(DBL_MAX), 80 minElectronEnergy(DBL_MAX), 81 newShellId(-1) 81 newShellId(-1) 82 { 82 { 83 anaPIXEshellCS = nullptr; 83 anaPIXEshellCS = nullptr; 84 PIXEshellCS = nullptr; 84 PIXEshellCS = nullptr; 85 ePIXEshellCS = nullptr; 85 ePIXEshellCS = nullptr; 86 emcorr = G4LossTableManager::Instance()->EmC 86 emcorr = G4LossTableManager::Instance()->EmCorrections(); 87 theElectron = G4Electron::Electron(); 87 theElectron = G4Electron::Electron(); 88 thePositron = G4Positron::Positron(); 88 thePositron = G4Positron::Positron(); 89 transitionManager = G4AtomicTransitionManage 89 transitionManager = G4AtomicTransitionManager::Instance(); 90 } 90 } 91 91 92 //....oooOO0OOooo........oooOO0OOooo........oo 92 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 93 93 94 G4UAtomicDeexcitation::~G4UAtomicDeexcitation( 94 G4UAtomicDeexcitation::~G4UAtomicDeexcitation() 95 { 95 { 96 delete anaPIXEshellCS; 96 delete anaPIXEshellCS; 97 delete PIXEshellCS; 97 delete PIXEshellCS; 98 delete ePIXEshellCS; 98 delete ePIXEshellCS; 99 } 99 } 100 100 101 //....oooOO0OOooo........oooOO0OOooo........oo 101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 102 102 103 void G4UAtomicDeexcitation::InitialiseForNewRu 103 void G4UAtomicDeexcitation::InitialiseForNewRun() 104 { 104 { 105 if(!IsFluoActive()) { return; } 105 if(!IsFluoActive()) { return; } 106 transitionManager->Initialise(); 106 transitionManager->Initialise(); 107 if(!IsPIXEActive()) { return; } 107 if(!IsPIXEActive()) { return; } 108 108 109 if(!anaPIXEshellCS) { 109 if(!anaPIXEshellCS) { 110 anaPIXEshellCS = new G4teoCrossSection("EC 110 anaPIXEshellCS = new G4teoCrossSection("ECPSSR_Analytical"); 111 } 111 } 112 G4cout << G4endl; 112 G4cout << G4endl; 113 G4cout << "### === G4UAtomicDeexcitation::In 113 G4cout << "### === G4UAtomicDeexcitation::InitialiseForNewRun()" << G4endl; 114 114 115 G4EmParameters* param = G4EmParameters::Inst 115 G4EmParameters* param = G4EmParameters::Instance(); 116 G4String namePIXExsModel = param->PIXECrossS 116 G4String namePIXExsModel = param->PIXECrossSectionModel(); 117 G4String namePIXExsElectronModel = param->PI 117 G4String namePIXExsElectronModel = param->PIXEElectronCrossSectionModel(); 118 118 119 // Check if old cross section for p/ion shou 119 // Check if old cross section for p/ion should be deleted 120 if(PIXEshellCS && namePIXExsModel != PIXEshe 120 if(PIXEshellCS && namePIXExsModel != PIXEshellCS->GetName()) 121 { 121 { 122 delete PIXEshellCS; 122 delete PIXEshellCS; 123 PIXEshellCS = nullptr; 123 PIXEshellCS = nullptr; 124 } 124 } 125 125 126 // Instantiate new proton/ion cross section 126 // Instantiate new proton/ion cross section 127 if(!PIXEshellCS) { 127 if(!PIXEshellCS) { 128 if (namePIXExsModel == "ECPSSR_FormFactor" 128 if (namePIXExsModel == "ECPSSR_FormFactor") 129 { 129 { 130 PIXEshellCS = new G4teoCrossSection(namePIXE 130 PIXEshellCS = new G4teoCrossSection(namePIXExsModel); 131 } 131 } 132 else if(namePIXExsModel == "ECPSSR_ANSTO") 132 else if(namePIXExsModel == "ECPSSR_ANSTO") 133 { 133 { 134 PIXEshellCS = new G4teoCrossSection(namePIXE 134 PIXEshellCS = new G4teoCrossSection(namePIXExsModel); 135 } 135 } 136 else if(namePIXExsModel == "Empirical") 136 else if(namePIXExsModel == "Empirical") 137 { 137 { 138 PIXEshellCS = new G4empCrossSection(namePIXE 138 PIXEshellCS = new G4empCrossSection(namePIXExsModel); 139 } 139 } 140 } 140 } 141 141 142 // Check if old cross section for e+- should 142 // Check if old cross section for e+- should be deleted 143 if(ePIXEshellCS && namePIXExsElectronModel ! 143 if(ePIXEshellCS && namePIXExsElectronModel != ePIXEshellCS->GetName()) 144 { 144 { 145 delete ePIXEshellCS; 145 delete ePIXEshellCS; 146 ePIXEshellCS = nullptr; 146 ePIXEshellCS = nullptr; 147 } 147 } 148 148 149 // Instantiate new e+- cross section 149 // Instantiate new e+- cross section 150 if(nullptr == ePIXEshellCS) << 150 if(!ePIXEshellCS) 151 { 151 { 152 if(namePIXExsElectronModel == "Empirical 152 if(namePIXExsElectronModel == "Empirical") 153 { 153 { 154 ePIXEshellCS = new G4empCrossSection("Empi 154 ePIXEshellCS = new G4empCrossSection("Empirical"); 155 } 155 } 156 else if(namePIXExsElectronModel == "ECPS 156 else if(namePIXExsElectronModel == "ECPSSR_Analytical") 157 { 157 { 158 ePIXEshellCS = new G4teoCrossSection("ECPS 158 ePIXEshellCS = new G4teoCrossSection("ECPSSR_Analytical"); 159 } 159 } 160 else if (namePIXExsElectronModel == "Pen 160 else if (namePIXExsElectronModel == "Penelope") 161 { 161 { 162 ePIXEshellCS = new G4PenelopeIonisationCro 162 ePIXEshellCS = new G4PenelopeIonisationCrossSection(); 163 } 163 } 164 else 164 else 165 { 165 { 166 ePIXEshellCS = new G4LivermoreIonisationCr 166 ePIXEshellCS = new G4LivermoreIonisationCrossSection(); 167 } 167 } 168 } 168 } 169 } 169 } 170 170 171 //....oooOO0OOooo........oooOO0OOooo........oo 171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 172 172 173 void G4UAtomicDeexcitation::InitialiseForExtra << 173 void G4UAtomicDeexcitation::InitialiseForExtraAtom(G4int /*Z*/) 174 {} 174 {} 175 175 176 //....oooOO0OOooo........oooOO0OOooo........oo 176 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 177 177 178 const G4AtomicShell* 178 const G4AtomicShell* 179 G4UAtomicDeexcitation::GetAtomicShell(G4int Z, 179 G4UAtomicDeexcitation::GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell) 180 { 180 { 181 return transitionManager->Shell(Z, (std::siz << 181 return transitionManager->Shell(Z, size_t(shell)); 182 } 182 } 183 183 184 //....oooOO0OOooo........oooOO0OOooo........oo 184 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 185 185 186 void G4UAtomicDeexcitation::GenerateParticles( 186 void G4UAtomicDeexcitation::GenerateParticles( 187 std::vector<G4DynamicParticle* << 187 std::vector<G4DynamicParticle*>* vectorOfParticles, 188 const G4AtomicShell* atomicShell, << 188 const G4AtomicShell* atomicShell, 189 G4int Z, << 189 G4int Z, 190 G4double gammaCut, << 190 G4double gammaCut, 191 G4double eCut) << 191 G4double eCut) 192 { 192 { 193 // Defined initial conditions 193 // Defined initial conditions 194 G4int givenShellId = atomicShell->ShellId(); 194 G4int givenShellId = atomicShell->ShellId(); 195 minGammaEnergy = gammaCut; 195 minGammaEnergy = gammaCut; 196 minElectronEnergy = eCut; 196 minElectronEnergy = eCut; 197 vacancyArray.clear(); << 197 198 << 199 // generation secondaries 198 // generation secondaries 200 G4DynamicParticle* aParticle=0; 199 G4DynamicParticle* aParticle=0; 201 G4int provShellId = 0; 200 G4int provShellId = 0; 202 201 203 //ORIGINAL METHOD BY ALFONSO MANTERO 202 //ORIGINAL METHOD BY ALFONSO MANTERO 204 if (!IsAugerCascadeActive()) 203 if (!IsAugerCascadeActive()) 205 { 204 { 206 //---------------------------- 205 //---------------------------- 207 G4int counter = 0; 206 G4int counter = 0; 208 207 209 // limits of the EPDL data << 208 // let's check that 5<Z<100 210 if (Z>5 && Z<105) { << 209 >> 210 if (Z>5 && Z<100) { 211 211 212 // The aim of this loop is to generate more 212 // The aim of this loop is to generate more than one fluorecence photon 213 // from the same ionizing event 213 // from the same ionizing event 214 do 214 do 215 { 215 { 216 if (counter == 0) 216 if (counter == 0) 217 // First call to GenerateParticles(... 217 // First call to GenerateParticles(...): 218 // givenShellId is given by the proces 218 // givenShellId is given by the process 219 { 219 { 220 provShellId = SelectTypeOfTransition(Z, gi 220 provShellId = SelectTypeOfTransition(Z, givenShellId); 221 221 222 if (provShellId >0) << 222 if ( provShellId >0) 223 { 223 { 224 aParticle = << 224 aParticle = GenerateFluorescence(Z,givenShellId,provShellId); 225 GenerateFluorescence(Z, givenShellId << 226 } 225 } 227 else if (provShellId == -1) << 226 else if ( provShellId == -1) 228 { 227 { 229 aParticle = GenerateAuger(Z, givenShel 228 aParticle = GenerateAuger(Z, givenShellId); 230 } 229 } >> 230 else >> 231 { >> 232 //G4Exception("G4UAtomicDeexcitation::GenerateParticles()", >> 233 // "de0002",JustWarning, "Energy deposited locally"); >> 234 } 231 } 235 } 232 else 236 else 233 // Following calls to GenerateParticle 237 // Following calls to GenerateParticles(...): 234 // newShellId is given by GenerateFluo 238 // newShellId is given by GenerateFluorescence(...) 235 { 239 { 236 provShellId = SelectTypeOfTransition(Z,new 240 provShellId = SelectTypeOfTransition(Z,newShellId); 237 if (provShellId >0) << 241 if (provShellId >0) 238 { 242 { 239 aParticle = GenerateFluorescence(Z,new 243 aParticle = GenerateFluorescence(Z,newShellId,provShellId); 240 } 244 } 241 else if ( provShellId == -1) 245 else if ( provShellId == -1) 242 { 246 { 243 aParticle = GenerateAuger(Z, newShellI 247 aParticle = GenerateAuger(Z, newShellId); 244 } 248 } >> 249 else >> 250 { >> 251 //G4Exception("G4UAtomicDeexcitation::GenerateParticles()","de0002",JustWarning, "Energy deposited locally"); >> 252 } 245 } 253 } 246 ++counter; << 254 counter++; 247 if (aParticle != 0) 255 if (aParticle != 0) 248 { 256 { 249 vectorOfParticles->push_back(aParticle); 257 vectorOfParticles->push_back(aParticle); >> 258 //G4cout << "Deexcitation Occurred!" << G4endl; //debug 250 } 259 } 251 else {provShellId = -2;} 260 else {provShellId = -2;} 252 } 261 } 253 while (provShellId > -2); 262 while (provShellId > -2); 254 } 263 } >> 264 else >> 265 { >> 266 //G4Exception("G4UAtomicDeexcitation::GenerateParticles()","de0001",JustWarning, "Energy deposited locally"); >> 267 } >> 268 255 } // Auger cascade is not active 269 } // Auger cascade is not active 256 270 257 //END OF ORIGINAL METHOD BY ALFONSO MANTERO 271 //END OF ORIGINAL METHOD BY ALFONSO MANTERO 258 //---------------------- 272 //---------------------- 259 273 260 // NEW METHOD 274 // NEW METHOD 261 // Auger cascade by Burkhant Suerfu on March 275 // Auger cascade by Burkhant Suerfu on March 24 2015 (Bugzilla 1727) 262 if (IsAugerCascadeActive()) 276 if (IsAugerCascadeActive()) 263 { 277 { 264 //---------------------- 278 //---------------------- 265 vacancyArray.push_back(givenShellId); 279 vacancyArray.push_back(givenShellId); 266 280 267 // let's check that 5<Z<100 281 // let's check that 5<Z<100 268 if (Z<6 || Z>104){ << 282 if (Z<6 || Z>99){ >> 283 //G4Exception("G4UAtomicDeexcitation::GenerateParticles()","de0001",JustWarning, "Energy deposited locally"); 269 return; 284 return; 270 } 285 } 271 286 272 // as long as there is vacancy to be fil 287 // as long as there is vacancy to be filled by either fluo or auger, stay in the loop. 273 while(!vacancyArray.empty()){ 288 while(!vacancyArray.empty()){ 274 // prepare to process the last element, and 289 // prepare to process the last element, and then delete it from the vector. 275 givenShellId = vacancyArray[0]; 290 givenShellId = vacancyArray[0]; 276 provShellId = SelectTypeOfTransition(Z,given 291 provShellId = SelectTypeOfTransition(Z,givenShellId); 277 292 278 //G4cout<<"\n------ Atom Transition with Z: 293 //G4cout<<"\n------ Atom Transition with Z: "<<Z<<"\tbetween current:" 279 // <<givenShellId<<" & target:"<<provShel 294 // <<givenShellId<<" & target:"<<provShellId<<G4endl; 280 if(provShellId>0){ 295 if(provShellId>0){ 281 aParticle = GenerateFluorescence(Z,givenSh 296 aParticle = GenerateFluorescence(Z,givenShellId,provShellId); 282 } 297 } 283 else if(provShellId == -1){ 298 else if(provShellId == -1){ 284 aParticle = GenerateAuger(Z, givenShellId) 299 aParticle = GenerateAuger(Z, givenShellId); 285 } 300 } >> 301 //else >> 302 // G4Exception("G4UAtomicDeexcitation::GenerateParticles()","de0002",JustWarning, "Energy deposited locally"); >> 303 286 // if a particle is created, put it in the 304 // if a particle is created, put it in the vector of new particles 287 if(aParticle!=0) 305 if(aParticle!=0) 288 vectorOfParticles->push_back(aParticle); 306 vectorOfParticles->push_back(aParticle); 289 << 307 else{;} 290 // one vacancy has been processed. Erase it 308 // one vacancy has been processed. Erase it. 291 vacancyArray.erase(vacancyArray.begin()); 309 vacancyArray.erase(vacancyArray.begin()); 292 } 310 } 293 //---------------------- 311 //---------------------- 294 //End of Auger cascade by Burkhant Suerf 312 //End of Auger cascade by Burkhant Suerfu on March 24 2015 (Bugzilla 1727) 295 313 296 } // Auger cascade is active 314 } // Auger cascade is active 297 } 315 } 298 316 299 //....oooOO0OOooo........oooOO0OOooo........oo 317 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 300 318 301 G4double 319 G4double 302 G4UAtomicDeexcitation::GetShellIonisationCross 320 G4UAtomicDeexcitation::GetShellIonisationCrossSectionPerAtom( 303 const G4ParticleDefinition* pdef, << 321 const G4ParticleDefinition* pdef, 304 G4int Z, << 322 G4int Z, 305 G4AtomicShellEnumerator shellEnum, << 323 G4AtomicShellEnumerator shellEnum, 306 G4double kineticEnergy, << 324 G4double kineticEnergy, 307 const G4Material* mat) << 325 const G4Material* mat) 308 { 326 { 309 // we must put a control on the shell that a 327 // we must put a control on the shell that are passed: 310 // some shells should not pass (line "0" or 328 // some shells should not pass (line "0" or "2") 311 329 312 // check atomic number 330 // check atomic number 313 G4double xsec = 0.0; 331 G4double xsec = 0.0; 314 if(Z > 93 || Z < 6 ) { return xsec; } //corr 332 if(Z > 93 || Z < 6 ) { return xsec; } //corrected by alf - Z<6 missing 315 G4int idx = G4int(shellEnum); 333 G4int idx = G4int(shellEnum); 316 if(idx >= G4AtomicShells::GetNumberOfShells( 334 if(idx >= G4AtomicShells::GetNumberOfShells(Z)) { return xsec; } 317 335 318 if(pdef == theElectron || pdef == thePositro 336 if(pdef == theElectron || pdef == thePositron) { 319 xsec = ePIXEshellCS->CrossSection(Z,shellE 337 xsec = ePIXEshellCS->CrossSection(Z,shellEnum,kineticEnergy,0.0,mat); 320 return xsec; 338 return xsec; 321 } 339 } 322 340 323 G4double mass = pdef->GetPDGMass(); 341 G4double mass = pdef->GetPDGMass(); 324 G4double escaled = kineticEnergy; 342 G4double escaled = kineticEnergy; 325 G4double q2 = 0.0; 343 G4double q2 = 0.0; 326 344 327 // scaling to protons for all particles excl << 345 // scaling to protons 328 G4int pdg = pdef->GetPDGEncoding(); << 346 if ((pdef->GetParticleName() != "proton" && pdef->GetParticleName() != "alpha" ) ) 329 if (pdg != 2212 && pdg != 1000020040) << 330 { 347 { 331 mass = proton_mass_c2; 348 mass = proton_mass_c2; 332 escaled = kineticEnergy*mass/(pdef->GetP 349 escaled = kineticEnergy*mass/(pdef->GetPDGMass()); 333 350 334 if(mat) { 351 if(mat) { 335 q2 = emcorr->EffectiveChargeSquareRatio(pdef 352 q2 = emcorr->EffectiveChargeSquareRatio(pdef,mat,kineticEnergy); 336 } else { 353 } else { 337 G4double q = pdef->GetPDGCharge()/eplus; 354 G4double q = pdef->GetPDGCharge()/eplus; 338 q2 = q*q; 355 q2 = q*q; 339 } 356 } 340 } 357 } 341 358 342 if(PIXEshellCS) { << 359 if(PIXEshellCS) { xsec = PIXEshellCS->CrossSection(Z,shellEnum,escaled,mass,mat); } 343 xsec = PIXEshellCS->CrossSection(Z,shellEn << 344 } << 345 if(xsec < 1e-100) { 360 if(xsec < 1e-100) { 346 xsec = anaPIXEshellCS->CrossSection(Z,shel 361 xsec = anaPIXEshellCS->CrossSection(Z,shellEnum,escaled,mass,mat); 347 } 362 } 348 363 349 if (q2) {xsec *= q2;} 364 if (q2) {xsec *= q2;} 350 365 351 return xsec; 366 return xsec; 352 } 367 } 353 368 354 //....oooOO0OOooo........oooOO0OOooo........oo 369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 355 370 356 void G4UAtomicDeexcitation::SetCutForSecondary 371 void G4UAtomicDeexcitation::SetCutForSecondaryPhotons(G4double cut) 357 { 372 { 358 minGammaEnergy = cut; 373 minGammaEnergy = cut; 359 } 374 } 360 375 361 //....oooOO0OOooo........oooOO0OOooo........oo 376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 362 377 363 void G4UAtomicDeexcitation::SetCutForAugerElec 378 void G4UAtomicDeexcitation::SetCutForAugerElectrons(G4double cut) 364 { 379 { 365 minElectronEnergy = cut; 380 minElectronEnergy = cut; 366 } 381 } 367 382 368 //....oooOO0OOooo........oooOO0OOooo........oo 383 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 369 384 370 G4double G4UAtomicDeexcitation::ComputeShellIo << 385 G4double 371 const G4ParticleDefinition* p, << 386 G4UAtomicDeexcitation::ComputeShellIonisationCrossSectionPerAtom( 372 G4int Z, << 387 const G4ParticleDefinition* p, 373 G4AtomicShellEnumerator shell, << 388 G4int Z, 374 G4double kinE, << 389 G4AtomicShellEnumerator shell, 375 const G4Material* mat) << 390 G4double kinE, >> 391 const G4Material* mat) 376 { 392 { 377 return GetShellIonisationCrossSectionPerAtom 393 return GetShellIonisationCrossSectionPerAtom(p,Z,shell,kinE,mat); 378 } 394 } 379 395 380 //....oooOO0OOooo........oooOO0OOooo........oo 396 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 381 397 382 G4int G4UAtomicDeexcitation::SelectTypeOfTrans 398 G4int G4UAtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId) 383 { 399 { 384 if (shellId <=0 ) { 400 if (shellId <=0 ) { >> 401 //G4Exception("G4UAtomicDeexcitation::SelecttypeOfTransition()","de0002", >> 402 // JustWarning, "Energy deposited locally"); 385 return 0; 403 return 0; 386 } 404 } 387 405 388 G4int provShellId = -1; 406 G4int provShellId = -1; 389 G4int shellNum = 0; 407 G4int shellNum = 0; 390 G4int maxNumOfShells = transitionManager->Nu 408 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z); 391 409 392 const G4FluoTransition* refShell = 410 const G4FluoTransition* refShell = 393 transitionManager->ReachableShell(Z,maxNum 411 transitionManager->ReachableShell(Z,maxNumOfShells-1); 394 412 395 // This loop gives shellNum the value of the 413 // This loop gives shellNum the value of the index of shellId 396 // in the vector storing the list of the she 414 // in the vector storing the list of the shells reachable through 397 // a radiative transition 415 // a radiative transition 398 if ( shellId <= refShell->FinalShellId()) 416 if ( shellId <= refShell->FinalShellId()) 399 { 417 { 400 while (shellId != transitionManager->Rea 418 while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId()) 401 { 419 { 402 if(shellNum ==maxNumOfShells-1) 420 if(shellNum ==maxNumOfShells-1) 403 { 421 { 404 break; 422 break; 405 } 423 } 406 shellNum++; 424 shellNum++; 407 } 425 } 408 G4int transProb = 0; //AM change 29/6/07 426 G4int transProb = 0; //AM change 29/6/07 was 1 409 427 410 G4double partialProb = G4UniformRand(); 428 G4double partialProb = G4UniformRand(); 411 G4double partSum = 0; 429 G4double partSum = 0; 412 const G4FluoTransition* aShell = transit 430 const G4FluoTransition* aShell = transitionManager->ReachableShell(Z,shellNum); 413 G4int trSize = (G4int)(aShell->Transiti << 431 G4int trSize = (aShell->TransitionProbabilities()).size(); 414 432 415 // Loop over the shells wich can provide 433 // Loop over the shells wich can provide an electron for a 416 // radiative transition towards shellId: 434 // radiative transition towards shellId: 417 // in every loop the partial sum of the 435 // in every loop the partial sum of the first transProb shells 418 // is calculated and compared with a ran 436 // is calculated and compared with a random number [0,1]. 419 // If the partial sum is greater, the sh 437 // If the partial sum is greater, the shell whose index is transProb 420 // is chosen as the starting shell for a 438 // is chosen as the starting shell for a radiative transition 421 // and its identity is returned 439 // and its identity is returned 422 // Else, terminateded the loop, -1 is re 440 // Else, terminateded the loop, -1 is returned 423 while(transProb < trSize){ 441 while(transProb < trSize){ 424 partSum += aShell->TransitionProbability(tra 442 partSum += aShell->TransitionProbability(transProb); 425 443 426 if(partialProb <= partSum) 444 if(partialProb <= partSum) 427 { 445 { 428 provShellId = aShell->OriginatingShellId 446 provShellId = aShell->OriginatingShellId(transProb); 429 break; 447 break; 430 } 448 } 431 ++transProb; << 449 transProb++; 432 } 450 } 433 // here provShellId is the right one or 451 // here provShellId is the right one or is -1. 434 // if -1, the control is passed to the A 452 // if -1, the control is passed to the Auger generation part of the package 435 } 453 } 436 else 454 else 437 { 455 { 438 provShellId = -1; 456 provShellId = -1; 439 } 457 } 440 return provShellId; 458 return provShellId; 441 } 459 } 442 460 443 //....oooOO0OOooo........oooOO0OOooo........oo 461 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 444 462 445 G4DynamicParticle* 463 G4DynamicParticle* 446 G4UAtomicDeexcitation::GenerateFluorescence(G4 464 G4UAtomicDeexcitation::GenerateFluorescence(G4int Z, G4int shellId, 447 G4int provShellId ) 465 G4int provShellId ) 448 { 466 { 449 if (shellId <=0 ) 467 if (shellId <=0 ) 450 { 468 { >> 469 //G4Exception("G4UAtomicDeexcitation::GenerateFluorescence()","de0002",JustWarning, "Energy deposited locally"); 451 return nullptr; 470 return nullptr; 452 } 471 } 453 472 454 //isotropic angular distribution for the out 473 //isotropic angular distribution for the outcoming photon 455 G4double newcosTh = 1.-2.*G4UniformRand(); 474 G4double newcosTh = 1.-2.*G4UniformRand(); 456 G4double newsinTh = std::sqrt((1.-newcosTh)* 475 G4double newsinTh = std::sqrt((1.-newcosTh)*(1. + newcosTh)); 457 G4double newPhi = twopi*G4UniformRand(); 476 G4double newPhi = twopi*G4UniformRand(); 458 477 459 G4double xDir = newsinTh*std::sin(newPhi); 478 G4double xDir = newsinTh*std::sin(newPhi); 460 G4double yDir = newsinTh*std::cos(newPhi); 479 G4double yDir = newsinTh*std::cos(newPhi); 461 G4double zDir = newcosTh; 480 G4double zDir = newcosTh; 462 481 463 G4ThreeVector newGammaDirection(xDir,yDir,zD 482 G4ThreeVector newGammaDirection(xDir,yDir,zDir); 464 483 465 G4int shellNum = 0; 484 G4int shellNum = 0; 466 G4int maxNumOfShells = transitionManager->Nu 485 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z); 467 486 468 // find the index of the shell named shellId 487 // find the index of the shell named shellId 469 while (shellId != transitionManager-> 488 while (shellId != transitionManager-> 470 ReachableShell(Z,shellNum)->FinalShellId()) 489 ReachableShell(Z,shellNum)->FinalShellId()) 471 { 490 { 472 if(shellNum == maxNumOfShells-1) 491 if(shellNum == maxNumOfShells-1) 473 { 492 { 474 break; 493 break; 475 } 494 } 476 ++shellNum; << 495 shellNum++; 477 } 496 } 478 // number of shell from wich an electron can 497 // number of shell from wich an electron can reach shellId 479 G4int transitionSize = (G4int)transitionMana << 498 size_t transitionSize = transitionManager-> 480 ReachableShell(Z,shellNum)->OriginatingShe 499 ReachableShell(Z,shellNum)->OriginatingShellIds().size(); 481 500 482 G4int index = 0; << 501 size_t index = 0; 483 502 484 // find the index of the shell named provShe 503 // find the index of the shell named provShellId in the vector 485 // storing the shells from which shellId can 504 // storing the shells from which shellId can be reached 486 while (provShellId != transitionManager-> 505 while (provShellId != transitionManager-> 487 ReachableShell(Z,shellNum)->OriginatingShel 506 ReachableShell(Z,shellNum)->OriginatingShellId(index)) 488 { 507 { 489 if(index == transitionSize-1) 508 if(index == transitionSize-1) 490 { 509 { 491 break; 510 break; 492 } 511 } 493 ++index; << 512 index++; 494 } 513 } 495 // energy of the gamma leaving provShellId f 514 // energy of the gamma leaving provShellId for shellId 496 G4double transitionEnergy = transitionManage 515 G4double transitionEnergy = transitionManager-> 497 ReachableShell(Z,shellNum)->TransitionEner 516 ReachableShell(Z,shellNum)->TransitionEnergy(index); 498 517 499 if (transitionEnergy < minGammaEnergy) retur 518 if (transitionEnergy < minGammaEnergy) return nullptr; 500 519 501 // This is the shell where the new vacancy i 520 // This is the shell where the new vacancy is: it is the same 502 // shell where the electron came from 521 // shell where the electron came from 503 newShellId = transitionManager-> 522 newShellId = transitionManager-> 504 ReachableShell(Z,shellNum)->OriginatingShe 523 ReachableShell(Z,shellNum)->OriginatingShellId(index); 505 524 506 G4DynamicParticle* newPart = new G4DynamicPa 525 G4DynamicParticle* newPart = new G4DynamicParticle(G4Gamma::Gamma(), 507 newGammaDirection, 526 newGammaDirection, 508 transitionEnergy); 527 transitionEnergy); 509 528 510 //Auger cascade by Burkhant Suerfu on March 529 //Auger cascade by Burkhant Suerfu on March 24 2015 (Bugzilla 1727) 511 if (IsAugerCascadeActive()) vacancyArray.pus 530 if (IsAugerCascadeActive()) vacancyArray.push_back(newShellId); 512 531 513 return newPart; 532 return newPart; 514 } 533 } 515 534 516 //....oooOO0OOooo........oooOO0OOooo........oo 535 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 517 536 518 G4DynamicParticle* G4UAtomicDeexcitation::Gene 537 G4DynamicParticle* G4UAtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId) 519 { 538 { 520 if(!IsAugerActive()) { 539 if(!IsAugerActive()) { 521 // G4cout << "auger inactive!" << G4end 540 // G4cout << "auger inactive!" << G4endl; //debug 522 return nullptr; 541 return nullptr; 523 } 542 } 524 543 525 if (shellId <=0 ) { 544 if (shellId <=0 ) { 526 //G4Exception("G4UAtomicDeexcitation::Gene 545 //G4Exception("G4UAtomicDeexcitation::GenerateAuger()","de0002", 527 // JustWarning, "Energy deposited local 546 // JustWarning, "Energy deposited locally"); 528 return nullptr; 547 return nullptr; 529 } 548 } 530 549 531 G4int maxNumOfShells = transitionManager->Nu 550 G4int maxNumOfShells = transitionManager->NumberOfReachableAugerShells(Z); 532 551 533 const G4AugerTransition* refAugerTransition 552 const G4AugerTransition* refAugerTransition = 534 transitionManager->ReachableAugerShell(Z,m 553 transitionManager->ReachableAugerShell(Z,maxNumOfShells-1); 535 554 536 // This loop gives to shellNum the value of 555 // This loop gives to shellNum the value of the index of shellId 537 // in the vector storing the list of the vac 556 // in the vector storing the list of the vacancies in the variuos shells 538 // that can originate a NON-radiative transi 557 // that can originate a NON-radiative transition 539 G4int shellNum = 0; 558 G4int shellNum = 0; 540 559 541 if ( shellId <= refAugerTransition->FinalShe 560 if ( shellId <= refAugerTransition->FinalShellId() ) 542 // "FinalShellId" is final from the point 561 // "FinalShellId" is final from the point of view of the electron 543 // who makes the transition, 562 // who makes the transition, 544 // being the Id of the shell in which ther 563 // being the Id of the shell in which there is a vacancy 545 { 564 { 546 G4int pippo = transitionManager->Reachab 565 G4int pippo = transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId(); 547 if (shellId != pippo ) { << 566 if (shellId != pippo ) { 548 do { 567 do { 549 ++shellNum; << 568 shellNum++; 550 if(shellNum == maxNumOfShells) 569 if(shellNum == maxNumOfShells) 551 { 570 { 552 // G4cout << "No Auger transition foun 571 // G4cout << "No Auger transition found" << G4endl; //debug 553 return 0; 572 return 0; 554 } 573 } 555 } 574 } 556 while (shellId != (transitionManager->Reacha 575 while (shellId != (transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId()) ); 557 } 576 } 558 577 559 // Now we have that shellnum is the shel 578 // Now we have that shellnum is the shellIndex of the shell named ShellId 560 // G4cout << " the index of the she 579 // G4cout << " the index of the shell is: "<<shellNum<<G4endl; 561 // But we have now to select two shells: 580 // But we have now to select two shells: one for the transition, 562 // and another for the auger emission. 581 // and another for the auger emission. 563 G4int transitionLoopShellIndex = 0; 582 G4int transitionLoopShellIndex = 0; 564 G4double partSum = 0; 583 G4double partSum = 0; 565 const G4AugerTransition* anAugerTransiti 584 const G4AugerTransition* anAugerTransition = 566 transitionManager->ReachableAugerShell(Z,she 585 transitionManager->ReachableAugerShell(Z,shellNum); 567 586 568 G4int transitionSize = (G4int) << 587 G4int transitionSize = 569 (anAugerTransition->TransitionOriginatingShe 588 (anAugerTransition->TransitionOriginatingShellIds())->size(); 570 while (transitionLoopShellIndex < transi 589 while (transitionLoopShellIndex < transitionSize) { 571 590 572 std::vector<G4int>::const_iterator pos 591 std::vector<G4int>::const_iterator pos = 573 anAugerTransition->TransitionOriginatingSh << 592 anAugerTransition->TransitionOriginatingShellIds()->begin(); 574 593 575 G4int transitionLoopShellId = *(pos+tr 594 G4int transitionLoopShellId = *(pos+transitionLoopShellIndex); 576 G4int numberOfPossibleAuger = (G4int) << 595 G4int numberOfPossibleAuger = 577 (anAugerTransition->AugerTransitionProbabi 596 (anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size(); 578 G4int augerIndex = 0; 597 G4int augerIndex = 0; 579 598 580 if (augerIndex < numberOfPossibleAuger) { 599 if (augerIndex < numberOfPossibleAuger) { 581 do 600 do 582 { 601 { 583 G4double thisProb = anAugerTransition- 602 G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex, 584 transitionLoopShellId); 603 transitionLoopShellId); 585 partSum += thisProb; 604 partSum += thisProb; 586 augerIndex++; 605 augerIndex++; 587 606 588 } while (augerIndex < numberOfPossibleAu 607 } while (augerIndex < numberOfPossibleAuger); 589 } << 608 } 590 ++transitionLoopShellIndex; << 609 transitionLoopShellIndex++; 591 } 610 } 592 611 593 G4double totalVacancyAugerProbability = 612 G4double totalVacancyAugerProbability = partSum; 594 613 595 //And now we start to select the right a 614 //And now we start to select the right auger transition and emission 596 G4int transitionRandomShellIndex = 0; 615 G4int transitionRandomShellIndex = 0; 597 G4int transitionRandomShellId = 1; 616 G4int transitionRandomShellId = 1; 598 G4int augerIndex = 0; 617 G4int augerIndex = 0; 599 partSum = 0; 618 partSum = 0; 600 G4double partialProb = G4UniformRand(); 619 G4double partialProb = G4UniformRand(); 601 620 602 G4int numberOfPossibleAuger = 0; 621 G4int numberOfPossibleAuger = 0; 603 G4bool foundFlag = false; 622 G4bool foundFlag = false; 604 623 605 while (transitionRandomShellIndex < tran 624 while (transitionRandomShellIndex < transitionSize) { 606 625 607 std::vector<G4int>::const_iterator pos 626 std::vector<G4int>::const_iterator pos = 608 anAugerTransition->TransitionOriginatingSh 627 anAugerTransition->TransitionOriginatingShellIds()->begin(); 609 628 610 transitionRandomShellId = *(pos+transi 629 transitionRandomShellId = *(pos+transitionRandomShellIndex); 611 630 612 augerIndex = 0; 631 augerIndex = 0; 613 numberOfPossibleAuger = (G4int)(anAugerTrans << 632 numberOfPossibleAuger = (anAugerTransition-> 614 AugerTransitionProbabilities(transiti 633 AugerTransitionProbabilities(transitionRandomShellId))->size(); 615 634 616 while (augerIndex < numberOfPossibleAu 635 while (augerIndex < numberOfPossibleAuger) { 617 G4double thisProb =anAugerTransition->Auge 636 G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex, 618 transitionRandomShellId); 637 transitionRandomShellId); 619 638 620 partSum += thisProb; 639 partSum += thisProb; 621 640 622 if (partSum >= (partialProb*totalVac 641 if (partSum >= (partialProb*totalVacancyAugerProbability) ) { // was / 623 foundFlag = true; 642 foundFlag = true; 624 break; 643 break; 625 } 644 } 626 augerIndex++; 645 augerIndex++; 627 } 646 } 628 if (partSum >= (partialProb*totalVacan 647 if (partSum >= (partialProb*totalVacancyAugerProbability) ) {break;} // was / 629 ++transitionRandomShellIndex; << 648 transitionRandomShellIndex++; 630 } 649 } 631 650 632 // Now we have the index of the shell fr 651 // Now we have the index of the shell from wich comes the auger electron (augerIndex), 633 // and the id of the shell, from which t 652 // and the id of the shell, from which the transition e- come (transitionRandomShellid) 634 // If no Transition has been found, 0 is 653 // If no Transition has been found, 0 is returned. 635 if (!foundFlag) { 654 if (!foundFlag) { 636 return nullptr; 655 return nullptr; 637 } 656 } 638 657 639 // Isotropic angular distribution for th 658 // Isotropic angular distribution for the outcoming e- 640 G4double newcosTh = 1.-2.*G4UniformRand( 659 G4double newcosTh = 1.-2.*G4UniformRand(); 641 G4double newsinTh = std::sqrt(1.-newcosT << 660 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh); 642 G4double newPhi = twopi*G4UniformRand(); 661 G4double newPhi = twopi*G4UniformRand(); 643 662 644 G4double xDir = newsinTh*std::sin(newPhi << 663 G4double xDir = newsinTh*std::sin(newPhi); 645 G4double yDir = newsinTh*std::cos(newPhi 664 G4double yDir = newsinTh*std::cos(newPhi); 646 G4double zDir = newcosTh; 665 G4double zDir = newcosTh; 647 666 648 G4ThreeVector newElectronDirection(xDir, 667 G4ThreeVector newElectronDirection(xDir,yDir,zDir); 649 668 650 // energy of the auger electron emitted 669 // energy of the auger electron emitted 651 G4double transitionEnergy = 670 G4double transitionEnergy = 652 anAugerTransition->AugerTransitionEnergy(aug 671 anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId); 653 672 654 if (transitionEnergy < minElectronEnergy 673 if (transitionEnergy < minElectronEnergy) { 655 return nullptr; 674 return nullptr; 656 } 675 } 657 676 658 // This is the shell where the new vacan 677 // This is the shell where the new vacancy is: it is the same 659 // shell where the electron came from 678 // shell where the electron came from 660 newShellId = transitionRandomShellId; 679 newShellId = transitionRandomShellId; 661 680 662 //Auger cascade by Burkhant Suerfu on Ma 681 //Auger cascade by Burkhant Suerfu on March 24 2015 (Bugzilla 1727) 663 if (IsAugerCascadeActive()) 682 if (IsAugerCascadeActive()) 664 { 683 { 665 vacancyArray.push_back(newShellId); 684 vacancyArray.push_back(newShellId); 666 vacancyArray.push_back(anAugerTransition-> 685 vacancyArray.push_back(anAugerTransition->AugerOriginatingShellId(augerIndex,transitionRandomShellId)); 667 } 686 } 668 687 669 return new G4DynamicParticle(G4Electron: 688 return new G4DynamicParticle(G4Electron::Electron(), 670 newElectronDirection, 689 newElectronDirection, 671 transitionEnergy); 690 transitionEnergy); 672 } 691 } 673 else 692 else 674 { 693 { 675 return nullptr; 694 return nullptr; 676 } 695 } 677 } 696 } 678 697