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 // G4RunManagerKernel implementation 27 // 28 // Author: M.Asai, 1 August 2003 29 // -------------------------------------------------------------------- 30 31 #include "G4RunManagerKernel.hh" 32 33 #include "G4AllocatorList.hh" 34 #include "G4ApplicationState.hh" 35 #include "G4AutoLock.hh" 36 #include "G4ExceptionHandler.hh" 37 #include "G4FieldManagerStore.hh" 38 #include "G4Geantino.hh" 39 #include "G4GeometryManager.hh" 40 #include "G4IonConstructor.hh" 41 #include "G4IonTable.hh" 42 #include "G4LogicalVolume.hh" 43 #include "G4LogicalVolumeStore.hh" 44 #include "G4MTRunManager.hh" 45 #include "G4NavigationHistoryPool.hh" 46 #include "G4ParallelWorldProcessStore.hh" 47 #include "G4ParticleDefinition.hh" 48 #include "G4ParticleTable.hh" 49 #include "G4ParticleTableIterator.hh" 50 #include "G4PathFinder.hh" 51 #include "G4PrimaryTransformer.hh" 52 #include "G4ProcessManager.hh" 53 #include "G4ProcessVector.hh" 54 #include "G4ProductionCuts.hh" 55 #include "G4ProductionCutsTable.hh" 56 #include "G4RNGHelper.hh" 57 #include "G4Region.hh" 58 #include "G4RegionStore.hh" 59 #include "G4SDManager.hh" 60 #include "G4ScoreSplittingProcess.hh" 61 #include "G4StateManager.hh" 62 #include "G4TransportationManager.hh" 63 #include "G4UImanager.hh" 64 #include "G4UnitsTable.hh" 65 #include "G4VPhysicalVolume.hh" 66 #include "G4VProcess.hh" 67 #include "G4VUserPhysicsList.hh" 68 #include "G4VVisManager.hh" 69 #include "G4Version.hh" 70 #include "G4ios.hh" 71 72 #include <vector> 73 74 #ifdef G4BT_DEBUG 75 # include "G4Backtrace.hh" 76 #endif 77 78 #ifdef G4FPE_DEBUG 79 # include "G4FPEDetection.hh" 80 #endif 81 82 // The following lines are needed since G4VUserPhysicsList 83 // uses a #define theParticleIterator 84 #ifdef theParticleIterator 85 # undef theParticleIterator 86 #endif 87 88 G4ThreadLocal G4RunManagerKernel* G4RunManagerKernel::fRunManagerKernel = nullptr; 89 90 // -------------------------------------------------------------------- 91 G4RunManagerKernel* G4RunManagerKernel::GetRunManagerKernel() 92 { 93 return fRunManagerKernel; 94 } 95 96 // -------------------------------------------------------------------- 97 G4RunManagerKernel::G4RunManagerKernel() 98 { 99 #ifdef G4FPE_DEBUG 100 InvalidOperationDetection(); 101 #endif 102 103 #ifdef G4BT_DEBUG 104 auto _signals = G4GetEnv<std::string>("G4BACKTRACE", ""); 105 if (_signals.empty()) { 106 G4Backtrace::Enable(); 107 } 108 else { 109 G4Backtrace::Enable(_signals); 110 } 111 #endif 112 113 G4AllocatorList* allocList = G4AllocatorList::GetAllocatorListIfExist(); 114 if (allocList != nullptr) numberOfStaticAllocators = (G4int)allocList->Size(); 115 116 if (G4StateManager::GetStateManager()->GetExceptionHandler() == nullptr) { 117 defaultExceptionHandler = new G4ExceptionHandler(); 118 } 119 if (fRunManagerKernel != nullptr) { 120 G4Exception("G4RunManagerKernel::G4RunManagerKernel()", "Run0001", FatalException, 121 "More than one G4RunManagerKernel is constructed."); 122 } 123 fRunManagerKernel = this; 124 125 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable(); 126 if (particleTable->entries() > 0) { 127 // No particle should be registered beforehand 128 G4ExceptionDescription ED; 129 ED << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << G4endl; 130 ED << " G4RunManagerKernel fatal exception" << G4endl; 131 ED << " -- Following particles have already been registered" << G4endl; 132 ED << " before G4RunManagerKernel is instantiated." << G4endl; 133 for (G4int i = 0; i < particleTable->entries(); ++i) { 134 ED << " " << particleTable->GetParticle(i)->GetParticleName() << G4endl; 135 } 136 ED << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << G4endl; 137 G4Exception("G4RunManagerKernel::G4RunManagerKernel()", "Run0002", FatalException, ED); 138 } 139 140 // construction of Geant4 kernel classes 141 eventManager = new G4EventManager(); 142 143 defaultRegion = new G4Region("DefaultRegionForTheWorld"); // deleted by store 144 defaultRegionForParallelWorld = 145 new G4Region("DefaultRegionForParallelWorld"); // deleted by store 146 defaultRegion->SetProductionCuts( 147 G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts()); 148 defaultRegionForParallelWorld->SetProductionCuts( 149 G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts()); 150 151 runManagerKernelType = sequentialRMK; 152 // set the initial application state 153 G4StateManager::GetStateManager()->SetNewState(G4State_PreInit); 154 155 // version banner 156 G4String vs = G4Version; 157 vs = vs.substr(1, vs.size() - 2); 158 versionString = " Geant4 version "; 159 versionString += vs; 160 versionString += " "; 161 versionString += G4Date; 162 G4cout << G4endl << "**************************************************************" << G4endl 163 << versionString << G4endl << " Copyright : Geant4 Collaboration" 164 << G4endl << " References : NIM A 506 (2003), 250-303" << G4endl 165 << " : IEEE-TNS 53 (2006), 270-278" << G4endl 166 << " : NIM A 835 (2016), 186-225" << G4endl 167 << " WWW : http://geant4.org/" << G4endl 168 << "**************************************************************" << G4endl << G4endl; 169 } 170 171 // -------------------------------------------------------------------- 172 G4RunManagerKernel::G4RunManagerKernel(RMKType rmkType) 173 { 174 // This version of the constructor should never be called in sequential mode! 175 #ifndef G4MULTITHREADED 176 G4ExceptionDescription msg; 177 msg << "Geant4 code is compiled without multi-threading support " 178 "(-DG4MULTITHREADED is set to off)."; 179 msg << " This type of RunManagerKernel can only be used in mult-threaded " 180 "applications."; 181 G4Exception("G4RunManagerKernel::G4RunManagerKernel(G4bool)", "Run0105", FatalException, msg); 182 #endif 183 184 #ifdef G4FPE_DEBUG 185 if (G4Threading::IsMasterThread()) { 186 InvalidOperationDetection(); 187 } 188 #endif 189 190 #ifdef G4BT_DEBUG 191 auto _signals = G4GetEnv<std::string>("G4BACKTRACE", ""); 192 if (_signals.empty()) { 193 G4Backtrace::Enable(); 194 } 195 else { 196 G4Backtrace::Enable(_signals); 197 } 198 #endif 199 200 if (G4StateManager::GetStateManager()->GetExceptionHandler() == nullptr) { 201 defaultExceptionHandler = new G4ExceptionHandler(); 202 } 203 204 if (fRunManagerKernel != nullptr) { 205 G4Exception("G4RunManagerKernel::G4RunManagerKernel()", "Run0001", FatalException, 206 "More than one G4RunManagerKernel is constructed."); 207 } 208 fRunManagerKernel = this; 209 // construction of Geant4 kernel classes 210 eventManager = new G4EventManager(); 211 212 switch (rmkType) { 213 case masterRMK: 214 // Master thread behvior 215 defaultRegion = new G4Region("DefaultRegionForTheWorld"); // deleted by store 216 defaultRegionForParallelWorld = 217 new G4Region("DefaultRegionForParallelWorld"); // deleted by store 218 defaultRegion->SetProductionCuts( 219 G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts()); 220 defaultRegionForParallelWorld->SetProductionCuts( 221 G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts()); 222 break; 223 case workerRMK: 224 // Worker thread behavior 225 defaultRegion = G4RegionStore::GetInstance()->GetRegion("DefaultRegionForTheWorld", true); 226 defaultRegionForParallelWorld = 227 G4RegionStore::GetInstance()->GetRegion("DefaultRegionForParallelWorld", true); 228 break; 229 default: 230 defaultRegion = nullptr; 231 defaultRegionForParallelWorld = nullptr; 232 G4ExceptionDescription msgx; 233 msgx << " This type of RunManagerKernel can only be used in mult-threaded " 234 "applications."; 235 G4Exception("G4RunManagerKernel::G4RunManagerKernel(G4bool)", "Run0106", FatalException, 236 msgx); 237 } 238 runManagerKernelType = rmkType; 239 240 // set the initial application state 241 G4StateManager::GetStateManager()->SetNewState(G4State_PreInit); 242 243 // version banner 244 G4String vs = G4Version; 245 vs = vs.substr(1, vs.size() - 2); 246 switch (rmkType) { 247 case masterRMK: 248 versionString = " Geant4 version "; 249 versionString += vs; 250 versionString += " "; 251 versionString += G4Date; 252 G4cout << G4endl << "**************************************************************" << G4endl 253 << versionString << G4endl << " << in Multi-threaded mode >> " << G4endl 254 << " Copyright : Geant4 Collaboration" << G4endl 255 << " References : NIM A 506 (2003), 250-303" << G4endl 256 << " : IEEE-TNS 53 (2006), 270-278" << G4endl 257 << " : NIM A 835 (2016), 186-225" << G4endl 258 << " WWW : http://geant4.org/" << G4endl 259 << "**************************************************************" << G4endl 260 << G4endl; 261 break; 262 default: 263 if (verboseLevel != 0) { 264 versionString = " Local thread RunManagerKernel version "; 265 versionString += vs; 266 G4cout << G4endl 267 << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" 268 "^^^^^^^^^" 269 << G4endl << versionString << G4endl 270 << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" 271 "^^^^^^^^^" 272 << G4endl << G4endl; 273 } 274 } 275 276 #ifdef G4MULTITHREADED 277 G4UnitDefinition::GetUnitsTable().Synchronize(); 278 #endif 279 } 280 281 // -------------------------------------------------------------------- 282 void G4RunManagerKernel::SetupDefaultRegion() 283 { 284 if (runManagerKernelType == workerRMK) return; 285 286 // Remove old world logical volume from the default region, if exist 287 if (defaultRegion->GetNumberOfRootVolumes() != 0u) { 288 if (defaultRegion->GetNumberOfRootVolumes() > size_t(1)) { 289 G4Exception("G4RunManager::SetupDefaultRegion", "Run0005", FatalException, 290 "Default world region should have a unique logical volume."); 291 } 292 auto lvItr = defaultRegion->GetRootLogicalVolumeIterator(); 293 defaultRegion->RemoveRootLogicalVolume(*lvItr, false); 294 if (verboseLevel > 1) 295 G4cout << "Obsolete world logical volume is removed from the default region." << G4endl; 296 } 297 } 298 299 // -------------------------------------------------------------------- 300 G4RunManagerKernel::~G4RunManagerKernel() 301 { 302 G4StateManager* pStateManager = G4StateManager::GetStateManager(); 303 // set the application state to the quite state 304 if (pStateManager->GetCurrentState() != G4State_Quit) { 305 if (verboseLevel > 1) G4cout << "G4 kernel has come to Quit state." << G4endl; 306 pStateManager->SetNewState(G4State_Quit); 307 } 308 309 // open geometry for deletion 310 G4GeometryManager::GetInstance()->OpenGeometry(); 311 312 // deletion of Geant4 kernel classes 313 delete G4ParallelWorldProcessStore::GetInstanceIfExist(); 314 delete G4SDManager::GetSDMpointerIfExist(); 315 if (verboseLevel > 1) G4cout << "G4SDManager deleted." << G4endl; 316 delete eventManager; 317 if (verboseLevel > 1) G4cout << "EventManager deleted." << G4endl; 318 319 G4UnitDefinition::ClearUnitsTable(); 320 if (verboseLevel > 1) G4cout << "Units table cleared." << G4endl; 321 322 // deletion of path-finder field-manager store, geometry and transportation 323 // manager 324 delete G4PathFinder::GetInstanceIfExist(); 325 delete G4FieldManagerStore::GetInstanceIfExist(); 326 delete G4GeometryManager::GetInstanceIfExist(); 327 delete G4TransportationManager::GetInstanceIfExist(); 328 if (verboseLevel > 1) G4cout << "TransportationManager deleted." << G4endl; 329 330 // deletion of navigation levels 331 if (verboseLevel > 1) G4NavigationHistoryPool::GetInstance()->Print(); 332 delete G4NavigationHistoryPool::GetInstance(); 333 334 // deletion of G4RNGHelper singleton 335 if (runManagerKernelType != workerRMK) { 336 delete G4RNGHelper::GetInstanceIfExist(); 337 if (verboseLevel > 1) G4cout << "G4RNGHelper object is deleted." << G4endl; 338 } 339 340 // deletion of allocators 341 G4AllocatorList* allocList = G4AllocatorList::GetAllocatorListIfExist(); 342 if (allocList != nullptr) { 343 allocList->Destroy(numberOfStaticAllocators, verboseLevel); 344 delete allocList; 345 if (verboseLevel > 1) G4cout << "G4Allocator objects are deleted." << G4endl; 346 } 347 348 G4UImanager* pUImanager = G4UImanager::GetUIpointer(); 349 if ((runManagerKernelType == workerRMK) && (verboseLevel > 1)) { 350 G4cout << "Thread-local UImanager is to be deleted." << G4endl 351 << "There should not be any thread-local G4cout/G4cerr hereafter." << G4endl; 352 } 353 delete pUImanager; 354 if (verboseLevel > 1) G4cout << "UImanager deleted." << G4endl; 355 356 delete pStateManager; 357 if (verboseLevel > 1) G4cout << "StateManager deleted." << G4endl; 358 delete defaultExceptionHandler; 359 if (verboseLevel > 1) G4cout << "RunManagerKernel is deleted. Good bye :)" << G4endl; 360 fRunManagerKernel = nullptr; 361 } 362 363 // -------------------------------------------------------------------- 364 void G4RunManagerKernel::WorkerUpdateWorldVolume() 365 { 366 G4MTRunManager* masterRM = G4MTRunManager::GetMasterRunManager(); 367 G4TransportationManager* transM = G4TransportationManager::GetTransportationManager(); 368 G4MTRunManager::masterWorlds_t masterWorlds = masterRM->GetMasterWorlds(); 369 for (const auto& masterWorld : masterWorlds) { 370 G4VPhysicalVolume* wv = masterWorld.second; 371 G4VPhysicalVolume* pWorld = 372 G4TransportationManager::GetTransportationManager()->IsWorldExisting(wv->GetName()); 373 if (pWorld == nullptr) { 374 transM->RegisterWorld(wv); 375 } 376 } 377 } 378 379 // -------------------------------------------------------------------- 380 void G4RunManagerKernel::WorkerDefineWorldVolume(G4VPhysicalVolume* worldVol, 381 G4bool topologyIsChanged) 382 { 383 G4StateManager* stateManager = G4StateManager::GetStateManager(); 384 G4ApplicationState currentState = stateManager->GetCurrentState(); 385 if (currentState != G4State_Init) { 386 if (currentState != G4State_Idle && currentState != G4State_PreInit) { 387 G4cout << "Current application state is " << stateManager->GetStateString(currentState) 388 << G4endl; 389 G4Exception("G4RunManagerKernel::DefineWorldVolume", "DefineWorldVolumeAtIncorrectState", 390 FatalException, "Geant4 kernel is not Init state : Method ignored."); 391 return; 392 } 393 394 stateManager->SetNewState(G4State_Init); 395 } 396 397 currentWorld = worldVol; 398 G4MTRunManager* masterRM = G4MTRunManager::GetMasterRunManager(); 399 G4TransportationManager* transM = G4TransportationManager::GetTransportationManager(); 400 G4MTRunManager::masterWorlds_t masterWorlds = masterRM->GetMasterWorlds(); 401 for (const auto& masterWorld : masterWorlds) { 402 if (masterWorld.first == 0) { 403 if (masterWorld.second != currentWorld) { 404 G4Exception("G4RunManagerKernel::WorkerDefineWorldVolume", "RUN3091", FatalException, 405 "Mass world is inconsistent"); 406 } 407 transM->SetWorldForTracking(masterWorld.second); 408 } 409 else { 410 transM->RegisterWorld(masterWorld.second); 411 } 412 } 413 414 if (topologyIsChanged) geometryNeedsToBeClosed = true; 415 416 // Notify the VisManager as well 417 if (G4Threading::IsMasterThread()) { 418 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); 419 if (pVVisManager != nullptr) pVVisManager->GeometryHasChanged(); 420 } 421 422 geometryInitialized = true; 423 stateManager->SetNewState(currentState); 424 if (physicsInitialized && currentState != G4State_Idle) { 425 stateManager->SetNewState(G4State_Idle); 426 } 427 } 428 429 // -------------------------------------------------------------------- 430 void G4RunManagerKernel::DefineWorldVolume(G4VPhysicalVolume* worldVol, G4bool topologyIsChanged) 431 { 432 G4StateManager* stateManager = G4StateManager::GetStateManager(); 433 G4ApplicationState currentState = stateManager->GetCurrentState(); 434 435 if (currentState != G4State_Init) { 436 if (currentState != G4State_Idle && currentState != G4State_PreInit) { 437 G4cout << "Current application state is " << stateManager->GetStateString(currentState) 438 << G4endl; 439 G4Exception("G4RunManagerKernel::DefineWorldVolume", "DefineWorldVolumeAtIncorrectState", 440 FatalException, "Geant4 kernel is not Init state : Method ignored."); 441 return; 442 } 443 444 stateManager->SetNewState(G4State_Init); 445 } 446 447 // The world volume MUST NOT have a region defined by the user 448 if (worldVol->GetLogicalVolume()->GetRegion() != nullptr) { 449 if (worldVol->GetLogicalVolume()->GetRegion() != defaultRegion) { 450 G4ExceptionDescription ED; 451 ED << "The world volume has a user-defined region <" 452 << worldVol->GetLogicalVolume()->GetRegion()->GetName() << ">." << G4endl; 453 ED << "World would have a default region assigned by RunManagerKernel." << G4endl; 454 G4Exception("G4RunManager::DefineWorldVolume", "Run0004", FatalException, ED); 455 } 456 } 457 458 SetupDefaultRegion(); 459 460 // Accept the world volume 461 currentWorld = worldVol; 462 463 // Set the default region to the world 464 465 G4LogicalVolume* worldLog = currentWorld->GetLogicalVolume(); 466 worldLog->SetRegion(defaultRegion); 467 defaultRegion->AddRootLogicalVolume(worldLog); 468 if (verboseLevel > 1) 469 G4cout << worldLog->GetName() << " is registered to the default region." << G4endl; 470 471 // Set the world volume, notify the Navigator and reset its state 472 G4TransportationManager::GetTransportationManager()->SetWorldForTracking(currentWorld); 473 if (topologyIsChanged) geometryNeedsToBeClosed = true; 474 475 // Notify the VisManager as well 476 if (G4Threading::IsMasterThread()) { 477 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); 478 if (pVVisManager != nullptr) pVVisManager->GeometryHasChanged(); 479 } 480 481 geometryInitialized = true; 482 stateManager->SetNewState(currentState); 483 if (physicsInitialized && currentState != G4State_Idle) { 484 stateManager->SetNewState(G4State_Idle); 485 } 486 } 487 488 // -------------------------------------------------------------------- 489 void G4RunManagerKernel::SetPhysics(G4VUserPhysicsList* uPhys) 490 { 491 physicsList = uPhys; 492 493 if (runManagerKernelType == workerRMK) return; 494 495 SetupPhysics(); 496 if (verboseLevel > 2) G4ParticleTable::GetParticleTable()->DumpTable(); 497 if (verboseLevel > 1) { 498 G4cout << "List of instantiated particles " 499 "============================================" 500 << G4endl; 501 G4int nPtcl = G4ParticleTable::GetParticleTable()->entries(); 502 for (G4int i = 0; i < nPtcl; ++i) { 503 G4ParticleDefinition* pd = G4ParticleTable::GetParticleTable()->GetParticle(i); 504 G4cout << pd->GetParticleName() << " "; 505 if (i % 10 == 9) G4cout << G4endl; 506 } 507 G4cout << G4endl; 508 } 509 } 510 511 // -------------------------------------------------------------------- 512 void G4RunManagerKernel::SetupPhysics() 513 { 514 G4ParticleTable::GetParticleTable()->SetReadiness(); 515 516 physicsList->ConstructParticle(); 517 518 // For sanity reason 519 G4Geantino::GeantinoDefinition(); 520 G4ParticleDefinition* gion = G4ParticleTable::GetParticleTable()->GetGenericIon(); 521 if (gion != nullptr) { 522 G4IonConstructor::ConstructParticle(); 523 } 524 G4ParticleTable::GetParticleTable()->GetIonTable()->InitializeLightIons(); 525 526 auto pItr = G4ParticleTable::GetParticleTable()->GetIterator(); 527 pItr->reset(); 528 while ((*pItr)()) { 529 G4ParticleDefinition* particle = pItr->value(); 530 if (!(particle->IsGeneralIon())) particle->SetParticleDefinitionID(); 531 } 532 533 if (gion != nullptr) { 534 G4int gionId = gion->GetParticleDefinitionID(); 535 pItr->reset(false); 536 while ((*pItr)()) { 537 G4ParticleDefinition* particle = pItr->value(); 538 if (particle->IsGeneralIon()) particle->SetParticleDefinitionID(gionId); 539 } 540 } 541 #ifdef G4MULTITHREADED 542 G4UnitDefinition::GetUnitsTable().Synchronize(); 543 #endif 544 } 545 546 // -------------------------------------------------------------------- 547 namespace 548 { 549 G4Mutex initphysicsmutex = G4MUTEX_INITIALIZER; 550 } 551 552 // -------------------------------------------------------------------- 553 void G4RunManagerKernel::InitializePhysics() 554 { 555 G4StateManager* stateManager = G4StateManager::GetStateManager(); 556 G4ApplicationState currentState = stateManager->GetCurrentState(); 557 if (currentState != G4State_Init) { 558 G4cout << "Current application state is " << stateManager->GetStateString(currentState) 559 << G4endl; 560 if (currentState != G4State_Idle && currentState != G4State_PreInit) { 561 G4Exception("G4RunManagerKernel::InitializePhysics", "InitializePhysicsIncorrectState", 562 FatalException, "Geant4 kernel is not Init state : Method ignored."); 563 return; 564 } 565 566 G4cout << "Warning : Geant4 kernel is not Init state : Assuming Init state." << G4endl; 567 stateManager->SetNewState(G4State_Init); 568 } 569 570 if (physicsList == nullptr) { 571 G4Exception("G4RunManagerKernel::InitializePhysics", "Run0012", FatalException, 572 "G4VUserPhysicsList is not defined"); 573 return; 574 } 575 576 if (verboseLevel > 1) G4cout << "physicsList->Construct() start." << G4endl; 577 if (numberOfParallelWorld > 0) physicsList->UseCoupledTransportation(); 578 physicsList->Construct(); 579 580 if (verboseLevel > 1) G4cout << "physicsList->CheckParticleList() start." << G4endl; 581 physicsList->CheckParticleList(); 582 583 // Cannot assume that SetCuts() and CheckRegions() are thread safe. 584 // We need to mutex (report from valgrind --tool=drd) 585 G4AutoLock l(&initphysicsmutex); 586 if (G4Threading::IsMasterThread()) { 587 if (verboseLevel > 1) G4cout << "physicsList->setCut() start." << G4endl; 588 physicsList->SetCuts(); 589 } 590 CheckRegions(); 591 l.unlock(); 592 593 physicsInitialized = true; 594 595 #ifdef G4MULTITHREADED 596 G4UnitDefinition::GetUnitsTable().Synchronize(); 597 #endif 598 599 stateManager->SetNewState(currentState); 600 if (geometryInitialized && currentState != G4State_Idle) { 601 stateManager->SetNewState(G4State_Idle); 602 } 603 } 604 605 // -------------------------------------------------------------------- 606 G4bool G4RunManagerKernel::RunInitialization(G4bool fakeRun) 607 { 608 G4StateManager* stateManager = G4StateManager::GetStateManager(); 609 G4ApplicationState currentState = stateManager->GetCurrentState(); 610 611 if (!geometryInitialized) { 612 G4Exception("G4RunManagerKernel::RunInitialization", "Run0021", JustWarning, 613 "Geometry has not yet initialized : method ignored."); 614 return false; 615 } 616 617 if (!physicsInitialized) { 618 G4Exception("G4RunManagerKernel::RunInitialization", "Run0022", JustWarning, 619 "Physics has not yet initialized : method ignored."); 620 return false; 621 } 622 623 if (currentState != G4State_Idle) { 624 G4Exception("G4RunManagerKernel::RunInitialization", "Run0023", JustWarning, 625 "Geant4 kernel not in Idle state : method ignored."); 626 return false; 627 } 628 629 if (geometryNeedsToBeClosed) CheckRegularGeometry(); 630 631 stateManager->SetNewState(G4State_Init); 632 PropagateGenericIonID(); 633 SetupShadowProcess(); 634 UpdateRegion(); 635 BuildPhysicsTables(fakeRun); 636 637 if (geometryNeedsToBeClosed) { 638 if(!fakeRun || resetNavigatorAtInitialization) ResetNavigator(); 639 // CheckRegularGeometry(); 640 // Notify the VisManager as well 641 if (G4Threading::IsMasterThread()) { 642 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); 643 if (pVVisManager != nullptr) pVVisManager->GeometryHasChanged(); 644 } 645 } 646 647 GetPrimaryTransformer()->CheckUnknown(); 648 649 #ifdef G4MULTITHREADED 650 G4UnitDefinition::GetUnitsTable().Synchronize(); 651 #endif 652 653 stateManager->SetNewState(G4State_Idle); 654 stateManager->SetNewState(G4State_GeomClosed); 655 return true; 656 } 657 658 // -------------------------------------------------------------------- 659 void G4RunManagerKernel::PropagateGenericIonID() 660 { 661 G4ParticleDefinition* gion = G4ParticleTable::GetParticleTable()->GetGenericIon(); 662 if (gion != nullptr) { 663 G4int gionId = gion->GetParticleDefinitionID(); 664 auto pItr = G4ParticleTable::GetParticleTable()->GetIterator(); 665 pItr->reset(false); 666 while ((*pItr)()) { 667 G4ParticleDefinition* particle = pItr->value(); 668 if (particle->IsGeneralIon()) particle->SetParticleDefinitionID(gionId); 669 } 670 } 671 } 672 673 // -------------------------------------------------------------------- 674 void G4RunManagerKernel::RunTermination() 675 { 676 if (runManagerKernelType != workerRMK) 677 { G4ProductionCutsTable::GetProductionCutsTable()->PhysicsTableUpdated(); } 678 G4StateManager::GetStateManager()->SetNewState(G4State_Idle); 679 } 680 681 // -------------------------------------------------------------------- 682 void G4RunManagerKernel::ResetNavigator() 683 { 684 G4GeometryManager* geomManager = G4GeometryManager::GetInstance(); 685 if (runManagerKernelType == workerRMK) { 686 // To ensure that it is called when using G4TaskRunManagerKernel 687 if( geomManager->IsParallelOptimisationConfigured() && 688 !geomManager->IsParallelOptimisationFinished() ) 689 { 690 geomManager->UndertakeOptimisation(); 691 } 692 geometryNeedsToBeClosed = false; 693 return; 694 } 695 696 // We have to tweak the navigator's state in case a geometry has been 697 // modified between runs. By the following calls we ensure that navigator's 698 // state is reset properly. It is required the geometry to be closed 699 // and previous optimisations to be cleared. 700 701 if (verboseLevel > 1) G4cout << "Start closing geometry." << G4endl; 702 703 geomManager->OpenGeometry(); 704 geomManager->CloseGeometry(geometryToBeOptimized, verboseLevel > 1); 705 706 geometryNeedsToBeClosed = false; 707 } 708 709 // -------------------------------------------------------------------- 710 void G4RunManagerKernel::UpdateRegion() 711 { 712 G4StateManager* stateManager = G4StateManager::GetStateManager(); 713 G4ApplicationState currentState = stateManager->GetCurrentState(); 714 if (currentState != G4State_Init) { 715 G4Exception("G4RunManagerKernel::UpdateRegion", "Run0024", JustWarning, 716 "Geant4 kernel not in Init state : method ignored."); 717 return; 718 } 719 720 if (runManagerKernelType == workerRMK) return; 721 722 CheckRegions(); 723 724 G4RegionStore::GetInstance()->UpdateMaterialList(currentWorld); 725 726 G4ProductionCutsTable::GetProductionCutsTable()->UpdateCoupleTable(currentWorld); 727 } 728 729 // -------------------------------------------------------------------- 730 void G4RunManagerKernel::BuildPhysicsTables(G4bool fakeRun) 731 { 732 if (G4ProductionCutsTable::GetProductionCutsTable()->IsModified() || physicsNeedsToBeReBuilt) { 733 #ifdef G4MULTITHREADED 734 if (runManagerKernelType == masterRMK) { 735 // make sure workers also rebuild physics tables 736 G4UImanager* pUImanager = G4UImanager::GetUIpointer(); 737 pUImanager->ApplyCommand("/run/physicsModified"); 738 } 739 #endif 740 physicsList->BuildPhysicsTable(); 741 physicsNeedsToBeReBuilt = false; 742 } 743 744 if (!fakeRun && verboseLevel > 1) DumpRegion(); 745 if (!fakeRun && verboseLevel > 0) physicsList->DumpCutValuesTable(); 746 if (!fakeRun) physicsList->DumpCutValuesTableIfRequested(); 747 } 748 749 // -------------------------------------------------------------------- 750 void G4RunManagerKernel::CheckRegions() 751 { 752 G4TransportationManager* transM = G4TransportationManager::GetTransportationManager(); 753 std::size_t nWorlds = transM->GetNoWorlds(); 754 std::vector<G4VPhysicalVolume*>::iterator wItr; 755 for (auto region : *G4RegionStore::GetInstance()) { 756 // Let each region have a pointer to the world volume where it belongs to. 757 // G4Region::SetWorld() checks if the region belongs to the given world and 758 // set it only if it does. Thus, here we go through all the registered world 759 // volumes. 760 region->SetWorld(nullptr); // reset 761 region->UsedInMassGeometry(false); 762 region->UsedInParallelGeometry(false); 763 wItr = transM->GetWorldsIterator(); 764 for (std::size_t iw = 0; iw < nWorlds; ++iw) { 765 if (region->BelongsTo(*wItr)) { 766 if (*wItr == currentWorld) { 767 region->UsedInMassGeometry(true); 768 } 769 else { 770 region->UsedInParallelGeometry(true); 771 } 772 } 773 region->SetWorld(*wItr); 774 ++wItr; 775 } 776 777 G4ProductionCuts* cuts = region->GetProductionCuts(); 778 if (cuts == nullptr) { 779 if (region->IsInMassGeometry() && verboseLevel > 0) { 780 G4cout << "Warning : Region <" << region->GetName() 781 << "> does not have specific production cuts," << G4endl 782 << "even though it appears in the current tracking world." << G4endl; 783 G4cout << "Default cuts are used for this region." << G4endl; 784 } 785 786 if (region->IsInMassGeometry() || region->IsInParallelGeometry()) { 787 region->SetProductionCuts( 788 G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts()); 789 } 790 } 791 } 792 793 // 794 // If a parallel world has no region, set default region for parallel world 795 // 796 797 wItr = transM->GetWorldsIterator(); 798 for (std::size_t iw = 0; iw < nWorlds; ++iw) { 799 if (*wItr != currentWorld) { 800 G4LogicalVolume* pwLogical = (*wItr)->GetLogicalVolume(); 801 if (pwLogical->GetRegion() == nullptr) { 802 pwLogical->SetRegion(defaultRegionForParallelWorld); 803 defaultRegionForParallelWorld->AddRootLogicalVolume(pwLogical); 804 } 805 } 806 ++wItr; 807 } 808 } 809 810 // -------------------------------------------------------------------- 811 void G4RunManagerKernel::DumpRegion(const G4String& rname) const 812 { 813 G4Region* region = G4RegionStore::GetInstance()->GetRegion(rname); 814 if (region != nullptr) DumpRegion(region); 815 } 816 817 // -------------------------------------------------------------------- 818 void G4RunManagerKernel::DumpRegion(G4Region* region) const 819 { 820 if (region == nullptr) { 821 for (const auto& i : *G4RegionStore::GetInstance()) { 822 DumpRegion(i); 823 } 824 } 825 else { 826 if (G4Threading::IsWorkerThread()) return; 827 G4cout << G4endl; 828 G4cout << "Region <" << region->GetName() << "> -- "; 829 if (region->GetWorldPhysical() != nullptr) { 830 G4cout << " -- appears in <" << region->GetWorldPhysical()->GetName() << "> world volume"; 831 } 832 else { 833 G4cout << " -- is not associated to any world."; 834 } 835 G4cout << G4endl; 836 if (region->IsInMassGeometry()) { 837 G4cout << " This region is in the mass world." << G4endl; 838 } 839 if (region->IsInParallelGeometry()) { 840 G4cout << " This region is in the parallel world." << G4endl; 841 } 842 843 G4cout << " Root logical volume(s) : "; 844 std::size_t nRootLV = region->GetNumberOfRootVolumes(); 845 auto lvItr = region->GetRootLogicalVolumeIterator(); 846 for (std::size_t j = 0; j < nRootLV; ++j) { 847 G4cout << (*lvItr)->GetName() << " "; 848 ++lvItr; 849 } 850 G4cout << G4endl; 851 852 G4cout << " Pointers : G4VUserRegionInformation[" << region->GetUserInformation() 853 << "], G4UserLimits[" << region->GetUserLimits() << "], G4FastSimulationManager[" 854 << region->GetFastSimulationManager() << "], G4UserSteppingAction[" 855 << region->GetRegionalSteppingAction() << "]" << G4endl; 856 857 G4cout << " Materials : "; 858 auto mItr = region->GetMaterialIterator(); 859 std::size_t nMaterial = region->GetNumberOfMaterials(); 860 for (std::size_t iMate = 0; iMate < nMaterial; ++iMate) { 861 G4cout << (*mItr)->GetName() << " "; 862 ++mItr; 863 } 864 G4cout << G4endl; 865 G4ProductionCuts* cuts = region->GetProductionCuts(); 866 if ((cuts == nullptr) && region->IsInMassGeometry()) { 867 G4cerr << "Warning : Region <" << region->GetName() 868 << "> does not have specific production cuts." << G4endl; 869 G4cerr << "Default cuts are used for this region." << G4endl; 870 region->SetProductionCuts( 871 G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts()); 872 } 873 else if (cuts != nullptr) { 874 G4cout << " Production cuts : " 875 << " gamma " << G4BestUnit(cuts->GetProductionCut("gamma"), "Length") << " e- " 876 << G4BestUnit(cuts->GetProductionCut("e-"), "Length") << " e+ " 877 << G4BestUnit(cuts->GetProductionCut("e+"), "Length") << " proton " 878 << G4BestUnit(cuts->GetProductionCut("proton"), "Length") << G4endl; 879 } 880 } 881 } 882 883 // -------------------------------------------------------------------- 884 void G4RunManagerKernel::CheckRegularGeometry() 885 { 886 G4LogicalVolumeStore* store = G4LogicalVolumeStore::GetInstance(); 887 for (const auto& pos : *store) { 888 if ((pos != nullptr) && (pos->GetNoDaughters() == 1)) { 889 if (pos->GetDaughter(0)->IsRegularStructure()) { 890 SetScoreSplitter(); 891 return; 892 } 893 } 894 } 895 } 896 897 // -------------------------------------------------------------------- 898 G4bool G4RunManagerKernel::ConfirmCoupledTransportation() 899 { 900 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable(); 901 auto theParticleIterator = theParticleTable->GetIterator(); 902 theParticleIterator->reset(); 903 while ((*theParticleIterator)()) { 904 G4ParticleDefinition* pd = theParticleIterator->value(); 905 G4ProcessManager* pm = pd->GetProcessManager(); 906 if (pm != nullptr) { 907 G4ProcessVector* pv = pm->GetAlongStepProcessVector(typeDoIt); 908 G4VProcess* p = (*pv)[0]; 909 return ((p->GetProcessName()) == "CoupledTransportation"); 910 } 911 } 912 return false; 913 } 914 915 // -------------------------------------------------------------------- 916 void G4RunManagerKernel::SetScoreSplitter() 917 { 918 auto pSplitter = new G4ScoreSplittingProcess(); 919 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable(); 920 auto theParticleIterator = theParticleTable->GetIterator(); 921 922 // Ensure that Process is added only once to the particles' process managers 923 static G4ThreadLocal G4bool InitSplitter = false; 924 if (!InitSplitter) { 925 InitSplitter = true; 926 927 theParticleIterator->reset(); 928 while ((*theParticleIterator)()) { 929 G4ParticleDefinition* particle = theParticleIterator->value(); 930 G4ProcessManager* pmanager = particle->GetProcessManager(); 931 if (pmanager != nullptr) { 932 pmanager->AddDiscreteProcess(pSplitter); 933 } 934 } 935 936 if (verboseLevel > 0) { 937 G4cout << "G4RunManagerKernel -- G4ScoreSplittingProcess is appended to all " 938 "particles." 939 << G4endl; 940 } 941 } 942 } 943 944 // -------------------------------------------------------------------- 945 void G4RunManagerKernel::SetupShadowProcess() const 946 { 947 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable(); 948 auto theParticleIterator = theParticleTable->GetIterator(); 949 theParticleIterator->reset(); 950 // loop on particles and get process manager from there list of processes 951 while ((*theParticleIterator)()) { 952 G4ParticleDefinition* pd = theParticleIterator->value(); 953 G4ProcessManager* pm = pd->GetProcessManager(); 954 if (pm != nullptr) { 955 G4ProcessVector& procs = *(pm->GetProcessList()); 956 for (G4int idx = 0; idx < (G4int)procs.size(); ++idx) { 957 const G4VProcess* masterP = procs[idx]->GetMasterProcess(); 958 if (masterP == nullptr) { 959 // Process does not have an associated shadow master process 960 // We are in master mode or sequential 961 procs[idx]->SetMasterProcess(const_cast<G4VProcess*>(procs[idx])); 962 } 963 } 964 } 965 } 966 } 967