Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4RunManagerKernel.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id$
28 //
29 //
30 
31 #include "G4RunManagerKernel.hh"
32 
33 #include <vector>
34 
35 #include "G4StateManager.hh"
36 #include "G4ApplicationState.hh"
37 #include "G4ExceptionHandler.hh"
38 #include "G4PrimaryTransformer.hh"
39 #include "G4GeometryManager.hh"
41 #include "G4VPhysicalVolume.hh"
42 #include "G4LogicalVolume.hh"
43 #include "G4VUserPhysicsList.hh"
44 #include "G4ParticleTable.hh"
45 #include "G4Region.hh"
46 #include "G4RegionStore.hh"
47 #include "G4ProductionCuts.hh"
48 #include "G4ProductionCutsTable.hh"
49 #include "G4SDManager.hh"
50 #include "G4UImanager.hh"
51 #include "G4VVisManager.hh"
52 #include "G4UnitsTable.hh"
53 #include "G4Version.hh"
54 #include "G4ios.hh"
55 
56 #ifdef G4FPE_DEBUG
57  #include "G4FPEDetection.hh"
58 #endif
59 
60 G4RunManagerKernel* G4RunManagerKernel::fRunManagerKernel = 0;
61 
63 { return fRunManagerKernel; }
64 
66 :physicsList(0),currentWorld(0),
67  geometryInitialized(false),physicsInitialized(false),
68  geometryNeedsToBeClosed(true),geometryToBeOptimized(true),
69  physicsNeedsToBeReBuilt(true),verboseLevel(0),
70  numberOfParallelWorld(0)
71 {
72 #ifdef G4FPE_DEBUG
73  InvalidOperationDetection();
74 #endif
75 
76  defaultExceptionHandler = new G4ExceptionHandler();
77  if(fRunManagerKernel)
78  {
79  G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0001",
80  FatalException,"More than one G4RunManagerKernel is constructed.");
81  }
82  fRunManagerKernel = this;
83 
85  if(particleTable->entries()>0)
86  {
87  // No particle should be registered beforehand
89  ED<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<G4endl;
90  ED<<" G4RunManagerKernel fatal exception"<<G4endl;
91  ED<<" -- Following particles have already been registered"<<G4endl;
92  ED<<" before G4RunManagerKernel is instantiated."<<G4endl;
93  for(int i=0;i<particleTable->entries();i++)
94  { ED<<" "<<particleTable->GetParticle(i)->GetParticleName()<<G4endl; }
95  ED<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<G4endl;
96  G4Exception("G4RunManagerKernel::G4RunManagerKernel()","Run0002",
97  FatalException,ED);
98  }
99 
100  // construction of Geant4 kernel classes
101  eventManager = new G4EventManager();
102  defaultRegion = new G4Region("DefaultRegionForTheWorld"); // deleted by store
103  defaultRegionForParallelWorld = new G4Region("DefaultRegionForParallelWorld"); // deleted by store
104  defaultRegion->SetProductionCuts(
105  G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts());
106  defaultRegionForParallelWorld->SetProductionCuts(
107  G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts());
108 
109  // Following line is tentatively moved from SetPhysics method
110  // Commented out for introduction of non-static particle definition // G4ParticleTable::GetParticleTable()->SetReadiness();
111  // set the initial application state
113 
114  // version banner
115  G4String vs = G4Version;
116  vs = vs.substr(1,vs.size()-2);
117  versionString = " Geant4 version ";
118  versionString += vs;
119  versionString += " ";
120  versionString += G4Date;
121  G4cout << G4endl
122  << "*************************************************************" << G4endl
123  << versionString << G4endl
124  << " Copyright : Geant4 Collaboration" << G4endl
125  << " Reference : NIM A 506 (2003), 250-303" << G4endl
126  << " WWW : http://cern.ch/geant4" << G4endl
127  << "*************************************************************" << G4endl
128  << G4endl;
129 }
130 
132 {
134  // set the application state to the quite state
135  if(pStateManager->GetCurrentState()!=G4State_Quit)
136  {
137  if(verboseLevel>0) G4cout << "G4 kernel has come to Quit state." << G4endl;
138  pStateManager->SetNewState(G4State_Quit);
139  }
140 
141  // open geometry for deletion
143 
144  // deletion of Geant4 kernel classes
146  if(fSDM)
147  {
148  delete fSDM;
149  if(verboseLevel>1) G4cout << "G4SDManager deleted." << G4endl;
150  }
151  delete eventManager;
152  if(verboseLevel>1) G4cout << "EventManager deleted." << G4endl;
153  G4UImanager* pUImanager = G4UImanager::GetUIpointer();
154  {
155  if(pUImanager) delete pUImanager;
156  if(verboseLevel>1) G4cout << "UImanager deleted." << G4endl;
157  }
159  if(verboseLevel>1) G4cout << "Units table cleared." << G4endl;
160  delete pStateManager;
161  if(verboseLevel>1) G4cout << "StateManager deleted." << G4endl;
162  delete defaultExceptionHandler;
163  if(verboseLevel>1) G4cout << "RunManagerKernel is deleted." << G4endl;
164  fRunManagerKernel = 0;
165 }
166 
168  G4bool topologyIsChanged)
169 {
171  G4ApplicationState currentState = stateManager->GetCurrentState();
172  if(!(currentState==G4State_Idle||currentState==G4State_PreInit))
173  {
174  G4Exception("G4RunManagerKernel::DefineWorldVolume",
175  "Run00031",
176  JustWarning,
177  "Geant4 kernel is not PreInit or Idle state : Method ignored.");
178  return;
179  }
180 
181  // The world volume MUST NOT have a region defined by the user
182  if(worldVol->GetLogicalVolume()->GetRegion())
183  {
184  if(worldVol->GetLogicalVolume()->GetRegion()!=defaultRegion)
185  {
187  ED << "The world volume has a user-defined region <"
188  << worldVol->GetLogicalVolume()->GetRegion()->GetName()
189  << ">." << G4endl;
190  ED << "World would have a default region assigned by RunManagerKernel."
191  << G4endl;
192  G4Exception("G4RunManager::DefineWorldVolume",
193  "Run0004", FatalException, ED);
194  }
195  }
196 
197  // Remove old world logical volume from the default region, if exist
198  if(defaultRegion->GetNumberOfRootVolumes())
199  {
200  if(defaultRegion->GetNumberOfRootVolumes()>size_t(1))
201  {
202  G4Exception("G4RunManager::DefineWorldVolume",
203  "Run0005",
205  "Default world region should have a unique logical volume.");
206  }
207  std::vector<G4LogicalVolume*>::iterator lvItr
208  = defaultRegion->GetRootLogicalVolumeIterator();
209  defaultRegion->RemoveRootLogicalVolume(*lvItr,false);
210  if(verboseLevel>1) G4cout
211  << "Obsolete world logical volume is removed from the default region." << G4endl;
212  }
213 
214  // Accept the world volume
215  currentWorld = worldVol;
216 
217  // Set the default region to the world
218  G4LogicalVolume* worldLog = currentWorld->GetLogicalVolume();
219  worldLog->SetRegion(defaultRegion);
220  defaultRegion->AddRootLogicalVolume(worldLog);
221  if(verboseLevel>1) G4cout << worldLog->GetName()
222  << " is registered to the default region." << G4endl;
223 
224  // Set the world volume, notify the Navigator and reset its state
226  ->SetWorldForTracking(currentWorld);
227  if(topologyIsChanged) geometryNeedsToBeClosed = true;
228 
229  // Notify the VisManager as well
231  if(pVVisManager) pVVisManager->GeometryHasChanged();
232 
233  geometryInitialized = true;
234  if(physicsInitialized && currentState!=G4State_Idle)
235  { stateManager->SetNewState(G4State_Idle); }
236 }
237 
239 {
240  physicsList = uPhys;
242  physicsList->ConstructParticle();
243  if(verboseLevel>2) G4ParticleTable::GetParticleTable()->DumpTable();
244  if(verboseLevel>1)
245  {
246  G4cout << "List of instantiated particles ============================================" << G4endl;
248  for(G4int i=0;i<nPtcl;i++)
249  {
251  G4cout << pd->GetParticleName() << " ";
252  if(i%10==9) G4cout << G4endl;
253  }
254  G4cout << G4endl;
255  }
256 }
257 
259 {
261  G4ApplicationState currentState = stateManager->GetCurrentState();
262  if(!(currentState==G4State_Idle||currentState==G4State_PreInit))
263  {
264  G4Exception("G4RunManagerKernel::InitializePhysics",
265  "Run0011", JustWarning,
266  "Geant4 kernel is not PreInit or Idle state : Method ignored.");
267  return;
268  }
269 
270  if(!physicsList)
271  {
272  G4Exception("G4RunManagerKernel::InitializePhysics",
273  "Run0012", FatalException,
274  "G4VUserPhysicsList is not defined");
275  return;
276  }
277 
278  if(verboseLevel>1) G4cout << "physicsList->Construct() start." << G4endl;
279  if(numberOfParallelWorld>0) physicsList->UseCoupledTransportation();
280  physicsList->Construct();
281 
282  if(verboseLevel>1) G4cout << "physicsList->CheckParticleList() start." << G4endl;
283  physicsList->CheckParticleList();
284  if(verboseLevel>1) G4cout << "physicsList->setCut() start." << G4endl;
285  physicsList->SetCuts();
286  CheckRegions();
287  physicsInitialized = true;
288  if(geometryInitialized && currentState!=G4State_Idle)
289  { stateManager->SetNewState(G4State_Idle); }
290 }
291 
293 {
295  G4ApplicationState currentState = stateManager->GetCurrentState();
296 
297  if(!geometryInitialized)
298  {
299  G4Exception("G4RunManagerKernel::RunInitialization",
300  "Run0021",
301  JustWarning,
302  "Geometry has not yet initialized : method ignored.");
303  return false;
304  }
305 
306  if(!physicsInitialized)
307  {
308  G4Exception("G4RunManagerKernel::RunInitialization",
309  "Run0022",
310  JustWarning,
311  "Physics has not yet initialized : method ignored.");
312  return false;
313  }
314 
315  if( currentState != G4State_Idle )
316  {
317  G4Exception("G4RunManagerKernel::RunInitialization",
318  "Run0023",
319  JustWarning,
320  "Geant4 kernel not in Idle state : method ignored.");
321  return false;
322  }
323 
324  //if(numberOfParallelWorld>0)
325  //{ // Confirm G4CoupledTransportation is used
326  // if(!ConfirmCoupledTransportation())
327  // { G4Exception("G4CoupledTransportation must be used for parallel world."); }
328  //}
329 
330  UpdateRegion();
331  BuildPhysicsTables();
332 
333  if(geometryNeedsToBeClosed)
334  {
335  ResetNavigator();
336  CheckRegularGeometry();
337  // Notify the VisManager as well
339  if(pVVisManager) pVVisManager->GeometryHasChanged();
340  }
341 
343 
344  stateManager->SetNewState(G4State_GeomClosed);
345  return true;
346 }
347 
350 
351 void G4RunManagerKernel::ResetNavigator()
352 {
353  // We have to tweak the navigator's state in case a geometry has been
354  // modified between runs. By the following calls we ensure that navigator's
355  // state is reset properly. It is required the geometry to be closed
356  // and previous optimisations to be cleared.
357 
359  if(verboseLevel>1) G4cout << "Start closing geometry." << G4endl;
360  geomManager->OpenGeometry();
361  geomManager->CloseGeometry(geometryToBeOptimized, verboseLevel>1);
362 
363  // Reseting Navigator has been moved to G4Eventmanager, so that resetting
364  // is now done for every event.
365  // G4ThreeVector center(0,0,0);
366  // G4Navigator* navigator =
367  // G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
368  // navigator->LocateGlobalPointAndSetup(center,0,false);
369 
370  geometryNeedsToBeClosed = false;
371 }
372 
374 {
376  G4ApplicationState currentState = stateManager->GetCurrentState();
377  if( currentState != G4State_Idle )
378  {
379  G4Exception("G4RunManagerKernel::UpdateRegion",
380  "Run0024",
381  JustWarning,
382  "Geant4 kernel not in Idle state : method ignored.");
383  return;
384  }
385 
386  CheckRegions();
389 }
390 
391 void G4RunManagerKernel::BuildPhysicsTables()
392 {
394  || physicsNeedsToBeReBuilt)
395  {
396  physicsList->BuildPhysicsTable();
398  physicsNeedsToBeReBuilt = false;
399  }
400 
401  if(verboseLevel>1) DumpRegion();
402  if(verboseLevel>0) physicsList->DumpCutValuesTable();
403  physicsList->DumpCutValuesTableIfRequested();
404 }
405 
406 void G4RunManagerKernel::CheckRegions()
407 {
409  size_t nWorlds = transM->GetNoWorlds();
410  std::vector<G4VPhysicalVolume*>::iterator wItr;
411  for(size_t i=0;i<G4RegionStore::GetInstance()->size();i++)
412  {
413  G4Region* region = (*(G4RegionStore::GetInstance()))[i];
414 
415  //Let each region have a pointer to the world volume where it belongs to.
416  //G4Region::SetWorld() checks if the region belongs to the given world and set it
417  //only if it does. Thus, here we go through all the registered world volumes.
418  region->SetWorld(0); // reset
419  region->UsedInMassGeometry(false);
420  region->UsedInParallelGeometry(false);
421  wItr = transM->GetWorldsIterator();
422  for(size_t iw=0;iw<nWorlds;iw++)
423  {
424  if(region->BelongsTo(*wItr))
425  {
426  if(*wItr==currentWorld)
427  { region->UsedInMassGeometry(true); }
428  else
429  { region->UsedInParallelGeometry(true); }
430  }
431  region->SetWorld(*wItr);
432  wItr++;
433  }
434 
435  G4ProductionCuts* cuts = region->GetProductionCuts();
436  if(!cuts)
437  {
438  if(region->IsInMassGeometry())
439  {
440  G4cerr << "Warning : Region <" << region->GetName()
441  << "> does not have specific production cuts," << G4endl
442  << "even though it appears in the current tracking world." << G4endl;
443  G4cerr << "Default cuts are used for this region." << G4endl;
444  }
445 
446  if(region->IsInMassGeometry()||region->IsInParallelGeometry())
447  {
448  region->SetProductionCuts(
450  ->GetDefaultProductionCuts());
451  }
452  }
453  }
454 
455  //
456  // If a parallel world has no region, set default region for parallel world
457  //
458 
459 //DumpRegion();
460 //
461 // while(defaultRegionForParallelWorld->GetNumberOfRootVolumes()>0)
462 // {
463 // std::vector<G4LogicalVolume*>::iterator lvItr
464 // = defaultRegionForParallelWorld->GetRootLogicalVolumeIterator();
465 // defaultRegionForParallelWorld->RemoveRootLogicalVolume(*lvItr,false);
466 // }
467 
468  wItr = transM->GetWorldsIterator();
469  for(size_t iw=0;iw<nWorlds;iw++)
470  {
471  //G4cout << "+++ " << (*wItr)->GetName() << G4endl;
472  if(*wItr!=currentWorld)
473  {
474  G4LogicalVolume* pwLogical = (*wItr)->GetLogicalVolume();
475  if(!(pwLogical->GetRegion()))
476  {
477  pwLogical->SetRegion(defaultRegionForParallelWorld);
478  defaultRegionForParallelWorld->AddRootLogicalVolume(pwLogical);
479  //G4cout << "+++++ defaultRegionForParallelWorld is set to "
480  // << (*wItr)->GetName() << " +++++" << G4endl;
481  }
482  }
483  wItr++;
484  }
485 
486 }
487 
488 void G4RunManagerKernel::DumpRegion(const G4String& rname) const
489 {
490  G4Region* region = G4RegionStore::GetInstance()->GetRegion(rname);
491  if(region) DumpRegion(region);
492 }
493 
495 {
496  if(!region)
497  {
498  for(size_t i=0;i<G4RegionStore::GetInstance()->size();i++)
499  { DumpRegion((*(G4RegionStore::GetInstance()))[i]); }
500  }
501  else
502  {
503  G4cout << G4endl;
504  G4cout << "Region <" << region->GetName() << "> -- ";
505  if(region->GetWorldPhysical())
506  {
507  G4cout << " -- appears in <"
508  << region->GetWorldPhysical()->GetName() << "> world volume";
509  }
510  else
511  { G4cout << " -- is not associated to any world."; }
512  G4cout << G4endl;
513  if(region->IsInMassGeometry())
514  { G4cout << " This region is in the mass world." << G4endl; }
515  if(region->IsInParallelGeometry())
516  { G4cout << " This region is in the parallel world." << G4endl; }
517 
518  G4cout << " Root logical volume(s) : ";
519  size_t nRootLV = region->GetNumberOfRootVolumes();
520  std::vector<G4LogicalVolume*>::iterator lvItr = region->GetRootLogicalVolumeIterator();
521  for(size_t j=0;j<nRootLV;j++)
522  { G4cout << (*lvItr)->GetName() << " "; lvItr++; }
523  G4cout << G4endl;
524 
525  G4cout << " Pointers : G4VUserRegionInformation[" << region->GetUserInformation()
526  << "], G4UserLimits[" << region->GetUserLimits()
527  << "], G4FastSimulationManager[" << region->GetFastSimulationManager()
528  << "], G4UserSteppingAction[" << region->GetRegionalSteppingAction() << "]" << G4endl;
529 
530 // if(region->GetWorldPhysical()!=currentWorld)
531 // {
532 // G4cout << G4endl;
533 // return;
534 // }
535  G4cout << " Materials : ";
536  std::vector<G4Material*>::const_iterator mItr = region->GetMaterialIterator();
537  size_t nMaterial = region->GetNumberOfMaterials();
538  for(size_t iMate=0;iMate<nMaterial;iMate++)
539  {
540  G4cout << (*mItr)->GetName() << " ";
541  mItr++;
542  }
543  G4cout << G4endl;
544  G4ProductionCuts* cuts = region->GetProductionCuts();
545  if(!cuts && region->IsInMassGeometry())
546  {
547  G4cerr << "Warning : Region <" << region->GetName()
548  << "> does not have specific production cuts." << G4endl;
549  G4cerr << "Default cuts are used for this region." << G4endl;
550  region->SetProductionCuts(
551  G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts());
552  }
553  else if(cuts)
554  {
555  G4cout << " Production cuts : "
556  << " gamma "
557  << G4BestUnit(cuts->GetProductionCut("gamma"),"Length")
558  << " e- "
559  << G4BestUnit(cuts->GetProductionCut("e-"),"Length")
560  << " e+ "
561  << G4BestUnit(cuts->GetProductionCut("e+"),"Length")
562  << " proton "
563  << G4BestUnit(cuts->GetProductionCut("proton"),"Length")
564  << G4endl;
565  }
566  }
567 }
568 
569 #include "G4LogicalVolumeStore.hh"
570 void G4RunManagerKernel::CheckRegularGeometry()
571 {
573  for(G4LogicalVolumeStore::iterator pos=store->begin(); pos!=store->end(); pos++)
574  {
575  if((*pos)&&((*pos)->GetNoDaughters()==1))
576  {
577  if((*pos)->GetDaughter(0)->IsRegularStructure())
578  {
579  SetScoreSplitter();
580  return;
581  }
582  }
583  }
584 }
585 
586 #include "G4ParticleTable.hh"
587 #include "G4ParticleDefinition.hh"
588 #include "G4ProcessManager.hh"
589 #include "G4ProcessVector.hh"
590 #include "G4VProcess.hh"
591 G4bool G4RunManagerKernel::ConfirmCoupledTransportation()
592 {
594  G4ParticleTable::G4PTblDicIterator* theParticleIterator = theParticleTable->GetIterator();
595  theParticleIterator->reset();
596  while((*theParticleIterator)())
597  {
598  G4ParticleDefinition* pd = theParticleIterator->value();
600  if(pm)
601  {
603  G4VProcess* p = (*pv)[0];
604  return ( (p->GetProcessName()) == "CoupledTransportation" );
605  }
606  }
607  return false;
608 }
609 
611 void G4RunManagerKernel::SetScoreSplitter()
612 {
615  G4ParticleTable::G4PTblDicIterator* theParticleIterator = theParticleTable->GetIterator();
616 
617  // Ensure that Process is added only once to the particles' process managers
618  static bool InitSplitter=false;
619  if( ! InitSplitter ) {
620  InitSplitter = true;
621 
622  theParticleIterator->reset();
623  while( (*theParticleIterator)() )
624  {
625  G4ParticleDefinition* particle = theParticleIterator->value();
626  G4ProcessManager* pmanager = particle->GetProcessManager();
627  if(pmanager)
628  { pmanager->AddDiscreteProcess(pSplitter); }
629  }
630 
631  if(verboseLevel>0)
632  {
633  G4cout << "G4RunManagerKernel -- G4ScoreSplittingProcess is appended to all particles." << G4endl;
634  }
635  }
636 }
637