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