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: G4EmConfigurator.cc,v 1.6 2009/11/22 19:48:30 vnivanch Exp $ >> 27 // GEANT4 tag $Name: geant4-09-03 $ 26 // 28 // 27 // ------------------------------------------- 29 // ------------------------------------------------------------------- 28 // 30 // 29 // GEANT4 Class 31 // GEANT4 Class 30 // 32 // 31 // File name: G4EmConfigurator 33 // File name: G4EmConfigurator 32 // 34 // 33 // Author: Vladimir Ivanchenko 35 // Author: Vladimir Ivanchenko 34 // 36 // 35 // Creation date: 14.07.2008 37 // Creation date: 14.07.2008 36 // 38 // 37 // Modifications: 39 // Modifications: 38 // 40 // 39 // Class Description: 41 // Class Description: 40 // 42 // 41 // This class provides configuration EM models 43 // This class provides configuration EM models for 42 // particles/processes/regions 44 // particles/processes/regions 43 // 45 // 44 46 45 // ------------------------------------------- 47 // ------------------------------------------------------------------- 46 // 48 // 47 49 48 #include "G4EmConfigurator.hh" 50 #include "G4EmConfigurator.hh" 49 #include "G4EmUtility.hh" << 50 #include "G4SystemOfUnits.hh" << 51 #include "G4ParticleTable.hh" 51 #include "G4ParticleTable.hh" 52 #include "G4ParticleDefinition.hh" 52 #include "G4ParticleDefinition.hh" 53 #include "G4ProcessManager.hh" 53 #include "G4ProcessManager.hh" 54 #include "G4VProcess.hh" 54 #include "G4VProcess.hh" 55 #include "G4ProcessVector.hh" 55 #include "G4ProcessVector.hh" 56 #include "G4RegionStore.hh" 56 #include "G4RegionStore.hh" 57 #include "G4Region.hh" 57 #include "G4Region.hh" 58 #include "G4DummyModel.hh" 58 #include "G4DummyModel.hh" 59 #include "G4VEnergyLossProcess.hh" 59 #include "G4VEnergyLossProcess.hh" 60 #include "G4VEmProcess.hh" 60 #include "G4VEmProcess.hh" 61 #include "G4VMultipleScattering.hh" 61 #include "G4VMultipleScattering.hh" 62 #include "G4TransportationWithMsc.hh" << 62 >> 63 enum PType {unknown=0, eloss, discrete, msc}; 63 64 64 //....oooOO0OOooo........oooOO0OOooo........oo 65 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 65 66 66 G4EmConfigurator::G4EmConfigurator(G4int val): << 67 G4EmConfigurator::G4EmConfigurator() 67 { 68 { 68 index = -10; 69 index = -10; 69 } 70 } 70 71 71 //....oooOO0OOooo........oooOO0OOooo........oo 72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 72 73 73 G4EmConfigurator::~G4EmConfigurator() = defaul << 74 G4EmConfigurator::~G4EmConfigurator() >> 75 {} 74 76 75 //....oooOO0OOooo........oooOO0OOooo........oo 77 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 76 78 77 void G4EmConfigurator::SetExtraEmModel(const G << 79 void G4EmConfigurator::AddExtraEmModel(const G4String& particleName, 78 const G << 80 G4VEmModel* em, 79 G4VEmMo << 81 G4VEmFluctuationModel* fm) 80 const G << 81 G4doubl << 82 G4doubl << 83 G4VEmFl << 84 { 82 { 85 if(nullptr == mod) { return; } << 83 particleList.push_back(particleName); 86 if(1 < verbose) { << 84 modelList.push_back(em); 87 G4cout << " G4EmConfigurator::SetExtraEmMo << 85 flucModelList.push_back(fm); 88 << " for " << particleName << 86 } 89 << " and " << processName << 90 << " in the region <" << regionName << 91 << "> Emin(MeV)= " << emin/MeV << 92 << " Emax(MeV)= " << emax/MeV << 93 << G4endl; << 94 } << 95 87 96 models.push_back(mod); << 88 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 97 flucModels.push_back(fm); << 98 G4double emin0 = std::max(emin, mod->LowEner << 99 G4double emax0 = std::min(emax, mod->HighEne << 100 mod->SetActivationHighEnergyLimit(emax0); << 101 89 >> 90 void G4EmConfigurator::AddModelForRegion(const G4String& particleName, >> 91 const G4String& processName, >> 92 const G4String& modelName, >> 93 const G4String& regionName, >> 94 G4double emin, G4double emax, >> 95 const G4String& flucModelName) >> 96 { 102 particles.push_back(particleName); 97 particles.push_back(particleName); 103 processes.push_back(processName); 98 processes.push_back(processName); >> 99 models.push_back(modelName); 104 regions.push_back(regionName); 100 regions.push_back(regionName); 105 lowEnergy.push_back(emin0); << 101 flucModels.push_back(flucModelName); 106 highEnergy.push_back(emax0); << 102 lowEnergy.push_back(emin); >> 103 highEnergy.push_back(emax); >> 104 } >> 105 >> 106 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... >> 107 >> 108 void G4EmConfigurator::SetExtraEmModel(const G4String& particleName, >> 109 const G4String& processName, >> 110 G4VEmModel* mod, >> 111 const G4String& regionName, >> 112 G4double emin, >> 113 G4double emax, >> 114 G4VEmFluctuationModel* fm) >> 115 { >> 116 AddExtraEmModel(particleName, mod, fm); >> 117 G4String fname = ""; >> 118 if(fm) fname = fm->GetName(); >> 119 G4String mname = ""; >> 120 if(mod) mname = mod->GetName(); >> 121 AddModelForRegion(particleName, processName, mname, regionName, >> 122 emin, emax, fname); 107 } 123 } 108 124 109 //....oooOO0OOooo........oooOO0OOooo........oo 125 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 110 126 111 void G4EmConfigurator::AddModels() 127 void G4EmConfigurator::AddModels() 112 { 128 { 113 size_t n = models.size(); << 129 size_t n = particles.size(); 114 if(1 < verbose) { << 130 //G4cout << " G4EmConfigurator::AddModels n= " << n << G4endl; 115 G4cout << "### G4EmConfigurator::AddModels << 116 } << 117 if(n > 0) { 131 if(n > 0) { 118 for(size_t i=0; i<n; ++i) { << 132 for(size_t i=0; i<n; i++) { 119 if(nullptr != models[i]) { << 133 SetModelForRegion(particles[i],processes[i],models[i],regions[i], 120 const G4Region* reg = G4EmUtility::Fin << 134 flucModels[i],lowEnergy[i],highEnergy[i]); 121 if(nullptr != reg) { << 122 --index; << 123 SetModelForRegion(models[i],flucMode << 124 particles[i],proce << 125 lowEnergy[i],highE << 126 } << 127 } << 128 } 135 } 129 } 136 } 130 Clear(); << 137 particles.clear(); >> 138 processes.clear(); >> 139 models.clear(); >> 140 flucModels.clear(); >> 141 regions.clear(); >> 142 lowEnergy.clear(); >> 143 highEnergy.clear(); 131 } 144 } 132 145 133 //....oooOO0OOooo........oooOO0OOooo........oo 146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 134 147 135 void G4EmConfigurator::SetModelForRegion(G4VEm << 148 void G4EmConfigurator::SetModelForRegion(const G4String& particleName, 136 G4VEm << 149 const G4String& processName, 137 const << 150 const G4String& modelName, 138 const << 151 const G4String& regionName, 139 const << 152 const G4String& flucModelName, 140 G4dou << 153 G4double emin, G4double emax) 141 { 154 { 142 if(nullptr == mod) { return; } << 155 //G4cout << " G4EmConfigurator::SetModelForRegion" << G4endl; 143 if(1 < verbose) { << 156 144 G4cout << " G4EmConfigurator::SetModelForR << 157 // new set 145 << G4endl; << 158 --index; 146 G4cout << " For " << particleName << 159 147 << " and " << processName << 160 G4ParticleTable::G4PTblDicIterator* theParticleIterator = 148 << " in the region <" << reg->GetNa << 161 G4ParticleTable::GetParticleTable()->GetIterator(); 149 << " Emin(MeV)= " << emin/MeV << 162 150 << " Emax(MeV)= " << emax/MeV; << 163 theParticleIterator->reset(); 151 if(nullptr != fm) { G4cout << " FLmodel " << 164 while( (*theParticleIterator)() ) { 152 G4cout << G4endl; << 165 const G4ParticleDefinition* part = theParticleIterator->value(); 153 } << 166 >> 167 //G4cout << particleName << " " << part->GetParticleName() << G4endl; >> 168 >> 169 if(particleName == part->GetParticleName() || >> 170 (particleName == "charged" && part->GetPDGCharge() != 0.0) ) { 154 171 155 // Loop checking, 03-Aug-2015, Vladimir Ivan << 156 auto myParticleIterator = G4ParticleTable::G << 157 myParticleIterator->reset(); << 158 while( (*myParticleIterator)() ) { << 159 const G4ParticleDefinition* part = myParti << 160 << 161 if((part->GetParticleName() == particleNam << 162 (particleName == "all") || << 163 (particleName == "charged" && part->Get << 164 172 165 // search for process 173 // search for process 166 G4ProcessManager* pmanager = part->GetPr 174 G4ProcessManager* pmanager = part->GetProcessManager(); 167 G4ProcessVector* plist = pmanager->GetPr 175 G4ProcessVector* plist = pmanager->GetProcessList(); 168 G4int np = pmanager->GetProcessListLengt 176 G4int np = pmanager->GetProcessListLength(); 169 177 170 if(1 < verbose) { << 178 //G4cout << processName << " in list of " << np << G4endl; 171 G4cout << "Check process <" << process << 172 << np << " processes" << G4endl << 173 } << 174 G4VProcess* proc = nullptr; << 175 for(G4int i=0; i<np; ++i) { << 176 if(processName == (*plist)[i]->GetProc << 177 proc = (*plist)[i]; << 178 break; << 179 } << 180 } << 181 if(nullptr == proc) { << 182 if(processName == "msc") { << 183 for (G4int i = 0; i < np; ++i) { << 184 auto* trans = dynamic_cast<G4Trans << 185 if (nullptr != trans) { << 186 G4cout << "G4TransportationWithM << 187 proc = trans; << 188 break; << 189 } << 190 } << 191 } << 192 if (nullptr == proc) { << 193 if (0 < verbose) { << 194 G4cout << "### G4EmConfigurator WA << 195 << "> for " << particleName << 196 } << 197 return; << 198 } << 199 } << 200 179 201 if(!UpdateModelEnergyRange(mod, emin, em << 180 G4VProcess* proc = 0; 202 // classify process << 181 for(G4int i=0; i<np; i++) { 203 G4int ii = proc->GetProcessSubType(); << 182 if(processName == (*plist)[i]->GetProcessName()) { 204 auto msc = dynamic_cast<G4VMscModel*>(mo << 183 proc = (*plist)[i]; 205 if (nullptr != msc) { << 184 break; 206 if (auto* trans = dynamic_cast<G4Trans << 185 } 207 trans->AddMscModel(msc, index, reg); << 208 if (1 < verbose) { << 209 G4cout << "### Added msc model ord << 210 << proc->GetProcessName() < << 211 } << 212 } << 213 else if (10 == ii) { << 214 auto p = dynamic_cast<G4VMultipleSca << 215 if (nullptr != p) { << 216 p->AddEmModel(index, msc, reg); << 217 if (1 < verbose) { << 218 G4cout << "### Added msc model o << 219 << processName << G4endl; << 220 } << 221 } << 222 } << 223 else { << 224 G4cout << "### Unable to add msc mod << 225 << G4endl; << 226 } << 227 } << 228 else if (2 <= ii && 4 >= ii) { << 229 auto p = dynamic_cast<G4VEnergyLossPro << 230 if (nullptr != p) { << 231 p->AddEmModel(index, mod, fm, reg); << 232 if (1 < verbose) { << 233 G4cout << "### Added eloss model o << 234 << processName << G4endl; << 235 } << 236 } << 237 } 186 } 238 else { << 187 if(!proc) { 239 auto p = dynamic_cast<G4VEmProcess*>(p << 188 G4cout << "### G4EmConfigurator WARNING: fails to find a process <" 240 if (nullptr != p) { << 189 << processName << "> for " << particleName << G4endl; 241 p->AddEmModel(index, mod, reg); << 190 242 if (1 < verbose) { << 191 } else { 243 G4cout << "### Added em model orde << 192 244 << processName << G4endl; << 193 // classify process 245 } << 194 PType ptype = discrete; 246 } << 195 G4int ii = proc->GetProcessSubType(); 247 else { << 196 if(10 == ii) ptype = msc; 248 G4cout << "### Unable to add em mode << 197 else if(2 <= ii && 4 >= ii) ptype = eloss; 249 << G4endl; << 198 250 } << 199 // find out model >> 200 G4VEmModel* mod = 0; >> 201 G4VEmFluctuationModel* fluc = 0; >> 202 >> 203 G4int nm = modelList.size(); >> 204 //G4cout << "Search model " << modelName << " in " << nm << G4endl; >> 205 >> 206 for(G4int i=0; i<nm; i++) { >> 207 G4String mname = ""; >> 208 if(modelList[i]) mname = modelList[i]->GetName(); >> 209 G4String fname = ""; >> 210 if(flucModelList[i]) fname = flucModelList[i]->GetName(); >> 211 if(modelName == mname && flucModelName == fname && >> 212 (particleList[i] == "" || particleList[i] == particleName) ) { >> 213 mod = modelList[i]; >> 214 fluc = flucModelList[i]; >> 215 break; >> 216 } >> 217 } >> 218 >> 219 if("dummy" == modelName) mod = new G4DummyModel(); >> 220 >> 221 if(!mod) { >> 222 >> 223 // set fluctuation model for ionisation processes >> 224 if(fluc && ptype == eloss) { >> 225 G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc); >> 226 p->SetFluctModel(fluc); >> 227 >> 228 } else { >> 229 G4cout << "### G4EmConfigurator WARNING: fails to find a model <" >> 230 << modelName << "> for process <" >> 231 << processName << "> and " << particleName >> 232 << G4endl; >> 233 if(flucModelName != "") { >> 234 G4cout << " fluctuation model <" >> 235 << flucModelName << G4endl; >> 236 } >> 237 } >> 238 } else { >> 239 >> 240 // search for region >> 241 G4Region* reg = 0; >> 242 G4RegionStore* regStore = G4RegionStore::GetInstance(); >> 243 G4String r = regionName; >> 244 if(r == "" || r == "world" || r == "World") r = "DefaultRegionForTheWorld"; >> 245 reg = regStore->GetRegion(r, true); >> 246 if(!reg) { >> 247 G4cout << "### G4EmConfigurator WARNING: fails to find a region <" >> 248 << r << "> for model <" << modelName << "> of the process " >> 249 << processName << " and " << particleName << G4endl; >> 250 return; >> 251 } >> 252 >> 253 // energy limits >> 254 G4double e1 = std::max(emin,mod->LowEnergyLimit()); >> 255 G4double e2 = std::min(emax,mod->HighEnergyLimit()); >> 256 if(e2 < e1) e2 = e1; >> 257 mod->SetLowEnergyLimit(e1); >> 258 mod->SetHighEnergyLimit(e2); >> 259 >> 260 //G4cout << "index= " << index << " e1= " << e1 << " e2= " << e2 << G4endl; >> 261 >> 262 // added model >> 263 if(ptype == eloss) { >> 264 G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc); >> 265 p->AddEmModel(index,mod,fluc,reg); >> 266 //G4cout << "### Added eloss model order= " << index << " for " >> 267 // << particleName << " and " << processName << " " << mod << G4endl; >> 268 } else if(ptype == discrete) { >> 269 G4VEmProcess* p = static_cast<G4VEmProcess*>(proc); >> 270 p->AddEmModel(index,mod,reg); >> 271 } else if(ptype == msc) { >> 272 //G4cout << "### Added msc model order= " << index << " for " >> 273 // << particleName << " and " << processName << " " << mod << G4endl; >> 274 G4VMultipleScattering* p = static_cast<G4VMultipleScattering*>(proc); >> 275 p->AddEmModel(index,mod,reg); >> 276 } >> 277 } 251 } 278 } 252 return; << 253 } 279 } 254 } 280 } 255 } 281 } 256 282 257 //....oooOO0OOooo........oooOO0OOooo........oo 283 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 258 284 259 void << 260 G4EmConfigurator::PrepareModels(const G4Partic << 261 G4VEnergyLossP << 262 { << 263 size_t n = particles.size(); << 264 if(1 < verbose) { << 265 G4cout << " G4EmConfigurator::PrepareModel << 266 << n << G4endl; << 267 } << 268 if(n > 0) { << 269 G4String particleName = aParticle->GetPart << 270 G4String processName = p->GetProcessName( << 271 //G4cout << particleName << " " << proc << 272 for(size_t i=0; i<n; ++i) { << 273 //G4cout << particles[i] << " " << pr << 274 if(processName == processes[i]) { << 275 if((particleName == particles[i]) || << 276 (particles[i] == "all") || << 277 (particles[i] == "charged" && aPart << 278 const G4Region* reg = G4EmUtility::F << 279 //G4cout << "Region " << reg << G4en << 280 if(nullptr != reg) { << 281 --index; << 282 G4VEmModel* mod = models[i]; << 283 G4VEmFluctuationModel* fm = flucMo << 284 if(nullptr != mod) { << 285 if(UpdateModelEnergyRange(mod, l << 286 p->AddEmModel(index,mod,fm,reg << 287 if(1 < verbose) { << 288 G4cout << "### Added eloss m << 289 << " and " << process << 290 } << 291 } << 292 } else if(nullptr != fm) { << 293 p->SetFluctModel(fm); << 294 } << 295 } << 296 } << 297 } << 298 } << 299 } << 300 } << 301 285 302 //....oooOO0OOooo........oooOO0OOooo........oo << 303 286 304 void << 305 G4EmConfigurator::PrepareModels(const G4Partic << 306 G4VEmProcess* << 307 { << 308 size_t n = particles.size(); << 309 if(1 < verbose) { << 310 G4cout << " G4EmConfigurator::PrepareModel << 311 << n << G4endl; << 312 } << 313 if(n > 0) { << 314 G4String particleName = aParticle->GetPart << 315 G4String processName = p->GetProcessName( << 316 //G4cout << particleName << " " << part << 317 for(size_t i=0; i<n; ++i) { << 318 if(processName == processes[i]) { << 319 if((particleName == particles[i]) || << 320 (particles[i] == "all") || << 321 (particles[i] == "charged" && aPart << 322 const G4Region* reg = G4EmUtility::F << 323 //G4cout << "Region " << reg << G4en << 324 if(nullptr != reg) { << 325 --index; << 326 G4VEmModel* mod = models[i]; << 327 if(nullptr != mod) { << 328 if(UpdateModelEnergyRange(mod, l << 329 p->AddEmModel(index,mod,reg); << 330 if(1 < verbose) { << 331 G4cout << "### Added em mode << 332 << particleName << " << 333 } << 334 } << 335 } << 336 } << 337 } << 338 } << 339 } << 340 } << 341 } << 342 287 343 //....oooOO0OOooo........oooOO0OOooo........oo << 344 288 345 void << 346 G4EmConfigurator::PrepareModels(const G4Partic << 347 G4VMultipleSca << 348 G4Transportati << 349 { << 350 size_t n = particles.size(); << 351 if(1 < verbose) { << 352 G4cout << " G4EmConfigurator::PrepareModel << 353 << n << G4endl; << 354 } << 355 289 356 if(n > 0) { << 357 G4String particleName = aParticle->GetPart << 358 G4String processName = (nullptr == p) ? G4 << 359 for(size_t i=0; i<n; ++i) { << 360 if(processName == processes[i]) { << 361 if ((particleName == particles[i]) || << 362 || (particles[i] == "charged" && a << 363 { << 364 const G4Region* reg = G4EmUtility::F << 365 if (nullptr != reg) { << 366 --index; << 367 auto mod = dynamic_cast<G4VMscMode << 368 if(nullptr != mod) { << 369 if(UpdateModelEnergyRange(mod, l << 370 if(nullptr != p) { << 371 p->AddEmModel(index, mod, re << 372 } << 373 else { << 374 trans->AddMscModel(mod, inde << 375 } << 376 //G4cout << "### Added msc mod << 377 // << particleName << " and << 378 } << 379 } << 380 } << 381 } << 382 } << 383 } << 384 } << 385 } << 386 290 387 //....oooOO0OOooo........oooOO0OOooo........oo << 388 << 389 void G4EmConfigurator::Clear() << 390 { << 391 particles.clear(); << 392 processes.clear(); << 393 models.clear(); << 394 flucModels.clear(); << 395 regions.clear(); << 396 lowEnergy.clear(); << 397 highEnergy.clear(); << 398 } << 399 291 400 //....oooOO0OOooo........oooOO0OOooo........oo << 401 << 402 G4bool G4EmConfigurator::UpdateModelEnergyRang << 403 << 404 { << 405 // energy limits << 406 G4double e1 = std::max(emin,mod->LowEnergyLi << 407 G4double e2 = std::min(emax,mod->HighEnergyL << 408 if(e2 <= e1) { << 409 G4cout << "### G4EmConfigurator WARNING: e << 410 << " for <" << mod->GetName() << 411 << "> Emin(MeV)= " << e1/CLHEP::Me << 412 << "> Emax(MeV)= " << e2/CLHEP::Me << 413 << G4endl; << 414 return false; << 415 } << 416 mod->SetLowEnergyLimit(e1); << 417 mod->SetHighEnergyLimit(e2); << 418 if(verbose > 1) { << 419 G4cout << "### G4EmConfigurator for " << m << 420 << " Emin(MeV)= " << e1/MeV << " Em << 421 << G4endl; << 422 } << 423 return true; << 424 } << 425 << 426 //....oooOO0OOooo........oooOO0OOooo........oo << 427 292