Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4TransportationManager.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// Class G4TransportationManager implementation
27//
28// Created : J.Apostolakis, 1997
29// Reviewed: G.Cosmo, 2006
30// --------------------------------------------------------------------
31
33
34#include <algorithm>
35
38#include "G4FieldManager.hh"
39#include "G4LogicalVolume.hh"
40#include "G4PVPlacement.hh"
41
42// Initialise the static instance of the singleton
43//
45G4TransportationManager::fTransportationManager = nullptr;
46
47// The first registered navigator -- expect this to be the master thread's navigator
48// If it has an external sub-navigator, it will be cloned for each worker thread.
49G4Navigator* G4TransportationManager::fFirstTrackingNavigator= nullptr;
50
51// ----------------------------------------------------------------------------
52// Constructor
53//
55{
56 if (fTransportationManager)
57 {
58 G4Exception("G4TransportationManager::G4TransportationManager()",
59 "GeomNav0002", FatalException,
60 "Only ONE instance of G4TransportationManager is allowed!");
61 }
62
63 // Create the navigator for tracking and activate it; add to collections
64 //
65 G4Navigator* trackingNavigator= nullptr;
66 if( fFirstTrackingNavigator && fFirstTrackingNavigator->GetExternalNavigation() )
67 {
68 trackingNavigator = fFirstTrackingNavigator->Clone();
69 }
70 else
71 {
72 trackingNavigator = new G4Navigator();
73 if( fFirstTrackingNavigator == nullptr )
74 fFirstTrackingNavigator = trackingNavigator;
75 }
76 trackingNavigator->Activate(true);
77 fNavigators.push_back(trackingNavigator);
78 fActiveNavigators.push_back(trackingNavigator);
79 fWorlds.push_back(trackingNavigator->GetWorldVolume()); // NULL registered
80
81 fGeomMessenger = new G4GeometryMessenger(this);
82 fFieldManager = new G4FieldManager(); // deleted by G4FieldManagerStore
83 fPropagatorInField= new G4PropagatorInField(trackingNavigator,fFieldManager);
84 fSafetyHelper = new G4SafetyHelper();
85}
86
87// ----------------------------------------------------------------------------
88// Destructor
89//
91{
92 delete fSafetyHelper;
93 delete fPropagatorInField;
94 delete fGeomMessenger;
95 ClearNavigators();
96 fTransportationManager = nullptr;
97}
98
99// ----------------------------------------------------------------------------
100// GetTransportationManager()
101//
102// Retrieve the static instance of the singleton and create it if not existing
103//
105{
106 if (fTransportationManager == nullptr)
107 {
108 fTransportationManager = new G4TransportationManager;
109 }
110 return fTransportationManager;
111}
112
113// ----------------------------------------------------------------------------
114// GetInstanceIfExist()
115//
116// Retrieve the static instance pointer of the singleton
117//
119{
120 return fTransportationManager;
121}
122
123// ----------------------------------------------------------------------------
124// SetFieldManager()
125//
126// Set the associated field manager.
127//
129{
130 fFieldManager = newFieldManager;
131
132 // Message the PropagatorInField,
133 // which also maintains this information (to be reviewed)
134 //
135 if( fPropagatorInField )
136 {
137 fPropagatorInField -> SetDetectorFieldManager( newFieldManager );
138 }
139}
140
141// ----------------------------------------------------------------------------
142// SetNavigatorForTracking()
143//
144// Set the active navigator for tracking, always
145// the first in the collection of registered navigators.
146//
148{
149 fNavigators[0] = newNavigator;
150 fActiveNavigators[0] = newNavigator;
151 fPropagatorInField->SetNavigatorForPropagating(newNavigator);
152}
153
154// ----------------------------------------------------------------------------
155// ClearNavigators()
156//
157// Clear collection of navigators and delete allocated objects.
158// Called only by the class destructor.
159//
160void G4TransportationManager::ClearNavigators()
161{
162 for (auto pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
163 {
164 delete *pNav;
165 }
166 fNavigators.clear();
167 fActiveNavigators.clear();
168 fWorlds.clear();
169}
170
171// ----------------------------------------------------------------------------
172// GetParallelWorld()
173//
174// Provided the name of a world volume, returns the associated world pointer.
175// If not existing, create (allocate) and register it in the collection.
176//
179{
180 G4VPhysicalVolume* wPV = IsWorldExisting(worldName);
181 if (wPV == nullptr)
182 {
184 G4LogicalVolume* wLV = wPV->GetLogicalVolume();
185 wLV = new G4LogicalVolume(wLV->GetSolid(), nullptr,
186 worldName);
187 wPV = new G4PVPlacement (wPV->GetRotation(),
188 wPV->GetTranslation(),
189 wLV, worldName, nullptr, false, 0);
190 RegisterWorld(wPV);
191 }
192 return wPV;
193}
194
195// ----------------------------------------------------------------------------
196// GetNavigator()
197//
198// Provided the name of a world volume, returns the associated navigator.
199// If not existing, create it and register it in the collection, throw an
200// exception if the associated parallel world does not exist.
201//
203{
204 // If already existing, return the stored pointer to the navigator
205 //
206 for (auto pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
207 {
208 if ((*pNav)->GetWorldVolume()->GetName() == worldName) { return *pNav; }
209 }
210
211 // Check if world of that name already exists,
212 // create a navigator and register it
213 //
214 G4Navigator* aNavigator = nullptr;
215 G4VPhysicalVolume* aWorld = IsWorldExisting(worldName);
216 if(aWorld != nullptr)
217 {
218 aNavigator = new G4Navigator();
219 aNavigator->SetWorldVolume(aWorld);
220 fNavigators.push_back(aNavigator);
221 }
222 else
223 {
224 G4String message
225 = "World volume with name -" + worldName
226 + "- does not exist. Create it first by GetParallelWorld() method!";
227 G4Exception("G4TransportationManager::GetNavigator(name)",
228 "GeomNav0002", FatalException, message);
229 }
230
231 return aNavigator;
232}
233
234// ----------------------------------------------------------------------------
235// GetNavigator()
236//
237// Provided a pointer to a world volume, returns the associated navigator.
238// Create it in case not existing and add it to the collection.
239// If world volume not existing, issue an exception.
240//
242{
243 for (auto pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
244 {
245 if ((*pNav)->GetWorldVolume() == aWorld) { return *pNav; }
246 }
247 G4Navigator* aNavigator = nullptr;
248 auto pWorld = std::find(fWorlds.cbegin(), fWorlds.cend(), aWorld);
249 if (pWorld != fWorlds.cend())
250 {
251 aNavigator = new G4Navigator();
252 aNavigator->SetWorldVolume(aWorld);
253 fNavigators.push_back(aNavigator);
254 }
255 else
256 {
257 G4String message
258 = "World volume with name -" + aWorld->GetName()
259 + "- does not exist. Create it first by GetParallelWorld() method!";
260 G4Exception("G4TransportationManager::GetNavigator(pointer)",
261 "GeomNav0002", FatalException, message);
262 }
263
264 return aNavigator;
265}
266
267// ----------------------------------------------------------------------------
268// DeRegisterNavigator()
269//
270// Provided a pointer to an already allocated navigator object, removes the
271// associated entry in the navigators collection (remove pair) but does not
272// delete the actual pointed object, which is still owned by the caller.
273// The navigator for tracking -cannot- be deregistered.
274//
276{
277 if (aNavigator == fNavigators[0])
278 {
279 G4Exception("G4TransportationManager::DeRegisterNavigator()",
280 "GeomNav0003", FatalException,
281 "The navigator for tracking CANNOT be deregistered!");
282 }
283 auto pNav = std::find(fNavigators.cbegin(), fNavigators.cend(), aNavigator);
284 if (pNav != fNavigators.cend())
285 {
286 // Deregister associated world volume
287 //
288 DeRegisterWorld((*pNav)->GetWorldVolume());
289
290 // Deregister the navigator
291 //
292 fNavigators.erase(pNav);
293 }
294 else
295 {
296 G4String message
297 = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
298 + "- not found in memory!";
299 G4Exception("G4TransportationManager::DeRegisterNavigator()",
300 "GeomNav1002", JustWarning, message);
301 }
302}
303
304// ----------------------------------------------------------------------------
305// ActivateNavigator()
306//
307// Provided a pointer to an already allocated navigator object, set to 'true'
308// the associated activation flag for the navigator in the collection.
309// If the provided navigator is not already registered, issue a warning
310// Return the index of the activated navigator. This index should be used for
311// ComputeStep() method of G4PathFinder.
312//
314{
315 auto pNav = std::find(fNavigators.cbegin(), fNavigators.cend(), aNavigator);
316 if (pNav == fNavigators.cend())
317 {
318 G4String message
319 = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
320 + "- not found in memory!";
321 G4Exception("G4TransportationManager::ActivateNavigator()",
322 "GeomNav1002", FatalException, message);
323 return -1;
324 }
325
326 aNavigator->Activate(true);
327 G4int id = 0;
328 for(auto pActiveNav=fActiveNavigators.cbegin();
329 pActiveNav!=fActiveNavigators.cend(); ++pActiveNav)
330 {
331 if (*pActiveNav == aNavigator) { return id; }
332 ++id;
333 }
334
335 fActiveNavigators.push_back(aNavigator);
336 return id;
337}
338
339// ----------------------------------------------------------------------------
340// DeActivateNavigator()
341//
342// Provided a pointer to an already allocated navigator object, set to 'false'
343// the associated activation flag in the navigators collection.
344// If the provided navigator is not already registered, issue a warning.
345//
347{
348 auto pNav = std::find(fNavigators.cbegin(), fNavigators.cend(), aNavigator);
349 if (pNav != fNavigators.cend())
350 {
351 (*pNav)->Activate(false);
352 }
353 else
354 {
355 G4String message
356 = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
357 + "- not found in memory!";
358 G4Exception("G4TransportationManager::DeActivateNavigator()",
359 "GeomNav1002", JustWarning, message);
360 }
361
362 auto pActiveNav = std::find(fActiveNavigators.cbegin(),
363 fActiveNavigators.cend(), aNavigator);
364 if (pActiveNav != fActiveNavigators.cend())
365 {
366 fActiveNavigators.erase(pActiveNav);
367 }
368}
369
370// ----------------------------------------------------------------------------
371// InactivateAll()
372//
373// Inactivate all the navigators except for the tracking one, and clear the
374// store of active navigators.
375//
377{
378 for (auto pNav=fActiveNavigators.cbegin();
379 pNav!=fActiveNavigators.cend(); ++pNav)
380 {
381 (*pNav)->Activate(false);
382 }
383 fActiveNavigators.clear();
384
385 // Restore status for the navigator for tracking
386 //
387 fNavigators[0]->Activate(true);
388 fActiveNavigators.push_back(fNavigators[0]);
389}
390
391// ----------------------------------------------------------------------------
392// IsWorldExisting()
393//
394// Verify existance or not of an istance of the world volume with
395// same name in the collection. Return the world pointer if existing.
396//
399{
400 auto pWorld = fWorlds.begin();
401 if ( *pWorld==nullptr ) { *pWorld=fNavigators[0]->GetWorldVolume(); }
402
403 for (auto cpWorld=fWorlds.cbegin(); cpWorld!=fWorlds.cend(); ++cpWorld)
404 {
405 if ((*cpWorld)->GetName() == name ) { return *cpWorld; }
406 }
407 return 0;
408}
409
410// ----------------------------------------------------------------------------
411// RegisterWorld()
412//
413// Provided a pointer to an already allocated world object, check and add the
414// associated entry in the worlds collection. Return 'true' if registration
415// succeeds and the new entry is created.
416//
418{
419 G4bool done = false;
420
421 auto pWorld = std::find(fWorlds.cbegin(), fWorlds.cend(), aWorld);
422 if (pWorld == fWorlds.cend())
423 {
424 fWorlds.push_back(aWorld);
425 done = true;
426 }
427 return done;
428}
429
430// ----------------------------------------------------------------------------
431// DeRegisterWorld()
432//
433// Provided a pointer to an already allocated world object, removes the
434// associated entry in the worlds collection but does not delete the actual
435// pointed object, which is still owned by the caller.
436//
437void G4TransportationManager::DeRegisterWorld( G4VPhysicalVolume* aWorld )
438{
439 auto pWorld = std::find(fWorlds.cbegin(), fWorlds.cend(), aWorld);
440 if (pWorld != fWorlds.cend())
441 {
442 fWorlds.erase(pWorld);
443 }
444 else
445 {
446 G4String message
447 = "World volume -" + aWorld->GetName() + "- not found in memory!";
448 G4Exception("G4TransportationManager::DeRegisterWorld()",
449 "GeomNav1002", JustWarning, message);
450 }
451}
452
453// ----------------------------------------------------------------------------
454// ClearParallelWorlds()
455//
456// Clear collection of navigators and delete allocated objects associated with
457// parallel worlds.
458// Called only by the RunManager when the entire geometry is rebuilt from
459// scratch.
460//
462{
463 auto pNav = fNavigators.cbegin();
464 G4Navigator* trackingNavigator = *pNav;
465 for (pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
466 {
467 if (*pNav != trackingNavigator) { delete *pNav; }
468 }
469 fNavigators.clear();
470 fActiveNavigators.clear();
471 fWorlds.clear();
472
473 fNavigators.push_back(trackingNavigator);
474 fActiveNavigators.push_back(trackingNavigator);
475 fWorlds.push_back(0); // NULL registered
476}
477
478// ----------------------------------------------------------------------------
479// GetFirstTrackingNavigator()
480//
481// Get pointer to the first tracking Navigator created
482//
484{
485 return fFirstTrackingNavigator;
486}
487
488// ----------------------------------------------------------------------------
489// GetFirstTrackingNavigator()
490//
491// Get pointer to the first tracking Navigator created
492
494{
495 fFirstTrackingNavigator= nav;
496}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4VSolid * GetSolid() const
void Activate(G4bool flag)
G4VExternalNavigation * GetExternalNavigation() const
G4Navigator * Clone() const
void SetWorldVolume(G4VPhysicalVolume *pWorld)
G4VPhysicalVolume * GetWorldVolume() const
void SetNavigatorForPropagating(G4Navigator *SimpleOrMultiNavigator)
G4bool RegisterWorld(G4VPhysicalVolume *aWorld)
G4VPhysicalVolume * GetParallelWorld(const G4String &worldName)
static G4TransportationManager * GetTransportationManager()
void SetFieldManager(G4FieldManager *newFieldManager)
static G4TransportationManager * GetInstanceIfExist()
static void SetFirstTrackingNavigator(G4Navigator *nav)
G4VPhysicalVolume * IsWorldExisting(const G4String &worldName)
G4Navigator * GetNavigatorForTracking() const
G4int ActivateNavigator(G4Navigator *aNavigator)
void DeActivateNavigator(G4Navigator *aNavigator)
G4Navigator * GetNavigator(const G4String &worldName)
void DeRegisterNavigator(G4Navigator *aNavigator)
void SetNavigatorForTracking(G4Navigator *newNavigator)
static G4Navigator * GetFirstTrackingNavigator()
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
#define G4ThreadLocal
Definition: tls.hh:77