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 // $Id: G4VEmModel.cc,v 1.30 2009/09/23 14:42:47 vnivanch Exp $ >> 27 // GEANT4 tag $Name: geant4-09-03 $ >> 28 // 26 // ------------------------------------------- 29 // ------------------------------------------------------------------- 27 // 30 // 28 // GEANT4 Class file 31 // GEANT4 Class file 29 // 32 // 30 // 33 // 31 // File name: G4VEmModel 34 // File name: G4VEmModel 32 // 35 // 33 // Author: Vladimir Ivanchenko 36 // Author: Vladimir Ivanchenko 34 // 37 // 35 // Creation date: 25.07.2005 38 // Creation date: 25.07.2005 36 // 39 // 37 // Modifications: 40 // Modifications: 38 // 25.10.2005 Set default highLimit=100.TeV (V 41 // 25.10.2005 Set default highLimit=100.TeV (V.Ivanchenko) 39 // 06.02.2006 add method ComputeMeanFreePath() 42 // 06.02.2006 add method ComputeMeanFreePath() (mma) 40 // 16.02.2009 Move implementations of virtual 43 // 16.02.2009 Move implementations of virtual methods to source (VI) 41 // 44 // 42 // 45 // 43 // Class Description: 46 // Class Description: 44 // 47 // 45 // Abstract interface to energy loss models 48 // Abstract interface to energy loss models 46 49 47 // ------------------------------------------- 50 // ------------------------------------------------------------------- 48 // 51 // 49 52 50 #include "G4VEmModel.hh" 53 #include "G4VEmModel.hh" 51 #include "G4ElementData.hh" << 52 #include "G4LossTableManager.hh" 54 #include "G4LossTableManager.hh" 53 #include "G4LossTableBuilder.hh" << 54 #include "G4ProductionCutsTable.hh" 55 #include "G4ProductionCutsTable.hh" 55 #include "G4ParticleChangeForLoss.hh" 56 #include "G4ParticleChangeForLoss.hh" 56 #include "G4ParticleChangeForGamma.hh" 57 #include "G4ParticleChangeForGamma.hh" 57 #include "G4EmParameters.hh" << 58 #include "G4SystemOfUnits.hh" << 59 #include "G4EmUtility.hh" << 60 #include "G4Log.hh" << 61 #include "Randomize.hh" << 62 #include <iostream> << 63 58 64 //....oooOO0OOooo........oooOO0OOooo........oo 59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 65 //....oooOO0OOooo........oooOO0OOooo........oo 60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 66 61 67 G4VEmModel::G4VEmModel(const G4String& nam): 62 G4VEmModel::G4VEmModel(const G4String& nam): 68 inveplus(1.0/CLHEP::eplus), << 63 fluc(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV), 69 lowLimit(0.1*CLHEP::keV), << 64 eMinActive(0.0),eMaxActive(DBL_MAX), 70 highLimit(100.0*CLHEP::TeV), << 65 polarAngleLimit(0.0),secondaryThreshold(DBL_MAX),theLPMflag(false), 71 polarAngleLimit(CLHEP::pi), << 66 pParticleChange(0),nuclearStopping(false), 72 name(nam) << 67 currentCouple(0),currentElement(0), >> 68 nsec(5),flagDeexcitation(false) 73 { 69 { 74 xsec.resize(nsec); 70 xsec.resize(nsec); 75 fEmManager = G4LossTableManager::Instance(); << 71 nSelectors = 0; 76 fEmManager->Register(this); << 72 G4LossTableManager::Instance()->Register(this); 77 isMaster = fEmManager->IsMaster(); << 78 << 79 G4LossTableBuilder* bld = fEmManager->GetTab << 80 theDensityFactor = bld->GetDensityFactors(); << 81 theDensityIdx = bld->GetCoupleIndexes(); << 82 } 73 } 83 74 84 //....oooOO0OOooo........oooOO0OOooo........oo 75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 85 76 86 G4VEmModel::~G4VEmModel() 77 G4VEmModel::~G4VEmModel() 87 { 78 { 88 if(localElmSelectors) { << 79 G4LossTableManager::Instance()->DeRegister(this); 89 for(G4int i=0; i<nSelectors; ++i) { << 80 G4int n = elmSelectors.size(); 90 delete (*elmSelectors)[i]; << 81 if(n > 0) { >> 82 for(G4int i=0; i<n; i++) { >> 83 delete elmSelectors[i]; 91 } 84 } 92 delete elmSelectors; << 93 } << 94 delete anglModel; << 95 << 96 if(localTable && xSectionTable != nullptr) { << 97 xSectionTable->clearAndDestroy(); << 98 delete xSectionTable; << 99 xSectionTable = nullptr; << 100 } 85 } 101 fEmManager->DeRegister(this); << 102 } 86 } 103 87 104 //....oooOO0OOooo........oooOO0OOooo........oo 88 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 105 89 106 G4ParticleChangeForLoss* G4VEmModel::GetPartic 90 G4ParticleChangeForLoss* G4VEmModel::GetParticleChangeForLoss() 107 { 91 { 108 G4ParticleChangeForLoss* p = nullptr; << 92 G4ParticleChangeForLoss* p = 0; 109 if (pParticleChange != nullptr) { << 93 if (pParticleChange) { 110 p = static_cast<G4ParticleChangeForLoss*>( 94 p = static_cast<G4ParticleChangeForLoss*>(pParticleChange); 111 } else { 95 } else { 112 p = new G4ParticleChangeForLoss(); 96 p = new G4ParticleChangeForLoss(); 113 pParticleChange = p; 97 pParticleChange = p; 114 } 98 } 115 if(fTripletModel != nullptr) { fTripletModel << 116 return p; 99 return p; 117 } 100 } 118 101 119 //....oooOO0OOooo........oooOO0OOooo........oo 102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 120 103 121 G4ParticleChangeForGamma* G4VEmModel::GetParti 104 G4ParticleChangeForGamma* G4VEmModel::GetParticleChangeForGamma() 122 { 105 { 123 G4ParticleChangeForGamma* p = nullptr; << 106 G4ParticleChangeForGamma* p = 0; 124 if (pParticleChange != nullptr) { << 107 if (pParticleChange) { 125 p = static_cast<G4ParticleChangeForGamma*> 108 p = static_cast<G4ParticleChangeForGamma*>(pParticleChange); 126 } else { 109 } else { 127 p = new G4ParticleChangeForGamma(); 110 p = new G4ParticleChangeForGamma(); 128 pParticleChange = p; 111 pParticleChange = p; 129 } 112 } 130 if(fTripletModel != nullptr) { fTripletModel << 131 return p; 113 return p; 132 } 114 } 133 115 134 //....oooOO0OOooo........oooOO0OOooo........oo 116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 135 117 136 void G4VEmModel::InitialiseElementSelectors(co << 118 void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p, 137 co << 119 const G4DataVector& cuts) 138 { 120 { 139 if(highLimit <= lowLimit) { return; } << 121 // initialise before run 140 G4EmUtility::InitialiseElementSelectors(this << 122 flagDeexcitation = false; 141 localElmSelectors = true; << 142 } << 143 << 144 //....oooOO0OOooo........oooOO0OOooo........oo << 145 << 146 void G4VEmModel::InitialiseLocal(const G4Parti << 147 {} << 148 123 149 //....oooOO0OOooo........oooOO0OOooo........oo << 124 G4int nbins = G4int(std::log10(highLimit/lowLimit) + 0.5); 150 << 125 if(nbins < 3) nbins = 3; 151 void G4VEmModel::InitialiseForMaterial(const G << 126 G4bool spline = G4LossTableManager::Instance()->SplineFlag(); 152 const G << 127 153 { << 128 G4ProductionCutsTable* theCoupleTable= 154 if(material != nullptr) { << 129 G4ProductionCutsTable::GetProductionCutsTable(); 155 G4int n = (G4int)material->GetNumberOfElem << 130 G4int numOfCouples = theCoupleTable->GetTableSize(); 156 for(G4int i=0; i<n; ++i) { << 131 157 G4int Z = material->GetElement(i)->GetZa << 132 // prepare vector 158 InitialiseForElement(part, Z); << 133 if(numOfCouples > nSelectors) elmSelectors.reserve(numOfCouples); >> 134 >> 135 // initialise vector >> 136 for(G4int i=0; i<numOfCouples; i++) { >> 137 currentCouple = theCoupleTable->GetMaterialCutsCouple(i); >> 138 const G4Material* material = currentCouple->GetMaterial(); >> 139 G4int idx = currentCouple->GetIndex(); >> 140 >> 141 // selector already exist check if should be deleted >> 142 G4bool create = true; >> 143 if(i < nSelectors) { >> 144 if(elmSelectors[i]) { >> 145 if(material == elmSelectors[i]->GetMaterial()) create = false; >> 146 else delete elmSelectors[i]; >> 147 } >> 148 } else { >> 149 nSelectors++; >> 150 elmSelectors.push_back(0); 159 } 151 } 160 } << 152 if(create) { >> 153 elmSelectors[i] = new G4EmElementSelector(this,material,nbins, >> 154 lowLimit,highLimit,spline); >> 155 } >> 156 elmSelectors[i]->Initialise(p, cuts[idx]); >> 157 //elmSelectors[i]->Dump(p); >> 158 } 161 } 159 } 162 160 163 //....oooOO0OOooo........oooOO0OOooo........oo 161 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 164 162 165 void G4VEmModel::InitialiseForElement(const G4 << 166 {} << 167 << 168 //....oooOO0OOooo........oooOO0OOooo........oo << 169 << 170 G4double G4VEmModel::ComputeDEDXPerVolume(cons 163 G4double G4VEmModel::ComputeDEDXPerVolume(const G4Material*, 171 cons << 164 const G4ParticleDefinition*, 172 G4do << 165 G4double,G4double) 173 { 166 { 174 return 0.0; 167 return 0.0; 175 } 168 } 176 169 177 //....oooOO0OOooo........oooOO0OOooo........oo 170 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 178 171 179 G4double G4VEmModel::CrossSectionPerVolume(con << 172 G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material, 180 con << 173 const G4ParticleDefinition* p, 181 G4d << 174 G4double ekin, 182 G4d << 175 G4double emin, 183 G4d << 176 G4double emax) 184 { << 177 { 185 SetupForMaterial(p, mat, ekin); << 178 SetupForMaterial(p, material, ekin); 186 const G4double* theAtomNumDensityVector = ma << 179 G4double cross = 0.0; 187 G4int nelm = (G4int)mat->GetNumberOfElements << 180 const G4ElementVector* theElementVector = material->GetElementVector(); >> 181 const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume(); >> 182 G4int nelm = material->GetNumberOfElements(); 188 if(nelm > nsec) { 183 if(nelm > nsec) { 189 xsec.resize(nelm); 184 xsec.resize(nelm); 190 nsec = nelm; 185 nsec = nelm; 191 } 186 } 192 G4double cross = 0.0; << 187 for (G4int i=0; i<nelm; i++) { 193 for (G4int i=0; i<nelm; ++i) { << 194 cross += theAtomNumDensityVector[i]* 188 cross += theAtomNumDensityVector[i]* 195 ComputeCrossSectionPerAtom(p,mat->GetEle << 189 ComputeCrossSectionPerAtom(p,(*theElementVector)[i],ekin,emin,emax); 196 xsec[i] = cross; 190 xsec[i] = cross; 197 } 191 } 198 return cross; 192 return cross; 199 } 193 } 200 194 201 //....oooOO0OOooo........oooOO0OOooo........oo 195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 202 196 203 G4double G4VEmModel::GetPartialCrossSection(co << 204 co << 205 G4 << 206 { << 207 return 0.0; << 208 } << 209 << 210 //....oooOO0OOooo........oooOO0OOooo........oo << 211 << 212 void G4VEmModel::StartTracking(G4Track*) << 213 {} << 214 << 215 //....oooOO0OOooo........oooOO0OOooo........oo << 216 << 217 const G4Element* G4VEmModel::SelectRandomAtom( << 218 << 219 << 220 << 221 << 222 { << 223 G4int n = (G4int)mat->GetNumberOfElements(); << 224 fCurrentElement = mat->GetElement(0); << 225 if (n > 1) { << 226 const G4double x = G4UniformRand()* << 227 G4VEmModel::CrossSectionPerVolume(mat,pd << 228 for(G4int i=0; i<n; ++i) { << 229 if (x <= xsec[i]) { << 230 fCurrentElement = mat->GetElement(i); << 231 break; << 232 } << 233 } << 234 } << 235 return fCurrentElement; << 236 } << 237 << 238 //....oooOO0OOooo........oooOO0OOooo........oo << 239 << 240 const G4Element* G4VEmModel::GetCurrentElement << 241 { << 242 const G4Element* elm = fCurrentElement; << 243 if(nullptr == elm && nullptr != mat) { << 244 elm = G4EmUtility::SampleRandomElement(mat << 245 } << 246 return elm; << 247 } << 248 << 249 //....oooOO0OOooo........oooOO0OOooo........oo << 250 << 251 G4int G4VEmModel::SelectRandomAtomNumber(const << 252 { << 253 const G4Element* elm = GetCurrentElement(mat << 254 return (nullptr == elm) ? 0 : elm->GetZasInt << 255 } << 256 << 257 //....oooOO0OOooo........oooOO0OOooo........oo << 258 << 259 const G4Isotope* G4VEmModel::GetCurrentIsotope << 260 { << 261 const G4Isotope* iso = nullptr; << 262 const G4Element* el = elm; << 263 if(nullptr == el && nullptr != fCurrentCoupl << 264 el = GetCurrentElement(fCurrentCouple->Get << 265 } << 266 if(nullptr != el) { << 267 iso = G4EmUtility::SampleRandomIsotope(el) << 268 } << 269 return iso; << 270 } << 271 << 272 //....oooOO0OOooo........oooOO0OOooo........oo << 273 << 274 G4int G4VEmModel::SelectIsotopeNumber(const G4 << 275 { << 276 auto iso = GetCurrentIsotope(elm); << 277 return (nullptr != iso) ? iso->GetN() : 0; << 278 } << 279 << 280 //....oooOO0OOooo........oooOO0OOooo........oo << 281 << 282 G4double G4VEmModel::ComputeCrossSectionPerAto 197 G4double G4VEmModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*, 283 << 198 G4double, G4double, G4double, 284 << 199 G4double, G4double) 285 { << 286 return 0.0; << 287 } << 288 << 289 //....oooOO0OOooo........oooOO0OOooo........oo << 290 << 291 G4double << 292 G4VEmModel::ComputeCrossSectionPerShell(const << 293 G4int, << 294 G4doub << 295 { 200 { 296 return 0.0; 201 return 0.0; 297 } 202 } 298 203 299 //....oooOO0OOooo........oooOO0OOooo........oo 204 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 300 205 301 void G4VEmModel::DefineForRegion(const G4Regio 206 void G4VEmModel::DefineForRegion(const G4Region*) 302 {} 207 {} 303 208 304 //....oooOO0OOooo........oooOO0OOooo........oo 209 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 305 210 306 void G4VEmModel::FillNumberOfSecondaries(G4int << 211 G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*, 307 G4int << 212 const G4MaterialCutsCouple*) 308 { 213 { 309 numberOfTriplets = 0; << 214 return 0.0; 310 numberOfRecoil = 0; << 311 } << 312 << 313 //....oooOO0OOooo........oooOO0OOooo........oo << 314 << 315 G4double G4VEmModel::ChargeSquareRatio(const G << 316 { << 317 return GetChargeSquareRatio(track.GetParticl << 318 track.GetMateria << 319 } 215 } 320 216 321 //....oooOO0OOooo........oooOO0OOooo........oo 217 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 322 218 323 G4double G4VEmModel::GetChargeSquareRatio(cons 219 G4double G4VEmModel::GetChargeSquareRatio(const G4ParticleDefinition* p, 324 cons << 220 const G4Material*, G4double) 325 { 221 { 326 const G4double q = p->GetPDGCharge()*inveplu << 222 G4double q = p->GetPDGCharge()/CLHEP::eplus; 327 return q*q; 223 return q*q; 328 } 224 } 329 225 330 //....oooOO0OOooo........oooOO0OOooo........oo 226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 331 227 332 G4double G4VEmModel::GetParticleCharge(const G 228 G4double G4VEmModel::GetParticleCharge(const G4ParticleDefinition* p, 333 const G << 229 const G4Material*, G4double) 334 { 230 { 335 return p->GetPDGCharge(); 231 return p->GetPDGCharge(); 336 } 232 } 337 233 338 //....oooOO0OOooo........oooOO0OOooo........oo 234 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 339 235 340 void G4VEmModel::CorrectionsAlongStep(const G4 236 void G4VEmModel::CorrectionsAlongStep(const G4MaterialCutsCouple*, 341 const G4 << 237 const G4DynamicParticle*, 342 const G4 << 238 G4double&,G4double&,G4double) 343 {} 239 {} 344 240 345 //....oooOO0OOooo........oooOO0OOooo........oo 241 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 346 242 347 G4double G4VEmModel::Value(const G4MaterialCut << 243 void G4VEmModel::SampleDeexcitationAlongStep(const G4Material*, 348 const G4ParticleDef << 244 const G4Track&, 349 { << 245 G4double& ) 350 SetCurrentCouple(couple); << 246 {} 351 return pFactor*e*e*CrossSectionPerVolume(pBa << 352 } << 353 << 354 //....oooOO0OOooo........oooOO0OOooo........oo << 355 << 356 G4double G4VEmModel::MinPrimaryEnergy(const G4 << 357 const G4 << 358 G4double << 359 { << 360 return 0.0; << 361 } << 362 << 363 //....oooOO0OOooo........oooOO0OOooo........oo << 364 << 365 G4double G4VEmModel::MinEnergyCut(const G4Part << 366 const G4Mate << 367 { << 368 return 0.0; << 369 } << 370 247 371 //....oooOO0OOooo........oooOO0OOooo........oo 248 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 372 249 373 G4double G4VEmModel::MaxSecondaryEnergy(const 250 G4double G4VEmModel::MaxSecondaryEnergy(const G4ParticleDefinition*, 374 G4doub << 251 G4double kineticEnergy) 375 { 252 { 376 return kineticEnergy; 253 return kineticEnergy; 377 } 254 } 378 255 379 //....oooOO0OOooo........oooOO0OOooo........oo 256 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 380 257 381 void G4VEmModel::SetupForMaterial(const G4Part << 258 void G4VEmModel::SetupForMaterial(const G4ParticleDefinition*, 382 const G4Mate << 259 const G4Material*, G4double) 383 { << 384 GetChargeSquareRatio(p, mat, ekin); << 385 } << 386 << 387 //....oooOO0OOooo........oooOO0OOooo........oo << 388 << 389 void << 390 G4VEmModel::SetParticleChange(G4VParticleChang << 391 { << 392 if(p != nullptr && pParticleChange != p) { p << 393 if(flucModel != f) { flucModel = f; } << 394 } << 395 << 396 //....oooOO0OOooo........oooOO0OOooo........oo << 397 << 398 void G4VEmModel::SetCrossSectionTable(G4Physic << 399 { << 400 xSectionTable = p; << 401 localTable = isLocal; << 402 } << 403 << 404 //....oooOO0OOooo........oooOO0OOooo........oo << 405 << 406 void G4VEmModel::SetLPMFlag(G4bool) << 407 { << 408 if (G4EmParameters::Instance()->Verbose() > << 409 G4ExceptionDescription ed; << 410 ed << "The obsolete method SetLPMFlag(..) << 411 << " is called. Please, use G4EmParamet << 412 << " instead"; << 413 G4Exception("G4VEmModel::SetLPMFlag", "em0 << 414 } << 415 } << 416 << 417 //....oooOO0OOooo........oooOO0OOooo........oo << 418 << 419 void G4VEmModel::SetMasterThread(G4bool) << 420 {} 260 {} 421 << 422 //....oooOO0OOooo........oooOO0OOooo........oo << 423 << 424 void G4VEmModel::ModelDescription(std::ostrea << 425 { << 426 outFile << "The description for this model h << 427 } << 428 261 429 //....oooOO0OOooo........oooOO0OOooo........oo 262 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 430 263