48static const G4double kToleranceNormalCheck = CLHEP::perThousand;
65 G4cout <<
" G4Navigator parameters: Action Threshold (No Zero Steps) = "
66 << fActionThreshold_NoZeroSteps
67 <<
" Abandon Threshold (No Zero Steps) = "
68 << fAbandonThreshold_NoZeroSteps <<
G4endl;
74 fregularNav.SetNormalNavigation( &fnormalNav );
82 fpSafetyCalculator->SetExternalNavigation(fpExternalNav);
94 delete fpSafetyCalculator;
109 fLastTriedStepComputation =
false;
134 const G4bool relativeSearch,
135 const G4bool ignoreDirection )
137 G4bool notKnownContained =
true, noResult;
144 G4bool considerDirection = (pGlobalDirection !=
nullptr) && ((!ignoreDirection) || fLocatedOnEdge);
146 fLastTriedStepComputation =
false;
147 fChangedGrandMotherRefFrame =
false;
149 if( considerDirection )
151 globalDirection=*pGlobalDirection;
158 G4cout <<
"*** G4Navigator::LocateGlobalPointAndSetup: ***" <<
G4endl;
160 <<
" Globalpoint = " << globalPoint <<
G4endl
161 <<
" RelativeSearch = " << relativeSearch <<
G4endl;
167 G4cout.precision(oldcoutPrec);
171 G4int noLevelsExited = 0;
173 if ( !relativeSearch )
190 fBlockedPhysicalVolume =
fHistory.GetTopVolume();
191 fBlockedReplicaNo =
fHistory.GetTopReplicaNo();
196 fLastLocatedPointLocal = localPoint;
197 fLocatedOutsideWorld =
true;
198 fBlockedPhysicalVolume =
nullptr;
199 fBlockedReplicaNo = -1;
228 fBlockedPhysicalVolume->GetCopyNo());
231 freplicaNav.ComputeTransformation(fBlockedReplicaNo,
232 fBlockedPhysicalVolume);
235 fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
238 if( fBlockedPhysicalVolume->GetRegularStructureId() == 0 )
243 pParam = fBlockedPhysicalVolume->GetParameterisation();
245 fBlockedPhysicalVolume);
247 fBlockedPhysicalVolume);
249 fBlockedPhysicalVolume);
252 fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
257 pLogical = fBlockedPhysicalVolume->GetLogicalVolume();
260 ComputeMaterial(fBlockedReplicaNo,
261 fBlockedPhysicalVolume,
266 G4Exception(
"G4Navigator::LocateGlobalPointAndSetup()",
268 "Extra levels not applicable for external volumes.");
272 fBlockedPhysicalVolume =
nullptr;
273 localPoint =
fHistory.GetTopTransform().TransformPoint(globalPoint);
274 notKnownContained =
false;
279 fBlockedPhysicalVolume =
nullptr;
296 while (notKnownContained)
301 targetSolid =
fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
302 localPoint =
fHistory.GetTopTransform().TransformPoint(globalPoint);
303 insideCode = targetSolid->
Inside(localPoint);
307 G4String solidResponse =
"-kInside-";
310 solidResponse =
"-kOutside-";
314 solidResponse =
"-kSurface-";
316 G4cout <<
"*** G4Navigator::LocateGlobalPointAndSetup(): ***" <<
G4endl
317 <<
" Invoked Inside() for solid: " << targetSolid->
GetName()
318 <<
". Solid replied: " << solidResponse <<
G4endl
319 <<
" For local point p: " << localPoint <<
G4endl;
327 insideCode = freplicaNav.BackLocate(
fHistory, globalPoint, localPoint,
328 fExiting, notKnownContained);
336 targetSolid =
fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
337 localPoint =
fHistory.GetTopTransform().TransformPoint(globalPoint);
339 fHistory.GetTopTransform().TransformAxis(globalDirection);
340 insideCode = fpExternalNav->Inside(targetSolid, localPoint, localDirection);
345 if ( insideCode ==
kInside ) {
break; }
355 fLocatedOutsideWorld =
true;
356 fLastLocatedPointLocal = localPoint;
360 fBlockedPhysicalVolume =
fHistory.GetTopVolume();
361 fBlockedReplicaNo =
fHistory.GetTopReplicaNo();
365 if( noLevelsExited > 1 )
369 if(
const auto *mRot = fBlockedPhysicalVolume->GetRotation())
371 fGrandMotherExitNormal *= (*mRot).inverse();
372 fChangedGrandMotherRefFrame =
true;
379 G4bool isExiting = fExiting;
380 if( (!fExiting) && considerDirection )
385 G4bool directionExiting =
false;
387 fHistory.GetTopTransform().TransformAxis(globalDirection);
392 localPoint=
fHistory.GetTopTransform().TransformPoint(globalPoint);
396 directionExiting = normal.
dot(localDirection) > 0.0;
397 isExiting = isExiting || directionExiting;
402 if ( !isExiting ) {
break; }
409 fLocatedOutsideWorld =
true;
410 fLastLocatedPointLocal = localPoint;
415 fValidExitNormal =
false;
416 fBlockedPhysicalVolume =
fHistory.GetTopVolume();
417 fBlockedReplicaNo =
fHistory.GetTopReplicaNo();
420 if( noLevelsExited > 1 )
425 fBlockedPhysicalVolume->GetRotation();
426 if( mRot !=
nullptr )
428 fGrandMotherExitNormal *= (*mRot).inverse();
429 fChangedGrandMotherRefFrame =
true;
450 targetPhysical =
fHistory.GetTopVolume();
451 if (targetPhysical ==
nullptr) {
break; }
459 fBlockedPhysicalVolume,
468 noResult = fnormalNav.LevelLocate(
fHistory,
469 fBlockedPhysicalVolume,
478 noResult = freplicaNav.LevelLocate(
fHistory,
479 fBlockedPhysicalVolume,
489 noResult = fparamNav.LevelLocate(
fHistory,
490 fBlockedPhysicalVolume,
499 noResult = fregularNav.LevelLocate(
fHistory,
500 fBlockedPhysicalVolume,
509 noResult = fpExternalNav->LevelLocate(
fHistory,
510 fBlockedPhysicalVolume,
528 fBlockedPhysicalVolume =
nullptr;
529 fBlockedReplicaNo = -1;
541 if( mRot !=
nullptr )
546 fGrandMotherExitNormal *= (*mRot);
547 fChangedGrandMotherRefFrame=
true;
551#ifdef G4DEBUG_NAVIGATION
555 G4cout <<
"*** G4Navigator::LocateGlobalPointAndSetup() ***" <<
G4endl;
563 fLastLocatedPointLocal = localPoint;
570 if (targetPhysical !=
nullptr) { curPhysVol_Name = targetPhysical->
GetName(); }
571 G4cout <<
" Return value = new volume = " << curPhysVol_Name <<
G4endl;
576 G4cout <<
"Upon exiting LocateGlobalPointAndSetup():" <<
G4endl;
579 G4cout.precision(oldcoutPrec);
583 fLocatedOutsideWorld =
false;
585 return targetPhysical;
604#ifdef G4DEBUG_NAVIGATION
611 fLastTriedStepComputation =
false;
612 fChangedGrandMotherRefFrame =
false;
629 fparamNav.RelocateWithinVolume( motherPhysical, fLastLocatedPointLocal );
635 fpExternalNav->RelocateWithinVolume( motherPhysical,
636 fLastLocatedPointLocal );
645 fBlockedPhysicalVolume =
nullptr;
646 fBlockedReplicaNo = -1;
669 fSaveState.sExitNormal = fExitNormal;
670 fSaveState.sValidExitNormal = fValidExitNormal;
671 fSaveState.sExiting = fExiting;
672 fSaveState.sEntering = fEntering;
674 fSaveState.spBlockedPhysicalVolume = fBlockedPhysicalVolume;
675 fSaveState.sBlockedReplicaNo = fBlockedReplicaNo;
677 fSaveState.sLastStepWasZero =
static_cast<G4int>(fLastStepWasZero);
679 fSaveState.sLocatedOutsideWorld = fLocatedOutsideWorld;
680 fSaveState.sLastLocatedPointLocal = fLastLocatedPointLocal;
687 fSaveState.sPreviousSftOrigin = fPreviousSftOrigin;
688 fSaveState.sPreviousSafety = fPreviousSafety;
699 fExitNormal = fSaveState.sExitNormal;
700 fValidExitNormal = fSaveState.sValidExitNormal;
701 fExiting = fSaveState.sExiting;
702 fEntering = fSaveState.sEntering;
704 fBlockedPhysicalVolume = fSaveState.spBlockedPhysicalVolume;
705 fBlockedReplicaNo = fSaveState.sBlockedReplicaNo;
707 fLastStepWasZero = (fSaveState.sLastStepWasZero != 0);
709 fLocatedOutsideWorld = fSaveState.sLocatedOutsideWorld;
710 fLastLocatedPointLocal = fSaveState.sLastLocatedPointLocal;
716 fPreviousSftOrigin = fSaveState.sPreviousSftOrigin;
717 fPreviousSafety = fSaveState.sPreviousSafety;
753 const G4double pCurrentProposedStepLength,
756#ifdef G4DEBUG_NAVIGATION
770 fChangedGrandMotherRefFrame =
false;
773 fCalculatedExitNormal =
false;
779 G4cout <<
"*** G4Navigator::ComputeStep: ***" <<
G4endl;
781 <<
" - Proposed step length = " << pCurrentProposedStepLength
783#ifdef G4DEBUG_NAVIGATION
787 <<
" Globalpoint = " << std::setw(25) << pGlobalpoint <<
G4endl
788 <<
" Direction = " << std::setw(25) << pDirection <<
G4endl;
801 if( newLocalPoint != fLastLocatedPointLocal )
806 G4double moveLenSq = (newLocalPoint-oldLocalPoint).mag2();
808 if ( moveLenSq >=
fSqTol )
811 ComputeStepLog(pGlobalpoint, moveLenSq);
827 pCurrentProposedStepLength,
834 &fBlockedPhysicalVolume,
842 Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
844 pCurrentProposedStepLength,
851 &fBlockedPhysicalVolume,
867 if(
fHistory.GetTopVolume()->GetRegularStructureId() == 0 )
871 "Point is relocated in voxels, while it should be outside!");
872 Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
874 pCurrentProposedStepLength,
881 &fBlockedPhysicalVolume,
887 ComputeStepSkippingEqualMaterials(fLastLocatedPointLocal,
889 pCurrentProposedStepLength,
896 &fBlockedPhysicalVolume,
906 Step = fparamNav.ComputeStep(fLastLocatedPointLocal,
908 pCurrentProposedStepLength,
915 &fBlockedPhysicalVolume,
920 Step = fregularNav.ComputeStep(fLastLocatedPointLocal,
922 pCurrentProposedStepLength,
929 &fBlockedPhysicalVolume,
934 G4Exception(
"G4Navigator::ComputeStep()",
"GeomNav0001",
938 Step = fpExternalNav->ComputeStep(fLastLocatedPointLocal,
940 pCurrentProposedStepLength,
947 &fBlockedPhysicalVolume,
958 Step = freplicaNav.ComputeStep(pGlobalpoint,
960 fLastLocatedPointLocal,
962 pCurrentProposedStepLength,
966 fCalculatedExitNormal,
970 &fBlockedPhysicalVolume,
976 fPreviousSftOrigin = pGlobalpoint;
977 fPreviousSafety = pNewSafety;
989 fLocatedOnEdge = fLastStepWasZero && (Step==0.0);
991 if (fPushed) { fPushed = fLastStepWasZero; }
995 if ( fLastStepWasZero )
999 G4bool act = fNumberZeroSteps >= fActionThreshold_NoZeroSteps;
1000 G4bool actAndReport =
false;
1001 G4bool abandon = fNumberZeroSteps >= fAbandonThreshold_NoZeroSteps;
1004 actAndReport = act && (!fPushed) && fWarnPush;
1006#ifdef G4DEBUG_NAVIGATION
1007 inform = fNumberZeroSteps > 1;
1010 if ( act || inform )
1012 if( act && !abandon )
1020 if( actAndReport || abandon || inform )
1022 std::ostringstream message;
1024 message.precision(16);
1025 message <<
"Stuck Track: potential geometry or navigation problem."
1027 message <<
" Track stuck, not moving for "
1028 << fNumberZeroSteps <<
" steps." <<
G4endl
1029 <<
" Current phys volume: '" << motherPhysical->
GetName()
1031 <<
" - at position : " << pGlobalpoint <<
G4endl
1032 <<
" in direction: " << pDirection <<
G4endl
1033 <<
" (local position: " << newLocalPoint <<
")" <<
G4endl
1034 <<
" (local direction: " << localDirection <<
")." <<
G4endl
1035 <<
" Previous phys volume: '"
1036 << ( fLastMotherPhys !=
nullptr ? fLastMotherPhys->GetName() :
G4String(
"") )
1038 if( actAndReport || abandon )
1040 message <<
" Likely geometry overlap - else navigation problem !"
1049 message <<
" Track *abandoned* due to excessive number of Zero steps."
1051 G4Exception(
"G4Navigator::ComputeStep()",
"GeomNav0003",
1059 message <<
" *** Trying to get *unstuck* using a push"
1060 <<
" - expanding step to " << Step <<
" (mm) ..."
1061 <<
" Potential overlap in geometry !" <<
G4endl;
1062 G4Exception(
"G4Navigator::ComputeStep()",
"GeomNav1002",
1066#ifdef G4DEBUG_NAVIGATION
1069 if( fNumberZeroSteps > 1 )
1071 message <<
", nav-comp-step calls # " << sNavCScalls
1072 <<
", Step= " << Step <<
G4endl;
1083 if (!fPushed) { fNumberZeroSteps = 0; }
1085 fLastMotherPhys = motherPhysical;
1091 + std::min(Step,pCurrentProposedStepLength) * pDirection;
1096#ifdef G4DEBUG_NAVIGATION
1099 G4cout <<
" At G4Nav CompStep End - if(exiting) - fExiting= " << fExiting
1100 <<
" fValidExitNormal = " << fValidExitNormal <<
G4endl;
1105 if ( fValidExitNormal || fCalculatedExitNormal )
1108 fGrandMotherExitNormal = fExitNormal;
1115 + localDirection*Step;
1127 if( mRot !=
nullptr )
1129 fChangedGrandMotherRefFrame =
true;
1130 fGrandMotherExitNormal = (*mRot).inverse() * exitNormalMotherFrame;
1134 fGrandMotherExitNormal = exitNormalMotherFrame;
1142 fCalculatedExitNormal =
false;
1149#ifdef G4DEBUG_NAVIGATION
1152 desc <<
"Problem in ComputeStep: Replica Navigation did not provide"
1153 <<
" valid exit Normal. " <<
G4endl;
1154 desc <<
" Do not know how calculate it in this case." <<
G4endl;
1155 desc <<
" Location = " << finalLocalPoint <<
G4endl;
1156 desc <<
" Volume name = " << motherPhysical->
GetName()
1158 G4Exception(
"G4Navigator::ComputeStep()",
"GeomNav0003",
1159 JustWarning, desc,
"Normal not available for exiting.");
1166 fCalculatedExitNormal =
true;
1171 if( fValidExitNormal || fCalculatedExitNormal )
1176 fExitNormalGlobalFrame =
fHistory.GetTransform(depth-1)
1177 .InverseTransformAxis( fGrandMotherExitNormal );
1181 fExitNormalGlobalFrame = fGrandMotherExitNormal;
1190 if( (Step == pCurrentProposedStepLength) && (!fExiting) && (!fEntering) )
1206 G4cout <<
" Returned step= " << Step;
1208 if( Step == kInfinity )
1210 G4cout <<
" Requested step= " << pCurrentProposedStepLength ;
1217 fLastTriedStepComputation =
true;
1230 const G4double pCurrentProposedStepLength,
1241 pCurrentProposedStepLength,
1266 fLocatedOnEdge =
false;
1267 fLastStepWasZero =
false;
1272 fValidExitNormal =
false;
1273 fChangedGrandMotherRefFrame =
false;
1274 fCalculatedExitNormal =
false;
1281 fPreviousSafety = 0.0;
1283 fNumberZeroSteps = 0;
1285 fBlockedPhysicalVolume =
nullptr;
1286 fBlockedReplicaNo = -1;
1288 fLastLocatedPointLocal =
G4ThreeVector( kInfinity, -kInfinity, 0.0 );
1289 fLocatedOutsideWorld =
false;
1291 fLastMotherPhys =
nullptr;
1305 for (
auto i = 1; i <= depth; ++i )
1307 switch (
fHistory.GetVolumeType(i) )
1313 freplicaNav.ComputeTransformation(
fHistory.GetReplicaNo(i),
fHistory.GetVolume(i));
1343 ComputeMaterial(replicaNo, current, pTouchable) );
1363 if ( fLastTriedStepComputation )
1369 if( fEntering && (fBlockedPhysicalVolume!=
nullptr) )
1371 candidateLogical = fBlockedPhysicalVolume->GetLogicalVolume();
1372 if( candidateLogical !=
nullptr )
1394 currentSolid = candidateLogical->
GetSolid();
1395 inSideIt = currentSolid->
Inside(daughterPointOwnLocal);
1396 onSurface = (inSideIt ==
kSurface);
1401 safety = (currentSolid->
DistanceToIn(daughterPointOwnLocal));
1404 else if (inSideIt ==
kInside )
1406 safety = (currentSolid->
DistanceToOut(daughterPointOwnLocal));
1413 nextSolidExitNormal =
1420 ExitNormal = MotherToDaughterTransform
1422 fCalculatedExitNormal =
true;
1427 if((
fVerbose == 1 ) && ( fCheck ))
1429 std::ostringstream message;
1430 message <<
"Point not on surface ! " <<
G4endl
1432 << daughterPointOwnLocal <<
G4endl
1433 <<
" Physical volume = "
1434 << fBlockedPhysicalVolume->GetName() <<
G4endl
1435 <<
" Logical volume = "
1437 <<
" Solid = " << currentSolid->
GetName()
1440 << *currentSolid <<
G4endl;
1443 message <<
"Point is Outside. " <<
G4endl
1444 <<
" Safety (from outside) = " << safety <<
G4endl;
1448 message <<
"Point is Inside. " <<
G4endl
1449 <<
" Safety (from inside) = " << safety <<
G4endl;
1451 G4Exception(
"G4Navigator::GetLocalExitNormal()",
"GeomNav1001",
1460 else if ( fExiting )
1462 ExitNormal = fGrandMotherExitNormal;
1464 fCalculatedExitNormal =
true;
1471 "Incorrect call to GetLocalSurfaceNormal." );
1480 ExitNormal = -(daughterSolid->
SurfaceNormal(fLastLocatedPointLocal));
1481 if( std::fabs(ExitNormal.
mag2()-1.0 ) > kToleranceNormalCheck )
1484 desc <<
" Parameters of solid: " << *daughterSolid
1485 <<
" Point for surface = " << fLastLocatedPointLocal << std::endl;
1488 "Surface Normal returned by Solid is not a Unit Vector." );
1490 fCalculatedExitNormal =
true;
1497 ExitNormal = fGrandMotherExitNormal;
1499 fCalculatedExitNormal =
true;
1504 fCalculatedExitNormal =
false;
1506 message <<
"Function called when *NOT* at a Boundary." <<
G4endl;
1507 message <<
"Exit Normal not calculated." <<
G4endl;
1524 G4int enteringReplicaNo,
1527 switch (enteringVolumeType)
1532 G4Exception(
"G4Navigator::GetMotherToDaughterTransform()",
1534 "Method NOT Implemented yet for replica volumes.");
1542 pParam->
ComputeSolid(enteringReplicaNo, pEnteringPhysVol);
1582#ifdef G4DEBUG_NAVIGATION
1585 if ( fLastTriedStepComputation )
1590 ExpectedBoundaryPointLocal =
1610 G4bool* pNormalCalculated)
1615 G4bool usingStored = fCalculatedExitNormal && (
1616 ( fLastTriedStepComputation && fExiting )
1618 ( !fLastTriedStepComputation
1628 globalNormal = fExitNormalGlobalFrame;
1630 if( std::fabs ( normMag2 - 1.0 ) < perThousand )
1632 *pNormalCalculated =
true;
1638 message.precision(10);
1639 message <<
" WARNING> Expected normal-global-frame to be valid, "
1640 <<
" i.e. a unit vector!" <<
G4endl
1641 <<
" - but |normal| = " << std::sqrt(normMag2)
1642 <<
" - and |normal|^2 = " << normMag2 <<
G4endl
1643 <<
" which differs from 1.0 by " << normMag2 - 1.0 <<
G4endl
1644 <<
" n = " << fExitNormalGlobalFrame <<
G4endl
1645 <<
" Global point: " << IntersectPointGlobal <<
G4endl
1649 if ( candLog !=
nullptr )
1656 message <<
"============================================================"
1660 message <<
" State of Navigator: " <<
G4endl;
1661 message << *
this <<
G4endl;
1663 message <<
"============================================================"
1668 "Value obtained from stored global-normal is not a unit vector.");
1674 *pNormalCalculated = fCalculatedExitNormal;
1675 globalNormal =
fHistory.GetTopTransform()
1676 .InverseTransformAxis(localNormal);
1682 *pNormalCalculated = fCalculatedExitNormal;
1684#ifdef G4DEBUG_NAVIGATION
1685 usingStored =
false;
1687 if( (!validNormal) && !fCalculatedExitNormal )
1690 edN <<
" Calculated = " << fCalculatedExitNormal <<
G4endl;
1691 edN <<
" Entering= " << fEntering <<
G4endl;
1694 edN <<
" State of Navigator: " <<
G4endl;
1700 "LocalExitNormalAndCheck() did not calculate Normal.");
1705 if( validNormal && (std::fabs(localMag2-1.0)) > kToleranceNormalCheck )
1709 edN <<
"G4Navigator::GetGlobalExitNormal: "
1710 <<
" Using Local Normal - from call to GetLocalExitNormalAndCheck. "
1712 <<
" Local Exit Normal : " <<
" || = " << std::sqrt(localMag2)
1713 <<
" vec = " << localNormal <<
G4endl
1714 <<
" Global Exit Normal : " <<
" || = " << globalNormal.
mag()
1715 <<
" vec = " << globalNormal <<
G4endl
1716 <<
" Global point: " << IntersectPointGlobal <<
G4endl;
1717 edN <<
" Calculated It = " << fCalculatedExitNormal <<
G4endl
1721 if ( candLog !=
nullptr )
1730 "Value obtained from new local *solid* is incorrect.");
1731 localNormal = localNormal.
unit();
1733 globalNormal =
fHistory.GetTopTransform()
1734 .InverseTransformAxis(localNormal);
1737#ifdef G4DEBUG_NAVIGATION
1744 globalNormAgn =
fHistory.GetTopTransform()
1745 .InverseTransformAxis(localNormal);
1748 G4ThreeVector diffNorm = globalNormAgn - fExitNormalGlobalFrame;
1749 if( diffNorm.
mag2() > kToleranceNormalCheck )
1752 edDfn <<
"Found difference in normals in case of exiting mother "
1753 <<
"- when Get is called after ComputingStep " <<
G4endl;
1754 edDfn <<
" Magnitude of diff = " << diffNorm.
mag() <<
G4endl;
1755 edDfn <<
" Normal stored (Global) = " << fExitNormalGlobalFrame
1757 edDfn <<
" Global Computed from Local = " << globalNormAgn <<
G4endl;
1758 G4Exception(
"G4Navigator::GetGlobalExitNormal()",
"GeomNav0003",
1766 fExitNormalGlobalFrame = globalNormal;
1768 return globalNormal;
1791 G4bool onSurface = endpointOnSurface && stayedOnEndpoint;
1794 safety= fpSafetyCalculator->SafetyInCurrentVolume(pGlobalpoint, motherPhysical, pMaxLength);
1799 fPreviousSftOrigin = pGlobalpoint;
1800 fPreviousSafety = safety;
1825 G4cout <<
"The current state of G4Navigator is: " <<
G4endl;
1826 G4cout <<
" ValidExitNormal= " << fValidExitNormal
1827 <<
" ExitNormal = " << fExitNormal
1828 <<
" Exiting = " << fExiting
1829 <<
" Entering = " << fEntering
1830 <<
" BlockedPhysicalVolume= " ;
1831 if (fBlockedPhysicalVolume==
nullptr)
1837 G4cout << fBlockedPhysicalVolume->GetName();
1840 <<
" BlockedReplicaNo = " << fBlockedReplicaNo
1841 <<
" LastStepWasZero = " << fLastStepWasZero
1847 G4cout << std::setw(30) <<
" ExitNormal " <<
" "
1848 << std::setw( 5) <<
" Valid " <<
" "
1849 << std::setw( 9) <<
" Exiting " <<
" "
1850 << std::setw( 9) <<
" Entering" <<
" "
1851 << std::setw(15) <<
" Blocked:Volume " <<
" "
1852 << std::setw( 9) <<
" ReplicaNo" <<
" "
1853 << std::setw( 8) <<
" LastStepZero " <<
" "
1855 G4cout <<
"( " << std::setw(7) << fExitNormal.x()
1856 <<
", " << std::setw(7) << fExitNormal.y()
1857 <<
", " << std::setw(7) << fExitNormal.z() <<
" ) "
1858 << std::setw( 5) << fValidExitNormal <<
" "
1859 << std::setw( 9) << fExiting <<
" "
1860 << std::setw( 9) << fEntering <<
" ";
1861 if ( fBlockedPhysicalVolume ==
nullptr )
1862 {
G4cout << std::setw(15) <<
"None"; }
1864 {
G4cout << std::setw(15)<< fBlockedPhysicalVolume->GetName(); }
1865 G4cout << std::setw( 9) << fBlockedReplicaNo <<
" "
1866 << std::setw( 8) << fLastStepWasZero <<
" "
1872 G4cout <<
" Current Localpoint = " << fLastLocatedPointLocal <<
G4endl;
1873 G4cout <<
" PreviousSftOrigin = " << fPreviousSftOrigin <<
G4endl;
1874 G4cout <<
" PreviousSafety = " << fPreviousSafety <<
G4endl;
1876 G4cout.precision(oldcoutPrec);
1883void G4Navigator::ComputeStepLog(
const G4ThreeVector& pGlobalpoint,
1905 G4double shiftOrigin = std::sqrt(shiftOriginSafSq);
1908 if( diffShiftSaf > fAccuracyForWarning )
1912 std::ostringstream message, suggestion;
1913 message <<
"Accuracy error or slightly inaccurate position shift."
1915 <<
" The Step's starting point has moved "
1916 << std::sqrt(moveLenSq)/mm <<
" mm " <<
G4endl
1917 <<
" since the last call to a Locate method." <<
G4endl
1918 <<
" This has resulted in moving "
1919 << shiftOrigin/mm <<
" mm "
1920 <<
" from the last point at which the safety "
1921 <<
" was calculated " <<
G4endl
1922 <<
" which is more than the computed safety= "
1924 <<
" This difference is "
1925 << diffShiftSaf/mm <<
" mm." <<
G4endl
1926 <<
" The tolerated accuracy is "
1927 << fAccuracyForException/mm <<
" mm.";
1931 if( ((++warnNow % 100) == 1) )
1934 <<
" This problem can be due to either " <<
G4endl
1935 <<
" - a process that has proposed a displacement"
1936 <<
" larger than the current safety , or" <<
G4endl
1937 <<
" - inaccuracy in the computation of the safety";
1938 suggestion <<
"We suggest that you " <<
G4endl
1939 <<
" - find i) what particle is being tracked, and "
1940 <<
" ii) through what part of your geometry " <<
G4endl
1941 <<
" for example by re-running this event with "
1943 <<
" /tracking/verbose 1 " <<
G4endl
1944 <<
" - check which processes you declare for"
1945 <<
" this particle (and look at non-standard ones)"
1947 <<
" - in case, create a detailed logfile"
1948 <<
" of this event using:" <<
G4endl
1949 <<
" /tracking/verbose 6 ";
1953 message, G4String(suggestion.str()));
1954 G4cout.precision(oldcoutPrec);
1955 G4cerr.precision(oldcerrPrec);
1957#ifdef G4DEBUG_NAVIGATION
1960 G4cerr <<
"WARNING - G4Navigator::ComputeStep()" <<
G4endl
1961 <<
" The Step's starting point has moved "
1962 << std::sqrt(moveLenSq) <<
"," <<
G4endl
1963 <<
" which has taken it to the limit of"
1964 <<
" the current safety. " <<
G4endl;
1968 G4double safetyPlus = fPreviousSafety + fAccuracyForException;
1969 if ( shiftOriginSafSq >
sqr(safetyPlus) )
1971 std::ostringstream message;
1972 message <<
"May lead to a crash or unreliable results." <<
G4endl
1973 <<
" Position has shifted considerably without"
1974 <<
" notifying the navigator !" <<
G4endl
1975 <<
" Tolerated safety: " << safetyPlus <<
G4endl
1976 <<
" Computed shift : " << shiftOriginSafSq;
1977 G4Exception(
"G4Navigator::ComputeStep()",
"GeomNav1002",
1990 G4bool foundOverlap =
false;
1991 G4int nPoints = 300000, ntrials = 9, numOverlaps = 5;
1992 G4double trialLength = 1.0 * CLHEP::centimeter;
1993 while ( ntrials-- > 0 && !foundOverlap )
1997 G4cout <<
" ** Running overlap checks in volume "
1999 <<
" with length = " << trialLength <<
G4endl;
2004 if ( trialLength <= 1.0e-5 ) { numOverlaps= 1;}
2006 return foundOverlap;
2021 G4long oldcoutPrec = os.precision(4);
2022 if( n.fVerbose >= 4 )
2024 os <<
"The current state of G4Navigator is: " <<
G4endl;
2025 os <<
" ValidExitNormal= " << n.fValidExitNormal <<
G4endl
2026 <<
" ExitNormal = " << n.fExitNormal <<
G4endl
2027 <<
" Exiting = " << n.fExiting <<
G4endl
2028 <<
" Entering = " << n.fEntering <<
G4endl
2029 <<
" BlockedPhysicalVolume= " ;
2030 if (n.fBlockedPhysicalVolume==
nullptr)
2036 os << n.fBlockedPhysicalVolume->GetName();
2039 <<
" BlockedReplicaNo = " << n.fBlockedReplicaNo <<
G4endl
2040 <<
" LastStepWasZero = " << n.fLastStepWasZero <<
G4endl
2043 if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )
2046 os << std::setw(30) <<
" ExitNormal " <<
" "
2047 << std::setw( 5) <<
" Valid " <<
" "
2048 << std::setw( 9) <<
" Exiting " <<
" "
2049 << std::setw( 9) <<
" Entering" <<
" "
2050 << std::setw(15) <<
" Blocked:Volume " <<
" "
2051 << std::setw( 9) <<
" ReplicaNo" <<
" "
2052 << std::setw( 8) <<
" LastStepZero " <<
" "
2054 os <<
"( " << std::setw(7) << n.fExitNormal.x()
2055 <<
", " << std::setw(7) << n.fExitNormal.y()
2056 <<
", " << std::setw(7) << n.fExitNormal.z() <<
" ) "
2057 << std::setw( 5) << n.fValidExitNormal <<
" "
2058 << std::setw( 9) << n.fExiting <<
" "
2059 << std::setw( 9) << n.fEntering <<
" ";
2060 if ( n.fBlockedPhysicalVolume==
nullptr )
2061 { os << std::setw(15) <<
"None"; }
2063 { os << std::setw(15)<< n.fBlockedPhysicalVolume->GetName(); }
2064 os << std::setw( 9) << n.fBlockedReplicaNo <<
" "
2065 << std::setw( 8) << n.fLastStepWasZero <<
" "
2068 if( n.fVerbose > 2 )
2071 os <<
" Current Localpoint = " << n.fLastLocatedPointLocal <<
G4endl;
2072 os <<
" PreviousSftOrigin = " << n.fPreviousSftOrigin <<
G4endl;
2073 os <<
" PreviousSafety = " << n.fPreviousSafety <<
G4endl;
2075 if( n.fVerbose > 3 || n.fVerbose == 0 )
2077 os <<
"Current History: " <<
G4endl << n.fHistory;
2080 os.precision(oldcoutPrec);
2091 fpvoxelNav = voxelNav;
2101 G4bool zeroStep = ( lastStep == 0.0 );
2102 fLocatedOnEdge = fLastStepWasZero && zeroStep;
2103 fLastStepWasZero = zeroStep;
2105 fExiting = exitsMotherVol;
2106 fEntering = entersDaughtVol;
2115 fpExternalNav = externalNav;
2116 fpSafetyCalculator->SetExternalNavigation(externalNav);
const G4double kCarTolerance
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4DEBUG_NAVIGATION
#define fLastLocatedPointLocal
#define fPreviousSftOrigin
std::ostream & operator<<(std::ostream &os, const G4Navigator &n)
EVolume VolumeType() const override
CLHEP::HepRotation G4RotationMatrix
CLHEP::Hep3Vector G4ThreeVector
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4TouchableHandle is a type providing reference counting mechanism for any kind of touchable objects....
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4LogicalVolume represents a leaf node or unpositioned subtree in the geometry hierarchy....
G4VSolid * GetSolid() const
const G4String & GetName() const
void SetSolid(G4VSolid *pSolid)
G4SmartVoxelHeader * GetVoxelHeader() const
void UpdateMaterial(G4Material *pMaterial)
void SetVerboseLevel(G4int level)
virtual void SetupHierarchy()
G4TouchableHistory * CreateTouchableHistory() const
G4ThreeVector fStepEndPoint
void SetExternalNavigation(G4VExternalNavigation *externalNav)
G4int GetVerboseLevel() const
virtual void ResetState()
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &rGlobP) const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
G4ThreeVector fLastStepEndPointLocal
G4bool fWasLimitedByGeometry
G4VoxelNavigation & GetVoxelNavigator()
G4bool CheckOverlapsIterative(G4VPhysicalVolume *vol)
EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
void SetVoxelNavigation(G4VoxelNavigation *voxelNav)
G4ThreeVector ComputeLocalAxis(const G4ThreeVector &pVec) const
virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &point, G4bool *valid)
virtual G4ThreeVector GetLocalExitNormal(G4bool *valid)
void InformLastStep(G4double lastStep, G4bool entersDaughtVol, G4bool exitsMotherVol)
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
G4AffineTransform GetMotherToDaughterTransform(G4VPhysicalVolume *dVolume, G4int dReplicaNo, EVolume dVolumeType)
void ResetStackAndState()
G4bool EnteredDaughterVolume() const
G4double CheckNextStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
G4int GetDaughtersRegularStructureId(const G4LogicalVolume *pLv) const
G4NavigationHistory fHistory
virtual G4TouchableHandle CreateTouchableHistoryHandle() const
const G4AffineTransform & GetGlobalToLocalTransform() const
G4SafetyCalculator is a class that provides an estimate of the isotropic safety (the minimum distance...
G4TouchableHistory is an object representing a touchable detector element, and its history in the geo...
const G4NavigationHistory * GetHistory() const
G4int MoveUpHistory(G4int num_levels=1)
G4VExternalNavigation is a pure virtual class to be specialised by the user for tracking with an exte...
G4VPVParameterisation ia an abstract base class for Parameterisation, able to compute the transformat...
virtual void ComputeTransformation(const G4int no, G4VPhysicalVolume *pv) const =0
virtual G4VSolid * ComputeSolid(const G4int no, G4VPhysicalVolume *pv)
virtual G4bool IsNested() const
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
virtual G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true, G4int errMax=1)
G4LogicalVolume * GetLogicalVolume() const
virtual G4int GetCopyNo() const =0
const G4String & GetName() const
virtual G4int GetRegularStructureId() const =0
virtual G4VPVParameterisation * GetParameterisation() const =0
G4VSolid is an abstract base class for solids, physical shapes that can be tracked through....
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
virtual G4GeometryType GetEntityType() const =0
G4VoxelNavigation is a concrete utility class for navigation in volumes containing only G4PVPlacement...
G4double ComputeStep(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) override
void RelocateWithinVolume(G4VPhysicalVolume *motherPhysical, const G4ThreeVector &localPoint) override
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) override
G4VoxelSafety is an utility class for the handling isotropic safety in volumes containing only G4PVPl...