53 fNoActiveNavigators= 0;
55 fLastLocatedPosition = Big3Vector;
56 fSafetyLocation = Big3Vector;
57 fPreStepLocation = Big3Vector;
59 fMinSafety_PreStepPt= -1.0;
60 fMinSafety_atSafLocation= -1.0;
61 fMinSafety= -kInfinity;
62 fTrueMinStep= fMinStep= -kInfinity;
64 for(
register int num=0; num< fMaxNav; ++num )
67 fLimitTruth[num] =
false;
69 fCurrentStepSize[num] = fNewSafety[num] = -1.0;
70 fLocatedVolume[num] = 0;
82 fLastMassWorld = pWorld;
100 G4double minSafety= kInfinity, minStep= kInfinity;
105 #ifdef G4DEBUG_NAVIGATION
108 G4cout <<
" G4MultiNavigator::ComputeStep : entered " <<
G4endl;
109 G4cout <<
" Input position= " << pGlobalPoint
110 <<
" direction= " << pDirection <<
G4endl;
111 G4cout <<
" Requested step= " << proposedStepLength <<
G4endl;
115 std::vector<G4Navigator*>::iterator pNavigatorIter;
117 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
122 for(
register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
126 step= (*pNavigatorIter)->ComputeStep( initialPosition,
130 if( safety < minSafety ){ minSafety = safety; }
131 if( step < minStep ) { minStep= step; }
133 fCurrentStepSize[num] = step;
134 fNewSafety[num]= safety;
137 #ifdef G4DEBUG_NAVIGATION
140 G4cout <<
"G4MultiNavigator::ComputeStep : Navigator ["
141 << num <<
"] -- step size " << step
142 <<
" safety= " << safety <<
G4endl;
149 fPreStepLocation = initialPosition;
150 fMinSafety_PreStepPt = minSafety;
153 if( fMinStep == kInfinity )
155 fTrueMinStep = proposedStepLength;
159 fTrueMinStep = minStep;
162 #ifdef G4DEBUG_NAVIGATION
165 G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
168 G4cout <<
"G4MultiNavigator::ComputeStep : "
169 <<
" initialPosition = " << initialPosition
170 <<
" and endPosition = " << endPosition <<
G4endl;
171 G4cout.precision( oldPrec );
175 pNewSafety = minSafety;
179 #ifdef G4DEBUG_NAVIGATION
182 G4cout <<
" G4MultiNavigator::ComputeStep : exits returning "
198 if( navigatorId > fNoActiveNavigators )
200 std::ostringstream message;
201 message <<
"Bad Navigator Id!" <<
G4endl
202 <<
" Navigator Id = " << navigatorId
203 <<
" No Active = " << fNoActiveNavigators <<
".";
204 G4Exception(
"G4MultiNavigator::ObtainFinalStep()",
"GeomNav0002",
210 pNewSafety = fNewSafety[ navigatorId ];
211 limitedStep = fLimitedStep[ navigatorId ];
214 #ifdef G4DEBUG_NAVIGATION
217 G4cout <<
" G4MultiNavigator::ComputeStep returns "
218 << fCurrentStepSize[ navigatorId ]
219 <<
" for Navigator " << navigatorId
220 <<
" Limited step = " << limitedStep
221 <<
" Safety(mm) = " << pNewSafety /
mm <<
G4endl;
225 return fCurrentStepSize[ navigatorId ];
233 #ifdef G4DEBUG_NAVIGATION
236 G4cout <<
" Entered G4MultiNavigator::PrepareNewTrack() " <<
G4endl;
257 #ifdef G4DEBUG_NAVIGATION
260 G4cout <<
" Entered G4MultiNavigator::PrepareNavigators() " <<
G4endl;
266 std::vector<G4Navigator*>::iterator pNavigatorIter;
267 fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators();
269 if( fNoActiveNavigators > fMaxNav )
271 std::ostringstream message;
272 message <<
"Too many active Navigators / worlds !" <<
G4endl
273 <<
" Active Navigators (worlds): "
274 << fNoActiveNavigators <<
G4endl
275 <<
" which is more than the number allowed: "
277 G4Exception(
"G4MultiNavigator::PrepareNavigators()",
"GeomNav0002",
281 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
282 for(
register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
284 fpNavigator[num] = *pNavigatorIter;
285 fLimitTruth[num] =
false;
286 fLimitedStep[num] =
kDoNot;
287 fCurrentStepSize[num] = 0.0;
288 fLocatedVolume[num] = 0;
297 if( (massWorld != fLastMassWorld) && (massWorld!=0) )
302 #ifdef G4DEBUG_NAVIGATION
305 G4cout <<
" G4MultiNavigator::PrepareNavigators() changed world volume "
306 <<
" for mass geometry to " << massWorld->
GetName() <<
G4endl;
310 fLastMassWorld = massWorld;
319 const G4bool pRelativeSearch,
320 const G4bool ignoreDirection )
325 G4bool relative = pRelativeSearch;
326 std::vector<G4Navigator*>::iterator pNavIter
329 if( pDirection ) { direction = *pDirection; }
331 #ifdef G4DEBUG_NAVIGATION
334 G4cout <<
" Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
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
345 for (
register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
349 (*pNavIter)->SetGeometricallyLimitedStep();
353 = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
354 relative, ignoreDirection );
357 fLocatedVolume[num] = pLocated;
361 fLimitedStep[num] =
kDoNot;
362 fCurrentStepSize[num] = 0.0;
363 fLimitTruth[ num ] =
false;
365 #ifdef G4DEBUG_NAVIGATION
368 G4cout <<
" Located in world: " << num <<
", at: " << position <<
G4endl
369 <<
" Used geomLimStp: " << fLimitTruth[num]
370 <<
", found in volume: " << pLocated <<
G4endl;
379 G4cout <<
"Null' Id: Not-Set ";
389 return volMassLocated;
399 std::vector<G4Navigator*>::iterator pNavIter
402 #ifdef G4DEBUG_NAVIGATION
405 G4cout <<
" Entered G4MultiNavigator::ReLocate() " <<
G4endl
406 <<
" Re-locating at position: " << position <<
G4endl;
410 for (
register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
414 (*pNavIter)->LocateGlobalPointWithinVolume( position );
418 fLimitedStep[num] =
kDoNot;
419 fCurrentStepSize[num] = 0.0;
421 fLimitTruth[ num ] =
false;
435 G4double minSafety = kInfinity, safety = kInfinity;
437 std::vector<G4Navigator*>::iterator pNavigatorIter;
438 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
440 for(
register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
442 safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
443 if( safety < minSafety ) { minSafety = safety; }
447 fMinSafety_atSafLocation = minSafety;
449 #ifdef G4DEBUG_NAVIGATION
452 G4cout <<
" G4MultiNavigator::ComputeSafety - returns: "
453 << minSafety <<
", at location: " << position <<
G4endl;
464 G4Exception(
"G4MultiNavigator::CreateTouchableHistoryHandle()",
466 "Getting a touchable from G4MultiNavigator is not defined.");
472 if( locatedVolume == 0 )
489 const G4int IdTransport= 0;
493 #ifdef G4DEBUG_NAVIGATION
496 G4cout <<
" Entered G4MultiNavigator::WhichLimited() " <<
G4endl;
502 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
503 && ( fMinStep!= kInfinity);
504 if( transportLimited )
509 for (
register int num= 0; num < fNoActiveNavigators; num++ )
513 G4double step= fCurrentStepSize[num];
515 limitedStep = ( step == fMinStep ) && ( step != kInfinity);
517 fLimitTruth[ num ] = limitedStep;
521 fLimitedStep[num] = shared;
526 fLimitedStep[num] =
kDoNot;
529 if( (last > -1) && (noLimited == 1 ) )
531 fLimitedStep[ last ] =
kUnique;
534 fNoLimitingStep= noLimited;
546 static G4String StrDoNot(
"DoNot"), StrUnique(
"Unique"),
547 StrUndefined(
"Undefined"),
548 StrSharedTransport(
"SharedTransport"),
549 StrSharedOther(
"SharedOther");
550 G4cout <<
"### G4MultiNavigator::PrintLimited() reports: " <<
G4endl;
551 G4cout <<
" Minimum step (true): " << fTrueMinStep
552 <<
", reported min: " << fMinStep <<
G4endl;
554 #ifdef G4DEBUG_NAVIGATION
557 G4cout << std::setw(5) <<
" NavId" <<
" "
558 << std::setw(12) <<
" step-size " <<
" "
559 << std::setw(12) <<
" raw-size " <<
" "
560 << std::setw(12) <<
" pre-safety " <<
" "
561 << std::setw(15) <<
" Limited / flag" <<
" "
562 << std::setw(15) <<
" World " <<
" "
567 for (
register int num= 0; num < fNoActiveNavigators; num++ )
569 G4double rawStep = fCurrentStepSize[num];
570 G4double stepLen = fCurrentStepSize[num];
571 if( stepLen > fTrueMinStep )
573 stepLen = fTrueMinStep;
577 G4cout << std::setw(5) << num <<
" "
578 << std::setw(12) << stepLen <<
" "
579 << std::setw(12) << rawStep <<
" "
580 << std::setw(12) << fNewSafety[num] <<
" "
581 << std::setw(5) << (fLimitTruth[num] ?
"YES" :
" NO") <<
" ";
583 switch ( fLimitedStep[num] )
585 case kDoNot : limitedStr= StrDoNot;
break;
586 case kUnique : limitedStr = StrUnique;
break;
589 default : limitedStr = StrUndefined;
break;
591 G4cout <<
" " << std::setw(15) << limitedStr <<
" ";
592 G4cout.precision(oldPrec);
604 G4cout <<
" " << WorldName ;
616 G4Exception(
"G4MultiNavigator::ResetState()",
"GeomNav0001",
618 "Cannot reset state for navigators of G4MultiNavigator.");
620 std::vector<G4Navigator*>::iterator pNavigatorIter;
621 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
622 for(
register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
634 "Cannot setup hierarchy for navigators of G4MultiNavigator.");
644 if( navTrackWorld != fLastMassWorld )
648 "Mass world pointer has been changed." );
671 G4Exception(
"G4MultiNavigator::ResetHierarchyAndLocate()",
673 "Cannot reset hierarchy before navigators are initialised.");
676 std::vector<G4Navigator*>::iterator pNavIter=
679 for (
register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
681 G4bool relativeSearch, ignoreDirection;
685 relativeSearch=
false,
686 ignoreDirection=
false);
700 G4int firstNavigatorId= -1;
701 G4bool oneObtained=
false;
703 if( fNoLimitingStep==1 )
706 normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->
GetGlobalExitNormal( argPoint, &isObtained);
707 *argpObtained= isObtained;
711 if( fNoLimitingStep > 1 )
713 std::vector<G4Navigator*>::iterator pNavIter=
716 for (
register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
719 if( fLimitedStep[ num ] )
725 if( !isObtained && (newNormal.
mag2() != 0.0) )
727 normalGlobalCrd= newNormal;
728 isObtained = oneObtained;
729 firstNavigatorId= num;
732 G4double dotNewPrevious= newNormal.
dot( normalGlobalCrd );
734 if( productMagSq > 0.0 )
736 G4double productMag= std::sqrt( productMagSq );
737 dotNewPrevious /= productMag;
740 *argpObtained=
false;
744 std::ostringstream message;
745 message <<
"Clash of Normal from different Navigators!" <<
G4endl
746 <<
" Previous Navigator Id = " << firstNavigatorId <<
G4endl
747 <<
" Current Navigator Id = " << num <<
G4endl;
748 message <<
" Dot product of 2 normals = " << dotNewPrevious <<
G4endl;
749 message <<
" Normal (previous) = " << normalGlobalCrd <<
G4endl;
750 message <<
" Normal (current) = " << newNormal <<
G4endl;
751 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
768 std::ostringstream message;
769 message <<
"No Normal obtained despite having " << fNoLimitingStep
770 <<
" candidate Navigators limiting the step!" <<
G4endl;
771 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
778 *argpObtained= isObtained;
779 return normalGlobalCrd;
792 if( fNoLimitingStep==1 )
796 *argpObtained= isObtained;
798 G4int static numberWarnings= 0;
799 G4int noWarningsStart= 10, noModuloWarnings=100;
801 if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) )
803 std::ostringstream message;
804 message <<
"Cannot obtain normal in local coordinates of two or more coordinate systems." <<
G4endl;
805 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
811 if( fNoLimitingStep > 1 )
814 std::ostringstream message;
815 message <<
"Cannot obtain normal in local coordinates of two or more coordinate systems." <<
G4endl;
816 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
821 *argpObtained= isObtained;
822 return normalGlobalCrd;