Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/src/G4RunManagerKernel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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