Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/src/G4WorkerRunManager.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 ]

Diff markup

Differences between /run/src/G4WorkerRunManager.cc (Version 11.3.0) and /run/src/G4WorkerRunManager.cc (Version 10.1.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4WorkerRunManager implementation           << 
 27 //                                                 26 //
 28 // Original authors: X.Dong, A.Dotti - 2013    << 
 29 // ------------------------------------------- << 
 30                                                    27 
 31 #include "G4WorkerRunManager.hh"                   28 #include "G4WorkerRunManager.hh"
 32                                                <<  29 #include "G4WorkerRunManagerKernel.hh"
 33 #include "G4AutoLock.hh"                       <<  30 #include "G4UImanager.hh"
 34 #include "G4CopyRandomState.hh"                <<  31 #include "G4VUserDetectorConstruction.hh"
 35 #include "G4MTRunManager.hh"                       32 #include "G4MTRunManager.hh"
 36 #include "G4ParallelWorldProcess.hh"           << 
 37 #include "G4ParallelWorldProcessStore.hh"      << 
 38 #include "G4RNGHelper.hh"                      << 
 39 #include "G4Run.hh"                            << 
 40 #include "G4SDManager.hh"                      << 
 41 #include "G4ScoringManager.hh"                     33 #include "G4ScoringManager.hh"
 42 #include "G4Timer.hh"                          << 
 43 #include "G4TransportationManager.hh"              34 #include "G4TransportationManager.hh"
 44 #include "G4UImanager.hh"                      <<  35 #include "G4ParallelWorldProcess.hh"
 45 #include "G4UserRunAction.hh"                  <<  36 #include "G4WorkerThread.hh"
                                                   >>  37 #include "G4VUserPhysicsList.hh"
                                                   >>  38 #include "G4VUserActionInitialization.hh"
 46 #include "G4UserWorkerInitialization.hh"           39 #include "G4UserWorkerInitialization.hh"
 47 #include "G4UserWorkerThreadInitialization.hh"     40 #include "G4UserWorkerThreadInitialization.hh"
 48 #include "G4VScoreNtupleWriter.hh"             <<  41 #include "G4UserRunAction.hh"
 49 #include "G4VScoringMesh.hh"                   <<  42 #include "G4RNGHelper.hh"
 50 #include "G4VUserActionInitialization.hh"      <<  43 #include "G4Run.hh"
 51 #include "G4VUserDetectorConstruction.hh"      << 
 52 #include "G4VUserPhysicsList.hh"               << 
 53 #include "G4VUserPrimaryGeneratorAction.hh"        44 #include "G4VUserPrimaryGeneratorAction.hh"
 54 #include "G4VVisManager.hh"                        45 #include "G4VVisManager.hh"
 55 #include "G4WorkerRunManagerKernel.hh"         <<  46 #include "G4SDManager.hh"
 56 #include "G4WorkerThread.hh"                   <<  47 #include "G4VScoringMesh.hh"
 57                                                <<  48 #include "G4Timer.hh"
 58 #include "G4GeometryManager.hh"   // For paral << 
 59                                                << 
 60 #include <fstream>                             << 
 61 #include <sstream>                                 49 #include <sstream>
 62                                                    50 
 63 // ------------------------------------------- << 
 64 G4WorkerRunManager* G4WorkerRunManager::GetWor     51 G4WorkerRunManager* G4WorkerRunManager::GetWorkerRunManager()
 65 {                                              <<  52 { return static_cast<G4WorkerRunManager*>(G4RunManager::GetRunManager()); }
 66   return static_cast<G4WorkerRunManager*>(G4Ru << 
 67 }                                              << 
 68                                                    53 
 69 // ------------------------------------------- << 
 70 G4WorkerRunManagerKernel* G4WorkerRunManager::     54 G4WorkerRunManagerKernel* G4WorkerRunManager::GetWorkerRunManagerKernel()
 71 {                                              <<  55 { return static_cast<G4WorkerRunManagerKernel*>(GetWorkerRunManager()->kernel); }
 72   return static_cast<G4WorkerRunManagerKernel* << 
 73 }                                              << 
 74                                                << 
 75 // ------------------------------------------- << 
 76 G4WorkerRunManager::G4WorkerRunManager() : G4R << 
 77 {                                              << 
 78   // This constructor should never be called i << 
 79                                                    56 
                                                   >>  57 G4WorkerRunManager::G4WorkerRunManager() : G4RunManager(workerRM) {
                                                   >>  58     //This constructor should never be called in non-multithreaded mode
 80 #ifndef G4MULTITHREADED                            59 #ifndef G4MULTITHREADED
 81   G4ExceptionDescription msg;                  <<  60     G4ExceptionDescription msg;
 82   msg << "Geant4 code is compiled without mult <<  61     msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
 83          "(-DG4MULTITHREADED "                 <<  62     msg<<" This type of RunManager can only be used in mult-threaded applications.";
 84          "is set to off).";                    <<  63     G4Exception("G4WorkerRunManager::G4WorkerRunManager()","Run0035",FatalException,msg);
 85   msg << " This type of RunManager can only be << 
 86          "applications.";                      << 
 87   G4Exception("G4WorkerRunManager::G4WorkerRun << 
 88 #endif                                             64 #endif
 89   // G4ParticleTable::GetParticleTable()->Work <<  65     G4ParticleTable::GetParticleTable()->WorkerG4ParticleTable();
 90      // WorkerG4ParticleTable() would be perfo <<  66     G4ScoringManager* masterScM = G4MTRunManager::GetMasterScoringManager();
 91      // as it is called already from G4Particl <<  67     if(masterScM) G4ScoringManager::GetScoringManager(); //TLS instance for a worker
 92      // which is called beforehand by other Ge <<  68 
 93   G4ScoringManager* masterScM = G4MTRunManager <<  69     eventLoopOnGoing = false;
 94   if (masterScM != nullptr) G4ScoringManager:: <<  70     runIsSeeded = false;
 95                                                <<  71     nevModulo = -1;
 96   // Properly initialise luxury level for Ranl <<  72     currEvID = -1;
 97   //                                           <<  73     workerContext = 0;
 98   if (dynamic_cast<const CLHEP::Ranlux64Engine << 
 99     const auto theEngine = dynamic_cast<const  << 
100     luxury = theEngine->getLuxury();           << 
101   }                                            << 
102   else if (dynamic_cast<const CLHEP::RanluxEng << 
103     const auto theEngine = dynamic_cast<const  << 
104     luxury = theEngine->getLuxury();           << 
105   }                                            << 
106                                                    74 
107   G4UImanager::GetUIpointer()->SetIgnoreCmdNot <<  75     G4UImanager::GetUIpointer()->SetIgnoreCmdNotFound(true);
108                                                    76 
109 #ifdef G4MULTITHREADED                             77 #ifdef G4MULTITHREADED
110   G4VVisManager* pVVis = G4VVisManager::GetCon <<  78     G4VVisManager* pVVis = G4VVisManager::GetConcreteInstance();
111   if (pVVis != nullptr) {                      <<  79     if(pVVis)
112     pVVis->SetUpForAThread();                  <<  80     {
113     visIsSetUp = true;                         <<  81       pVVis->SetUpForAThread();
114   }                                            <<  82       visIsSetUp = true;
                                                   >>  83     }
                                                   >>  84     else
                                                   >>  85     { visIsSetUp = false; }
115 #endif                                             86 #endif
116 }                                                  87 }
117                                                    88 
118 // ------------------------------------------- <<  89 #include "G4MTRunManager.hh"
119 G4WorkerRunManager::~G4WorkerRunManager()      <<  90 
120 {                                              <<  91 G4WorkerRunManager::~G4WorkerRunManager() {
121   CleanUpPreviousEvents();                     <<  92     // Delete thread-local process manager objects
122   // Put these pointers to zero: owned by mast <<  93     physicsList->RemoveProcessManager();
123   // If not to zero, the base class destructor <<  94 
124   // delete them                               <<  95     //Put these pointers to zero: owned by master thread
125   userDetector = nullptr;                      <<  96     //If not to zero, the base class destructor will attempt to
126   userWorkerInitialization = nullptr;          <<  97     //delete them
127   userWorkerThreadInitialization = nullptr;    <<  98     userDetector = 0;
128   userActionInitialization = nullptr;          <<  99     userWorkerInitialization = 0;
129   physicsList->TerminateWorker();              << 100     userWorkerThreadInitialization = 0;
130   physicsList = nullptr;                       << 101     userActionInitialization = 0;
131   if (verboseLevel > 1) G4cout << "Destroying  << 102     physicsList = 0;
132 }                                              << 103     if(verboseLevel>0) G4cout<<"Destroying WorkerRunManager ("<<this<<")"<<G4endl;
133                                                << 
134 // ------------------------------------------- << 
135 void G4WorkerRunManager::InitializeGeometry()  << 
136 {                                              << 
137   if (userDetector == nullptr) {               << 
138     G4Exception("G4RunManager::InitializeGeome << 
139                 "G4VUserDetectorConstruction i << 
140     return;                                    << 
141   }                                            << 
142                                                << 
143   if (fGeometryHasBeenDestroyed) {             << 
144     G4TransportationManager::GetTransportation << 
145   }                                            << 
146                                                << 
147   // Step 0: Contribute to the voxelisation of << 
148   G4GeometryManager* geomManager = G4GeometryM << 
149   if( geomManager->IsParallelOptimisationConfi << 
150     G4cout << "G4RunManager::InitializeGeometr << 
151            << G4endl;  // TODO - suppress / de << 
152     geomManager->UndertakeOptimisation();      << 
153   }                                            << 
154   //  A barrier must ensure that all that all  << 
155   //  Currently we rely on the (later) barrier << 
156                                                << 
157   // Step1: Get pointer to the physiWorld (not << 
158   // pointer, i.e. the one shared by all threa << 
159   G4RunManagerKernel* masterKernel = G4MTRunMa << 
160   G4VPhysicalVolume* worldVol = masterKernel-> << 
161   // Step2:, Call a new "WorkerDefineWorldVolu << 
162   kernel->WorkerDefineWorldVolume(worldVol, fa << 
163   kernel->SetNumberOfParallelWorld(masterKerne << 
164   // Step3: Call user's ConstructSDandField()  << 
165   userDetector->ConstructSDandField();         << 
166   userDetector->ConstructParallelSD();         << 
167   geometryInitialized = true;                  << 
168 }                                                 104 }
169                                                   105 
170 // ------------------------------------------- << 106 
                                                   >> 107 void G4WorkerRunManager::InitializeGeometry() {
                                                   >> 108     if(!userDetector)
                                                   >> 109     {
                                                   >> 110         G4Exception("G4RunManager::InitializeGeometry", "Run0033",
                                                   >> 111                     FatalException, "G4VUserDetectorConstruction is not defined!");
                                                   >> 112         return;
                                                   >> 113     }
                                                   >> 114     if(fGeometryHasBeenDestroyed) 
                                                   >> 115     { G4TransportationManager::GetTransportationManager()->ClearParallelWorlds(); }
                                                   >> 116 
                                                   >> 117     //Step1: Get pointer to the physiWorld (note: needs to get the "super pointer, i.e. the one shared by all threads"
                                                   >> 118     G4RunManagerKernel* masterKernel = G4MTRunManager::GetMasterRunManagerKernel();
                                                   >> 119     G4VPhysicalVolume* worldVol = masterKernel->GetCurrentWorld();
                                                   >> 120     //Step2:, Call a new "WorkerDefineWorldVolume( pointer from 2-, false); 
                                                   >> 121     kernel->WorkerDefineWorldVolume(worldVol,false);
                                                   >> 122     kernel->SetNumberOfParallelWorld(masterKernel->GetNumberOfParallelWorld());
                                                   >> 123     //Step3: Call user's ConstructSDandField()
                                                   >> 124     userDetector->ConstructSDandField();
                                                   >> 125     userDetector->ConstructParallelSD();
                                                   >> 126     geometryInitialized = true;
                                                   >> 127 }
                                                   >> 128 
                                                   >> 129 #include "G4ParallelWorldProcessStore.hh"
                                                   >> 130 
171 void G4WorkerRunManager::RunInitialization()      131 void G4WorkerRunManager::RunInitialization()
172 {                                                 132 {
173 #ifdef G4MULTITHREADED                            133 #ifdef G4MULTITHREADED
174   if (!visIsSetUp) {                           << 134   if(!visIsSetUp)
                                                   >> 135   {
175     G4VVisManager* pVVis = G4VVisManager::GetC    136     G4VVisManager* pVVis = G4VVisManager::GetConcreteInstance();
176     if (pVVis != nullptr) {                    << 137     if(pVVis)
                                                   >> 138     {
177       pVVis->SetUpForAThread();                   139       pVVis->SetUpForAThread();
178       visIsSetUp = true;                          140       visIsSetUp = true;
179     }                                             141     }
180   }                                               142   }
181 #endif                                            143 #endif
182                                                   144 
183   if (!(kernel->RunInitialization(fakeRun))) r << 145   if(!(kernel->RunInitialization(fakeRun))) return;
184                                                   146 
185   // Signal this thread can start event loop.  << 147   //Signal this thread can start event loop.
186   // Note this will return only when all threa << 148   //Note this will return only when all threads reach this point
187   G4MTRunManager::GetMasterRunManager()->ThisW    149   G4MTRunManager::GetMasterRunManager()->ThisWorkerReady();
188   if (fakeRun) return;                         << 150   if(fakeRun) return;
189                                                   151 
190   const G4UserWorkerInitialization* uwi =      << 152   const G4UserWorkerInitialization* uwi
191     G4MTRunManager::GetMasterRunManager()->Get << 153        = G4MTRunManager::GetMasterRunManager()->GetUserWorkerInitialization();
192   CleanUpPreviousEvents();                        154   CleanUpPreviousEvents();
193   delete currentRun;                           << 155   if(currentRun) delete currentRun;
194   currentRun = nullptr;                        << 156   currentRun = 0;
195                                                   157 
196   if (fGeometryHasBeenDestroyed) G4ParallelWor << 158   if(fGeometryHasBeenDestroyed) G4ParallelWorldProcessStore::GetInstance()->UpdateWorlds();
197   // Call a user hook: this is guaranteed all  << 159   //Call a user hook: this is guaranteed all threads are "synchronized"
198   if (uwi != nullptr) uwi->WorkerRunStart();   << 160   if(uwi) uwi->WorkerRunStart();
199                                                   161 
200   if (userRunAction != nullptr) currentRun = u << 162   if(userRunAction) currentRun = userRunAction->GenerateRun();
201   if (currentRun == nullptr) currentRun = new  << 163   if(!currentRun) currentRun = new G4Run();
202                                                   164 
203   currentRun->SetRunID(runIDCounter);             165   currentRun->SetRunID(runIDCounter);
204   currentRun->SetNumberOfEventToBeProcessed(nu    166   currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
205                                                   167 
206   currentRun->SetDCtable(DCtable);                168   currentRun->SetDCtable(DCtable);
207   G4SDManager* fSDM = G4SDManager::GetSDMpoint    169   G4SDManager* fSDM = G4SDManager::GetSDMpointerIfExist();
208   if (fSDM != nullptr) {                       << 170   if(fSDM)
209     currentRun->SetHCtable(fSDM->GetHCtable()) << 171   { currentRun->SetHCtable(fSDM->GetHCtable()); }
210   }                                            << 
211                                                << 
212   if (G4VScoreNtupleWriter::Instance() != null << 
213     auto hce = (fSDM != nullptr) ? fSDM->Prepa << 
214     isScoreNtupleWriter = G4VScoreNtupleWriter << 
215     delete hce;                                << 
216   }                                            << 
217                                                   172 
218   std::ostringstream oss;                         173   std::ostringstream oss;
219   G4Random::saveFullState(oss);                << 174     G4Random::saveFullState(oss);
220   randomNumberStatusForThisRun = oss.str();       175   randomNumberStatusForThisRun = oss.str();
221   currentRun->SetRandomNumberStatus(randomNumb    176   currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
222                                                   177 
223   for (G4int i_prev = 0; i_prev < n_perviousEv << 178   for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
224     previousEvents->push_back(nullptr);        << 179   { previousEvents->push_back((G4Event*)0); }
225   }                                            << 
226                                                   180 
227   if (printModulo > 0 || verboseLevel > 0) {   << 181   if(printModulo>0 || verboseLevel>0)
                                                   >> 182   {
228     G4cout << "### Run " << currentRun->GetRun    183     G4cout << "### Run " << currentRun->GetRunID() << " starts on worker thread "
229            << G4Threading::G4GetThreadId() <<     184            << G4Threading::G4GetThreadId() << "." << G4endl;
230   }                                               185   }
231   if (userRunAction != nullptr) userRunAction- << 186   if(userRunAction) userRunAction->BeginOfRunAction(currentRun);
232                                                   187 
233   if (isScoreNtupleWriter) {                   << 188   if(storeRandomNumberStatus) {
234     G4VScoreNtupleWriter::Instance()->OpenFile << 189       G4String fileN = "currentRun";
235   }                                            << 190       if ( rngStatusEventsFlag ) {
236                                                << 191           std::ostringstream os;
237   if (storeRandomNumberStatus) {               << 192           os << "run" << currentRun->GetRunID();
238     G4String fileN = "currentRun";             << 193           fileN = os.str();
239     if (rngStatusEventsFlag) {                 << 194       }
240       std::ostringstream os;                   << 195       StoreRNGStatus(fileN);
241       os << "run" << currentRun->GetRunID();   << 
242       fileN = os.str();                        << 
243     }                                          << 
244     StoreRNGStatus(fileN);                     << 
245   }                                               196   }
246                                                   197 
247   runAborted = false;                             198   runAborted = false;
248   numberOfEventProcessed = 0;                     199   numberOfEventProcessed = 0;
249 }                                                 200 }
250                                                   201 
251 // ------------------------------------------- << 202 void G4WorkerRunManager::DoEventLoop(G4int n_event, const char* macroFile , G4int n_select)
252 void G4WorkerRunManager::DoEventLoop(G4int n_e << 
253 {                                                 203 {
254   if (userPrimaryGeneratorAction == nullptr) { << 204     if(!userPrimaryGeneratorAction)
255     G4Exception("G4RunManager::GenerateEvent() << 205     {
                                                   >> 206       G4Exception("G4RunManager::GenerateEvent()", "Run0032", FatalException,
256                 "G4VUserPrimaryGeneratorAction    207                 "G4VUserPrimaryGeneratorAction is not defined!");
257   }                                            << 208     }
258                                                   209 
259   // This is the same as in the sequential cas << 210     //This is the same as in the sequential case, just the for-loop indexes are
260   // different                                 << 211     //different
261   InitializeEventLoop(n_event, macroFile, n_se << 212     InitializeEventLoop(n_event,macroFile,n_select);
262                                                << 213 
263   // Reset random number seeds queue           << 214     // Reset random number seeds queue
264   while (!seedsQueue.empty()) {                << 215     while(seedsQueue.size()>0)
265     seedsQueue.pop();                          << 216     { seedsQueue.pop(); }
266   }                                            << 217     // for each run, worker should receive at least one set of random number seeds.
267   // for each run, worker should receive at le << 218     runIsSeeded = false; 
268   // seeds.                                    << 219 
269   runIsSeeded = false;                         << 220     // Event loop
270                                                << 221     eventLoopOnGoing = true;
271   // Event loop                                << 222 ///////    G4int i_event = workerContext->GetThreadId();
272   eventLoopOnGoing = true;                     << 223     G4int i_event = -1;
273   ///////    G4int i_event = workerContext->Ge << 224     nevModulo = -1;
274   G4int i_event = -1;                          << 225     currEvID = -1;
275   nevModulo = -1;                              << 226 
276   currEvID = -1;                               << 227     while(eventLoopOnGoing)
277                                                << 228     {
278   while (eventLoopOnGoing) {                   << 229       ProcessOneEvent(i_event);
279     ProcessOneEvent(i_event);                  << 230       if(eventLoopOnGoing)
280     if (eventLoopOnGoing) {                    << 231       {
281       TerminateOneEvent();                     << 232         TerminateOneEvent();
282       if (runAborted) {                        << 233         if(runAborted)
283         eventLoopOnGoing = false;              << 234         { eventLoopOnGoing = false; }
                                                   >> 235 //////        else
                                                   >> 236 //////        {
                                                   >> 237 //////          i_event += workerContext->GetNumberThreads();
                                                   >> 238 //////          eventLoopOnGoing = i_event<n_event;
                                                   >> 239 //////        }
284       }                                           240       }
285     }                                             241     }
286   }                                            << 242      
287                                                << 243     TerminateEventLoop();
288   TerminateEventLoop();                        << 
289 }                                                 244 }
290                                                   245 
291 // ------------------------------------------- << 
292 void G4WorkerRunManager::ProcessOneEvent(G4int    246 void G4WorkerRunManager::ProcessOneEvent(G4int i_event)
293 {                                                 247 {
294   currentEvent = GenerateEvent(i_event);          248   currentEvent = GenerateEvent(i_event);
295   if (eventLoopOnGoing) {                      << 249   if(eventLoopOnGoing)
                                                   >> 250   {  
296     eventManager->ProcessOneEvent(currentEvent    251     eventManager->ProcessOneEvent(currentEvent);
297     AnalyzeEvent(currentEvent);                   252     AnalyzeEvent(currentEvent);
298     UpdateScoring();                              253     UpdateScoring();
299     if (currentEvent->GetEventID() < n_select_ << 254     if(currentEvent->GetEventID()<n_select_msg) G4UImanager::GetUIpointer()->ApplyCommand(msgText);
300       G4UImanager::GetUIpointer()->ApplyComman << 
301   }                                               255   }
302 }                                                 256 }
303                                                   257 
304 // ------------------------------------------- << 
305 G4Event* G4WorkerRunManager::GenerateEvent(G4i    258 G4Event* G4WorkerRunManager::GenerateEvent(G4int i_event)
306 {                                                 259 {
307   auto anEvent = new G4Event(i_event);         << 260   G4Event* anEvent = new G4Event(i_event);
308   G4long s1 = 0;                               << 261   long s1 = 0;
309   G4long s2 = 0;                               << 262   long s2 = 0;
310   G4long s3 = 0;                               << 263   long s3 = 0;
311   G4bool eventHasToBeSeeded = true;               264   G4bool eventHasToBeSeeded = true;
312   if (G4MTRunManager::SeedOncePerCommunication << 265   if(G4MTRunManager::SeedOncePerCommunication()==1 && runIsSeeded)
313     eventHasToBeSeeded = false;                << 266   { eventHasToBeSeeded = false; }
314   }                                            << 
315                                                   267 
316   if (i_event < 0) {                           << 268   if(i_event<0)
                                                   >> 269   {
317     G4int nevM = G4MTRunManager::GetMasterRunM    270     G4int nevM = G4MTRunManager::GetMasterRunManager()->GetEventModulo();
318     if (nevM == 1) {                           << 271     if(nevM==1)
319       eventLoopOnGoing = G4MTRunManager::GetMa << 272     {
320                                                << 273       eventLoopOnGoing = G4MTRunManager::GetMasterRunManager()
                                                   >> 274                        ->SetUpAnEvent(anEvent,s1,s2,s3,eventHasToBeSeeded);
321       runIsSeeded = true;                         275       runIsSeeded = true;
322     }                                             276     }
323     else {                                     << 277     else
324       if (nevModulo <= 0) {                    << 278     {
325         G4int nevToDo = G4MTRunManager::GetMas << 279       if(nevModulo<=0)
326                                                << 280       {
327         if (nevToDo == 0) {                    << 281         G4int nevToDo = G4MTRunManager::GetMasterRunManager()
328           eventLoopOnGoing = false;            << 282                          ->SetUpNEvents(anEvent,&seedsQueue,eventHasToBeSeeded);
329         }                                      << 283         if(nevToDo==0)
330         else {                                 << 284         { eventLoopOnGoing = false; }
                                                   >> 285         else
                                                   >> 286         {
331           currEvID = anEvent->GetEventID();       287           currEvID = anEvent->GetEventID();
332           nevModulo = nevToDo - 1;                288           nevModulo = nevToDo - 1;
333         }                                         289         }
334       }                                           290       }
335       else {                                   << 291       else
336         if (G4MTRunManager::SeedOncePerCommuni << 292       {
                                                   >> 293         if(G4MTRunManager::SeedOncePerCommunication()>0) eventHasToBeSeeded = false;
337         anEvent->SetEventID(++currEvID);          294         anEvent->SetEventID(++currEvID);
338         --nevModulo;                           << 295         nevModulo--;
339       }                                           296       }
340       if (eventLoopOnGoing && eventHasToBeSeed << 297       if(eventLoopOnGoing && eventHasToBeSeeded)
341         s1 = seedsQueue.front();               << 298       {
342         seedsQueue.pop();                      << 299         s1 = seedsQueue.front(); seedsQueue.pop();
343         s2 = seedsQueue.front();               << 300         s2 = seedsQueue.front(); seedsQueue.pop();
344         seedsQueue.pop();                      << 
345       }                                           301       }
346     }                                             302     }
347                                                   303 
348     if (!eventLoopOnGoing) {                   << 304     if(!eventLoopOnGoing)
                                                   >> 305     {
349       delete anEvent;                             306       delete anEvent;
350       return nullptr;                          << 307       return 0;
351     }                                             308     }
352   }                                               309   }
353   else if (eventHasToBeSeeded) {               << 310   else if(eventHasToBeSeeded)
354     // Need to reseed random number generator  << 311   {
                                                   >> 312     //Need to reseed random number generator
355     G4RNGHelper* helper = G4RNGHelper::GetInst    313     G4RNGHelper* helper = G4RNGHelper::GetInstance();
356     s1 = helper->GetSeed(i_event * 2);         << 314     s1 = helper->GetSeed(i_event*2);
357     s2 = helper->GetSeed(i_event * 2 + 1);     << 315     s2 = helper->GetSeed(i_event*2+1);
358   }                                               316   }
359                                                   317 
360   if (eventHasToBeSeeded) {                    << 318   if(eventHasToBeSeeded) 
361     G4long seeds[3] = {s1, s2, 0};             << 319   {
362     G4Random::setTheSeeds(seeds, luxury);      << 320     long seeds[3] = { s1, s2, 0 };
                                                   >> 321     G4Random::setTheSeeds(seeds,-1);
363     runIsSeeded = true;                           322     runIsSeeded = true;
                                                   >> 323 ////G4cout<<"Event "<<currEvID<<" is seeded with { "<<s1<<", "<<s2<<" }"<<G4endl;
364   }                                               324   }
365                                                   325 
366   // Read from file seed.                      << 326   if(storeRandomNumberStatusToG4Event==1 || storeRandomNumberStatusToG4Event==3)
367   // Andrea Dotti 4 November 2015              << 327   {
368   // This is required for strong-reproducibili << 
369   // thread produces, for each event a status  << 
370   // Search a random file with the format run{ << 
371                                                << 
372   // This is the filename base constructed fro << 
373   const auto filename = [&] {                  << 
374     std::ostringstream os;                     << 
375     os << "run" << currentRun->GetRunID() << " << 
376     return os.str();                           << 
377   };                                           << 
378                                                << 
379   G4bool RNGstatusReadFromFile = false;        << 
380   if (readStatusFromFile) {                    << 
381     // Build full path of RNG status file for  << 
382     std::ostringstream os;                     << 
383     os << filename() << ".rndm";               << 
384     const G4String& randomStatusFile = os.str( << 
385     std::ifstream ifile(randomStatusFile.c_str << 
386     if (ifile) {  // File valid and readable   << 
387       RNGstatusReadFromFile = true;            << 
388       G4Random::restoreEngineStatus(randomStat << 
389     }                                          << 
390   }                                            << 
391                                                << 
392   if (storeRandomNumberStatusToG4Event == 1 || << 
393     std::ostringstream oss;                       328     std::ostringstream oss;
394     G4Random::saveFullState(oss);                 329     G4Random::saveFullState(oss);
395     randomNumberStatusForThisEvent = oss.str()    330     randomNumberStatusForThisEvent = oss.str();
396     anEvent->SetRandomNumberStatus(randomNumbe    331     anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
397   }                                               332   }
398                                                   333 
399   if (storeRandomNumberStatus && !RNGstatusRea << 334   if(storeRandomNumberStatus) {
400   {  // If reading from file, avoid to rewrite << 335       G4String fileN = "currentEvent";
401     G4String fileN = "currentEvent";           << 336       if ( rngStatusEventsFlag ) {
402     if (rngStatusEventsFlag) {                 << 337           std::ostringstream os;
403       fileN = filename();                      << 338           os << "run" << currentRun->GetRunID() << "evt" << anEvent->GetEventID();
404     }                                          << 339           fileN = os.str();
405     StoreRNGStatus(fileN);                     << 340       }
                                                   >> 341       StoreRNGStatus(fileN);
406   }                                               342   }
407                                                   343 
408   if (printModulo > 0 && anEvent->GetEventID() << 344   if(printModulo > 0 && anEvent->GetEventID()%printModulo == 0 )
409     G4cout << "--> Event " << anEvent->GetEven << 345   {
410     if (eventHasToBeSeeded) {                  << 346     G4cout << "--> Event " << anEvent->GetEventID() << " starts with initial seeds ("
411       G4cout << " with initial seeds (" << s1  << 347            << s1 << "," << s2 << ")." << G4endl;
412     }                                          << 
413     G4cout << "." << G4endl;                   << 
414   }                                               348   }
415   userPrimaryGeneratorAction->GeneratePrimarie    349   userPrimaryGeneratorAction->GeneratePrimaries(anEvent);
416   return anEvent;                                 350   return anEvent;
417 }                                                 351 }
418                                                   352 
419 // ------------------------------------------- << 353 void G4WorkerRunManager::MergePartialResults()
420 void G4WorkerRunManager::MergePartialResults(G << 
421 {                                                 354 {
422   // Merge partial results into global run     << 355     //Merge partial results into global run
423   G4MTRunManager* mtRM = G4MTRunManager::GetMa << 356     G4MTRunManager* mtRM = G4MTRunManager::GetMasterRunManager();
424   G4ScoringManager* ScM = G4ScoringManager::Ge << 357     G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
425   if (ScM != nullptr) mtRM->MergeScores(ScM);  << 358     if(ScM) mtRM->MergeScores(ScM);
426 #ifdef G4VERBOSE                               << 359     mtRM->MergeRun(currentRun);
427   if(mergeEvents && verboseLevel>3) {          << 
428     auto eventVector = currentRun->GetEventVec << 
429     if(eventVector!=nullptr || !(eventVector-> << 
430       G4cout<<"G4WorkerRunManager::MergePartia << 
431             <<eventVector->size()<<" events."< << 
432     }                                          << 
433   }                                            << 
434 #endif                                         << 
435   if(mergeEvents) mtRM->MergeRun(currentRun);  << 
436 }                                                 360 }
437                                                   361 
438 // ------------------------------------------- << 
439 void G4WorkerRunManager::RunTermination()         362 void G4WorkerRunManager::RunTermination()
440 {                                                 363 {
441   if (!fakeRun) {                              << 364   if(!fakeRun)
                                                   >> 365   {
442     MergePartialResults();                        366     MergePartialResults();
443                                                << 367     
444     // Call a user hook: note this is before t << 368     //Call a user hook: note this is before the next barrier
445     // so threads execute this method asyncrho << 369     //so threads execute this method asyncrhonouzly
446     //(TerminateRun allows for synch via G4Run    370     //(TerminateRun allows for synch via G4RunAction::EndOfRun)
447     const G4UserWorkerInitialization* uwi =    << 371     const G4UserWorkerInitialization* uwi
448       G4MTRunManager::GetMasterRunManager()->G << 372        = G4MTRunManager::GetMasterRunManager()->GetUserWorkerInitialization();
449     if (uwi != nullptr) uwi->WorkerRunEnd();   << 373     if(uwi) uwi->WorkerRunEnd();
450   }                                               374   }
451                                                   375 
452   G4RunManager::RunTermination();                 376   G4RunManager::RunTermination();
453   // Signal this thread has finished envent-lo << 377   //Signal this thread has finished envent-loop.
454   // Note this will return only whan all threa << 378   //Note this will return only whan all threads reach this point
455   G4MTRunManager::GetMasterRunManager()->ThisW    379   G4MTRunManager::GetMasterRunManager()->ThisWorkerEndEventLoop();
                                                   >> 380 
456 }                                                 381 }
457                                                   382 
458 // ------------------------------------------- << 
459 void G4WorkerRunManager::TerminateEventLoop()     383 void G4WorkerRunManager::TerminateEventLoop()
460 {                                                 384 {
461   if (verboseLevel > 0 && !fakeRun) {          << 385     if(verboseLevel>0 && !fakeRun)
462     timer->Stop();                             << 386     {
463     G4cout << "Thread-local run terminated." < << 387         timer->Stop();
464     G4cout << "Run Summary" << G4endl;         << 388         G4cout << "Thread-local run terminated." << G4endl;
465     if (runAborted) {                          << 389         G4cout << "Run Summary" << G4endl;
466       G4cout << "  Run Aborted after " << numb << 390         if(runAborted)
467     }                                          << 391         { G4cout << "  Run Aborted after " << numberOfEventProcessed << " events processed." << G4endl; }
468     else {                                     << 392         else
469       G4cout << "  Number of events processed  << 393         { G4cout << "  Number of events processed : " << numberOfEventProcessed << G4endl; }
                                                   >> 394         G4cout << "  "  << *timer << G4endl;
470     }                                             395     }
471     G4cout << "  " << *timer << G4endl;        << 
472   }                                            << 
473 }                                                 396 }
474                                                   397 
475 // ------------------------------------------- << 398 /****************************
476 namespace                                      << 399 void G4WorkerRunManager::BeamOn(G4int n_event,const char* macroFile,G4int n_select)
477 {                                              << 400 { 
478 G4Mutex ConstructScoringWorldsMutex = G4MUTEX_ << 401   if(n_event>0) 
                                                   >> 402   { G4RunManager::BeamOn(n_event,macroFile,n_select); }
                                                   >> 403   else
                                                   >> 404   {
                                                   >> 405     // fake BeamOn.
                                                   >> 406     G4MTRunManager::GetMasterRunManager()->ThisWorkerReady();
                                                   >> 407     G4MTRunManager::GetMasterRunManager()->ThisWorkerEndEventLoop();
                                                   >> 408   }
479 }                                                 409 }
                                                   >> 410 ******************************/
480                                                   411 
481 // ------------------------------------------- << 412 #include "G4AutoLock.hh"
                                                   >> 413 namespace { G4Mutex ConstructScoringWorldsMutex = G4MUTEX_INITIALIZER; }
482 void G4WorkerRunManager::ConstructScoringWorld    414 void G4WorkerRunManager::ConstructScoringWorlds()
483 {                                                 415 {
484   using MeshShape = G4VScoringMesh::MeshShape; << 416     // Return if unnecessary
485                                                << 417     G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
486   // Return if unnecessary                     << 418     if(!ScM) return;
487   G4ScoringManager* ScM = G4ScoringManager::Ge << 419     G4int nPar = ScM->GetNumberOfMesh();
488   if (ScM == nullptr) return;                  << 420     if(nPar<1) return;
489   auto nPar = (G4int)ScM->GetNumberOfMesh();   << 421 
490   if (nPar < 1) return;                        << 422     // Update thread-local G4TransportationManager of all the world volumes
491                                                << 423     kernel->WorkerUpdateWorldVolume();
492   // Update thread-local G4TransportationManag << 424 
493   kernel->WorkerUpdateWorldVolume();           << 425     G4ScoringManager* masterScM = G4MTRunManager::GetMasterScoringManager();
494                                                << 426     assert( masterScM != NULL );
495   G4ScoringManager* masterScM = G4MTRunManager << 427     
496                                                << 428     G4ParticleTable::G4PTblDicIterator* particleIterator
497   auto particleIterator = G4ParticleTable::Get << 429      = G4ParticleTable::GetParticleTable()->GetIterator();
498                                                << 430     
499   for (G4int iw = 0; iw < nPar; ++iw) {        << 431     for(G4int iw=0;iw<nPar;iw++)
500     G4VScoringMesh* mesh = ScM->GetMesh(iw);   << 432     {
501     if (fGeometryHasBeenDestroyed) mesh->Geome << 433       G4VScoringMesh* mesh = ScM->GetMesh(iw);
502     G4VPhysicalVolume* pWorld = nullptr;       << 434       if(fGeometryHasBeenDestroyed) mesh->GeometryHasBeenDestroyed();
503     if (mesh->GetShape() != MeshShape::realWor << 435       G4VPhysicalVolume* pWorld
504       pWorld =                                 << 436        = G4TransportationManager::GetTransportationManager()
505         G4TransportationManager::GetTransporta << 437          ->IsWorldExisting(ScM->GetWorldName(iw));
506       if (pWorld == nullptr) {                 << 438       if(!pWorld)
                                                   >> 439       {
507         G4ExceptionDescription ed;                440         G4ExceptionDescription ed;
508         ed << "Mesh name <" << ScM->GetWorldNa << 441         ed<<"Mesh name <"<<ScM->GetWorldName(iw)<<"> is not found in the masther thread.";
509         G4Exception("G4WorkerRunManager::Const << 442         G4Exception("G4WorkerRunManager::ConstructScoringWorlds()","RUN79001",
510       }                                        << 443                       FatalException,ed);
511     }                                          << 444       }
512     if ((mesh->GetMeshElementLogical()) == nul << 445       if(!(mesh->GetMeshElementLogical()))
513       G4AutoLock l(&ConstructScoringWorldsMute << 446       {
514       G4VScoringMesh* masterMesh = masterScM-> << 447         G4AutoLock l(&ConstructScoringWorldsMutex);
515       mesh->SetMeshElementLogical(masterMesh-> << 448         G4VScoringMesh* masterMesh = masterScM->GetMesh(iw);
516       l.unlock();                              << 449         mesh->SetMeshElementLogical(masterMesh->GetMeshElementLogical());
517                                                << 450         l.unlock();
518       if (mesh->GetShape() != MeshShape::realW << 451         
519         G4ParallelWorldProcess* theParallelWor    452         G4ParallelWorldProcess* theParallelWorldProcess = mesh->GetParallelWorldProcess();
520         if (theParallelWorldProcess != nullptr << 453         if(theParallelWorldProcess)
521           theParallelWorldProcess->SetParallel << 454         { theParallelWorldProcess->SetParallelWorld(ScM->GetWorldName(iw)); }
522         }                                      << 455         else
523         else {                                 << 456         {
524           theParallelWorldProcess = new G4Para    457           theParallelWorldProcess = new G4ParallelWorldProcess(ScM->GetWorldName(iw));
525           mesh->SetParallelWorldProcess(thePar    458           mesh->SetParallelWorldProcess(theParallelWorldProcess);
526           theParallelWorldProcess->SetParallel    459           theParallelWorldProcess->SetParallelWorld(ScM->GetWorldName(iw));
527                                                   460 
528           particleIterator->reset();              461           particleIterator->reset();
529           while ((*particleIterator)()) {      << 462           while( (*particleIterator)() ){
530             G4ParticleDefinition* particle = p    463             G4ParticleDefinition* particle = particleIterator->value();
531             G4ProcessManager* pmanager = parti    464             G4ProcessManager* pmanager = particle->GetProcessManager();
532             if (pmanager != nullptr) {         << 465             if(pmanager)
                                                   >> 466             {
533               pmanager->AddProcess(theParallel    467               pmanager->AddProcess(theParallelWorldProcess);
534               if (theParallelWorldProcess->IsA << 468               if(theParallelWorldProcess->IsAtRestRequired(particle))
535                 pmanager->SetProcessOrdering(t << 469               { pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9999); }
536               }                                << 
537               pmanager->SetProcessOrderingToSe    470               pmanager->SetProcessOrderingToSecond(theParallelWorldProcess, idxAlongStep);
538               pmanager->SetProcessOrdering(the << 471               pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9999);
539             }  // if(pmanager)                 << 472             } //if(pmanager)
540           }  // while                          << 473           }//while
541         }                                         474         }
542         theParallelWorldProcess->SetLayeredMat << 
543       }                                           475       }
                                                   >> 476       mesh->WorkerConstruct(pWorld);
544     }                                             477     }
545     mesh->WorkerConstruct(pWorld);             << 
546   }                                            << 
547 }                                                 478 }
548                                                   479 
549 // ------------------------------------------- << 
550 void G4WorkerRunManager::SetUserInitialization    480 void G4WorkerRunManager::SetUserInitialization(G4UserWorkerInitialization*)
551 {                                                 481 {
552   G4Exception("G4RunManager::SetUserInitializa << 482     G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerInitialization*)", "Run3021",
553               FatalException, "This method sho << 483                 FatalException, "This method should be used only with an instance of G4MTRunManager");
554 }                                                 484 }
555                                                   485 
556 // ------------------------------------------- << 
557 void G4WorkerRunManager::SetUserInitialization    486 void G4WorkerRunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)
558 {                                                 487 {
559   G4Exception("G4RunManager::SetUserInitializa << 488     G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)", "Run3021",
560               FatalException, "This method sho << 489                 FatalException, "This method should be used only with an instance of G4MTRunManager");
561 }                                                 490 }
562                                                   491 
563 // ------------------------------------------- << 
564 void G4WorkerRunManager::SetUserInitialization    492 void G4WorkerRunManager::SetUserInitialization(G4VUserActionInitialization*)
565 {                                                 493 {
566   G4Exception("G4RunManager::SetUserInitializa << 494     G4Exception("G4RunManager::SetUserInitialization(G4VUserActionInitialization*)", "Run3021",
567               FatalException, "This method sho << 495                 FatalException, "This method should be used only with an instance of G4MTRunManager");
568 }                                                 496 }
569                                                   497 
570 // ------------------------------------------- << 
571 void G4WorkerRunManager::SetUserInitialization    498 void G4WorkerRunManager::SetUserInitialization(G4VUserDetectorConstruction*)
572 {                                                 499 {
573   G4Exception("G4RunManager::SetUserInitializa << 500     G4Exception("G4RunManager::SetUserInitialization(G4VUserDetectorConstruction*)", "Run3021",
574               FatalException, "This method sho << 501                 FatalException, "This method should be used only with an instance of G4MTRunManager");
575 }                                                 502 }
576                                                   503 
577 // ------------------------------------------- << 
578 void G4WorkerRunManager::SetUserInitialization    504 void G4WorkerRunManager::SetUserInitialization(G4VUserPhysicsList* pl)
579 {                                                 505 {
580   pl->InitializeWorker();                      << 506     pl->InitializeWorker();
581   G4RunManager::SetUserInitialization(pl);     << 507     G4RunManager::SetUserInitialization(pl);
582 }                                                 508 }
583                                                   509 
584 // ------------------------------------------- << 
585 void G4WorkerRunManager::SetUserAction(G4UserR    510 void G4WorkerRunManager::SetUserAction(G4UserRunAction* userAction)
586 {                                                 511 {
587   G4RunManager::SetUserAction(userAction);     << 512     G4RunManager::SetUserAction(userAction);
588   if (userAction != nullptr) userAction->SetMa << 513     userAction->SetMaster(false);
589 }                                                 514 }
590                                                   515 
591 // ------------------------------------------- << 
592 void G4WorkerRunManager::SetupDefaultRNGEngine    516 void G4WorkerRunManager::SetupDefaultRNGEngine()
593 {                                                 517 {
594   const CLHEP::HepRandomEngine* mrnge =        << 518     const CLHEP::HepRandomEngine* mrnge = G4MTRunManager::GetMasterRunManager()->getMasterRandomEngine();
595     G4MTRunManager::GetMasterRunManager()->get << 519     assert(mrnge);//Master has created RNG
596   const G4UserWorkerThreadInitialization* uwti << 520     const G4UserWorkerThreadInitialization* uwti
597     G4MTRunManager::GetMasterRunManager()->Get << 521       =G4MTRunManager::GetMasterRunManager()->GetUserWorkerThreadInitialization();
598   uwti->SetupRNGEngine(mrnge);                 << 522     uwti->SetupRNGEngine(mrnge);
599 }                                                 523 }
600                                                   524 
601 // Forward calls (avoid GCC compilation warnin << 
602                                                   525 
603 // ------------------------------------------- << 526 //Forward calls (avoid GCC compilation warnings)
604 void G4WorkerRunManager::SetUserAction(G4UserE    527 void G4WorkerRunManager::SetUserAction(G4UserEventAction* ua)
605 {                                                 528 {
606   G4RunManager::SetUserAction(ua);             << 529     G4RunManager::SetUserAction(ua);
607 }                                                 530 }
608                                                   531 
609 // ------------------------------------------- << 
610 void G4WorkerRunManager::SetUserAction(G4VUser    532 void G4WorkerRunManager::SetUserAction(G4VUserPrimaryGeneratorAction* ua)
611 {                                                 533 {
612   G4RunManager::SetUserAction(ua);             << 534     G4RunManager::SetUserAction(ua);
613 }                                                 535 }
614                                                   536 
615 // ------------------------------------------- << 
616 void G4WorkerRunManager::SetUserAction(G4UserS    537 void G4WorkerRunManager::SetUserAction(G4UserStackingAction* ua)
617 {                                                 538 {
618   G4RunManager::SetUserAction(ua);             << 539     G4RunManager::SetUserAction(ua);
619 }                                                 540 }
620                                                   541 
621 // ------------------------------------------- << 
622 void G4WorkerRunManager::SetUserAction(G4UserT    542 void G4WorkerRunManager::SetUserAction(G4UserTrackingAction* ua)
623 {                                                 543 {
624   G4RunManager::SetUserAction(ua);             << 544     G4RunManager::SetUserAction(ua);
625 }                                                 545 }
626                                                   546 
627 // ------------------------------------------- << 
628 void G4WorkerRunManager::SetUserAction(G4UserS    547 void G4WorkerRunManager::SetUserAction(G4UserSteppingAction* ua)
629 {                                                 548 {
630   G4RunManager::SetUserAction(ua);             << 549     G4RunManager::SetUserAction(ua);
631 }                                                 550 }
632                                                   551 
633 // ------------------------------------------- << 552 void G4WorkerRunManager::StoreRNGStatus(const G4String& fn )
634 void G4WorkerRunManager::StoreRNGStatus(const  << 
635 {                                                 553 {
636   std::ostringstream os;                       << 554     std::ostringstream os;
637   os << randomNumberStatusDir << "G4Worker" << << 555     os << randomNumberStatusDir << "G4Worker"<<workerContext->GetThreadId()<<"_"<<fn <<".rndm";
638   G4Random::saveEngineStatus(os.str().c_str()) << 556     G4Random::saveEngineStatus(os.str().c_str());    
639 }                                              << 
640                                                << 
641 // ------------------------------------------- << 
642 void G4WorkerRunManager::rndmSaveThisRun()     << 
643 {                                              << 
644   G4int runNumber = 0;                         << 
645   if (currentRun != nullptr) runNumber = curre << 
646   if (!storeRandomNumberStatus) {              << 
647     G4cerr << "Warning from G4RunManager::rndm << 
648            << " Random number status was not s << 
649            << "/random/setSavingFlag command m << 
650            << "Command ignored." << G4endl;    << 
651     return;                                    << 
652   }                                            << 
653                                                << 
654   std::ostringstream oos;                      << 
655   oos << "G4Worker" << workerContext->GetThrea << 
656       << "currentRun.rndm"                     << 
657       << "\0";                                 << 
658   G4fs::path fileIn = randomNumberStatusDir +  << 
659                                                << 
660   std::ostringstream os;                       << 
661   os << "run" << runNumber << ".rndm" << '\0'; << 
662   G4fs::path fileOut = randomNumberStatusDir + << 
663                                                << 
664   if (G4CopyRandomState(fileIn, fileOut, "G4Wo << 
665       && verboseLevel > 0)                     << 
666   {                                            << 
667     G4cout << fileIn << " is copied to " << fi << 
668   }                                            << 
669 }                                              << 
670                                                << 
671 // ------------------------------------------- << 
672 void G4WorkerRunManager::rndmSaveThisEvent()   << 
673 {                                              << 
674   if (currentEvent == nullptr) {               << 
675     G4cerr << "Warning from G4RunManager::rndm << 
676            << " there is no currentEvent avail << 
677     return;                                    << 
678   }                                            << 
679                                                << 
680   if (!storeRandomNumberStatus) {              << 
681     G4cerr << "Warning from G4RunManager::rndm << 
682            << " Random number engine status is << 
683            << "/random/setSavingFlag command m << 
684            << "prior to the start of the run.  << 
685     return;                                    << 
686   }                                            << 
687                                                << 
688   std::ostringstream oos;                      << 
689   oos << "G4Worker" << workerContext->GetThrea << 
690       << "currentEvent.rndm"                   << 
691       << "\0";                                 << 
692   G4fs::path fileIn = randomNumberStatusDir +  << 
693                                                << 
694   std::ostringstream os;                       << 
695   os << "run" << currentRun->GetRunID() << "ev << 
696   G4fs::path fileOut = randomNumberStatusDir + << 
697                                                << 
698   if (G4CopyRandomState(fileIn, fileOut, "G4Wo << 
699       && verboseLevel > 0)                     << 
700   {                                            << 
701     G4cout << fileIn << " is copied to " << fi << 
702   }                                            << 
703 }                                              << 
704                                                << 
705 // ------------------------------------------- << 
706 void G4WorkerRunManager::DoWork()              << 
707 {                                              << 
708   G4MTRunManager* mrm = G4MTRunManager::GetMas << 
709   G4MTRunManager::WorkerActionRequest nextActi << 
710   while (nextAction != G4MTRunManager::WorkerA << 
711     if (nextAction == G4MTRunManager::WorkerAc << 
712                                                << 
713     {                                          << 
714       // The following code deals with changin << 
715       static G4ThreadLocal G4bool skipInitiali << 
716       if (skipInitialization) {                << 
717         // re-initialization is not necessary  << 
718         skipInitialization = false;            << 
719       }                                        << 
720       else {                                   << 
721         //        ReinitializeGeometry();      << 
722         workerContext->UpdateGeometryAndPhysic << 
723       }                                        << 
724                                                << 
725       // Execute UI commands stored in the mas << 
726       std::vector<G4String> cmds = mrm->GetCom << 
727       G4UImanager* uimgr = G4UImanager::GetUIp << 
728       for (const auto& cmd : cmds) {           << 
729         uimgr->ApplyCommand(cmd);              << 
730       }                                        << 
731       // Start this run                        << 
732       G4int numevents = mrm->GetNumberOfEvents << 
733       G4String macroFile = mrm->GetSelectMacro << 
734       G4int numSelect = mrm->GetNumberOfSelect << 
735       if (macroFile.empty() || macroFile == "  << 
736         this->BeamOn(numevents);               << 
737       }                                        << 
738       else {                                   << 
739         this->BeamOn(numevents, macroFile, num << 
740       }                                        << 
741     }                                          << 
742     else if (nextAction == G4MTRunManager::Wor << 
743       std::vector<G4String> cmds = mrm->GetCom << 
744       G4UImanager* uimgr = G4UImanager::GetUIp << 
745       for (const auto& cmd : cmds) {           << 
746         uimgr->ApplyCommand(cmd);              << 
747       }                                        << 
748       mrm->ThisWorkerProcessCommandsStackDone( << 
749     }                                          << 
750     else {                                     << 
751       G4ExceptionDescription d;                << 
752       d << "Cannot continue, this worker has b << 
753         << static_cast<std::underlying_type<G4 << 
754       G4Exception("G4WorkerRunManager::DoWork" << 
755     }                                          << 
756                                                << 
757     // Now wait for master thread to signal ne << 
758     nextAction = mrm->ThisWorkerWaitForNextAct << 
759   }  // No more actions to perform             << 
760                                                << 
761   return;                                      << 
762 }                                                 557 }
763                                                   558