source: trunk/source/geometry/navigation/src/G4MultiNavigator.cc @ 921

Last change on this file since 921 was 921, checked in by garnier, 15 years ago

en test de gl2ps. Problemes de libraries

File size: 21.1 KB
Line 
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//
27// $Id: G4MultiNavigator.cc,v 1.8 2008/10/24 14:00:03 gcosmo Exp $
28// GEANT4 tag $ Name:  $
29//
30// class G4PathFinder Implementation
31//
32// Author:  John Apostolakis, November 2006
33// --------------------------------------------------------------------
34
35#include "G4MultiNavigator.hh"
36
37class G4FieldManager;
38
39#include "G4Navigator.hh"
40#include "G4PropagatorInField.hh"
41#include "G4TransportationManager.hh"
42
43#include <iomanip>
44
45// ********************************************************************
46// Constructor
47// ********************************************************************
48//
49G4MultiNavigator::G4MultiNavigator() 
50  : G4Navigator()
51{
52  fNoActiveNavigators= 0; 
53  G4ThreeVector Big3Vector( DBL_MAX, DBL_MAX, DBL_MAX ); 
54  fLastLocatedPosition = Big3Vector;
55  fSafetyLocation  = Big3Vector;
56  fPreStepLocation = Big3Vector;
57
58  fMinSafety_PreStepPt=  -1.0; 
59  fMinSafety_atSafLocation= -1.0; 
60  fMinSafety= -DBL_MAX; 
61  fMinStep=   -DBL_MAX; 
62
63  for(register int num=0; num<= fMaxNav; ++num )
64  {
65    fpNavigator[num] =  0;   
66    fLimitTruth[num] = false;
67    fLimitedStep[num] = kUndefLimited;
68    fCurrentStepSize[num] = -1.0; 
69    fLocatedVolume[num] = 0; 
70  }
71
72  pTransportManager= G4TransportationManager::GetTransportationManager();
73
74  G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
75  if( massNav )
76  { 
77    G4VPhysicalVolume* pWorld= massNav->GetWorldVolume(); 
78    if( pWorld )
79    { 
80      SetWorldVolume( pWorld ); 
81      fLastMassWorld = pWorld; 
82    }
83  }
84}
85
86G4MultiNavigator::~G4MultiNavigator() 
87{
88}
89
90G4double G4MultiNavigator::ComputeStep(const G4ThreeVector &pGlobalPoint,
91                                       const G4ThreeVector &pDirection,
92                                       const G4double       proposedStepLength,
93                                             G4double      &pNewSafety)
94{
95  G4double safety= 0.0, step=0.0;
96  G4double minSafety= DBL_MAX, minStep= DBL_MAX;
97
98#ifdef G4DEBUG_NAVIGATION
99  if( fVerbose > 2 )
100  {
101    G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
102    G4cout << "   Input position= " << pGlobalPoint
103           << "   direction= "      << pDirection         << G4endl;
104    G4cout << "   Requested step= " << proposedStepLength << G4endl;
105  }
106#endif
107
108  std::vector<G4Navigator*>::iterator pNavigatorIter;
109
110  pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
111
112  G4ThreeVector initialPosition = pGlobalPoint;
113  G4ThreeVector initialDirection= pDirection;
114
115  for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
116  {
117     safety= DBL_MAX;
118
119     step= (*pNavigatorIter)->ComputeStep( initialPosition, 
120                                           initialDirection,
121                                           proposedStepLength,
122                                           safety ); 
123     if( safety < minSafety ){ minSafety = safety; } 
124     if( step < minStep )    { minStep= step; } 
125
126     fCurrentStepSize[num] = step; 
127     fNewSafety[num]= safety; 
128      // This is currently the safety from the last sub-step
129
130#ifdef G4DEBUG_NAVIGATION
131     if( fVerbose > 2 )
132     {
133       G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
134              << num << "] -- step size " << step
135              << " safety= " << safety << G4endl;
136     }
137#endif
138  } 
139
140  // Save safety value, related position
141  //
142  fPreStepLocation     = initialPosition; 
143  fMinSafety_PreStepPt = minSafety;
144  fMinStep = minStep; 
145
146  if( fMinStep == kInfinity )
147  {
148     fTrueMinStep = proposedStepLength;   //  Use this below for endpoint !!
149  }
150  else
151  {
152     fTrueMinStep = minStep;
153  }
154
155#ifdef G4DEBUG_NAVIGATION
156  if( fVerbose > 1 )
157  {
158    G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
159
160    G4int oldPrec = G4cout.precision(8); 
161    G4cout << "G4MultiNavigator::ComputeStep : "
162           << " initialPosition = " << initialPosition
163           << " and endPosition = " << endPosition << G4endl;
164    G4cout.precision( oldPrec );
165  }
166#endif
167
168  pNewSafety = minSafety; 
169
170  this->WhichLimited(); 
171
172#ifdef G4DEBUG_NAVIGATION
173  if( fVerbose > 2 )
174  {
175    G4cout << " G4MultiNavigator::ComputeStep : exits returning "
176           << minStep << G4endl;
177  }
178#endif
179
180  return minStep;  // must return kInfinity if do not limit step
181}
182
183// ----------------------------------------------------------------------
184
185G4double
186G4MultiNavigator::ObtainFinalStep( G4int     navigatorId, 
187                                   G4double &pNewSafety,  // for this geometry
188                                   G4double &minStep,
189                                   ELimited &limitedStep) 
190{
191  G4int navigatorNo=-1; 
192
193  if( navigatorId <= fNoActiveNavigators )
194  {
195     navigatorNo= navigatorId;
196  }
197  else
198  { 
199     G4cerr << "ERROR - G4MultiNavigator::ObtainFinalStep()"
200            << "        Navigator Id = " << navigatorId
201            << "        No Active = " << fNoActiveNavigators << " . "
202            << G4endl;
203     G4Exception("G4MultiNavigator::ObtainFinalStep()", "InvalidSetup",
204                 FatalException, "Bad Navigator Id" ); 
205  }
206
207  // Prepare the information to return
208  pNewSafety  = fNewSafety[ navigatorNo ]; 
209  limitedStep = fLimitedStep[ navigatorNo ];
210  minStep= fMinStep; 
211
212  // if( (minStep==kInfinity) || (fVerbose > 1) ){
213#ifdef G4DEBUG_NAVIGATION
214  if( fVerbose > 1 ){ 
215     G4cout << " G4MultiNavigator::ComputeStep returns " << fCurrentStepSize[ navigatorNo ]
216            << " for Navigator " << navigatorNo << " Limited step = " << limitedStep
217            << " Safety(mm) = " << pNewSafety / mm << G4endl; 
218  }
219#endif
220
221  return fCurrentStepSize[ navigatorNo ];
222}
223
224// ----------------------------------------------------------------------
225
226void G4MultiNavigator::PrepareNewTrack( const G4ThreeVector position, 
227                                        const G4ThreeVector direction )
228{
229#ifdef G4DEBUG_NAVIGATION
230  if( fVerbose > 1 )
231  {
232    G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
233  }
234#endif
235
236  G4MultiNavigator::PrepareNavigators(); 
237
238  LocateGlobalPointAndSetup( position, &direction, false, false );   
239  //
240  // The first location for each Navigator must be non-relative
241  // or else call ResetStackAndState() for each Navigator
242  // Use direction to get correct side of boundary (ignore dir= false)
243}
244
245// ----------------------------------------------------------------------
246
247void G4MultiNavigator::PrepareNavigators()
248{
249  // Key purposes:
250  //   - Check and cache set of active navigators
251  //   - Reset state for new track
252
253#ifdef G4DEBUG_NAVIGATION
254  if( fVerbose > 1 )
255  {
256    G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
257  }
258#endif
259
260  // Message the transportation-manager to find active navigators
261
262  std::vector<G4Navigator*>::iterator pNavigatorIter; 
263  fNoActiveNavigators=  pTransportManager-> GetNoActiveNavigators();
264
265  if( fNoActiveNavigators > fMaxNav )
266  {
267    G4cerr << "ERROR - G4MultiNavigator::PrepareNavigators()"
268           << "        Too many active Navigators (worlds): "
269           << fNoActiveNavigators << G4endl
270           << "        which is more than the number allowed: "
271           << fMaxNav << " !" << G4endl;
272    G4Exception("G4MultiNavigator::PrepareNavigators()", "InvalidSetup", 
273                FatalException, "Too many active Navigators / worlds !"); 
274  }
275
276  pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
277  for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
278  {
279     fpNavigator[num] =  *pNavigatorIter;   
280     fLimitTruth[num] = false;
281     fLimitedStep[num] = kDoNot;
282     fCurrentStepSize[num] = 0.0; 
283     fLocatedVolume[num] = 0; 
284  }
285  fWasLimitedByGeometry = false; 
286
287  // Check the world volume of the mass navigator
288  // in case a call to SetWorldVolume() changed it
289
290  G4VPhysicalVolume* massWorld = GetWorldVolume();
291
292  if( (massWorld != fLastMassWorld) && (massWorld!=0) )
293  { 
294     // Pass along change to Mass Navigator
295     fpNavigator[0] -> SetWorldVolume( massWorld );
296
297#ifdef G4DEBUG_NAVIGATION
298     if( fVerbose > 0 )
299     { 
300       G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume " 
301              << " for mass geometry to " << massWorld->GetName() << G4endl; 
302     }
303#endif
304
305     fLastMassWorld = massWorld;
306  }
307}
308
309// ----------------------------------------------------------------------
310
311G4VPhysicalVolume* 
312G4MultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position,
313                                            const G4ThreeVector* pDirection,
314                                            const G4bool pRelativeSearch,
315                                            const G4bool ignoreDirection )
316{
317  // Locate the point in each geometry
318
319  G4ThreeVector direction(0.0, 0.0, 0.0);
320  G4bool relative = pRelativeSearch; 
321  std::vector<G4Navigator*>::iterator pNavIter
322    = pTransportManager->GetActiveNavigatorsIterator(); 
323
324  if( pDirection ) { direction = *pDirection; }
325
326#ifdef G4DEBUG_NAVIGATION
327  if( fVerbose > 2 )
328  {
329    G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
330           << G4endl;
331    G4cout << "   Locating at position: " << position
332           << ", with direction: " << direction << G4endl
333           << "   Relative: " << relative
334           << ", ignore direction: " << ignoreDirection << G4endl;
335    G4cout << "   Number of active navigators: " << fNoActiveNavigators
336           << G4endl;
337  }
338#endif
339
340  for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
341  {
342     if( fWasLimitedByGeometry && fLimitTruth[num] )
343     { 
344        (*pNavIter)->SetGeometricallyLimitedStep(); 
345     }
346
347     G4VPhysicalVolume *pLocated
348       = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
349                                                 relative, ignoreDirection );   
350     // Set the state related to the location
351     //
352     fLocatedVolume[num] = pLocated; 
353
354     // Clear state related to the step
355     //
356     fLimitedStep[num]   = kDoNot; 
357     fCurrentStepSize[num] = 0.0;     
358     fLimitTruth[ num ] = false;   // Always clear on locating (see Navigator)
359   
360#ifdef G4DEBUG_NAVIGATION
361     if( fVerbose > 2 )
362     {
363       G4cout << " Located in world: " << num << ", at: " << position << G4endl
364              << " Used geomLimStp: " << fLimitTruth[num]
365              << ", found in volume: " << pLocated << G4endl; 
366       G4cout << " Name = '" ;       
367       if( pLocated )
368       { 
369         G4cout << pLocated->GetName() << "'"; 
370         G4cout << " - CopyNo= " << pLocated->GetCopyNo(); 
371       }
372       else
373       { 
374         G4cout <<  "Null'   Id: Not-Set "; 
375       }
376       G4cout << G4endl; 
377     }
378#endif
379  }
380
381  fWasLimitedByGeometry = false;   // Clear on locating
382  G4VPhysicalVolume* volMassLocated= fLocatedVolume[0]; 
383
384  return volMassLocated;
385}
386
387// ----------------------------------------------------------------------
388
389void
390G4MultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position)
391{
392  // Relocate the point in each geometry
393
394  std::vector<G4Navigator*>::iterator pNavIter
395    = pTransportManager->GetActiveNavigatorsIterator(); 
396
397#ifdef G4DEBUG_NAVIGATION
398  if( fVerbose > 2 )
399  {
400    G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
401           << "  Re-locating at position: " << position  << G4endl; 
402  }
403#endif
404
405  for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
406  {
407     //  ... none limited the step
408
409     (*pNavIter)->LocateGlobalPointWithinVolume( position ); 
410
411     // Clear state related to the step
412     //
413     fLimitedStep[num]     = kDoNot; 
414     fCurrentStepSize[num] = 0.0;     
415
416     fLimitTruth[ num ] = false;   // Always clear on locating (see Navigator)
417  }
418  fWasLimitedByGeometry = false;   // Clear on locating
419  fLastLocatedPosition  = position; 
420}
421
422// ----------------------------------------------------------------------
423
424G4double G4MultiNavigator::ComputeSafety( const G4ThreeVector& position,
425                                          const G4double       maxDistance,
426                                          const G4bool         state)
427{
428    // Recompute safety for the relevant point
429
430    G4double minSafety = DBL_MAX, safety = DBL_MAX;
431 
432    std::vector<G4Navigator*>::iterator pNavigatorIter;
433    pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
434
435    for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
436    {
437       safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
438       if( safety < minSafety ) { minSafety = safety; } 
439    } 
440
441    fSafetyLocation = position;
442    fMinSafety_atSafLocation = minSafety;
443
444#ifdef G4DEBUG_NAVIGATION
445    if( fVerbose > 1 )
446    { 
447      G4cout << " G4MultiNavigator::ComputeSafety - returns: " 
448             << minSafety << ", at location: " << position << G4endl;
449    }
450#endif
451    return minSafety; 
452}
453
454// -----------------------------------------------------------------------
455
456G4TouchableHistoryHandle
457G4MultiNavigator::CreateTouchableHistoryHandle() const
458{
459  G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()", 
460               "215-TouchableFromWrongNavigator", FatalException, 
461               "Getting a touchable from G4MultiNavigator is not defined."); 
462
463  G4TouchableHistory* touchHist;
464  touchHist= fpNavigator[0] -> CreateTouchableHistory(); 
465
466  G4VPhysicalVolume* locatedVolume= fLocatedVolume[0]; 
467  if( locatedVolume == 0 )
468  {
469    // Workaround to ensure that the touchable is fixed !! // TODO: fix
470    //
471    touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
472  }
473   
474  return G4TouchableHistoryHandle(touchHist); 
475}
476
477// -----------------------------------------------------------------------
478
479void G4MultiNavigator::WhichLimited()
480{
481  // Flag which processes limited the step
482
483  G4int last=-1; 
484  const G4int IdTransport= 0;  // Id of Mass Navigator !!
485  G4int noLimited=0; 
486  ELimited shared= kSharedOther; 
487
488#ifdef G4DEBUG_NAVIGATION
489  if( fVerbose > 2 )
490  {
491    G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
492  }
493#endif
494
495  // Assume that [IdTransport] is Mass / Transport
496  //
497  G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
498                         && ( fMinStep!= kInfinity); 
499  if( transportLimited )
500  { 
501     shared= kSharedTransport;
502  }
503
504  for ( register int num= 0; num < fNoActiveNavigators; num++ )
505  { 
506    G4bool limitedStep;
507
508    G4double step= fCurrentStepSize[num]; 
509
510    limitedStep = ( step == fMinStep ) && ( step != kInfinity); 
511   
512    fLimitTruth[ num ] = limitedStep; 
513    if( limitedStep )
514    {
515      noLimited++; 
516      fLimitedStep[num] = shared;
517      last= num; 
518    }
519    else
520    {
521      fLimitedStep[num] = kDoNot;
522    }
523  }
524  if( (last > -1) && (noLimited == 1 ) )
525  {
526    fLimitedStep[ last ] = kUnique; 
527  }
528}
529
530// -----------------------------------------------------------------------
531
532void
533G4MultiNavigator::PrintLimited()
534{
535  // Report results -- for checking   
536
537  static G4String StrDoNot("DoNot"), StrUnique("Unique"),
538                  StrUndefined("Undefined"),
539                  StrSharedTransport("SharedTransport"),
540                  StrSharedOther("SharedOther");
541  G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
542  G4cout << "    Minimum step (true): " << fTrueMinStep
543         << ", reported min: " << fMinStep << G4endl; 
544
545#ifdef G4DEBUG_NAVIGATION
546  if(fVerbose>=2)
547  {
548    G4cout << std::setw(5) << " NavId"  << " "
549           << std::setw(12) << " step-size " << " "
550           << std::setw(12) << " raw-size "  << " "
551           << std::setw(12) << " pre-safety " << " " 
552           << std::setw(15) << " Limited / flag"  << " "
553           << std::setw(15) << "  World "  << " "
554           << G4endl; 
555  }
556#endif
557
558  for ( register int num= 0; num < fNoActiveNavigators; num++ )
559  { 
560    G4double rawStep = fCurrentStepSize[num]; 
561    G4double stepLen = fCurrentStepSize[num]; 
562    if( stepLen > fTrueMinStep )
563    { 
564      stepLen = fTrueMinStep;     // did not limit (went as far as asked)
565    }
566    G4int oldPrec= G4cout.precision(9); 
567
568    G4cout << std::setw(5) << num  << " "
569           << std::setw(12) << stepLen << " "
570           << std::setw(12) << rawStep << " "
571           << std::setw(12) << fNewSafety[num] << " "
572           << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
573    G4String limitedStr;
574    switch ( fLimitedStep[num] )
575    {
576      case kDoNot          : limitedStr= StrDoNot; break;
577      case kUnique         : limitedStr = StrUnique; break; 
578      case kSharedTransport: limitedStr= StrSharedTransport; break; 
579      case kSharedOther    : limitedStr = StrSharedOther; break;
580      default              : limitedStr = StrUndefined; break;
581    }
582    G4cout << " " << std::setw(15) << limitedStr << " "; 
583    G4cout.precision(oldPrec); 
584
585    G4Navigator *pNav= fpNavigator[ num ]; 
586    G4String  WorldName( "Not-Set" ); 
587    if (pNav)
588    {
589       G4VPhysicalVolume *pWorld= pNav->GetWorldVolume(); 
590       if( pWorld )
591       {
592           WorldName = pWorld->GetName(); 
593       }
594    }
595    G4cout << " " << WorldName ; 
596    G4cout << G4endl;
597  }
598}
599 
600
601// -----------------------------------------------------------------------
602
603void G4MultiNavigator::ResetState()
604{
605   fWasLimitedByGeometry= false; 
606
607   G4Exception("G4MultiNavigator::ResetState()", "217-NotImplemented", 
608               FatalException, 
609               "Cannot call ResetState() for navigators of G4MultiNavigator.");
610   
611   std::vector<G4Navigator*>::iterator pNavigatorIter;
612   pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
613   for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
614   {
615       //  (*pNavigatorIter)->ResetState();  // KEEP THIS comment !!!
616   } 
617}
618
619// -----------------------------------------------------------------------
620
621void G4MultiNavigator::SetupHierarchy()
622{
623  G4Exception( "G4MultiNavigator::SetupHierarchy()", 
624               "217-NotImplemented", FatalException, 
625           "Cannot call SetupHierarchy() for navigators of G4MultiNavigator."); 
626}
627
628// -----------------------------------------------------------------------
629
630void G4MultiNavigator::CheckMassWorld()
631{
632   G4VPhysicalVolume* navTrackWorld=
633     pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
634
635   if( navTrackWorld != fLastMassWorld )
636   { 
637      G4Exception( "G4MultiNavigator::CheckMassWorld()",
638                   "220-InvalidSetup", FatalException, 
639                   "Mass world pointer has been changed." ); 
640   }
641}
642
643// -----------------------------------------------------------------------
644
645G4VPhysicalVolume*
646G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point,
647                                          const G4ThreeVector &direction,
648                                          const G4TouchableHistory &MassHistory)
649{
650   // Reset geometry for all -- and use the touchable for the mass history
651
652   G4VPhysicalVolume* massVolume=0; 
653   G4Navigator* pMassNavigator= fpNavigator[0]; 
654
655   if( pMassNavigator )
656   {
657      massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
658                                                           MassHistory); 
659   }
660   else
661   {
662      G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
663                  "218-TooEarlyToReset", FatalException,
664                  "Cannot reset hierarchy before navigators are initialised.");
665   }
666
667   std::vector<G4Navigator*>::iterator pNavIter= 
668       pTransportManager->GetActiveNavigatorsIterator(); 
669
670   for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
671   {
672      G4bool relativeSearch, ignoreDirection; 
673
674      (*pNavIter)-> LocateGlobalPointAndSetup( point, 
675                                               &direction, 
676                                               relativeSearch=false,
677                                               ignoreDirection=false);
678   }
679   return massVolume; 
680}
Note: See TracBrowser for help on using the repository browser.