Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // 27 // 28 // Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it) 29 // Alfonso Mantero (Alfonso.Mantero@ge.infn.it) 30 // 31 // History: 32 // ----------- 33 // 16 Sep 2001 E. Guardincerri First Committed to cvs 34 // 35 // ------------------------------------------------------------------- 36 37 #include "G4AtomicTransitionManager.hh" 38 #include "G4EmParameters.hh" 39 #include "G4FluoData.hh" 40 #include "G4AugerData.hh" 41 #include "G4AutoLock.hh" 42 namespace { G4Mutex AtomicTransitionManagerMutex = G4MUTEX_INITIALIZER; } 43 44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 45 G4AtomicTransitionManager* G4AtomicTransitionManager::instance = nullptr; 46 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 48 G4AtomicTransitionManager* G4AtomicTransitionManager::Instance() 49 { 50 if (instance == nullptr) { 51 instance = new G4AtomicTransitionManager(); 52 } 53 return instance; 54 } 55 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 57 G4AtomicTransitionManager::G4AtomicTransitionManager() 58 : augerData(nullptr), 59 verboseLevel(0), 60 isInitialized(false) 61 {} 62 63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 64 G4AtomicTransitionManager::~G4AtomicTransitionManager() 65 { 66 delete augerData; 67 68 for (auto& pos : shellTable){ 69 std::vector<G4AtomicShell*>vec = pos.second; 70 std::size_t vecSize = vec.size(); 71 for (std::size_t i=0; i< vecSize; ++i){ 72 G4AtomicShell* shell = vec[i]; 73 delete shell; 74 } 75 } 76 77 for (auto& ppos : transitionTable) 78 { 79 std::vector<G4FluoTransition*>vec = ppos.second; 80 std::size_t vecSize=vec.size(); 81 82 for (std::size_t i=0; i< vecSize; ++i){ 83 G4FluoTransition* transition = vec[i]; 84 delete transition; 85 } 86 } 87 } 88 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 89 G4AtomicShell* 90 G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex) const 91 { 92 auto pos = shellTable.find(Z); 93 94 if (pos!= shellTable.end()) 95 { 96 std::vector<G4AtomicShell*> v = (*pos).second; 97 if (shellIndex < v.size()) { return v[shellIndex]; } 98 99 else 100 { 101 size_t lastShell = v.size(); 102 G4ExceptionDescription ed; 103 ed << "No de-excitation for Z= " << Z 104 << " shellIndex= " << shellIndex 105 << ">= numberOfShells= " << lastShell; 106 if (verboseLevel > 0) 107 G4Exception("G4AtomicTransitionManager::Shell()","de0001", 108 JustWarning,ed," AtomicShell not found"); 109 if (lastShell > 0) { return v[lastShell - 1]; } 110 } 111 } 112 else 113 { 114 G4ExceptionDescription ed; 115 ed << "No de-excitation for Z= " << Z 116 << " shellIndex= " << shellIndex 117 << ". AtomicShell not found - check if data are uploaded"; 118 G4Exception("G4AtomicTransitionManager::Shell()","de0001", 119 FatalException,ed,""); 120 } 121 return 0; 122 } 123 124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 125 126 // This function gives, upon Z and the Index of the initial shell where 127 // the vacancy is, the radiative transition that can happen (originating 128 // shell, energy, probability) 129 const G4FluoTransition* 130 G4AtomicTransitionManager::ReachableShell(G4int Z,size_t shellIndex) const 131 { 132 auto pos = transitionTable.find(Z); 133 if (pos!= transitionTable.end()) 134 { 135 std::vector<G4FluoTransition*> v = (*pos).second; 136 if (shellIndex < v.size()) { return(v[shellIndex]); } 137 138 else { 139 G4ExceptionDescription ed; 140 ed << "No fluo transition for Z= " << Z 141 << " shellIndex= " << shellIndex; 142 G4Exception("G4AtomicTransitionManager::ReachebleShell()","de0002", 143 FatalException,ed,""); 144 } 145 } 146 else 147 { 148 G4ExceptionDescription ed; 149 ed << "No transition table for Z= " << Z 150 << " shellIndex= " << shellIndex; 151 G4Exception("G4AtomicTransitionManager::ReachableShell()","de0001", 152 FatalException,ed,""); 153 } 154 return 0; 155 } 156 157 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 158 const G4AugerTransition* 159 G4AtomicTransitionManager::ReachableAugerShell(G4int Z, 160 G4int vacancyShellIndex) const 161 { 162 return augerData->GetAugerTransition(Z,vacancyShellIndex); 163 } 164 165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 166 G4int G4AtomicTransitionManager::NumberOfShells (G4int Z) const 167 { 168 auto pos = shellTable.find(Z); 169 170 std::size_t res = 0; 171 if (pos != shellTable.cend()){ 172 173 res = ((*pos).second).size(); 174 175 } else { 176 G4ExceptionDescription ed; 177 ed << "No deexcitation for Z= " << Z; 178 G4Exception("G4AtomicTransitionManager::NumberOfShells()","de0001", 179 FatalException, ed, ""); 180 } 181 return (G4int)res; 182 } 183 184 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 185 // This function returns the number of possible radiative transitions for 186 // the atom with atomic number Z i.e. the number of shell in wich a vacancy 187 // can be filled with a radiative transition 188 G4int G4AtomicTransitionManager::NumberOfReachableShells(G4int Z) const 189 { 190 auto pos = transitionTable.find(Z); 191 std::size_t res = 0; 192 if (pos!= transitionTable.cend()) 193 { 194 res = ((*pos).second).size(); 195 } 196 else 197 { 198 G4ExceptionDescription ed; 199 ed << "No deexcitation for Z= " << Z 200 << ", so energy deposited locally"; 201 G4Exception("G4AtomicTransitionManager::NumberOfReachebleShells()", 202 "de0001",FatalException,ed,""); 203 } 204 return (G4int)res; 205 } 206 207 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 208 // This function returns the number of possible NON-radiative transitions 209 // for the atom with atomic number Z i.e. the number of shell in wich a 210 // vacancy can be filled with a NON-radiative transition 211 G4int G4AtomicTransitionManager::NumberOfReachableAugerShells(G4int Z)const 212 { 213 return (G4int)augerData->NumberOfVacancies(Z); 214 } 215 216 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 217 G4double G4AtomicTransitionManager::TotalRadiativeTransitionProbability( 218 G4int Z, size_t shellIndex) const 219 { 220 auto pos = transitionTable.find(Z); 221 G4double totalRadTransProb = 0.0; 222 223 if (pos!= transitionTable.end()) 224 { 225 std::vector<G4FluoTransition*> v = (*pos).second; 226 227 if (shellIndex < v.size()) 228 { 229 G4FluoTransition* transition = v[shellIndex]; 230 G4DataVector transProb = transition->TransitionProbabilities(); 231 232 for (size_t j=0; j<transProb.size(); ++j) 233 { 234 totalRadTransProb += transProb[j]; 235 } 236 } 237 else 238 { 239 G4ExceptionDescription ed; 240 ed << "Zero transition probability for Z=" << Z 241 << " shellIndex= " << shellIndex; 242 G4Exception( 243 "G4AtomicTransitionManager::TotalRadiativeTransitionProbability()", 244 "de0002",FatalException,"Incorrect de-excitation"); 245 } 246 } 247 else 248 { 249 G4ExceptionDescription ed; 250 ed << "No deexcitation for Z=" << Z 251 << " shellIndex= " << shellIndex; 252 G4Exception( 253 "G4AtomicTransitionManager::TotalRadiativeTransitionProbability()", 254 "de0001",FatalException,ed,"Cannot compute transition probability"); 255 } 256 return totalRadTransProb; 257 } 258 259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 260 G4double G4AtomicTransitionManager::TotalNonRadiativeTransitionProbability( 261 G4int Z, size_t shellIndex) const 262 { 263 G4double prob = 1.0 - TotalRadiativeTransitionProbability(Z, shellIndex); 264 if(prob > 1.0 || prob < 0.0) { 265 G4ExceptionDescription ed; 266 ed << "Total probability mismatch Z= " << Z 267 << " shellIndex= " << shellIndex 268 << " prob= " << prob; 269 G4Exception( 270 "G4AtomicTransitionManager::TotalNonRadiativeTransitionProbability()", 271 "de0003",FatalException,ed,"Cannot compute non-radiative probability"); 272 return 0.0; 273 } 274 return prob; 275 } 276 277 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 278 void G4AtomicTransitionManager::Initialise() 279 { 280 if(isInitialized) { return; } 281 G4AutoLock l(&AtomicTransitionManagerMutex); 282 283 if(isInitialized) { return; } 284 isInitialized = true; 285 286 // Selection of fluorescence files 287 288 const G4String& defaultDirectory = "/fluor"; 289 G4String fluoDirectory = defaultDirectory; 290 G4String bindingDirectory = defaultDirectory; 291 G4EmFluoDirectory fdir = G4EmParameters::Instance()->FluoDirectory(); 292 G4int zLim = zMax + 1; 293 if(fdir == fluoBearden) { 294 zMax = 100; 295 supTableLimit = 100; 296 bindingDirectory = fluoDirectory = "/fluor_Bearden"; 297 } else if(fdir == fluoANSTO) { 298 zLim = 93; 299 fluoDirectory = "/fluor_ANSTO"; 300 } else if(fdir == fluoXDB_EADL) { 301 zMax = 100; 302 supTableLimit = 100; 303 bindingDirectory = fluoDirectory = "/fluor_XDB_EADL"; 304 } 305 306 // infTableLimit is initialized to 6 because EADL lacks data for Z<=5 307 G4ShellData* shellManager = new G4ShellData(1, zMax, false); 308 shellManager->LoadData(bindingDirectory + "/binding"); 309 310 // initialization of the data for auger effect 311 augerData = new G4AugerData; 312 313 // Fills shellTable with the data from EADL, identities and binding 314 // energies of shells 315 for (G4int Z = zMin; Z <= zMax; ++Z) 316 { 317 std::vector<G4AtomicShell*> vectorOfShells; 318 G4int shellIndex = 0; 319 320 G4int numberOfShells = (G4int)shellManager->NumberOfShells(Z); 321 for (shellIndex = 0; shellIndex<numberOfShells; ++shellIndex) 322 { 323 G4int shellId = shellManager->ShellId(Z,shellIndex); 324 G4double bindingEnergy = shellManager->BindingEnergy(Z,shellIndex); 325 G4AtomicShell * shell = new G4AtomicShell(shellId,bindingEnergy); 326 vectorOfShells.push_back(shell); 327 } 328 shellTable[Z] = std::move(vectorOfShells); 329 } 330 331 // Fills transitionTable with the data on identities, transition 332 // energies and transition probabilities 333 G4String dir = std::move(fluoDirectory); 334 for (G4int Znum= infTableLimit; Znum<=supTableLimit; ++Znum) 335 { 336 if (Znum == zLim) { dir = defaultDirectory; } 337 G4FluoData* fluoManager = new G4FluoData(dir); 338 std::vector<G4FluoTransition*> vectorOfTransitions; 339 fluoManager->LoadData(Znum); 340 341 G4int numberOfVacancies = (G4int)fluoManager->NumberOfVacancies(); 342 for(G4int vacancyIndex = 0; vacancyIndex<numberOfVacancies; 343 ++vacancyIndex) 344 { 345 std::vector<G4int> vectorOfIds; 346 G4DataVector vectorOfEnergies; 347 G4DataVector vectorOfProbabilities; 348 349 G4int finalShell = fluoManager->VacancyId(vacancyIndex); 350 G4int numberOfTransitions = (G4int) 351 fluoManager->NumberOfTransitions(vacancyIndex); 352 for (G4int origShellIndex = 0; origShellIndex < numberOfTransitions; 353 ++origShellIndex) 354 { 355 G4int originatingShellId = 356 fluoManager->StartShellId(origShellIndex,vacancyIndex); 357 vectorOfIds.push_back(originatingShellId); 358 359 G4double transitionEnergy = 360 fluoManager->StartShellEnergy(origShellIndex,vacancyIndex); 361 vectorOfEnergies.push_back(transitionEnergy); 362 G4double transitionProbability = 363 fluoManager->StartShellProb(origShellIndex,vacancyIndex); 364 vectorOfProbabilities.push_back(transitionProbability); 365 } 366 G4FluoTransition* transition = 367 new G4FluoTransition (finalShell,vectorOfIds, 368 vectorOfEnergies,vectorOfProbabilities); 369 vectorOfTransitions.push_back(transition); 370 } 371 transitionTable[Znum] = std::move(vectorOfTransitions); 372 delete fluoManager; 373 } 374 delete shellManager; 375 l.unlock(); 376 } 377