Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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:35
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