Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/navigation/src/G4TransportationManager.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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