Geant4  10.02.p01
G4MultiNavigator.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 //
27 // $Id: G4MultiNavigator.cc 83466 2014-08-25 10:31:39Z gcosmo $
28 // GEANT4 tag $ Name: $
29 //
30 // class G4PathFinder Implementation
31 //
32 // Author: John Apostolakis, November 2006
33 // --------------------------------------------------------------------
34 
35 #include <iomanip>
36 
37 #include "G4MultiNavigator.hh"
38 
39 class G4FieldManager;
40 
41 #include "G4SystemOfUnits.hh"
42 #include "G4Navigator.hh"
43 #include "G4PropagatorInField.hh"
45 
46 // ********************************************************************
47 // Constructor
48 // ********************************************************************
49 //
51  : G4Navigator(), fLastMassWorld(0)
52 {
54  G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity );
55  fLastLocatedPosition = Big3Vector;
56  fSafetyLocation = Big3Vector;
57  fPreStepLocation = Big3Vector;
58 
59  fMinSafety_PreStepPt= -1.0;
63 
64  for(G4int num=0; num< fMaxNav; ++num )
65  {
66  fpNavigator[num] = 0;
67  fLimitTruth[num] = false;
69  fCurrentStepSize[num] = fNewSafety[num] = -1.0;
70  fLocatedVolume[num] = 0;
71  }
72 
74 
76  if( massNav )
77  {
78  G4VPhysicalVolume* pWorld= massNav->GetWorldVolume();
79  if( pWorld )
80  {
81  SetWorldVolume( pWorld );
82  fLastMassWorld = pWorld;
83  }
84  }
85 
86  fNoLimitingStep= -1;
87  fIdNavLimiting= -1;
88 }
89 
91 {
92 }
93 
95  const G4ThreeVector &pDirection,
96  const G4double proposedStepLength,
97  G4double &pNewSafety)
98 {
99  G4double safety= 0.0, step=0.0;
101 
102  fNoLimitingStep= -1;
103  fIdNavLimiting= -1; // Reset for new step
104 
105 #ifdef G4DEBUG_NAVIGATION
106  if( fVerbose > 2 )
107  {
108  G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
109  G4cout << " Input position= " << pGlobalPoint
110  << " direction= " << pDirection << G4endl;
111  G4cout << " Requested step= " << proposedStepLength << G4endl;
112  }
113 #endif
114 
115  std::vector<G4Navigator*>::iterator pNavigatorIter;
116 
117  pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
118 
119  G4ThreeVector initialPosition = pGlobalPoint;
120  G4ThreeVector initialDirection= pDirection;
121 
122  for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
123  {
124  safety= kInfinity;
125 
126  step= (*pNavigatorIter)->ComputeStep( initialPosition,
127  initialDirection,
128  proposedStepLength,
129  safety );
130  if( safety < minSafety ){ minSafety = safety; }
131  if( step < minStep ) { minStep= step; }
132 
133  fCurrentStepSize[num] = step;
134  fNewSafety[num]= safety;
135  // This is currently the safety from the last sub-step
136 
137 #ifdef G4DEBUG_NAVIGATION
138  if( fVerbose > 2 )
139  {
140  G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
141  << num << "] -- step size " << step
142  << " safety= " << safety << G4endl;
143  }
144 #endif
145  }
146 
147  // Save safety value, related position
148  //
149  fPreStepLocation = initialPosition;
151  fMinStep = minStep;
152 
153  if( fMinStep == kInfinity )
154  {
155  fTrueMinStep = proposedStepLength; // Use this below for endpoint !!
156  }
157  else
158  {
159  fTrueMinStep = minStep;
160  }
161 
162 #ifdef G4DEBUG_NAVIGATION
163  if( fVerbose > 1 )
164  {
165  G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
166 
167  G4int oldPrec = G4cout.precision(8);
168  G4cout << "G4MultiNavigator::ComputeStep : "
169  << " initialPosition = " << initialPosition
170  << " and endPosition = " << endPosition << G4endl;
171  G4cout.precision( oldPrec );
172  }
173 #endif
174 
175  pNewSafety = minSafety;
176 
177  this->WhichLimited();
178 
179 #ifdef G4DEBUG_NAVIGATION
180  if( fVerbose > 2 )
181  {
182  G4cout << " G4MultiNavigator::ComputeStep : exits returning "
183  << minStep << G4endl;
184  }
185 #endif
186 
187  return minStep; // must return kInfinity if do not limit step
188 }
189 
190 // ----------------------------------------------------------------------
191 
192 G4double
194  G4double &pNewSafety, // for this geometry
195  G4double &minStep,
196  ELimited &limitedStep)
197 {
198  if( navigatorId > fNoActiveNavigators )
199  {
200  std::ostringstream message;
201  message << "Bad Navigator Id!" << G4endl
202  << " Navigator Id = " << navigatorId
203  << " No Active = " << fNoActiveNavigators << ".";
204  G4Exception("G4MultiNavigator::ObtainFinalStep()", "GeomNav0002",
205  FatalException, message);
206  }
207 
208  // Prepare the information to return
209  //
210  pNewSafety = fNewSafety[ navigatorId ];
211  limitedStep = fLimitedStep[ navigatorId ];
212  minStep= fMinStep;
213 
214 #ifdef G4DEBUG_NAVIGATION
215  if( fVerbose > 1 )
216  {
217  G4cout << " G4MultiNavigator::ComputeStep returns "
218  << fCurrentStepSize[ navigatorId ]
219  << " for Navigator " << navigatorId
220  << " Limited step = " << limitedStep
221  << " Safety(mm) = " << pNewSafety / mm << G4endl;
222  }
223 #endif
224 
225  return fCurrentStepSize[ navigatorId ];
226 }
227 
228 // ----------------------------------------------------------------------
229 
231  const G4ThreeVector direction )
232 {
233 #ifdef G4DEBUG_NAVIGATION
234  if( fVerbose > 1 )
235  {
236  G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
237  }
238 #endif
239 
241 
242  LocateGlobalPointAndSetup( position, &direction, false, false );
243  //
244  // The first location for each Navigator must be non-relative
245  // or else call ResetStackAndState() for each Navigator
246  // Use direction to get correct side of boundary (ignore dir= false)
247 }
248 
249 // ----------------------------------------------------------------------
250 
252 {
253  // Key purposes:
254  // - Check and cache set of active navigators
255  // - Reset state for new track
256 
257 #ifdef G4DEBUG_NAVIGATION
258  if( fVerbose > 1 )
259  {
260  G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
261  }
262 #endif
263 
264  // Message the transportation-manager to find active navigators
265 
266  std::vector<G4Navigator*>::iterator pNavigatorIter;
267  fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators();
268 
270  {
271  std::ostringstream message;
272  message << "Too many active Navigators / worlds !" << G4endl
273  << " Active Navigators (worlds): "
275  << " which is more than the number allowed: "
276  << fMaxNav << " !";
277  G4Exception("G4MultiNavigator::PrepareNavigators()", "GeomNav0002",
278  FatalException, message);
279  }
280 
281  pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
282  for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
283  {
284  fpNavigator[num] = *pNavigatorIter;
285  fLimitTruth[num] = false;
286  fLimitedStep[num] = kDoNot;
287  fCurrentStepSize[num] = 0.0;
288  fLocatedVolume[num] = 0;
289  }
290  fWasLimitedByGeometry = false;
291 
292  // Check the world volume of the mass navigator
293  // in case a call to SetWorldVolume() changed it
294 
295  G4VPhysicalVolume* massWorld = GetWorldVolume();
296 
297  if( (massWorld != fLastMassWorld) && (massWorld!=0) )
298  {
299  // Pass along change to Mass Navigator
300  fpNavigator[0] -> SetWorldVolume( massWorld );
301 
302 #ifdef G4DEBUG_NAVIGATION
303  if( fVerbose > 0 )
304  {
305  G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume "
306  << " for mass geometry to " << massWorld->GetName() << G4endl;
307  }
308 #endif
309 
310  fLastMassWorld = massWorld;
311  }
312 }
313 
314 // ----------------------------------------------------------------------
315 
318  const G4ThreeVector* pDirection,
319  const G4bool pRelativeSearch,
320  const G4bool ignoreDirection )
321 {
322  // Locate the point in each geometry
323 
324  G4ThreeVector direction(0.0, 0.0, 0.0);
325  G4bool relative = pRelativeSearch;
326  std::vector<G4Navigator*>::iterator pNavIter
328 
329  if( pDirection ) { direction = *pDirection; }
330 
331 #ifdef G4DEBUG_NAVIGATION
332  if( fVerbose > 2 )
333  {
334  G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
335  << G4endl;
336  G4cout << " Locating at position: " << position
337  << ", with direction: " << direction << G4endl
338  << " Relative: " << relative
339  << ", ignore direction: " << ignoreDirection << G4endl;
340  G4cout << " Number of active navigators: " << fNoActiveNavigators
341  << G4endl;
342  }
343 #endif
344 
345  for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
346  {
347  if( fWasLimitedByGeometry && fLimitTruth[num] )
348  {
349  (*pNavIter)->SetGeometricallyLimitedStep();
350  }
351 
352  G4VPhysicalVolume *pLocated
353  = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
354  relative, ignoreDirection );
355  // Set the state related to the location
356  //
357  fLocatedVolume[num] = pLocated;
358 
359  // Clear state related to the step
360  //
361  fLimitedStep[num] = kDoNot;
362  fCurrentStepSize[num] = 0.0;
363  fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
364 
365 #ifdef G4DEBUG_NAVIGATION
366  if( fVerbose > 2 )
367  {
368  G4cout << " Located in world: " << num << ", at: " << position << G4endl
369  << " Used geomLimStp: " << fLimitTruth[num]
370  << ", found in volume: " << pLocated << G4endl;
371  G4cout << " Name = '" ;
372  if( pLocated )
373  {
374  G4cout << pLocated->GetName() << "'";
375  G4cout << " - CopyNo= " << pLocated->GetCopyNo();
376  }
377  else
378  {
379  G4cout << "Null' Id: Not-Set ";
380  }
381  G4cout << G4endl;
382  }
383 #endif
384  }
385 
386  fWasLimitedByGeometry = false; // Clear on locating
387  G4VPhysicalVolume* volMassLocated= fLocatedVolume[0];
388 
389  return volMassLocated;
390 }
391 
392 // ----------------------------------------------------------------------
393 
394 void
396 {
397  // Relocate the point in each geometry
398 
399  std::vector<G4Navigator*>::iterator pNavIter
401 
402 #ifdef G4DEBUG_NAVIGATION
403  if( fVerbose > 2 )
404  {
405  G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
406  << " Re-locating at position: " << position << G4endl;
407  }
408 #endif
409 
410  for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
411  {
412  // ... none limited the step
413 
414  (*pNavIter)->LocateGlobalPointWithinVolume( position );
415 
416  // Clear state related to the step
417  //
418  fLimitedStep[num] = kDoNot;
419  fCurrentStepSize[num] = 0.0;
420 
421  fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
422  }
423  fWasLimitedByGeometry = false; // Clear on locating
425 }
426 
427 // ----------------------------------------------------------------------
428 
430  const G4double maxDistance,
431  const G4bool state)
432 {
433  // Recompute safety for the relevant point
434 
436 
437  std::vector<G4Navigator*>::iterator pNavigatorIter;
438  pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
439 
440  for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
441  {
442  safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
443  if( safety < minSafety ) { minSafety = safety; }
444  }
445 
448 
449 #ifdef G4DEBUG_NAVIGATION
450  if( fVerbose > 1 )
451  {
452  G4cout << " G4MultiNavigator::ComputeSafety - returns: "
453  << minSafety << ", at location: " << position << G4endl;
454  }
455 #endif
456  return minSafety;
457 }
458 
459 // -----------------------------------------------------------------------
460 
463 {
464  G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()",
465  "GeomNav0001", FatalException,
466  "Getting a touchable from G4MultiNavigator is not defined.");
467 
468  G4TouchableHistory* touchHist;
469  touchHist= fpNavigator[0] -> CreateTouchableHistory();
470 
471  G4VPhysicalVolume* locatedVolume= fLocatedVolume[0];
472  if( locatedVolume == 0 )
473  {
474  // Workaround to ensure that the touchable is fixed !! // TODO: fix
475  //
476  touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
477  }
478 
479  return G4TouchableHistoryHandle(touchHist);
480 }
481 
482 // -----------------------------------------------------------------------
483 
485 {
486  // Flag which processes limited the step
487 
488  G4int last=-1;
489  const G4int IdTransport= 0; // Id of Mass Navigator !!
490  G4int noLimited=0;
491  ELimited shared= kSharedOther;
492 
493 #ifdef G4DEBUG_NAVIGATION
494  if( fVerbose > 2 )
495  {
496  G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
497  }
498 #endif
499 
500  // Assume that [IdTransport] is Mass / Transport
501  //
502  G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
503  && ( fMinStep!= kInfinity);
504  if( transportLimited )
505  {
506  shared= kSharedTransport;
507  }
508 
509  for ( G4int num= 0; num < fNoActiveNavigators; num++ )
510  {
511  G4bool limitedStep;
512 
513  G4double step= fCurrentStepSize[num];
514 
515  limitedStep = ( step == fMinStep ) && ( step != kInfinity);
516 
517  fLimitTruth[ num ] = limitedStep;
518  if( limitedStep )
519  {
520  noLimited++;
521  fLimitedStep[num] = shared;
522  last= num;
523  }
524  else
525  {
526  fLimitedStep[num] = kDoNot;
527  }
528  }
529  if( (last > -1) && (noLimited == 1 ) )
530  {
531  fLimitedStep[ last ] = kUnique;
532  fIdNavLimiting = last;
533  }
534 
535  fNoLimitingStep= noLimited;
536 
537  return;
538 }
539 
540 // -----------------------------------------------------------------------
541 
542 void
544 {
545  // Report results -- for checking
546 
547  static const G4String StrDoNot("DoNot"), StrUnique("Unique"),
548  StrUndefined("Undefined"),
549  StrSharedTransport("SharedTransport"),
550  StrSharedOther("SharedOther");
551  G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
552  G4cout << " Minimum step (true): " << fTrueMinStep
553  << ", reported min: " << fMinStep << G4endl;
554 
555 #ifdef G4DEBUG_NAVIGATION
556  if(fVerbose>=2)
557  {
558  G4cout << std::setw(5) << " NavId" << " "
559  << std::setw(12) << " step-size " << " "
560  << std::setw(12) << " raw-size " << " "
561  << std::setw(12) << " pre-safety " << " "
562  << std::setw(15) << " Limited / flag" << " "
563  << std::setw(15) << " World " << " "
564  << G4endl;
565  }
566 #endif
567 
568  for ( G4int num= 0; num < fNoActiveNavigators; num++ )
569  {
570  G4double rawStep = fCurrentStepSize[num];
571  G4double stepLen = fCurrentStepSize[num];
572  if( stepLen > fTrueMinStep )
573  {
574  stepLen = fTrueMinStep; // did not limit (went as far as asked)
575  }
576  G4int oldPrec= G4cout.precision(9);
577 
578  G4cout << std::setw(5) << num << " "
579  << std::setw(12) << stepLen << " "
580  << std::setw(12) << rawStep << " "
581  << std::setw(12) << fNewSafety[num] << " "
582  << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
583  G4String limitedStr;
584  switch ( fLimitedStep[num] )
585  {
586  case kDoNot : limitedStr= StrDoNot; break;
587  case kUnique : limitedStr = StrUnique; break;
588  case kSharedTransport: limitedStr= StrSharedTransport; break;
589  case kSharedOther : limitedStr = StrSharedOther; break;
590  default : limitedStr = StrUndefined; break;
591  }
592  G4cout << " " << std::setw(15) << limitedStr << " ";
593  G4cout.precision(oldPrec);
594 
595  G4Navigator *pNav= fpNavigator[ num ];
596  G4String WorldName( "Not-Set" );
597  if (pNav)
598  {
599  G4VPhysicalVolume *pWorld= pNav->GetWorldVolume();
600  if( pWorld )
601  {
602  WorldName = pWorld->GetName();
603  }
604  }
605  G4cout << " " << WorldName ;
606  G4cout << G4endl;
607  }
608 }
609 
610 
611 // -----------------------------------------------------------------------
612 
614 {
615  fWasLimitedByGeometry= false;
616 
617  G4Exception("G4MultiNavigator::ResetState()", "GeomNav0001",
619  "Cannot reset state for navigators of G4MultiNavigator.");
620 
621  std::vector<G4Navigator*>::iterator pNavigatorIter;
622  pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
623  for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
624  {
625  // (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!!
626  }
627 }
628 
629 // -----------------------------------------------------------------------
630 
632 {
633  G4Exception( "G4MultiNavigator::SetupHierarchy()",
634  "GeomNav0001", FatalException,
635  "Cannot setup hierarchy for navigators of G4MultiNavigator.");
636 }
637 
638 // -----------------------------------------------------------------------
639 
641 {
642  G4VPhysicalVolume* navTrackWorld=
644 
645  if( navTrackWorld != fLastMassWorld )
646  {
647  G4Exception( "G4MultiNavigator::CheckMassWorld()",
648  "GeomNav0003", FatalException,
649  "Mass world pointer has been changed." );
650  }
651 }
652 
653 // -----------------------------------------------------------------------
654 
657  const G4ThreeVector &direction,
658  const G4TouchableHistory &MassHistory)
659 {
660  // Reset geometry for all -- and use the touchable for the mass history
661 
662  G4VPhysicalVolume* massVolume=0;
663  G4Navigator* pMassNavigator= fpNavigator[0];
664 
665  if( pMassNavigator )
666  {
667  massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
668  MassHistory);
669  }
670  else
671  {
672  G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
673  "GeomNav0002", FatalException,
674  "Cannot reset hierarchy before navigators are initialised.");
675  }
676 
677  std::vector<G4Navigator*>::iterator pNavIter=
679 
680  for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
681  {
682  G4bool relativeSearch, ignoreDirection;
683 
684  (*pNavIter)-> LocateGlobalPointAndSetup( point,
685  &direction,
686  relativeSearch=false,
687  ignoreDirection=false);
688  }
689  return massVolume;
690 }
691 
692 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
693 
696  G4bool* argpObtained) // obtained valid
697 {
698  G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
699  G4bool isObtained= false;
700  // These default values will be used if fNoLimitingStep== 0
701  G4int firstNavigatorId= -1;
702  G4bool oneObtained= false;
703 
704  if( fNoLimitingStep==1 )
705  {
706  // Only message the Navigator which limited the step!
707  normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetGlobalExitNormal( argPoint, &isObtained);
708  *argpObtained= isObtained;
709  }
710  else
711  {
712  if( fNoLimitingStep > 1 )
713  {
714  std::vector<G4Navigator*>::iterator pNavIter=
716 
717  for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
718  {
719  G4ThreeVector oneNormal;
720  if( fLimitTruth[ num ] ) // Did this geometry limit the step ?
721  {
722  G4ThreeVector newNormal= (*pNavIter)-> GetGlobalExitNormal( argPoint, &oneObtained );
723  if( oneObtained )
724  {
725  // Keep first one - only if it is valid (ie not null)
726  if( !isObtained && (newNormal.mag2() != 0.0) )
727  {
728  normalGlobalCrd= newNormal;
729  isObtained = oneObtained;
730  firstNavigatorId= num;
731  }else{
732  // Check for clash
733  G4double dotNewPrevious= newNormal.dot( normalGlobalCrd );
734  G4double productMagSq= normalGlobalCrd.mag2() * newNormal.mag2();
735  if( productMagSq > 0.0 )
736  {
737  G4double productMag= std::sqrt( productMagSq );
738  dotNewPrevious /= productMag; // Normalise
739  if( dotNewPrevious < (1 - perThousand) )
740  {
741  *argpObtained= false;
742 
743  if( fVerbose > 2 ) // dotNewPrevious <= 0.0 )
744  {
745  std::ostringstream message;
746  message << "Clash of Normal from different Navigators!" << G4endl
747  << " Previous Navigator Id = " << firstNavigatorId << G4endl
748  << " Current Navigator Id = " << num << G4endl;
749  message << " Dot product of 2 normals = " << dotNewPrevious << G4endl;
750  message << " Normal (previous) = " << normalGlobalCrd << G4endl;
751  message << " Normal (current) = " << newNormal << G4endl;
752  G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
753  JustWarning, message);
754  }
755  }
756  else
757  {
758  // Close agreement - Do not change
759  }
760  }
761  }
762  }
763  }
764  } // end for over the Navigators
765 
766  // Report if no Normal was obtained
767  if( !oneObtained )
768  {
769  std::ostringstream message;
770  message << "No Normal obtained despite having " << fNoLimitingStep
771  << " candidate Navigators limiting the step!" << G4endl;
772  G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
773  JustWarning, message);
774  }
775 
776  } // end if ( fNoLimiting > 1 )
777  } // end else
778 
779  *argpObtained= isObtained;
780  return normalGlobalCrd;
781 }
782 
783 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
784 
787 {
788  // If it is the mass navigator, then expect
789  G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
790  G4bool isObtained= false;
791  // These default values will be used if fNoLimitingStep== 0
792 
793  if( fNoLimitingStep==1 )
794  {
795  // Only message the Navigator which limited the step!
796  normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetLocalExitNormal( &isObtained);
797  *argpObtained= isObtained;
798 
799  static G4ThreadLocal G4int numberWarnings= 0;
800  G4int noWarningsStart= 10, noModuloWarnings=100;
801  numberWarnings++;
802  if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) )
803  {
804  std::ostringstream message;
805  message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
806  G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
807  JustWarning, message);
808  }
809  }
810  else
811  {
812  if( fNoLimitingStep > 1 )
813  {
814  // Does not make sense - cannot obtain *local* normal in several coordinate systems
815  std::ostringstream message;
816  message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
817  G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
818  FatalException, message);
819  }
820  }
821 
822  *argpObtained= isObtained;
823  return normalGlobalCrd;
824 }
825 
826 
827 // ----------------- ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
828 
831  G4bool* obtained)
832 {
833  return G4MultiNavigator::GetLocalExitNormal( obtained);
834 }
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &CurrentE_Point, G4bool *obtained)
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=false)
static const G4double kInfinity
Definition: geomdefs.hh:42
G4bool fLimitTruth[fMaxNav]
G4VPhysicalVolume * fLocatedVolume[fMaxNav]
CLHEP::Hep3Vector G4ThreeVector
G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
void PrepareNewTrack(const G4ThreeVector position, const G4ThreeVector direction)
ELimited
G4double fMinSafety_atSafLocation
G4int fVerbose
Definition: G4Navigator.hh:392
G4Navigator * GetNavigatorForTracking() const
G4TransportationManager * pTransportManager
G4Navigator * fpNavigator[fMaxNav]
G4VPhysicalVolume * fLastMassWorld
G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=0, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
static const double perThousand
Definition: G4SIunits.hh:330
#define G4ThreadLocal
Definition: tls.hh:89
G4ReferenceCountedHandle< G4TouchableHistory > G4TouchableHistoryHandle
int G4int
Definition: G4Types.hh:78
G4ThreeVector fPreStepLocation
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
Definition: G4Navigator.cc:92
G4bool fWasLimitedByGeometry
Definition: G4Navigator.hh:382
#define position
Definition: xmlparse.cc:622
G4TouchableHistoryHandle CreateTouchableHistoryHandle() const
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
G4double fNewSafety[fMaxNav]
virtual G4ThreeVector GetLocalExitNormal(G4bool *valid)
bool G4bool
Definition: G4Types.hh:79
virtual G4ThreeVector GetLocalExitNormal(G4bool *obtained)
G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
static G4TransportationManager * GetTransportationManager()
static const G4double minSafety
G4TouchableHistory * CreateTouchableHistory() const
G4ThreeVector fSafetyLocation
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
virtual G4int GetCopyNo() const =0
void SetWorldVolume(G4VPhysicalVolume *pWorld)
G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, G4double &minStepLast, ELimited &limitedStep)
ELimited fLimitedStep[fMaxNav]
void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
G4double fCurrentStepSize[fMaxNav]
#define G4endl
Definition: G4ios.hh:61
virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &CurrentE_Point, G4bool *obtained)
void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=0)
const G4NavigationHistory * GetHistory() const
double G4double
Definition: G4Types.hh:76
static const G4int fMaxNav
static const double mm
Definition: G4SIunits.hh:114
G4VPhysicalVolume * GetWorldVolume() const
G4double fMinSafety_PreStepPt
G4ThreeVector fLastLocatedPosition