45 fLastLocatedPosition = Big3Vector;
46 fSafetyLocation = Big3Vector;
47 fPreStepLocation = Big3Vector;
49 for(
auto num=0; num< fMaxNav; ++num )
51 fpNavigator[num] =
nullptr;
52 fLimitTruth[num] =
false;
54 fCurrentStepSize[num] = fNewSafety[num] = -1.0;
55 fLocatedVolume[num] =
nullptr;
60 G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
61 if( massNav !=
nullptr )
64 if( pWorld !=
nullptr )
67 fLastMassWorld = pWorld;
80 G4double minSafety= kInfinity, minStep= kInfinity;
85#ifdef G4DEBUG_NAVIGATION
88 G4cout <<
" G4MultiNavigator::ComputeStep : entered " <<
G4endl;
89 G4cout <<
" Input position= " << pGlobalPoint
90 <<
" direction= " << pDirection <<
G4endl;
91 G4cout <<
" Requested step= " << proposedStepLength <<
G4endl;
95 std::vector<G4Navigator*>::iterator pNavigatorIter;
97 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
102 for(
auto num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
106 step= (*pNavigatorIter)->ComputeStep( initialPosition,
110 if( safety < minSafety ){ minSafety = safety; }
111 if( step < minStep ) { minStep= step; }
113 fCurrentStepSize[num] = step;
114 fNewSafety[num]= safety;
117#ifdef G4DEBUG_NAVIGATION
120 G4cout <<
"G4MultiNavigator::ComputeStep : Navigator ["
121 << num <<
"] -- step size " << step
122 <<
" safety= " << safety <<
G4endl;
129 fPreStepLocation = initialPosition;
130 fMinSafety_PreStepPt = minSafety;
133 if( fMinStep == kInfinity )
135 fTrueMinStep = proposedStepLength;
139 fTrueMinStep = minStep;
142#ifdef G4DEBUG_NAVIGATION
145 G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
148 G4cout <<
"G4MultiNavigator::ComputeStep : "
149 <<
" initialPosition = " << initialPosition
150 <<
" and endPosition = " << endPosition <<
G4endl;
151 G4cout.precision( oldPrec );
155 pNewSafety = minSafety;
159#ifdef G4DEBUG_NAVIGATION
162 G4cout <<
" G4MultiNavigator::ComputeStep : exits returning "
178 if( navigatorId > fNoActiveNavigators )
180 std::ostringstream message;
181 message <<
"Bad Navigator Id!" <<
G4endl
182 <<
" Navigator Id = " << navigatorId
183 <<
" No Active = " << fNoActiveNavigators <<
".";
184 G4Exception(
"G4MultiNavigator::ObtainFinalStep()",
"GeomNav0002",
190 pNewSafety = fNewSafety[ navigatorId ];
191 limitedStep = fLimitedStep[ navigatorId ];
194#ifdef G4DEBUG_NAVIGATION
197 G4cout <<
" G4MultiNavigator::ComputeStep returns "
198 << fCurrentStepSize[ navigatorId ]
199 <<
" for Navigator " << navigatorId
200 <<
" Limited step = " << limitedStep
201 <<
" Safety(mm) = " << pNewSafety / mm <<
G4endl;
205 return fCurrentStepSize[ navigatorId ];
213#ifdef G4DEBUG_NAVIGATION
216 G4cout <<
" Entered G4MultiNavigator::PrepareNewTrack() " <<
G4endl;
237#ifdef G4DEBUG_NAVIGATION
240 G4cout <<
" Entered G4MultiNavigator::PrepareNavigators() " <<
G4endl;
246 std::vector<G4Navigator*>::const_iterator pNavigatorIter;
247 fNoActiveNavigators = (
G4int)pTransportManager-> GetNoActiveNavigators();
249 if( fNoActiveNavigators > fMaxNav )
251 std::ostringstream message;
252 message <<
"Too many active Navigators / worlds !" <<
G4endl
253 <<
" Active Navigators (worlds): "
254 << fNoActiveNavigators <<
G4endl
255 <<
" which is more than the number allowed: "
257 G4Exception(
"G4MultiNavigator::PrepareNavigators()",
"GeomNav0002",
261 pNavigatorIter= pTransportManager->GetActiveNavigatorsIterator();
262 for(
auto num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
264 fpNavigator[num] = *pNavigatorIter;
265 fLimitTruth[num] =
false;
266 fLimitedStep[num] =
kDoNot;
267 fCurrentStepSize[num] = 0.0;
268 fLocatedVolume[num] =
nullptr;
277 if( (massWorld != fLastMassWorld) && (massWorld!=
nullptr) )
282#ifdef G4DEBUG_NAVIGATION
285 G4cout <<
" G4MultiNavigator::PrepareNavigators() changed world volume "
286 <<
" for mass geometry to " << massWorld->
GetName() <<
G4endl;
290 fLastMassWorld = massWorld;
299 const G4bool pRelativeSearch,
300 const G4bool ignoreDirection )
305 G4bool relative = pRelativeSearch;
306 auto pNavIter = pTransportManager->GetActiveNavigatorsIterator();
308 if( pDirection !=
nullptr ) { direction = *pDirection; }
310#ifdef G4DEBUG_NAVIGATION
313 G4cout <<
" Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
316 <<
", with direction: " << direction <<
G4endl
317 <<
" Relative: " << relative
318 <<
", ignore direction: " << ignoreDirection <<
G4endl;
319 G4cout <<
" Number of active navigators: " << fNoActiveNavigators
324 for (
auto num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
328 (*pNavIter)->SetGeometricallyLimitedStep();
332 = (*pNavIter)->LocateGlobalPointAndSetup(
position, &direction,
333 relative, ignoreDirection );
336 fLocatedVolume[num] = pLocated;
340 fLimitedStep[num] =
kDoNot;
341 fCurrentStepSize[num] = 0.0;
342 fLimitTruth[ num ] =
false;
344#ifdef G4DEBUG_NAVIGATION
348 <<
" Used geomLimStp: " << fLimitTruth[num]
349 <<
", found in volume: " << pLocated <<
G4endl;
358 G4cout <<
"Null' Id: Not-Set ";
368 return volMassLocated;
378 auto pNavIter = pTransportManager->GetActiveNavigatorsIterator();
380#ifdef G4DEBUG_NAVIGATION
383 G4cout <<
" Entered G4MultiNavigator::ReLocate() " <<
G4endl
388 for (
auto num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
392 (*pNavIter)->LocateGlobalPointWithinVolume(
position );
396 fLimitedStep[num] =
kDoNot;
397 fCurrentStepSize[num] = 0.0;
399 fLimitTruth[ num ] =
false;
413 G4double minSafety = kInfinity, safety = kInfinity;
415 std::vector<G4Navigator*>::iterator pNavigatorIter;
416 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
418 for(
auto num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
420 safety = (*pNavigatorIter)->ComputeSafety(
position, maxDistance, state);
421 if( safety < minSafety ) { minSafety = safety; }
425 fMinSafety_atSafLocation = minSafety;
427#ifdef G4DEBUG_NAVIGATION
430 G4cout <<
" G4MultiNavigator::ComputeSafety - returns: "
441 G4Exception(
"G4MultiNavigator::CreateTouchableHistoryHandle()",
443 "Getting a touchable from G4MultiNavigator is not defined.");
449 if( locatedVolume ==
nullptr )
466 const G4int IdTransport= 0;
470#ifdef G4DEBUG_NAVIGATION
473 G4cout <<
" Entered G4MultiNavigator::WhichLimited() " <<
G4endl;
479 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
480 && ( fMinStep!= kInfinity);
481 if( transportLimited )
486 for (
auto num = 0; num < fNoActiveNavigators; ++num )
490 G4double step = fCurrentStepSize[num];
492 limitedStep = ( step == fMinStep ) && ( step != kInfinity);
494 fLimitTruth[ num ] = limitedStep;
498 fLimitedStep[num] = shared;
503 fLimitedStep[num] =
kDoNot;
506 if( (last > -1) && (noLimited == 1 ) )
508 fLimitedStep[ last ] =
kUnique;
509 fIdNavLimiting = last;
512 fNoLimitingStep = noLimited;
524 static const G4String StrDoNot(
"DoNot"), StrUnique(
"Unique"),
525 StrUndefined(
"Undefined"),
526 StrSharedTransport(
"SharedTransport"),
527 StrSharedOther(
"SharedOther");
528 G4cout <<
"### G4MultiNavigator::PrintLimited() reports: " <<
G4endl;
529 G4cout <<
" Minimum step (true): " << fTrueMinStep
530 <<
", reported min: " << fMinStep <<
G4endl;
532#ifdef G4DEBUG_NAVIGATION
535 G4cout << std::setw(5) <<
" NavId" <<
" "
536 << std::setw(12) <<
" step-size " <<
" "
537 << std::setw(12) <<
" raw-size " <<
" "
538 << std::setw(12) <<
" pre-safety " <<
" "
539 << std::setw(15) <<
" Limited / flag" <<
" "
540 << std::setw(15) <<
" World " <<
" "
545 for (
auto num = 0; num < fNoActiveNavigators; ++num )
547 G4double rawStep = fCurrentStepSize[num];
548 G4double stepLen = fCurrentStepSize[num];
549 if( stepLen > fTrueMinStep )
551 stepLen = fTrueMinStep;
555 G4cout << std::setw(5) << num <<
" "
556 << std::setw(12) << stepLen <<
" "
557 << std::setw(12) << rawStep <<
" "
558 << std::setw(12) << fNewSafety[num] <<
" "
559 << std::setw(5) << (fLimitTruth[num] ?
"YES" :
" NO") <<
" ";
561 switch ( fLimitedStep[num] )
563 case kDoNot : limitedStr = StrDoNot;
break;
564 case kUnique : limitedStr = StrUnique;
break;
567 default : limitedStr = StrUndefined;
break;
569 G4cout <<
" " << std::setw(15) << limitedStr <<
" ";
570 G4cout.precision(oldPrec);
577 if( pWorld !=
nullptr )
582 G4cout <<
" " << WorldName ;
594 G4Exception(
"G4MultiNavigator::ResetState()",
"GeomNav0001",
596 "Cannot reset state for navigators of G4MultiNavigator.");
613 "Cannot setup hierarchy for navigators of G4MultiNavigator.");
621 pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
623 if( navTrackWorld != fLastMassWorld )
627 "Mass world pointer has been changed." );
643 if( pMassNavigator !=
nullptr )
650 G4Exception(
"G4MultiNavigator::ResetHierarchyAndLocate()",
652 "Cannot reset hierarchy before navigators are initialised.");
655 auto pNavIter= pTransportManager->GetActiveNavigatorsIterator();
657 for (
auto num = 0; num < fNoActiveNavigators ; ++pNavIter,++num )
659 G4bool relativeSearch, ignoreDirection;
663 relativeSearch=
false,
664 ignoreDirection=
false);
676 G4bool isObtained =
false;
678 G4int firstNavigatorId = -1;
679 G4bool oneObtained =
false;
681 if( fNoLimitingStep == 1 )
684 normalGlobalCrd = fpNavigator[ fIdNavLimiting ]
685 ->GetGlobalExitNormal( argPoint, &isObtained );
686 *argpObtained = isObtained;
690 if( fNoLimitingStep > 1 )
692 auto pNavIter= pTransportManager->GetActiveNavigatorsIterator();
694 for (
auto num = 0; num < fNoActiveNavigators ; ++pNavIter, ++num )
697 if( fLimitTruth[ num ] )
700 (*pNavIter)->GetGlobalExitNormal( argPoint, &oneObtained );
704 if( !isObtained && (newNormal.
mag2() != 0.0) )
706 normalGlobalCrd = newNormal;
707 isObtained = oneObtained;
708 firstNavigatorId = num;
713 G4double dotNewPrevious = newNormal.
dot( normalGlobalCrd );
715 if( productMagSq > 0.0 )
717 G4double productMag = std::sqrt( productMagSq );
718 dotNewPrevious /= productMag;
719 if( dotNewPrevious < (1 - perThousand) )
721 *argpObtained =
false;
725 std::ostringstream message;
726 message <<
"Clash of Normal from different Navigators!"
728 <<
" Previous Navigator Id = "
729 << firstNavigatorId <<
G4endl
730 <<
" Current Navigator Id = "
732 message <<
" Dot product of 2 normals = "
733 << dotNewPrevious <<
G4endl;
734 message <<
" Normal (previous) = "
735 << normalGlobalCrd <<
G4endl;
736 message <<
" Normal (current) = " << newNormal <<
G4endl;
737 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
754 std::ostringstream message;
755 message <<
"No Normal obtained despite having " << fNoLimitingStep
756 <<
" candidate Navigators limiting the step!" <<
G4endl;
757 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
764 *argpObtained = isObtained;
765 return normalGlobalCrd;
775 G4bool isObtained =
false;
778 if( fNoLimitingStep == 1 )
781 normalGlobalCrd = fpNavigator[ fIdNavLimiting ]
782 ->GetLocalExitNormal( &isObtained );
783 *argpObtained = isObtained;
786 G4int noWarningsStart = 10, noModuloWarnings = 100;
788 if( (numberWarnings < noWarningsStart )
789 || (numberWarnings%noModuloWarnings == 0) )
791 std::ostringstream message;
792 message <<
"Cannot obtain normal in local coordinates of two or more "
793 <<
"coordinate systems." <<
G4endl;
794 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
800 if( fNoLimitingStep > 1 )
802 std::ostringstream message;
803 message <<
"Cannot obtain normal in local coordinates of two or more "
804 <<
"coordinate systems." <<
G4endl;
805 G4Exception(
"G4MultiNavigator::GetGlobalExitNormal()",
"GeomNav0002",
810 *argpObtained = isObtained;
811 return normalGlobalCrd;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4TouchableHandle is a type providing reference counting mechanism for any kind of touchable objects....
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &point, G4bool *obtained) override
G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true) override
G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, G4double &minStepLast, ELimited &limitedStep)
void ResetState() override
void SetupHierarchy() override
G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *obtained) override
void LocateGlobalPointWithinVolume(const G4ThreeVector &position) override
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=false) override
G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety) override
G4ThreeVector GetLocalExitNormal(G4bool *obtained) override
void PrepareNewTrack(const G4ThreeVector &position, const G4ThreeVector direction)
G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h) override
G4TouchableHandle CreateTouchableHistoryHandle() const override
G4TouchableHistory * CreateTouchableHistory() const
G4bool fWasLimitedByGeometry
void SetWorldVolume(G4VPhysicalVolume *pWorld)
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
G4VPhysicalVolume * GetWorldVolume() const
G4TouchableHistory is an object representing a touchable detector element, and its history in the geo...
void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=nullptr)
const G4NavigationHistory * GetHistory() const
static G4TransportationManager * GetTransportationManager()
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
virtual G4int GetCopyNo() const =0
const G4String & GetName() const