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