Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // ------------------------------------------- 27 // 28 // GEANT4 Class file 29 // 30 // 31 // File name: G4LossTableManager 32 // 33 // Author: Vladimir Ivanchenko 34 // 35 // Creation date: 03.01.2002 36 // 37 // Modifications: by V.Ivanchenko 38 // 39 // 40 // Class Description: 41 // 42 // ------------------------------------------- 43 // 44 //....oooOO0OOooo........oooOO0OOooo........oo 45 //....oooOO0OOooo........oooOO0OOooo........oo 46 47 #include "G4LossTableManager.hh" 48 #include "G4SystemOfUnits.hh" 49 50 #include "G4VMultipleScattering.hh" 51 #include "G4VEmProcess.hh" 52 53 #include "G4EmParameters.hh" 54 #include "G4EmSaturation.hh" 55 #include "G4EmConfigurator.hh" 56 #include "G4ElectronIonPair.hh" 57 #include "G4NIELCalculator.hh" 58 #include "G4EmCorrections.hh" 59 #include "G4LossTableBuilder.hh" 60 #include "G4VAtomDeexcitation.hh" 61 #include "G4VSubCutProducer.hh" 62 63 #include "G4PhysicsTable.hh" 64 #include "G4ParticleDefinition.hh" 65 #include "G4MaterialCutsCouple.hh" 66 #include "G4ProcessManager.hh" 67 #include "G4Electron.hh" 68 #include "G4Proton.hh" 69 #include "G4ProductionCutsTable.hh" 70 #include "G4PhysicsTableHelper.hh" 71 #include "G4EmTableType.hh" 72 #include "G4Region.hh" 73 #include "G4PhysicalConstants.hh" 74 75 #include "G4Gamma.hh" 76 #include "G4Positron.hh" 77 #include "G4OpticalPhoton.hh" 78 #include "G4Neutron.hh" 79 #include "G4MuonPlus.hh" 80 #include "G4MuonMinus.hh" 81 #include "G4GenericIon.hh" 82 83 //....oooOO0OOooo........oooOO0OOooo........oo 84 85 static std::once_flag applyOnce; 86 G4ThreadLocal G4LossTableManager* G4LossTableM 87 88 G4LossTableManager* G4LossTableManager::Instan 89 { 90 if(nullptr == instance) { 91 static G4ThreadLocalSingleton<G4LossTableM 92 instance = inst.Instance(); 93 } 94 return instance; 95 } 96 97 //....oooOO0OOooo........oooOO0OOooo........oo 98 99 G4LossTableManager::~G4LossTableManager() 100 { 101 for (auto const & p : loss_vector) { delete 102 for (auto const & p : msc_vector) { delete p 103 for (auto const & p : emp_vector) { delete p 104 for (auto const & p : p_vector) { delete p; 105 106 std::size_t mod = mod_vector.size(); 107 std::size_t fmod = fmod_vector.size(); 108 for (std::size_t a=0; a<mod; ++a) { 109 if( nullptr != mod_vector[a] ) { 110 for (std::size_t b=0; b<fmod; ++b) { 111 if((G4VEmModel*)(fmod_vector[b]) == mo 112 fmod_vector[b] = nullptr; 113 } 114 } 115 delete mod_vector[a]; 116 mod_vector[a] = nullptr; 117 } 118 } 119 for (auto const & p : fmod_vector) { delete 120 121 Clear(); 122 delete tableBuilder; 123 delete emCorrections; 124 delete emConfigurator; 125 delete emElectronIonPair; 126 delete nielCalculator; 127 delete atomDeexcitation; 128 delete subcutProducer; 129 } 130 131 //....oooOO0OOooo........oooOO0OOooo........oo 132 133 G4LossTableManager::G4LossTableManager() 134 { 135 theParameters = G4EmParameters::Instance(); 136 theElectron = G4Electron::Electron(); 137 138 // only one thread is the master 139 std::call_once(applyOnce, [this]() { isMaste 140 verbose = isMaster ? theParameters->Verbose( 141 142 tableBuilder = new G4LossTableBuilder(isMast 143 emCorrections = new G4EmCorrections(verbose) 144 145 std::size_t n = 70; 146 loss_vector.reserve(n); 147 part_vector.reserve(n); 148 base_part_vector.reserve(n); 149 dedx_vector.reserve(n); 150 range_vector.reserve(n); 151 inv_range_vector.reserve(n); 152 tables_are_built.reserve(n); 153 isActive.reserve(n); 154 msc_vector.reserve(10); 155 emp_vector.reserve(16); 156 mod_vector.reserve(150); 157 fmod_vector.reserve(60); 158 } 159 160 //....oooOO0OOooo........oooOO0OOooo........oo 161 162 void G4LossTableManager::Clear() 163 { 164 all_tables_are_built = false; 165 currentLoss = nullptr; 166 currentParticle = nullptr; 167 if(n_loss) { 168 dedx_vector.clear(); 169 range_vector.clear(); 170 inv_range_vector.clear(); 171 loss_map.clear(); 172 loss_vector.clear(); 173 part_vector.clear(); 174 base_part_vector.clear(); 175 tables_are_built.clear(); 176 isActive.clear(); 177 n_loss = 0; 178 } 179 } 180 181 //....oooOO0OOooo........oooOO0OOooo........oo 182 183 void G4LossTableManager::Register(G4VEnergyLos 184 { 185 if (nullptr == p) { return; } 186 for (G4int i=0; i<n_loss; ++i) { 187 if(loss_vector[i] == p) { return; } 188 } 189 if(verbose > 1) { 190 G4cout << "G4LossTableManager::Register G4 191 << p->GetProcessName() << " idx= " 192 } 193 ++n_loss; 194 loss_vector.push_back(p); 195 part_vector.push_back(nullptr); 196 base_part_vector.push_back(nullptr); 197 dedx_vector.push_back(nullptr); 198 range_vector.push_back(nullptr); 199 inv_range_vector.push_back(nullptr); 200 tables_are_built.push_back(false); 201 isActive.push_back(true); 202 all_tables_are_built = false; 203 } 204 205 //....oooOO0OOooo........oooOO0OOooo........oo 206 207 void G4LossTableManager::ResetParameters() 208 { 209 // initialisation once per run 210 if (!resetParam) { return; } 211 resetParam = false; 212 startInitialisation = true; 213 verbose = theParameters->Verbose(); 214 if(!isMaster) { 215 verbose = theParameters->WorkerVerbose(); 216 } else { 217 if(verbose > 0) { theParameters->Dump(); } 218 } 219 220 tableBuilder->InitialiseBaseMaterials(); 221 if (nullptr != nielCalculator) { nielCalcula 222 223 emCorrections->SetVerbose(verbose); 224 if(nullptr != emConfigurator) { emConfigurat 225 if(nullptr != emElectronIonPair) { emElectro 226 if(nullptr != atomDeexcitation) { 227 atomDeexcitation->SetVerboseLevel(verbose) 228 atomDeexcitation->InitialiseAtomicDeexcita 229 } 230 if (1 < verbose) { 231 G4cout << "====== G4LossTableManager::Rese 232 << " Nloss=" << loss_vector.size() 233 << " run=" << run << " master=" << isMast 234 << G4endl; 235 } 236 } 237 238 //....oooOO0OOooo........oooOO0OOooo........oo 239 240 void G4LossTableManager::DeRegister(G4VEnergyL 241 { 242 if (nullptr == p) { return; } 243 for (G4int i=0; i<n_loss; ++i) { 244 if(loss_vector[i] == p) { 245 loss_vector[i] = nullptr; 246 break; 247 } 248 } 249 } 250 251 //....oooOO0OOooo........oooOO0OOooo........oo 252 253 void G4LossTableManager::Register(G4VMultipleS 254 { 255 if (nullptr == p) { return; } 256 std::size_t n = msc_vector.size(); 257 for (std::size_t i=0; i<n; ++i) { 258 if(msc_vector[i] == p) { return; } 259 } 260 if(verbose > 1) { 261 G4cout << "G4LossTableManager::Register G4 262 << p->GetProcessName() << " idx= " 263 } 264 msc_vector.push_back(p); 265 } 266 267 //....oooOO0OOooo........oooOO0OOooo........oo 268 269 void G4LossTableManager::DeRegister(G4VMultipl 270 { 271 if (nullptr == p) { return; } 272 std::size_t msc = msc_vector.size(); 273 for (std::size_t i=0; i<msc; ++i) { 274 if(msc_vector[i] == p) { 275 msc_vector[i] = nullptr; 276 break; 277 } 278 } 279 } 280 281 //....oooOO0OOooo........oooOO0OOooo........oo 282 283 void G4LossTableManager::Register(G4VEmProcess 284 { 285 if (nullptr == p) { return; } 286 std::size_t n = emp_vector.size(); 287 for (std::size_t i=0; i<n; ++i) { 288 if(emp_vector[i] == p) { return; } 289 } 290 if(verbose > 1) { 291 G4cout << "G4LossTableManager::Register G4 292 << p->GetProcessName() << " idx= " 293 } 294 emp_vector.push_back(p); 295 } 296 297 //....oooOO0OOooo........oooOO0OOooo........oo 298 299 void G4LossTableManager::DeRegister(G4VEmProce 300 { 301 if (nullptr == p) { return; } 302 std::size_t emp = emp_vector.size(); 303 for (std::size_t i=0; i<emp; ++i) { 304 if(emp_vector[i] == p) { 305 emp_vector[i] = nullptr; 306 break; 307 } 308 } 309 } 310 311 //....oooOO0OOooo........oooOO0OOooo........oo 312 313 void G4LossTableManager::Register(G4VProcess* 314 { 315 if (nullptr == p) { return; } 316 std::size_t n = p_vector.size(); 317 for (std::size_t i=0; i<n; ++i) { 318 if(p_vector[i] == p) { return; } 319 } 320 if(verbose > 1) { 321 G4cout << "G4LossTableManager::Register G4 322 << p->GetProcessName() << " idx= " 323 } 324 p_vector.push_back(p); 325 } 326 327 //....oooOO0OOooo........oooOO0OOooo........oo 328 329 void G4LossTableManager::DeRegister(G4VProcess 330 { 331 if (nullptr == p) { return; } 332 std::size_t emp = p_vector.size(); 333 for (std::size_t i=0; i<emp; ++i) { 334 if(p_vector[i] == p) { 335 p_vector[i] = nullptr; 336 break; 337 } 338 } 339 } 340 341 //....oooOO0OOooo........oooOO0OOooo........oo 342 343 void G4LossTableManager::Register(G4VEmModel* 344 { 345 mod_vector.push_back(p); 346 if(verbose > 1) { 347 G4cout << "G4LossTableManager::Register G4 348 << p->GetName() << " " << p << " 349 } 350 } 351 352 //....oooOO0OOooo........oooOO0OOooo........oo 353 354 void G4LossTableManager::DeRegister(G4VEmModel 355 { 356 //G4cout << "G4LossTableManager::DeRegister 357 std::size_t n = mod_vector.size(); 358 for (std::size_t i=0; i<n; ++i) { 359 if(mod_vector[i] == p) { 360 mod_vector[i] = nullptr; 361 break; 362 } 363 } 364 } 365 366 //....oooOO0OOooo........oooOO0OOooo........oo 367 368 void G4LossTableManager::Register(G4VEmFluctua 369 { 370 fmod_vector.push_back(p); 371 if(verbose > 1) { 372 G4cout << "G4LossTableManager::Register G4 373 << p->GetName() << " " << fmod_vec 374 } 375 } 376 377 //....oooOO0OOooo........oooOO0OOooo........oo 378 379 void G4LossTableManager::DeRegister(G4VEmFluct 380 { 381 std::size_t n = fmod_vector.size(); 382 for (std::size_t i=0; i<n; ++i) { 383 if(fmod_vector[i] == p) { fmod_vector[i] = 384 } 385 } 386 387 //....oooOO0OOooo........oooOO0OOooo........oo 388 389 void G4LossTableManager::RegisterExtraParticle 390 const G4ParticleDefinition* part, 391 G4VEnergyLossProcess* p) 392 { 393 if (nullptr == p || nullptr == part) { retur 394 for (G4int i=0; i<n_loss; ++i) { 395 if(loss_vector[i] == p) { return; } 396 } 397 if(verbose > 1) { 398 G4cout << "G4LossTableManager::RegisterExt 399 << part->GetParticleName() << " G4 400 << p->GetProcessName() << " idx= " 401 } 402 ++n_loss; 403 loss_vector.push_back(p); 404 part_vector.push_back(part); 405 base_part_vector.push_back(p->BaseParticle() 406 dedx_vector.push_back(nullptr); 407 range_vector.push_back(nullptr); 408 inv_range_vector.push_back(nullptr); 409 tables_are_built.push_back(false); 410 all_tables_are_built = false; 411 } 412 413 //....oooOO0OOooo........oooOO0OOooo........oo 414 415 G4VEnergyLossProcess* 416 G4LossTableManager::GetEnergyLossProcess(const 417 { 418 if(aParticle != currentParticle) { 419 currentParticle = aParticle; 420 std::map<PD,G4VEnergyLossProcess*,std::les 421 if ((pos = loss_map.find(aParticle)) != lo 422 currentLoss = (*pos).second; 423 } else { 424 currentLoss = nullptr; 425 if(0.0 != aParticle->GetPDGCharge() && 426 (pos = loss_map.find(theGenericIon)) != los 427 currentLoss = (*pos).second; 428 } 429 } 430 } 431 return currentLoss; 432 } 433 434 //....oooOO0OOooo........oooOO0OOooo........oo 435 436 void 437 G4LossTableManager::PreparePhysicsTable(const 438 G4VEne 439 { 440 if (1 < verbose) { 441 G4cout << "G4LossTableManager::PreparePhys 442 << particle->GetParticleName() 443 << " and " << p->GetProcessName() < 444 << " loss_vector " << loss_vector 445 << " run=" << run << " master=" << isMast 446 << G4endl; 447 } 448 449 // start initialisation for the first run 450 if( -1 == run ) { 451 if (nullptr != emConfigurator) { emConfigu 452 453 // initialise particles for given process 454 for (G4int j=0; j<n_loss; ++j) { 455 if (p == loss_vector[j] && nullptr == pa 456 part_vector[j] = particle; 457 if (particle->GetParticleName() == "Ge 458 theGenericIon = particle; 459 } 460 } 461 } 462 } 463 ResetParameters(); 464 } 465 466 //....oooOO0OOooo........oooOO0OOooo........oo 467 468 void 469 G4LossTableManager::PreparePhysicsTable(const 470 G4VEmP 471 { 472 if (1 < verbose) { 473 G4cout << "G4LossTableManager::PreparePhys 474 << particle->GetParticleName() 475 << " and " << p->GetProcessName() 476 << " run=" << run << " master=" << isMast 477 << G4endl; 478 } 479 480 // start initialisation for the first run 481 if( -1 == run ) { 482 if (nullptr != emConfigurator) { emConfigu 483 } 484 485 ResetParameters(); 486 } 487 488 //....oooOO0OOooo........oooOO0OOooo........oo 489 490 void 491 G4LossTableManager::PreparePhysicsTable(const 492 G4VMul 493 { 494 if (1 < verbose) { 495 G4cout << "G4LossTableManager::PreparePhys 496 << particle->GetParticleName() 497 << " and " << p->GetProcessName() 498 << " run=" << run << " master=" << isMast 499 << G4endl; 500 } 501 502 // start initialisation for the first run 503 if ( -1 == run ) { 504 if (nullptr != emConfigurator) { emConfigu 505 } 506 507 ResetParameters(); 508 } 509 510 //....oooOO0OOooo........oooOO0OOooo........oo 511 512 void 513 G4LossTableManager::BuildPhysicsTable(const G4 514 { 515 if(-1 == run && startInitialisation) { 516 if (nullptr != emConfigurator) { emConfigu 517 } 518 if (startInitialisation) { resetParam = true 519 } 520 521 //....oooOO0OOooo........oooOO0OOooo........oo 522 523 void G4LossTableManager::LocalPhysicsTables( 524 const G4ParticleDefinition* aParticle, 525 G4VEnergyLossProcess* p) 526 { 527 if (1 < verbose) { 528 G4cout << "### G4LossTableManager::LocalPh 529 << aParticle->GetParticleName() 530 << " and process " << p->GetProcess 531 << G4endl; 532 } 533 534 if(-1 == run && startInitialisation) { 535 if (nullptr != emConfigurator) { emConfigu 536 firstParticle = aParticle; 537 } 538 539 if (startInitialisation) { 540 ++run; 541 if (1 < verbose) { 542 G4cout << "===== G4LossTableManager::Loc 543 << run << " =====" << G4endl; 544 } 545 currentParticle = nullptr; 546 startInitialisation = false; 547 resetParam = true; 548 for (G4int i=0; i<n_loss; ++i) { 549 if (nullptr != loss_vector[i]) { 550 tables_are_built[i] = false; 551 } else { 552 tables_are_built[i] = true; 553 part_vector[i] = nullptr; 554 } 555 } 556 } 557 558 all_tables_are_built= true; 559 for (G4int i=0; i<n_loss; ++i) { 560 if(p == loss_vector[i]) { 561 tables_are_built[i] = true; 562 isActive[i] = true; 563 part_vector[i] = p->Particle(); 564 base_part_vector[i] = p->BaseParticle(); 565 dedx_vector[i] = p->DEDXTable(); 566 range_vector[i] = p->RangeTableForLoss() 567 inv_range_vector[i] = p->InverseRangeTab 568 if(0 == run && p->IsIonisationProcess()) 569 loss_map[part_vector[i]] = p; 570 } 571 572 if(1 < verbose) { 573 G4cout << i <<". "<< p->GetProcessNa 574 if(part_vector[i]) { 575 G4cout << " for " << part_vector[i 576 } 577 G4cout << " active= " << isActive[i] 578 << " table= " << tables_are_bu 579 << " isIonisation= " << p->IsI 580 << G4endl; 581 } 582 break; 583 } else if(!tables_are_built[i]) { 584 all_tables_are_built = false; 585 } 586 } 587 588 if(1 < verbose) { 589 G4cout << "### G4LossTableManager::LocalPh 590 << G4endl; 591 } 592 if(all_tables_are_built) { 593 if(1 < verbose) { 594 G4cout << "%%%%% All dEdx and Range tabl 595 << run << " %%%%%" << G4endl; 596 } 597 } 598 } 599 600 //....oooOO0OOooo........oooOO0OOooo........oo 601 602 void G4LossTableManager::BuildPhysicsTable( 603 const G4ParticleDefinition* aParticle, 604 G4VEnergyLossProcess* p) 605 { 606 if(1 < verbose) { 607 G4cout << "### G4LossTableManager::BuildPh 608 << aParticle->GetParticleName() 609 << " and process " << p->GetProcess 610 } 611 // clear configurator 612 if(-1 == run && startInitialisation) { 613 if( nullptr != emConfigurator) { emConfigu 614 firstParticle = aParticle; 615 } 616 if(startInitialisation) { 617 ++run; 618 resetParam = true; 619 startInitialisation = false; 620 if(1 < verbose) { 621 G4cout << "===== G4LossTableManager::Bui 622 << run << " ===== " << atomDeexci 623 } 624 currentParticle = nullptr; 625 all_tables_are_built = false; 626 627 for (G4int i=0; i<n_loss; ++i) { 628 G4VEnergyLossProcess* el = loss_vector[i 629 630 if(nullptr != el) { 631 isActive[i] = true; 632 part_vector[i] = el->Particle(); 633 base_part_vector[i] = el->BaseParticle 634 tables_are_built[i] = false; 635 if(1 < verbose) { 636 G4cout << i <<". "<< el->GetProces 637 if(el->Particle()) { 638 G4cout << " for " << el->Particl 639 } 640 G4cout << " active= " << isActive[i 641 << " table= " << tables_are_ 642 << " isIonisation= " << el-> 643 if(base_part_vector[i]) { 644 G4cout << " base particle " 645 << base_part_vector[i]->Get 646 } 647 G4cout << G4endl; 648 } 649 } else { 650 tables_are_built[i] = true; 651 part_vector[i] = nullptr; 652 isActive[i] = false; 653 } 654 } 655 } 656 657 if (all_tables_are_built) { 658 theParameters->SetIsPrintedFlag(true); 659 return; 660 } 661 662 // Build tables for given particle 663 all_tables_are_built = true; 664 665 for(G4int i=0; i<n_loss; ++i) { 666 if(p == loss_vector[i] && !tables_are_buil 667 const G4ParticleDefinition* curr_part = 668 if(1 < verbose) { 669 G4cout << "### Build Table for " << p- 670 << " and " << curr_part->GetPar 671 << " " << tables_are_built[i] 672 << G4endl; 673 } 674 G4VEnergyLossProcess* curr_proc = BuildT 675 if(curr_proc) { 676 CopyTables(curr_part, curr_proc); 677 if(p == curr_proc && 0 == run && p->Is 678 loss_map[aParticle] = p; 679 //G4cout << "G4LossTableManager::Bui 680 // << aParticle->GetParticleName 681 // << " added to map " << p 682 } 683 } 684 } 685 if ( !tables_are_built[i] ) { all_tables_a 686 } 687 if(1 < verbose) { 688 G4cout << "### G4LossTableManager::BuildPh 689 << "all_tables_are_built= " << all_ 690 << aParticle->GetParticleName() << 691 } 692 } 693 694 //....oooOO0OOooo........oooOO0OOooo........oo 695 696 void G4LossTableManager::CopyTables(const G4Pa 697 G4VEnergyL 698 { 699 for (G4int j=0; j<n_loss; ++j) { 700 701 G4VEnergyLossProcess* proc = loss_vector[j 702 703 if (!tables_are_built[j] && part == base_p 704 tables_are_built[j] = true; 705 // for base particle approach only ionis 706 proc->SetDEDXTable(base_proc->Ionisation 707 proc->SetDEDXTable(base_proc->DEDXunRest 708 proc->SetCSDARangeTable(base_proc->CSDAR 709 proc->SetRangeTableForLoss(base_proc->Ra 710 proc->SetInverseRangeTable(base_proc->In 711 proc->SetLambdaTable(base_proc->LambdaTa 712 if(proc->IsIonisationProcess()) { 713 range_vector[j] = base_proc->RangeTabl 714 inv_range_vector[j] = base_proc->Inver 715 loss_map[part_vector[j]] = proc; 716 //G4cout << "G4LossTableManager::CopyT 717 // << part_vector[j]->GetParticl 718 // << " added to map " << proc < 719 } 720 if (1 < verbose) { 721 G4cout << " CopyTables for " << pro 722 << " for " << part_vector[j]-> 723 << " base_part= " << part->Get 724 << " tables are assigned" 725 << G4endl; 726 } 727 } 728 } 729 } 730 731 //....oooOO0OOooo........oooOO0OOooo........oo 732 733 G4VEnergyLossProcess* G4LossTableManager::Buil 734 const G4ParticleDefiniti 735 { 736 if(1 < verbose) { 737 G4cout << " G4LossTableManager::BuildTab 738 << aParticle->GetParticleName() << 739 } 740 741 std::vector<G4PhysicsTable*> t_list; 742 std::vector<G4VEnergyLossProcess*> loss_list 743 std::vector<G4bool> build_flags; 744 G4VEnergyLossProcess* em = nullptr; 745 G4VEnergyLossProcess* p = nullptr; 746 G4int iem = 0; 747 G4PhysicsTable* dedx = nullptr; 748 G4int i; 749 750 G4ProcessVector* pvec = 751 aParticle->GetProcessManager()->GetProcess 752 G4int nvec = (G4int)pvec->size(); 753 754 for (i=0; i<n_loss; ++i) { 755 p = loss_vector[i]; 756 if (nullptr != p) { 757 G4bool yes = (aParticle == part_vector[i 758 759 // possible case of process sharing betw 760 if(!yes) { 761 auto ptr = static_cast<G4VProcess*>(p) 762 for(G4int j=0; j<nvec; ++j) { 763 //G4cout << "j= " << j << " " << (*p 764 if(ptr == (*pvec)[j]) { 765 yes = true; 766 break; 767 } 768 } 769 } 770 // process belong to this particle 771 if(yes && isActive[i]) { 772 if (p->IsIonisationProcess() || !em) { 773 em = p; 774 iem= i; 775 } 776 // tables may be shared between partic 777 G4bool val = false; 778 if (!tables_are_built[i]) { 779 val = true; 780 dedx = p->BuildDEDXTable(fRestricted 781 //G4cout << "===Build DEDX table for 782 // << " idx= " << i << " dedx:" << d 783 p->SetDEDXTable(dedx,fRestricted); 784 tables_are_built[i] = true; 785 } else { 786 dedx = p->DEDXTable(); 787 } 788 t_list.push_back(dedx); 789 loss_list.push_back(p); 790 build_flags.push_back(val); 791 } 792 } 793 } 794 795 G4int n_dedx = (G4int)t_list.size(); 796 if (0 == n_dedx || !em) { 797 G4cout << "G4LossTableManager WARNING: no 798 << aParticle->GetParticleName() << 799 return nullptr; 800 } 801 G4int nSubRegions = em->NumberOfSubCutoffReg 802 803 if (1 < verbose) { 804 G4cout << " Start to build the sum of 805 << " iem= " << iem << " em= " << em 806 << " buildCSDARange= " << theParame 807 << " nSubRegions= " << nSubRegions; 808 if(subcutProducer) { 809 G4cout << " SubCutProducer " << subcutPr 810 } 811 G4cout << G4endl; 812 } 813 // do not build tables if producer class is 814 if(subcutProducer) { nSubRegions = 0; } 815 816 dedx = em->DEDXTable(); 817 em->SetDEDXTable(dedx, fIsIonisation); 818 819 if (1 < n_dedx) { 820 dedx = nullptr; 821 dedx = G4PhysicsTableHelper::PreparePhysic 822 tableBuilder->BuildDEDXTable(dedx, t_list) 823 em->SetDEDXTable(dedx, fRestricted); 824 } 825 826 dedx_vector[iem] = dedx; 827 828 G4PhysicsTable* range = em->RangeTableForLos 829 if(!range) range = G4PhysicsTableHelper::Pr 830 range_vector[iem] = range; 831 832 G4PhysicsTable* invrange = em->InverseRangeT 833 if(!invrange) invrange = G4PhysicsTableHelpe 834 inv_range_vector[iem] = invrange; 835 836 tableBuilder->BuildRangeTable(dedx, range); 837 tableBuilder->BuildInverseRangeTable(range, 838 839 em->SetRangeTableForLoss(range); 840 em->SetInverseRangeTable(invrange); 841 842 std::vector<G4PhysicsTable*> listCSDA; 843 844 for (i=0; i<n_dedx; ++i) { 845 p = loss_list[i]; 846 if(build_flags[i]) { 847 p->SetLambdaTable(p->BuildLambdaTable(fR 848 } 849 if(theParameters->BuildCSDARange()) { 850 dedx = p->BuildDEDXTable(fTotal); 851 p->SetDEDXTable(dedx,fTotal); 852 listCSDA.push_back(dedx); 853 } 854 } 855 856 if(theParameters->BuildCSDARange()) { 857 G4PhysicsTable* dedxCSDA = em->DEDXunRestr 858 if (1 < n_dedx) { 859 dedxCSDA = G4PhysicsTableHelper::Prepare 860 tableBuilder->BuildDEDXTable(dedxCSDA, l 861 em->SetDEDXTable(dedxCSDA,fTotal); 862 } 863 G4PhysicsTable* rCSDA = em->CSDARangeTable 864 if(!rCSDA) { rCSDA = G4PhysicsTableHelper: 865 tableBuilder->BuildRangeTable(dedxCSDA, rC 866 em->SetCSDARangeTable(rCSDA); 867 } 868 869 if (1 < verbose) { 870 G4cout << "G4LossTableManager::BuildTables 871 << aParticle->GetParticleName() 872 << "; ionisation process: " << em-> 873 << " " << em 874 << G4endl; 875 } 876 return em; 877 } 878 879 //....oooOO0OOooo........oooOO0OOooo........oo 880 881 void G4LossTableManager::ParticleHaveNoLoss( 882 const G4ParticleDefinition* aParticle) 883 { 884 G4ExceptionDescription ed; 885 ed << "Energy loss process not found for " < 886 << " !"; 887 G4Exception("G4LossTableManager::ParticleHav 888 FatalException, ed); 889 } 890 891 //....oooOO0OOooo........oooOO0OOooo........oo 892 893 void G4LossTableManager::SetVerbose(G4int val) 894 { 895 verbose = val; 896 } 897 898 //....oooOO0OOooo........oooOO0OOooo........oo 899 900 const std::vector<G4VEnergyLossProcess*>& 901 G4LossTableManager::GetEnergyLossProcessVector 902 { 903 return loss_vector; 904 } 905 906 //....oooOO0OOooo........oooOO0OOooo........oo 907 908 const std::vector<G4VEmProcess*>& G4LossTableM 909 { 910 return emp_vector; 911 } 912 913 //....oooOO0OOooo........oooOO0OOooo........oo 914 915 const std::vector<G4VMultipleScattering*>& 916 G4LossTableManager::GetMultipleScatteringVecto 917 { 918 return msc_vector; 919 } 920 921 //....oooOO0OOooo........oooOO0OOooo........oo 922 923 G4EmSaturation* G4LossTableManager::EmSaturati 924 { 925 return theParameters->GetEmSaturation(); 926 } 927 928 //....oooOO0OOooo........oooOO0OOooo........oo 929 930 G4EmConfigurator* G4LossTableManager::EmConfig 931 { 932 if(!emConfigurator) { 933 emConfigurator = new G4EmConfigurator(verb 934 } 935 return emConfigurator; 936 } 937 938 //....oooOO0OOooo........oooOO0OOooo........oo 939 940 G4ElectronIonPair* G4LossTableManager::Electro 941 { 942 if(!emElectronIonPair) { 943 emElectronIonPair = new G4ElectronIonPair( 944 } 945 return emElectronIonPair; 946 } 947 948 //....oooOO0OOooo........oooOO0OOooo........oo 949 950 void G4LossTableManager::SetNIELCalculator(G4N 951 { 952 if(nullptr != ptr && ptr != nielCalculator) 953 delete nielCalculator; 954 nielCalculator = ptr; 955 } 956 } 957 958 //....oooOO0OOooo........oooOO0OOooo........oo 959 960 G4NIELCalculator* G4LossTableManager::NIELCalc 961 { 962 if(!nielCalculator) { 963 nielCalculator = new G4NIELCalculator(null 964 } 965 return nielCalculator; 966 } 967 968 //....oooOO0OOooo........oooOO0OOooo........oo 969 970 void G4LossTableManager::SetAtomDeexcitation(G 971 { 972 if(atomDeexcitation != p) { 973 delete atomDeexcitation; 974 atomDeexcitation = p; 975 } 976 } 977 978 //....oooOO0OOooo........oooOO0OOooo........oo 979 980 void G4LossTableManager::SetSubCutProducer(G4V 981 { 982 if(subcutProducer != p) { 983 delete subcutProducer; 984 subcutProducer = p; 985 } 986 } 987 988 //....oooOO0OOooo........oooOO0OOooo........oo 989 990 void G4LossTableManager::PrintEWarning(G4Strin 991 { 992 G4String ss = "G4LossTableManager::" + tit; 993 G4ExceptionDescription ed; 994 /* 995 ed << "Parameter is out of range: " << val 996 << " it will have no effect!\n" << " ## " 997 << " nbins= " << nbinsLambda 998 << " nbinsPerDecade= " << nbinsPerDecade 999 << " Emin(keV)= " << minKinEnergy/keV 1000 << " Emax(GeV)= " << maxKinEnergy/GeV; 1001 */ 1002 G4Exception(ss, "em0044", JustWarning, ed); 1003 } 1004 1005 //....oooOO0OOooo........oooOO0OOooo........o 1006 1007 void G4LossTableManager::DumpHtml() 1008 { 1009 // Automatic generation of html documentati 1010 // List processes and models for the most i 1011 // particles in descending order of importa 1012 // NB. for model names with length > 18 cha 1013 // to be edited by hand. Or modify G4EmMod 1014 1015 char* dirName = std::getenv("G4PhysListDocD 1016 char* physList = std::getenv("G4PhysListNam 1017 if (dirName && physList) { 1018 G4String physListName = G4String(physList 1019 G4String pathName = G4String(dirName) + " 1020 1021 std::ofstream outFile; 1022 outFile.open(pathName); 1023 1024 outFile << physListName << G4endl; 1025 outFile << std::string(physListName.lengt 1026 1027 std::vector<G4ParticleDefinition*> partic 1028 G4Gamma::Gamma(), 1029 G4Electron::Electron(), 1030 G4Positron::Positron(), 1031 G4Proton::ProtonDefinition(), 1032 G4MuonPlus::MuonPlusDefinition(), 1033 G4MuonMinus::MuonMinusDefinition(), 1034 }; 1035 1036 std::vector<G4VEmProcess*> emproc_vector 1037 std::vector<G4VEnergyLossProcess*> enloss 1038 GetEnergyLossProcessVector(); 1039 std::vector<G4VMultipleScattering*> mscat 1040 GetMultipleScatteringVector(); 1041 1042 for (auto theParticle : particles) { 1043 outFile << G4endl << "**" << theParticl 1044 << "**" << G4endl << G4endl << 1045 1046 G4ProcessManager* pm = theParticle->Get 1047 G4ProcessVector* pv = pm->GetProcessLi 1048 G4int plen = pm->GetProcessListLength() 1049 1050 for (auto emproc : emproc_vector) { 1051 for (G4int i = 0; i < plen; ++i) { 1052 G4VProcess* proc = (*pv)[i]; 1053 if (proc == emproc) { 1054 outFile << G4endl; 1055 proc->ProcessDescription(outFile) 1056 break; 1057 } 1058 } 1059 } 1060 1061 for (auto mscproc : mscat_vector) { 1062 for (G4int i = 0; i < plen; ++i) { 1063 G4VProcess* proc = (*pv)[i]; 1064 if (proc == mscproc) { 1065 outFile << G4endl; 1066 proc->ProcessDescription(outFile) 1067 break; 1068 } 1069 } 1070 } 1071 1072 for (auto enlossproc : enloss_vector) { 1073 for (G4int i = 0; i < plen; ++i) { 1074 G4VProcess* proc = (*pv)[i]; 1075 if (proc == enlossproc) { 1076 outFile << G4endl; 1077 proc->ProcessDescription(outFile) 1078 break; 1079 } 1080 } 1081 } 1082 } 1083 outFile.close(); 1084 } 1085 } 1086 1087 //....oooOO0OOooo........oooOO0OOooo........o 1088 1089