90 for(
auto num=0; num<
fMaxNav; ++num )
117 G4Navigator *navigatorForPropagation =
nullptr, *massNavigator =
nullptr;
130 navigatorForPropagation = massNavigator;
153#ifdef G4DEBUG_PATHFINDER
157 G4cout <<
" G4PathFinder::ComputeStep - entered " <<
G4endl;
158 G4cout <<
" - stepNo = " << std::setw(4) << stepNo <<
" "
159 <<
" navigatorId = " << std::setw(2) << navigatorNo <<
" "
160 <<
" proposed step len = " << proposedStepLength <<
" " <<
G4endl;
161 G4cout <<
" PF::ComputeStep requested step "
169 std::ostringstream message;
170 message <<
"Bad Navigator ID !" <<
G4endl
171 <<
" Requested Navigator ID = " << navigatorNo <<
G4endl
173 G4Exception(
"G4PathFinder::ComputeStep()",
"GeomNav0002",
196#ifdef G4DEBUG_PATHFINDER
199 G4double moveLen= std::sqrt( moveLenSq );
200 G4cout <<
" G4PathFinder::ComputeStep : Point moved since last step "
201 <<
" -- at step # = " << stepNo <<
G4endl
202 <<
" by " << moveLen <<
" to " << newPosition <<
G4endl;
209 Locate( newPosition, newDirection );
217 G4bool fieldExertsForce = false ;
218 if( particleCharge != 0.0 )
224 fieldExertsForce = (fieldMgr !=
nullptr)
231 if( fieldExertsForce )
242#ifdef G4DEBUG_PATHFINDER
246 std::ostringstream message;
247 message <<
"Number of geometries limiting the step not set." <<
G4endl
248 <<
" Number of geometries limiting step = "
255#ifdef G4DEBUG_PATHFINDER
258 const G4double checkTolerance = 1.0e-9;
259 if( proposedStepLength <
fTrueMinStep * ( 1.0 - checkTolerance) )
261 std::ostringstream message;
262 message.precision( 12 );
263 message <<
"Problem in step size request." <<
G4endl
264 <<
" Being requested to make a step which is shorter"
265 <<
" than the minimum Step " <<
G4endl
266 <<
" already computed for any Navigator/geometry during"
267 <<
" this tracking-step: " <<
G4endl
268 <<
" This could happen due to an error in process ordering."
270 <<
" Check that all physics processes are registered"
271 <<
" before all processes with a navigator/geometry."
273 <<
" If using pre-packaged physics list and/or"
274 <<
" functionality, please report this error."
276 <<
" Additional information for problem: " <<
G4endl
277 <<
" Steps request/proposed = " << proposedStepLength
281 <<
" MinimumStep (navraw) = " <<
fMinStep
283 <<
" Navigator raw return value" <<
G4endl
284 <<
" Requested step now = " << proposedStepLength
286 <<
" Difference min-req (absolute) = "
288 <<
" Relative (to max of two) = "
291 <<
" -- Step info> stepNo= " << stepNo
306 G4cout <<
" G4P::CS -> Not calling DoNextLinearStep: "
307 <<
" stepNo= " << stepNo <<
" last= " <<
fLastStepNo
324#ifdef G4DEBUG_PATHFINDER
327 G4cout <<
" G4PathFinder::ComputeStep returns "
329 <<
" for Navigator " << navigatorNo
330 <<
" Limited step = " << limitedStep
331 <<
" Safety(mm) = " << pNewSafety /
mm
365 std::vector<G4Navigator*>::iterator pNavigatorIter;
370 std::ostringstream message;
371 message <<
"Too many active Navigators / worlds." <<
G4endl
372 <<
" Transportation Manager has "
374 <<
" This is more than the number allowed = "
376 G4Exception(
"G4PathFinder::PrepareNewTrack()",
"GeomNav0002",
446 std::ostringstream message;
447 message.precision(16);
448 message <<
"Endpoint moved between value returned by ComputeStep()"
449 <<
" and call to Locate(). " <<
G4endl
450 <<
" Change of " << Quantity <<
" is "
452 <<
" and its vector is "
453 << (1.0/
mm) * moveVec <<
" mm " <<
G4endl
454 <<
" Endpoint of ComputeStep() was " << OldVector
456 <<
" and current position to locate is " << NewVector;
457 G4Exception(
"G4PathFinder::ReportMove()",
"GeomNav1002",
474#ifdef G4DEBUG_PATHFINDER
479 if( (!
fNewTrack) && ( moveLenSq > movLenTol ) )
482 " (End) Position / G4PathFinder::Locate" );
491 <<
" with direction " << direction
492 <<
" relative= " << relative <<
G4endl;
495 G4cout <<
" lastEndPosition = " << lastEndPosition
496 <<
" moveVec = " << moveVec
510 if(
fLimitTruth[num] ) { (*pNavIter)->SetGeometricallyLimitedStep(); }
513 (*pNavIter)->LocateGlobalPointAndSetup(
position, &direction,
525#ifdef G4DEBUG_PATHFINDER
529 <<
" gives volume= " << pLocated ;
532 G4cout <<
" name = '" << pLocated->GetName() <<
"'";
533 G4cout <<
" - CopyNo= " << pLocated->GetCopyNo();
547 std::vector<G4Navigator*>::iterator pNavIter =
550#ifdef G4DEBUG_PATHFINDER
575 G4double distCheckEnd_sq = ( moveLenEndPosSq - endPointSafety_Est1
576 *endPointSafety_Est1 );
580 G4bool longMoveEnd = distCheckEnd_sq > 0.0;
581 G4bool longMoveSaf = distCheckSaf_sq > 0.0;
585 if( (!
fNewTrack) && ( longMoveEnd && longMoveSaf ) )
593 const G4double cErrorTolerance = 1e-12;
596 G4double distCheckRevisedEnd = moveLenEndPosSq -
sqr(revisedSafety);
598 G4bool longMoveRevisedEnd = ( distCheckRevisedEnd > 0. ) ;
601 G4double moveLenEndPosition = std::sqrt( moveLenEndPosSq );
602 moveMinusSafety = moveLenEndPosition - revisedSafety;
604 if ( longMoveRevisedEnd && ( moveMinusSafety > 0.0 )
605 && ( revisedSafety > 0.0 ) )
612 G4cout <<
" G4PF:Relocate> Ratio to revised safety is "
613 << std::fabs(moveMinusSafety)/revisedSafety <<
G4endl;
616 G4double absMoveMinusSafety = std::fabs(moveMinusSafety);
617 G4bool smallRatio = absMoveMinusSafety < kRadTolerance * revisedSafety;
622 G4bool smallValue= absMoveMinusSafety < cErrorTolerance * maxCoordPos;
623 if( !(smallRatio || smallValue) )
625 G4cout <<
" G4PF:Relocate> Ratio to revised safety is "
626 << std::fabs(moveMinusSafety)/revisedSafety <<
G4endl;
627 G4cout <<
" Difference of move and safety is not very small."
632 moveMinusSafety = 0.0;
633 longMoveRevisedEnd =
false;
635 G4cout <<
" Difference of move & safety is very small in magnitude, "
636 << absMoveMinusSafety <<
G4endl;
639 G4cout <<
" ratio to safety " << revisedSafety
640 <<
" is " << absMoveMinusSafety / revisedSafety
641 <<
"smaller than " << kRadTolerance <<
" of safety ";
645 G4cout <<
" as fraction " << absMoveMinusSafety / maxCoordPos
646 <<
" of position vector max-coord " << maxCoordPos
647 <<
" smaller than " << cErrorTolerance ;
649 G4cout <<
" -- reset moveMinusSafety to "
650 << moveMinusSafety <<
G4endl;
654 if ( longMoveEnd && longMoveSaf
655 && longMoveRevisedEnd && (moveMinusSafety>0.0) )
657 std::ostringstream message;
658 message.precision(9);
659 message <<
"ReLocation is further than end-safety value." <<
G4endl
660 <<
" Moved from last endpoint by " << moveLenEndPosition
661 <<
" compared to end safety (from preStep point) = "
662 << endPointSafety_Est1 <<
G4endl
669 <<
" --> last EndStep Location was " << lastEndPosition
671 <<
" safety value = " << endPointSafety_Est1
672 <<
" raw-value = " << endPointSafety_raw <<
G4endl
673 <<
" --> Calling again at this endpoint, we get "
674 << revisedSafety <<
" as safety value." <<
G4endl
679 <<
" move from safety location = "
680 << std::sqrt(moveLenSafSq) <<
G4endl
681 <<
" again= " << moveVecSafety.
mag() <<
G4endl
682 <<
" safety - Move-from-end= "
683 << revisedSafety - moveLenEndPosition
684 <<
" (negative is Bad.)" <<
G4endl
685 <<
" Debug: distCheckRevisedEnd = "
686 << distCheckRevisedEnd;
688 G4Exception(
"G4PathFinder::ReLocate",
"GeomNav0003",
696 G4cout <<
" G4PathFinder::ReLocate : entered " <<
G4endl;
701 G4cout <<
" lastEndPosition = " << lastEndPosition
702 <<
" moveVec from step-end = " << moveVecEndPos
713 (*pNavIter)->LocateGlobalPointWithinVolume(
position );
725#ifdef G4DEBUG_PATHFINDER
728 G4cout <<
" G4PathFinder::ReLocate : exiting "
742 std::vector<G4Navigator*>::iterator pNavigatorIter;
748 if( safety < minSafety ) { minSafety = safety; }
755#ifdef G4DEBUG_PATHFINDER
758 G4cout <<
" G4PathFinder::ComputeSafety - returns "
771#ifdef G4DEBUG_PATHFINDER
774 G4cout <<
"G4PathFinder::CreateTouchableHandle : navId = "
783 if( locatedVolume ==
nullptr )
790#ifdef G4DEBUG_PATHFINDER
794 if( locatedVolume ) { VolumeName = locatedVolume->
GetName(); }
795 G4cout <<
" Touchable History created at address " << touchHist
796 <<
"; volume = " << locatedVolume <<
"; name= " << VolumeName
808 std::vector<G4Navigator*>::iterator pNavigatorIter;
812 const G4int IdTransport = 0;
815#ifdef G4DEBUG_PATHFINDER
818 G4cout <<
" G4PathFinder::DoNextLinearStep : entered " <<
G4endl;
819 G4cout <<
" Input field track= " << initialState <<
G4endl;
820 G4cout <<
" Requested step= " << proposedStepLength <<
G4endl;
837 MagShift= std::sqrt(MagSqShift) ;
839#ifdef G4PATHFINDER_OPTIMISATION
851 if( proposedStepLength < fullSafety )
862 minSafety=
std::min( safety, minSafety );
867#ifdef G4DEBUG_PATHFINDER
870 G4cout <<
"G4PathFinder::DoNextLinearStep : Quick Stepping. " <<
G4endl
871 <<
" proposedStepLength " << proposedStepLength
872 <<
" < (full) safety = " << fullSafety
873 <<
" at " << initialPosition
893#ifdef G4PATHFINDER_OPTIMISATION
894 if( proposedStepLength <= safety )
900#ifdef G4DEBUG_PATHFINDER
902 G4cout <<
"PathFinder::ComputeStep> small proposed step = "
903 << proposedStepLength
904 <<
" <= safety = " << safety <<
" for nav " << num
905 <<
" Step fully taken. " <<
G4endl;
911#ifdef G4DEBUG_PATHFINDER
914 step = (*pNavigatorIter)->ComputeStep( initialPosition,
921#ifdef G4DEBUG_PATHFINDER
925 G4cout <<
"PathFinder::ComputeStep> long proposed step = "
926 << proposedStepLength
927 <<
" > safety = " << previousSafety
928 <<
" for nav " << num
929 <<
" . New safety = " << safety <<
" step= " << step
947 minSafety =
std::min( safety, minSafety );
949#ifdef G4DEBUG_PATHFINDER
952 G4cout <<
"G4PathFinder::DoNextLinearStep : Navigator ["
953 << num <<
"] -- step size " << step <<
G4endl;
974 minStep = proposedStepLength;
983 endPosition = initialPosition + minStep * initialDirection ;
985#ifdef G4DEBUG_PATHFINDER
989 G4cout <<
"G4PathFinder::DoNextLinearStep : "
990 <<
" initialPosition = " << initialPosition
991 <<
" and endPosition = " << endPosition<<
G4endl;
992 G4cout.precision(oldPrec);
1013#ifdef G4DEBUG_PATHFINDER
1016 G4cout <<
" G4PathFinder::DoNextLinearStep : exits returning "
1030 G4int num = -1, last = -1;
1031 G4int noLimited = 0;
1034 const G4int IdTransport = 0;
1041 if( transportLimited )
1069 if( (last > -1) && (noLimited == 1 ) )
1074#ifdef G4DEBUG_PATHFINDER
1080 G4cout <<
" G4PathFinder::WhichLimited - exiting. " <<
G4endl;
1090 G4cout <<
"G4PathFinder::PrintLimited reports: " ;
1096 G4cout << std::setw(5) <<
" Step#" <<
" "
1097 << std::setw(5) <<
" NavId" <<
" "
1098 << std::setw(12) <<
" step-size " <<
" "
1099 << std::setw(12) <<
" raw-size " <<
" "
1100 << std::setw(12) <<
" pre-safety " <<
" "
1101 << std::setw(15) <<
" Limited / flag" <<
" "
1102 << std::setw(15) <<
" World " <<
" "
1116 << std::setw(5) << num <<
" "
1117 << std::setw(12) << stepLen <<
" "
1118 << std::setw(12) << rawStep <<
" "
1120 << std::setw(5) << (
fLimitTruth[num] ?
"YES" :
" NO") <<
" ";
1122 G4cout <<
" " << std::setw(15) << limitedStr <<
" ";
1123 G4cout.precision(oldPrec);
1127 if (pNav !=
nullptr)
1132 WorldName = pWorld->
GetName();
1135 G4cout <<
" " << WorldName ;
1141 G4cout <<
" G4PathFinder::PrintLimited - exiting. " <<
G4endl;
1150 const G4double toleratedRelativeError = 1.0e-10;
1164#ifdef G4DEBUG_PATHFINDER
1168 G4cout <<
" G4PathFinder::DoNextCurvedStep ****** " <<
G4endl;
1169 G4cout <<
" Initial value of field track is " << fieldTrack
1170 <<
" and proposed step= " << proposedStepLength <<
G4endl;
1186 minSafety =
std::min( safety, minSafety );
1202 pCurrentPhysicalVolume,
1227#ifdef G4DEBUG_PATHFINDER
1230 G4cout <<
"G4PathFinder::DoNextCurvedStep : " <<
G4endl
1231 <<
" initialState = " << initialState <<
G4endl
1233 G4cout <<
"G4PathFinder::DoNextCurvedStep : "
1234 <<
" minStep = " << minStep
1235 <<
" proposedStepLength " << proposedStepLength
1236 <<
" safety = " << newSafety <<
G4endl;
1240 if( minStep < proposedStepLength )
1245 G4int noLimited = 0;
1248 G4double finalStep, lastPreSafety = 0.0, minStepLast;
1253 minStepLast, didLimit );
1262 diffStep = (finalStep-minStepLast);
1263 if ( std::abs(diffStep) <= toleratedRelativeError * finalStep )
1267 currentStepSize += diffStep;
1284 if( limited ) { ++noLimited; }
1286#ifdef G4DEBUG_PATHFINDER
1287 G4bool StepError = (currentStepSize < 0)
1288 || ( (minStepLast !=
kInfinity) && (diffStep < 0) ) ;
1293 G4cout <<
" G4PathFinder::ComputeStep. Geometry " << numNav
1295 <<
" from final-step= " << finalStep
1297 <<
" minStepLast= " << minStepLast
1298 <<
" limited = " << (
fLimitTruth[numNav] ?
"YES" :
" NO")
1300 G4cout <<
" status = " << limitedString <<
" #= " << didLimit
1305 std::ostringstream message;
1306 message <<
"Incorrect calculation of step size for one navigator"
1308 <<
" currentStepSize = " << currentStepSize
1309 <<
", diffStep= " << diffStep <<
G4endl
1310 <<
"ERROR in computing step size for this navigator.";
1320 else if ( (minStep == proposedStepLength)
1322 || ( std::abs(minStep-proposedStepLength)
1323 < toleratedRelativeError * proposedStepLength ) )
1332 currentStepSize = minStep;
1344 std::ostringstream message;
1345 message <<
"Incorrect calculation of step size for one navigator." <<
G4endl
1346 <<
" currentStepSize = " << minStep <<
" is larger than "
1347 <<
" proposed StepSize = " << proposedStepLength <<
".";
1352#ifdef G4DEBUG_PATHFINDER
1355 G4cout <<
" Exiting G4PathFinder::DoNextCurvedStep " <<
G4endl;
1367 StrUnique(
"Unique"),
1368 StrUndefined(
"Undefined"),
1369 StrSharedTransport(
"SharedTransport"),
1370 StrSharedOther(
"SharedOther");
1375 case kDoNot: limitedStr = &StrDoNot;
break;
1376 case kUnique: limitedStr = &StrUnique;
break;
1378 case kSharedOther: limitedStr = &StrSharedOther;
break;
1379 default: limitedStr = &StrUndefined;
break;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
static constexpr double mm
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4GLOB_DLL std::ostream G4cout
virtual void SetChargeMomentumMass(G4ChargeState particleCharge, G4double MomentumXc, G4double MassXc2)=0
const G4Field * GetDetectorField() const
void SetProperTimeOfFlight(G4double tofProper)
const G4ChargeState * GetChargeState() const
G4ThreeVector GetMomentumDirection() const
G4double GetCharge() const
G4ThreeVector GetPosition() const
void SetPosition(G4ThreeVector nPos)
G4double GetRestMass() const
G4ThreeVector GetMomentum() const
G4double GetSurfaceTolerance() const
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, G4double &minStepLast, ELimited &limitedStep)
G4TouchableHistory * CreateTouchableHistory() const
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4VPhysicalVolume * GetWorldVolume() const
G4double ComputeSafety(const G4ThreeVector &globalPoint)
void EnableParallelNavigation(G4bool enableChoice=true)
G4ThreeVector fPreSafetyLocation
G4Navigator * GetNavigator(G4int n) const
void ReLocate(const G4ThreeVector &position)
G4bool fLimitTruth[fMaxNav]
static G4ThreadLocal G4PathFinder * fpPathFinder
void ReportMove(const G4ThreeVector &OldV, const G4ThreeVector &NewV, const G4String &Quantity) const
G4ThreeVector fPreStepLocation
static const G4int fMaxNav
G4Navigator * fpNavigator[fMaxNav]
G4double DoNextLinearStep(const G4FieldTrack &FieldTrack, G4double proposedStepLength)
G4double fCurrentStepSize[fMaxNav]
G4double fPreSafetyMinValue
void PushPostSafetyToPreSafety()
G4int fNoGeometriesLimiting
G4double fPreSafetyValues[fMaxNav]
G4double fMinSafety_PreStepPt
G4double fNewSafetyComputed[fMaxNav]
G4double ComputeStep(const G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4int navigatorId, G4int stepNo, G4double &pNewSafety, ELimited &limitedStep, G4FieldTrack &EndState, G4VPhysicalVolume *currentVolume)
G4double DoNextCurvedStep(const G4FieldTrack &FieldTrack, G4double proposedStepLength, G4VPhysicalVolume *pCurrentPhysVolume)
G4TransportationManager * fpTransportManager
void Locate(const G4ThreeVector &position, const G4ThreeVector &direction, G4bool relativeSearch=true)
G4bool fFieldExertedForce
G4ThreeVector fLastLocatedPosition
G4ThreeVector fSafetyLocation
G4String & LimitedString(ELimited lim)
G4double fMinSafety_atSafLocation
G4VPhysicalVolume * fLocatedVolume[fMaxNav]
ELimited fLimitedStep[fMaxNav]
G4double fCurrentPreStepSafety[fMaxNav]
void PrepareNewTrack(const G4ThreeVector &position, const G4ThreeVector &direction, G4VPhysicalVolume *massStartVol=nullptr)
G4int fNoActiveNavigators
G4bool fPreStepCenterRenewed
G4MultiNavigator * fpMultiNavigator
static G4PathFinder * GetInstance()
G4TouchableHandle CreateTouchableHandle(G4int navId) const
static G4PathFinder * GetInstanceIfExist()
G4PropagatorInField * fpFieldPropagator
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
void SetNavigatorForPropagating(G4Navigator *SimpleOrMultiNavigator)
G4EquationOfMotion * GetCurrentEquationOfMotion()
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=nullptr, G4bool canRelaxDeltaChord=false)
void EnableParallelNavigation(G4bool parallel)
void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=nullptr)
const G4NavigationHistory * GetHistory() const
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
static G4TransportationManager * GetTransportationManager()
G4PropagatorInField * GetPropagatorInField() const
G4SafetyHelper * GetSafetyHelper() const
G4Navigator * GetNavigatorForTracking() const
const G4String & GetName() const
static const G4double kInfinity
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments