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 11.1.3)


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