Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Navigator Class Reference

#include <G4Navigator.hh>

+ Inheritance diagram for G4Navigator:

Public Member Functions

 G4Navigator ()
 
 G4Navigator (const G4Navigator &)=delete
 
G4Navigatoroperator= (const G4Navigator &)=delete
 
virtual ~G4Navigator ()
 
virtual G4double ComputeStep (const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
 
G4double CheckNextStep (const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
 
virtual G4VPhysicalVolumeResetHierarchyAndLocate (const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
 
virtual G4VPhysicalVolumeLocateGlobalPointAndSetup (const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
 
virtual void LocateGlobalPointWithinVolume (const G4ThreeVector &position)
 
void LocateGlobalPointAndUpdateTouchableHandle (const G4ThreeVector &position, const G4ThreeVector &direction, G4TouchableHandle &oldTouchableToUpdate, const G4bool RelativeSearch=true)
 
void LocateGlobalPointAndUpdateTouchable (const G4ThreeVector &position, const G4ThreeVector &direction, G4VTouchable *touchableToUpdate, const G4bool RelativeSearch=true)
 
void LocateGlobalPointAndUpdateTouchable (const G4ThreeVector &position, G4VTouchable *touchableToUpdate, const G4bool RelativeSearch=true)
 
void SetGeometricallyLimitedStep ()
 
virtual G4double ComputeSafety (const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
 
G4VPhysicalVolumeGetWorldVolume () const
 
void SetWorldVolume (G4VPhysicalVolume *pWorld)
 
G4TouchableHistoryCreateTouchableHistory () const
 
G4TouchableHistoryCreateTouchableHistory (const G4NavigationHistory *) const
 
virtual G4TouchableHandle CreateTouchableHistoryHandle () const
 
virtual G4ThreeVector GetLocalExitNormal (G4bool *valid)
 
virtual G4ThreeVector GetLocalExitNormalAndCheck (const G4ThreeVector &point, G4bool *valid)
 
virtual G4ThreeVector GetGlobalExitNormal (const G4ThreeVector &point, G4bool *valid)
 
G4int GetVerboseLevel () const
 
void SetVerboseLevel (G4int level)
 
G4bool IsActive () const
 
void Activate (G4bool flag)
 
G4bool EnteredDaughterVolume () const
 
G4bool ExitedMotherVolume () const
 
void CheckMode (G4bool mode)
 
G4bool IsCheckModeActive () const
 
void SetPushVerbosity (G4bool mode)
 
void PrintState () const
 
const G4AffineTransformGetGlobalToLocalTransform () const
 
const G4AffineTransform GetLocalToGlobalTransform () const
 
G4AffineTransform GetMotherToDaughterTransform (G4VPhysicalVolume *dVolume, G4int dReplicaNo, EVolume dVolumeType)
 
void ResetStackAndState ()
 
G4int SeverityOfZeroStepping (G4int *noZeroSteps) const
 
G4ThreeVector GetCurrentLocalCoordinate () const
 
G4ThreeVector NetTranslation () const
 
G4RotationMatrix NetRotation () const
 
void EnableBestSafety (G4bool value=false)
 
G4VExternalNavigationGetExternalNavigation () const
 
void SetExternalNavigation (G4VExternalNavigation *externalNav)
 
G4VoxelNavigationGetVoxelNavigator ()
 
void SetVoxelNavigation (G4VoxelNavigation *voxelNav)
 
G4NavigatorClone () const
 
G4ThreeVector GetLastStepEndPoint () const
 
void InformLastStep (G4double lastStep, G4bool entersDaughtVol, G4bool exitsMotherVol)
 

Protected Member Functions

void SetSavedState ()
 
void RestoreSavedState ()
 
virtual void ResetState ()
 
G4ThreeVector ComputeLocalPoint (const G4ThreeVector &rGlobPoint) const
 
G4ThreeVector ComputeLocalAxis (const G4ThreeVector &pVec) const
 
EVolume VolumeType (const G4VPhysicalVolume *pVol) const
 
EVolume CharacteriseDaughters (const G4LogicalVolume *pLog) const
 
G4int GetDaughtersRegularStructureId (const G4LogicalVolume *pLv) const
 
virtual void SetupHierarchy ()
 
G4bool CheckOverlapsIterative (G4VPhysicalVolume *vol)
 

Protected Attributes

G4double kCarTolerance
 
G4double fMinStep
 
G4double fSqTol
 
G4NavigationHistory fHistory
 
G4ThreeVector fStepEndPoint
 
G4ThreeVector fLastStepEndPointLocal
 
G4int fVerbose = 0
 
G4bool fEnteredDaughter
 
G4bool fExitedMother
 
G4bool fWasLimitedByGeometry = false
 

Friends

std::ostream & operator<< (std::ostream &os, const G4Navigator &n)
 

Detailed Description

Definition at line 66 of file G4Navigator.hh.

Constructor & Destructor Documentation

◆ G4Navigator() [1/2]

G4Navigator::G4Navigator ( )

Definition at line 54 of file G4Navigator.cc.

55{
57 // Initialises also all
58 // - exit / entry flags
59 // - flags & variables for exit normals
60 // - zero step counters
61 // - blocked volume
62
63 if( fVerbose > 2 )
64 {
65 G4cout << " G4Navigator parameters: Action Threshold (No Zero Steps) = "
66 << fActionThreshold_NoZeroSteps
67 << " Abandon Threshold (No Zero Steps) = "
68 << fAbandonThreshold_NoZeroSteps << G4endl;
69 }
73
74 fregularNav.SetNormalNavigation( &fnormalNav );
75
76 fStepEndPoint = G4ThreeVector( kInfinity, kInfinity, kInfinity );
77 fLastStepEndPointLocal = G4ThreeVector( kInfinity, kInfinity, kInfinity );
78
79 fpVoxelSafety = new G4VoxelSafety();
80 fpvoxelNav = new G4VoxelNavigation();
81 fpSafetyCalculator = new G4SafetyCalculator( *this, fHistory );
82 fpSafetyCalculator->SetExternalNavigation(fpExternalNav);
83}
CLHEP::Hep3Vector G4ThreeVector
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4double fMinStep
G4ThreeVector fStepEndPoint
G4ThreeVector fLastStepEndPointLocal
G4double fSqTol
G4double kCarTolerance
void ResetStackAndState()
G4NavigationHistory fHistory
void SetNormalNavigation(G4NormalNavigation *fnormnav)
void SetExternalNavigation(G4VExternalNavigation *externalNav)
T sqr(const T &x)
Definition templates.hh:128

◆ G4Navigator() [2/2]

G4Navigator::G4Navigator ( const G4Navigator & )
delete

◆ ~G4Navigator()

G4Navigator::~G4Navigator ( )
virtual

Definition at line 89 of file G4Navigator.cc.

90{
91 delete fpVoxelSafety;
92 delete fpExternalNav;
93 delete fpvoxelNav;
94 delete fpSafetyCalculator;
95}

Member Function Documentation

◆ Activate()

◆ CharacteriseDaughters()

EVolume G4Navigator::CharacteriseDaughters ( const G4LogicalVolume * pLog) const
inlineprotected

◆ CheckMode()

void G4Navigator::CheckMode ( G4bool mode)
inline

◆ CheckNextStep()

G4double G4Navigator::CheckNextStep ( const G4ThreeVector & pGlobalPoint,
const G4ThreeVector & pDirection,
const G4double pCurrentProposedStepLength,
G4double & pNewSafety )

Definition at line 1226 of file G4Navigator.cc.

1230{
1231 G4double step;
1232
1233 // Save the state, for this parasitic call
1234 //
1235 SetSavedState();
1236
1237 step = ComputeStep ( pGlobalpoint,
1238 pDirection,
1239 pCurrentProposedStepLength,
1240 pNewSafety );
1241
1242 // It is a parasitic call, so attempt to restore the key parts of the state
1243 //
1245 // NOTE: the state of the current subnavigator is NOT restored.
1246 // ***> TODO: restore subnavigator state
1247 // if( last_located) Need Position of last location
1248 // if( last_computed step) Need Endposition of last step
1249
1250 return step;
1251}
double G4double
Definition G4Types.hh:83
void RestoreSavedState()
void SetSavedState()
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)

Referenced by G4SafetyHelper::CheckNextStep().

◆ CheckOverlapsIterative()

G4bool G4Navigator::CheckOverlapsIterative ( G4VPhysicalVolume * vol)
protected

Definition at line 1984 of file G4Navigator.cc.

1985{
1986 // Check and report overlaps
1987 //
1988 G4bool foundOverlap = false;
1989 G4int nPoints = 300000, ntrials = 9, numOverlaps = 5;
1990 G4double trialLength = 1.0 * CLHEP::centimeter;
1991 while ( ntrials-- > 0 && !foundOverlap )
1992 {
1993 if ( fVerbose > 1 )
1994 {
1995 G4cout << " ** Running overlap checks in volume "
1996 << vol->GetName()
1997 << " with length = " << trialLength << G4endl;
1998 }
1999 foundOverlap = vol->CheckOverlaps(nPoints, trialLength,
2000 fVerbose != 0, numOverlaps);
2001 trialLength *= 0.1;
2002 if ( trialLength <= 1.0e-5 ) { numOverlaps= 1;}
2003 }
2004 return foundOverlap;
2005}
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
virtual G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true, G4int errMax=1)
const G4String & GetName() const

Referenced by ComputeStep().

◆ Clone()

◆ ComputeLocalAxis()

G4ThreeVector G4Navigator::ComputeLocalAxis ( const G4ThreeVector & pVec) const
inlineprotected

Referenced by ComputeStep().

◆ ComputeLocalPoint()

G4ThreeVector G4Navigator::ComputeLocalPoint ( const G4ThreeVector & rGlobPoint) const
inlineprotected

◆ ComputeSafety()

G4double G4Navigator::ComputeSafety ( const G4ThreeVector & globalpoint,
const G4double pProposedMaxLength = DBL_MAX,
const G4bool keepState = true )
virtual

Reimplemented in G4ErrorPropagationNavigator, and G4MultiNavigator.

Definition at line 1778 of file G4Navigator.cc.

1781{
1782 G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1783 G4double safety = 0.0;
1784
1785 G4double distEndpointSq = (pGlobalpoint-fStepEndPoint).mag2();
1786 G4bool stayedOnEndpoint = distEndpointSq < sqr(kCarTolerance);
1787 G4bool endpointOnSurface = fEnteredDaughter || fExitedMother;
1788
1789 G4bool onSurface = endpointOnSurface && stayedOnEndpoint;
1790 if( ! onSurface )
1791 {
1792 safety= fpSafetyCalculator->SafetyInCurrentVolume(pGlobalpoint, motherPhysical, pMaxLength);
1793 // offload to G4SafetyCalculator - avoids need to save / reload state
1794
1795 // Remember last safety origin & value
1796 //
1797 fPreviousSftOrigin = pGlobalpoint;
1798 fPreviousSafety = safety;
1799 // We overwrite the Safety 'sphere' - keeping old behaviour
1800 }
1801
1802 return safety;
1803}
G4VPhysicalVolume * GetTopVolume() const
G4bool fExitedMother
G4bool fEnteredDaughter
G4double SafetyInCurrentVolume(const G4ThreeVector &globalpoint, G4VPhysicalVolume *physicalVolume, const G4double pProposedMaxLength=DBL_MAX, G4bool verbose=false)

Referenced by G4FastSimulationManagerProcess::AlongStepGetPhysicalInteractionLength(), G4ImportanceProcess::AlongStepGetPhysicalInteractionLength(), G4ParallelWorldProcess::AlongStepGetPhysicalInteractionLength(), G4ParallelWorldScoringProcess::AlongStepGetPhysicalInteractionLength(), G4Transportation::AlongStepGetPhysicalInteractionLength(), G4WeightCutOffProcess::AlongStepGetPhysicalInteractionLength(), G4WeightWindowProcess::AlongStepGetPhysicalInteractionLength(), G4ErrorPropagationNavigator::ComputeSafety(), G4SafetyHelper::ComputeSafety(), and G4PathFinder::DoNextCurvedStep().

◆ ComputeStep()

G4double G4Navigator::ComputeStep ( const G4ThreeVector & pGlobalPoint,
const G4ThreeVector & pDirection,
const G4double pCurrentProposedStepLength,
G4double & pNewSafety )
virtual

Reimplemented in G4ErrorPropagationNavigator, and G4MultiNavigator.

Definition at line 749 of file G4Navigator.cc.

753{
754#ifdef G4DEBUG_NAVIGATION
755 static G4ThreadLocal G4int sNavCScalls = 0;
756 ++sNavCScalls;
757#endif
758
759 G4ThreeVector localDirection = ComputeLocalAxis(pDirection);
760 G4double Step = kInfinity;
761 G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
762 G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
763
764 // All state relating to exiting normals must be reset
765 //
766 fExitNormalGlobalFrame = G4ThreeVector( 0., 0., 0.);
767 // Reset value - to erase its memory
768 fChangedGrandMotherRefFrame = false;
769 // Reset - used for local exit normal
770 fGrandMotherExitNormal = G4ThreeVector( 0., 0., 0.);
771 fCalculatedExitNormal = false;
772 // Reset for new step
773
774#ifdef G4VERBOSE
775 if( fVerbose > 0 )
776 {
777 G4cout << "*** G4Navigator::ComputeStep: ***" << G4endl;
778 G4cout << " Volume = " << motherPhysical->GetName()
779 << " - Proposed step length = " << pCurrentProposedStepLength
780 << G4endl;
781#ifdef G4DEBUG_NAVIGATION
782 if( fVerbose >= 2 )
783 {
784 G4cout << " Called with the arguments: " << G4endl
785 << " Globalpoint = " << std::setw(25) << pGlobalpoint << G4endl
786 << " Direction = " << std::setw(25) << pDirection << G4endl;
787 if( fVerbose >= 4 )
788 {
789 G4cout << " ---- Upon entering : State" << G4endl;
790 PrintState();
791 }
792 }
793#endif
794 }
795#endif
796
797 G4ThreeVector newLocalPoint = ComputeLocalPoint(pGlobalpoint);
798
799 if( newLocalPoint != fLastLocatedPointLocal )
800 {
801 // Check whether the relocation is within safety
802 //
803 G4ThreeVector oldLocalPoint = fLastLocatedPointLocal;
804 G4double moveLenSq = (newLocalPoint-oldLocalPoint).mag2();
805
806 if ( moveLenSq >= fSqTol )
807 {
808#ifdef G4VERBOSE
809 ComputeStepLog(pGlobalpoint, moveLenSq);
810#endif
811 // Relocate the point within the same volume
812 //
813 LocateGlobalPointWithinVolume( pGlobalpoint );
814 }
815 }
817 {
818 switch( CharacteriseDaughters(motherLogical) )
819 {
820 case kNormal:
821 if ( motherLogical->GetVoxelHeader() != nullptr )
822 {
823 Step = GetVoxelNavigator().ComputeStep(fLastLocatedPointLocal,
824 localDirection,
825 pCurrentProposedStepLength,
826 pNewSafety,
827 fHistory,
828 fValidExitNormal,
829 fExitNormal,
830 fExiting,
831 fEntering,
832 &fBlockedPhysicalVolume,
833 fBlockedReplicaNo);
834
835 }
836 else
837 {
838 if( motherPhysical->GetRegularStructureId() == 0 )
839 {
840 Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
841 localDirection,
842 pCurrentProposedStepLength,
843 pNewSafety,
844 fHistory,
845 fValidExitNormal,
846 fExitNormal,
847 fExiting,
848 fEntering,
849 &fBlockedPhysicalVolume,
850 fBlockedReplicaNo);
851 }
852 else // Regular (non-voxelised) structure
853 {
854 LocateGlobalPointAndSetup( pGlobalpoint, &pDirection, true, true );
855 //
856 // if physical process limits the step, the voxel will not be the
857 // one given by ComputeStepSkippingEqualMaterials() and the local
858 // point will be wrongly calculated.
859
860 // There is a problem: when msc limits the step and the point is
861 // assigned wrongly to phantom in previous step (while it is out
862 // of the container volume). Then LocateGlobalPointAndSetup() has
863 // reset the history topvolume to world.
864 //
866 {
867 G4Exception("G4Navigator::ComputeStep()",
868 "GeomNav1001", JustWarning,
869 "Point is relocated in voxels, while it should be outside!");
870 Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
871 localDirection,
872 pCurrentProposedStepLength,
873 pNewSafety,
874 fHistory,
875 fValidExitNormal,
876 fExitNormal,
877 fExiting,
878 fEntering,
879 &fBlockedPhysicalVolume,
880 fBlockedReplicaNo);
881 }
882 else
883 {
884 Step = fregularNav.
885 ComputeStepSkippingEqualMaterials(fLastLocatedPointLocal,
886 localDirection,
887 pCurrentProposedStepLength,
888 pNewSafety,
889 fHistory,
890 fValidExitNormal,
891 fExitNormal,
892 fExiting,
893 fEntering,
894 &fBlockedPhysicalVolume,
895 fBlockedReplicaNo,
896 motherPhysical);
897 }
898 }
899 }
900 break;
901 case kParameterised:
902 if( GetDaughtersRegularStructureId(motherLogical) != 1 )
903 {
904 Step = fparamNav.ComputeStep(fLastLocatedPointLocal,
905 localDirection,
906 pCurrentProposedStepLength,
907 pNewSafety,
908 fHistory,
909 fValidExitNormal,
910 fExitNormal,
911 fExiting,
912 fEntering,
913 &fBlockedPhysicalVolume,
914 fBlockedReplicaNo);
915 }
916 else // Regular structure
917 {
918 Step = fregularNav.ComputeStep(fLastLocatedPointLocal,
919 localDirection,
920 pCurrentProposedStepLength,
921 pNewSafety,
922 fHistory,
923 fValidExitNormal,
924 fExitNormal,
925 fExiting,
926 fEntering,
927 &fBlockedPhysicalVolume,
928 fBlockedReplicaNo);
929 }
930 break;
931 case kReplica:
932 G4Exception("G4Navigator::ComputeStep()", "GeomNav0001",
933 FatalException, "Not applicable for replicated volumes.");
934 break;
935 case kExternal:
936 Step = fpExternalNav->ComputeStep(fLastLocatedPointLocal,
937 localDirection,
938 pCurrentProposedStepLength,
939 pNewSafety,
940 fHistory,
941 fValidExitNormal,
942 fExitNormal,
943 fExiting,
944 fEntering,
945 &fBlockedPhysicalVolume,
946 fBlockedReplicaNo);
947 break;
948 }
949 }
950 else
951 {
952 // In the case of a replica, it must handle the exiting
953 // edge/corner problem by itself
954 //
955 fExiting = fExitedMother;
956 Step = freplicaNav.ComputeStep(pGlobalpoint,
957 pDirection,
958 fLastLocatedPointLocal,
959 localDirection,
960 pCurrentProposedStepLength,
961 pNewSafety,
962 fHistory,
963 fValidExitNormal,
964 fCalculatedExitNormal,
965 fExitNormal,
966 fExiting,
967 fEntering,
968 &fBlockedPhysicalVolume,
969 fBlockedReplicaNo);
970 }
971
972 // Remember last safety origin & value.
973 //
974 fPreviousSftOrigin = pGlobalpoint;
975 fPreviousSafety = pNewSafety;
976
977 // Count zero steps - one can occur due to changing momentum at a boundary
978 // - one, two (or a few) can occur at common edges between
979 // volumes
980 // - more than two is likely a problem in the geometry
981 // description or the Navigation
982
983 // Rule of thumb: likely at an Edge if two consecutive steps are zero,
984 // because at least two candidate volumes must have been
985 // checked
986 //
987 fLocatedOnEdge = fLastStepWasZero && (Step==0.0);
988 fLastStepWasZero = (Step<fMinStep);
989 if (fPushed) { fPushed = fLastStepWasZero; }
990
991 // Handle large number of consecutive zero steps
992 //
993 if ( fLastStepWasZero )
994 {
995 ++fNumberZeroSteps;
996
997 G4bool act = fNumberZeroSteps >= fActionThreshold_NoZeroSteps;
998 G4bool actAndReport = false;
999 G4bool abandon = fNumberZeroSteps >= fAbandonThreshold_NoZeroSteps;
1000 G4bool inform = false;
1001#ifdef G4VERBOSE
1002 actAndReport = act && (!fPushed) && fWarnPush;
1003#endif
1004#ifdef G4DEBUG_NAVIGATION
1005 inform = fNumberZeroSteps > 1;
1006#endif
1007
1008 if ( act || inform )
1009 {
1010 if( act && !abandon )
1011 {
1012 // Act to recover this stuck track. Pushing it along original direction
1013 //
1014 Step += 100*kCarTolerance;
1015 fPushed = true;
1016 }
1017
1018 if( actAndReport || abandon || inform )
1019 {
1020 std::ostringstream message;
1021
1022 message.precision(16);
1023 message << "Stuck Track: potential geometry or navigation problem."
1024 << G4endl;
1025 message << " Track stuck, not moving for "
1026 << fNumberZeroSteps << " steps." << G4endl
1027 << " Current phys volume: '" << motherPhysical->GetName()
1028 << "'" << G4endl
1029 << " - at position : " << pGlobalpoint << G4endl
1030 << " in direction: " << pDirection << G4endl
1031 << " (local position: " << newLocalPoint << ")" << G4endl
1032 << " (local direction: " << localDirection << ")." << G4endl
1033 << " Previous phys volume: '"
1034 << ( fLastMotherPhys != nullptr ? fLastMotherPhys->GetName() : G4String("") )
1035 << "'" << G4endl << G4endl;
1036 if( actAndReport || abandon )
1037 {
1038 message << " Likely geometry overlap - else navigation problem !"
1039 << G4endl;
1040 }
1041 if( abandon ) // i.e. fNumberZeroSteps >= fAbandonThreshold_NoZeroSteps
1042 {
1043 // Must kill this stuck track
1044#ifdef G4VERBOSE
1045 if ( fWarnPush ) { CheckOverlapsIterative(motherPhysical); }
1046#endif
1047 message << " Track *abandoned* due to excessive number of Zero steps."
1048 << " Event aborted. " << G4endl << G4endl;
1049 G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
1050 EventMustBeAborted, message);
1051 }
1052 else
1053 {
1054#ifdef G4VERBOSE
1055 if ( actAndReport ) // (!fPushed => !wasPushed) && (fWarnPush))
1056 {
1057 message << " *** Trying to get *unstuck* using a push"
1058 << " - expanding step to " << Step << " (mm) ..."
1059 << " Potential overlap in geometry !" << G4endl;
1060 G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
1061 JustWarning, message);
1062 }
1063#endif
1064#ifdef G4DEBUG_NAVIGATION
1065 else
1066 {
1067 if( fNumberZeroSteps > 1 )
1068 {
1069 message << ", nav-comp-step calls # " << sNavCScalls
1070 << ", Step= " << Step << G4endl;
1071 G4cout << message.str();
1072 }
1073 }
1074#endif
1075 } // end of else if ( abandon )
1076 } // end of if( actAndReport || abandon || inform )
1077 } // end of if ( act || inform )
1078 }
1079 else
1080 {
1081 if (!fPushed) { fNumberZeroSteps = 0; }
1082 }
1083 fLastMotherPhys = motherPhysical;
1084
1085 fEnteredDaughter = fEntering; // I expect to enter a volume in this Step
1086 fExitedMother = fExiting;
1087
1088 fStepEndPoint = pGlobalpoint
1089 + std::min(Step,pCurrentProposedStepLength) * pDirection;
1090 fLastStepEndPointLocal = fLastLocatedPointLocal + Step * localDirection;
1091
1092 if( fExiting )
1093 {
1094#ifdef G4DEBUG_NAVIGATION
1095 if( fVerbose > 2 )
1096 {
1097 G4cout << " At G4Nav CompStep End - if(exiting) - fExiting= " << fExiting
1098 << " fValidExitNormal = " << fValidExitNormal << G4endl;
1099 G4cout << " fExitNormal= " << fExitNormal << G4endl;
1100 }
1101#endif
1102
1103 if ( fValidExitNormal || fCalculatedExitNormal )
1104 {
1105 // Convention: fExitNormal is in the 'grand-mother' coordinate system
1106 fGrandMotherExitNormal = fExitNormal;
1107 }
1108 else
1109 {
1110 // We must calculate the normal anyway (in order to have it if requested)
1111 //
1112 G4ThreeVector finalLocalPoint = fLastLocatedPointLocal
1113 + localDirection*Step;
1114
1116 {
1117 // Find normal in the 'mother' coordinate system
1118 //
1119 G4ThreeVector exitNormalMotherFrame=
1120 motherLogical->GetSolid()->SurfaceNormal(finalLocalPoint);
1121
1122 // Transform it to the 'grand-mother' coordinate system
1123 //
1124 const G4RotationMatrix* mRot = motherPhysical->GetRotation();
1125 if( mRot != nullptr )
1126 {
1127 fChangedGrandMotherRefFrame = true;
1128 fGrandMotherExitNormal = (*mRot).inverse() * exitNormalMotherFrame;
1129 }
1130 else
1131 {
1132 fGrandMotherExitNormal = exitNormalMotherFrame;
1133 }
1134
1135 // Do not set fValidExitNormal -- this signifies
1136 // that the solid is convex!
1137 }
1138 else
1139 {
1140 fCalculatedExitNormal = false;
1141 //
1142 // Nothing can be done at this stage currently - to solve this
1143 // Replica Navigation must have calculated the normal for this case
1144 // already.
1145 // Cases: mother is not convex, and exit is at previous replica level
1146
1147#ifdef G4DEBUG_NAVIGATION
1149
1150 desc << "Problem in ComputeStep: Replica Navigation did not provide"
1151 << " valid exit Normal. " << G4endl;
1152 desc << " Do not know how calculate it in this case." << G4endl;
1153 desc << " Location = " << finalLocalPoint << G4endl;
1154 desc << " Volume name = " << motherPhysical->GetName()
1155 << " copy/replica No = " << motherPhysical->GetCopyNo() << G4endl;
1156 G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
1157 JustWarning, desc, "Normal not available for exiting.");
1158#endif
1159 }
1160 }
1161
1163 {
1164 fCalculatedExitNormal = true;
1165 }
1166
1167 // Now transform it to the global reference frame !!
1168 //
1169 if( fValidExitNormal || fCalculatedExitNormal )
1170 {
1171 auto depth = (G4int)fHistory.GetDepth();
1172 if( depth > 0 )
1173 {
1174 fExitNormalGlobalFrame = fHistory.GetTransform(depth-1)
1175 .InverseTransformAxis( fGrandMotherExitNormal );
1176 }
1177 else
1178 {
1179 fExitNormalGlobalFrame = fGrandMotherExitNormal;
1180 }
1181 }
1182 else
1183 {
1184 fExitNormalGlobalFrame = G4ThreeVector( 0., 0., 0.);
1185 }
1186 }
1187
1188 if( (Step == pCurrentProposedStepLength) && (!fExiting) && (!fEntering) )
1189 {
1190 // This if Step is not really limited by the geometry.
1191 // The Navigator is obliged to return "infinity"
1192 //
1193 Step = kInfinity;
1194 }
1195
1196#ifdef G4VERBOSE
1197 if( fVerbose > 1 )
1198 {
1199 if( fVerbose >= 4 )
1200 {
1201 G4cout << " ----- Upon exiting :" << G4endl;
1202 PrintState();
1203 }
1204 G4cout << " Returned step= " << Step;
1205 if( fVerbose > 5 ) { G4cout << G4endl; }
1206 if( Step == kInfinity )
1207 {
1208 G4cout << " Requested step= " << pCurrentProposedStepLength ;
1209 if( fVerbose > 5) { G4cout << G4endl; }
1210 }
1211 G4cout << " Safety = " << pNewSafety << G4endl;
1212 }
1213#endif
1214
1215 fLastTriedStepComputation = true;
1216
1217 return Step;
1218}
@ JustWarning
@ FatalException
@ EventMustBeAborted
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define fLastStepWasZero
G4ThreeVector InverseTransformAxis(const G4ThreeVector &axis) const
G4VSolid * GetSolid() const
G4SmartVoxelHeader * GetVoxelHeader() const
EVolume GetTopVolumeType() const
std::size_t GetDepth() const
const G4AffineTransform & GetTransform(G4int n) const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
G4VoxelNavigation & GetVoxelNavigator()
G4bool CheckOverlapsIterative(G4VPhysicalVolume *vol)
EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &rGlobPoint) const
void PrintState() const
G4ThreeVector ComputeLocalAxis(const G4ThreeVector &pVec) const
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
G4int GetDaughtersRegularStructureId(const G4LogicalVolume *pLv) const
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) final
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) override
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) final
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4bool &calculatedExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
virtual 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)=0
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
virtual G4int GetCopyNo() const =0
virtual G4int GetRegularStructureId() const =0
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) override
@ kNormal
Definition geomdefs.hh:84
@ kParameterised
Definition geomdefs.hh:86
@ kExternal
Definition geomdefs.hh:87
@ kReplica
Definition geomdefs.hh:85
#define G4ThreadLocal
Definition tls.hh:77

Referenced by G4Transportation::AlongStepGetPhysicalInteractionLength(), CheckNextStep(), G4AdjointPrimaryGenerator::ComputeAccumulatedDepthVectorAlongBackRay(), and G4ErrorPropagationNavigator::ComputeStep().

◆ CreateTouchableHistory() [1/2]

◆ CreateTouchableHistory() [2/2]

G4TouchableHistory * G4Navigator::CreateTouchableHistory ( const G4NavigationHistory * ) const
inline

◆ CreateTouchableHistoryHandle()

G4TouchableHandle G4Navigator::CreateTouchableHistoryHandle ( ) const
virtual

Reimplemented in G4MultiNavigator.

Definition at line 1809 of file G4Navigator.cc.

1810{
1812}
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4TouchableHistory * CreateTouchableHistory() const

Referenced by G4VIntersectionLocator::LocateGlobalPointWithinVolumeAndCheck().

◆ EnableBestSafety()

void G4Navigator::EnableBestSafety ( G4bool value = false)
inline

◆ EnteredDaughterVolume()

G4bool G4Navigator::EnteredDaughterVolume ( ) const
inline

◆ ExitedMotherVolume()

G4bool G4Navigator::ExitedMotherVolume ( ) const
inline

◆ GetCurrentLocalCoordinate()

G4ThreeVector G4Navigator::GetCurrentLocalCoordinate ( ) const
inline

◆ GetDaughtersRegularStructureId()

G4int G4Navigator::GetDaughtersRegularStructureId ( const G4LogicalVolume * pLv) const
inlineprotected

◆ GetExternalNavigation()

◆ GetGlobalExitNormal()

G4ThreeVector G4Navigator::GetGlobalExitNormal ( const G4ThreeVector & point,
G4bool * valid )
virtual

Reimplemented in G4ErrorPropagationNavigator, and G4MultiNavigator.

Definition at line 1607 of file G4Navigator.cc.

1609{
1610 G4bool validNormal;
1611 G4ThreeVector localNormal, globalNormal;
1612
1613 G4bool usingStored = fCalculatedExitNormal && (
1614 ( fLastTriedStepComputation && fExiting ) // Just calculated it
1615 || // No locate in between
1616 ( !fLastTriedStepComputation
1617 && (IntersectPointGlobal-fStepEndPoint).mag2() < 10.0*fSqTol ) );
1618 // Calculated it 'just' before & then called locate
1619 // but it did not move position
1620
1621 if( usingStored )
1622 {
1623 // This was computed in last call to ComputeStep
1624 // and only if it arrived at boundary
1625 //
1626 globalNormal = fExitNormalGlobalFrame;
1627 G4double normMag2 = globalNormal.mag2();
1628 if( std::fabs ( normMag2 - 1.0 ) < perThousand ) // was perMillion
1629 {
1630 *pNormalCalculated = true; // ComputeStep always computes it if Exiting
1631 // (fExiting==true)
1632 }
1633 else
1634 {
1635 G4ExceptionDescription message;
1636 message.precision(10);
1637 message << " WARNING> Expected normal-global-frame to be valid, "
1638 << " i.e. a unit vector!" << G4endl
1639 << " - but |normal| = " << std::sqrt(normMag2)
1640 << " - and |normal|^2 = " << normMag2 << G4endl
1641 << " which differs from 1.0 by " << normMag2 - 1.0 << G4endl
1642 << " n = " << fExitNormalGlobalFrame << G4endl
1643 << " Global point: " << IntersectPointGlobal << G4endl
1644 << " Volume: " << fHistory.GetTopVolume()->GetName() << G4endl;
1645#ifdef G4VERBOSE
1647 if ( candLog != nullptr )
1648 {
1649 message << " Solid: " << candLog->GetSolid()->GetName()
1650 << ", Type: " << candLog->GetSolid()->GetEntityType() << G4endl
1651 << *candLog->GetSolid() << G4endl;
1652 }
1653#endif
1654 message << "============================================================"
1655 << G4endl;
1656 G4int oldVerbose = fVerbose;
1657 fVerbose = 4;
1658 message << " State of Navigator: " << G4endl;
1659 message << *this << G4endl;
1660 fVerbose = oldVerbose;
1661 message << "============================================================"
1662 << G4endl;
1663
1664 G4Exception("G4Navigator::GetGlobalExitNormal()",
1665 "GeomNav0003",JustWarning, message,
1666 "Value obtained from stored global-normal is not a unit vector.");
1667
1668 // (Re)Compute it now -- as either it was not computed, or it is wrong.
1669 //
1670 localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,
1671 &validNormal);
1672 *pNormalCalculated = fCalculatedExitNormal;
1673 globalNormal = fHistory.GetTopTransform()
1674 .InverseTransformAxis(localNormal);
1675 }
1676 }
1677 else
1678 {
1679 localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,&validNormal);
1680 *pNormalCalculated = fCalculatedExitNormal;
1681
1682#ifdef G4DEBUG_NAVIGATION
1683 usingStored = false;
1684
1685 if( (!validNormal) && !fCalculatedExitNormal )
1686 {
1688 edN << " Calculated = " << fCalculatedExitNormal << G4endl;
1689 edN << " Entering= " << fEntering << G4endl;
1690 G4int oldVerbose = this->GetVerboseLevel();
1691 this->SetVerboseLevel(4);
1692 edN << " State of Navigator: " << G4endl;
1693 edN << *this << G4endl;
1694 this->SetVerboseLevel( oldVerbose );
1695
1696 G4Exception("G4Navigator::GetGlobalExitNormal()",
1697 "GeomNav0003", JustWarning, edN,
1698 "LocalExitNormalAndCheck() did not calculate Normal.");
1699 }
1700#endif
1701
1702 G4double localMag2 = localNormal.mag2();
1703 if( validNormal && (std::fabs(localMag2-1.0)) > kToleranceNormalCheck )
1704 {
1706 edN.precision(10);
1707 edN << "G4Navigator::GetGlobalExitNormal: "
1708 << " Using Local Normal - from call to GetLocalExitNormalAndCheck. "
1709 << G4endl
1710 << " Local Exit Normal : " << " || = " << std::sqrt(localMag2)
1711 << " vec = " << localNormal << G4endl
1712 << " Global Exit Normal : " << " || = " << globalNormal.mag()
1713 << " vec = " << globalNormal << G4endl
1714 << " Global point: " << IntersectPointGlobal << G4endl;
1715 edN << " Calculated It = " << fCalculatedExitNormal << G4endl
1716 << " Volume: " << fHistory.GetTopVolume()->GetName() << G4endl;
1717#ifdef G4VERBOSE
1719 if ( candLog != nullptr )
1720 {
1721 edN << " Solid: " << candLog->GetSolid()->GetName()
1722 << ", Type: " << candLog->GetSolid()->GetEntityType() << G4endl
1723 << *candLog->GetSolid();
1724 }
1725#endif
1726 G4Exception("G4Navigator::GetGlobalExitNormal()",
1727 "GeomNav0003",JustWarning, edN,
1728 "Value obtained from new local *solid* is incorrect.");
1729 localNormal = localNormal.unit(); // Should we correct it ??
1730 }
1731 globalNormal = fHistory.GetTopTransform()
1732 .InverseTransformAxis(localNormal);
1733 }
1734
1735#ifdef G4DEBUG_NAVIGATION
1736 if( usingStored )
1737 {
1738 G4ThreeVector globalNormAgn;
1739
1740 localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,&validNormal);
1741
1742 globalNormAgn = fHistory.GetTopTransform()
1743 .InverseTransformAxis(localNormal);
1744
1745 // Check the value computed against fExitNormalGlobalFrame
1746 G4ThreeVector diffNorm = globalNormAgn - fExitNormalGlobalFrame;
1747 if( diffNorm.mag2() > kToleranceNormalCheck )
1748 {
1750 edDfn << "Found difference in normals in case of exiting mother "
1751 << "- when Get is called after ComputingStep " << G4endl;
1752 edDfn << " Magnitude of diff = " << diffNorm.mag() << G4endl;
1753 edDfn << " Normal stored (Global) = " << fExitNormalGlobalFrame
1754 << G4endl;
1755 edDfn << " Global Computed from Local = " << globalNormAgn << G4endl;
1756 G4Exception("G4Navigator::GetGlobalExitNormal()", "GeomNav0003",
1757 JustWarning, edDfn);
1758 }
1759 }
1760#endif
1761
1762 // Synchronise stored global exit normal as possibly re-computed here
1763 //
1764 fExitNormalGlobalFrame = globalNormal;
1765
1766 return globalNormal;
1767}
#define fExitNormalGlobalFrame
Hep3Vector unit() const
double mag2() const
double mag() const
const G4AffineTransform & GetTopTransform() const
void SetVerboseLevel(G4int level)
G4int GetVerboseLevel() const
virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &point, G4bool *valid)
G4String GetName() const
virtual G4GeometryType GetEntityType() const =0

Referenced by G4ErrorPropagationNavigator::GetGlobalExitNormal(), G4MultiNavigator::GetGlobalExitNormal(), G4XrayReflection::GetMeanFreePath(), and G4MicroElecSurface::PostStepDoIt().

◆ GetGlobalToLocalTransform()

const G4AffineTransform & G4Navigator::GetGlobalToLocalTransform ( ) const
inline

◆ GetLastStepEndPoint()

G4ThreeVector G4Navigator::GetLastStepEndPoint ( ) const
inline

Definition at line 301 of file G4Navigator.hh.

301{ return fStepEndPoint;}

Referenced by G4SafetyCalculator::SafetyInCurrentVolume().

◆ GetLocalExitNormal()

G4ThreeVector G4Navigator::GetLocalExitNormal ( G4bool * valid)
virtual

Reimplemented in G4MultiNavigator.

Definition at line 1355 of file G4Navigator.cc.

1356{
1357 G4ThreeVector ExitNormal(0.,0.,0.);
1358 G4VSolid* currentSolid = nullptr;
1359 G4LogicalVolume* candidateLogical;
1360
1361 if ( fLastTriedStepComputation )
1362 {
1363 // use fLastLocatedPointLocal and next candidate volume
1364 //
1365 G4ThreeVector nextSolidExitNormal(0.,0.,0.);
1366
1367 if( fEntering && (fBlockedPhysicalVolume!=nullptr) )
1368 {
1369 candidateLogical = fBlockedPhysicalVolume->GetLogicalVolume();
1370 if( candidateLogical != nullptr )
1371 {
1372 // fLastStepEndPointLocal is in the coordinates of the mother
1373 // we need it in the daughter's coordinate system.
1374
1375 // The following code should also work in case of Replica
1376 {
1377 // First transform fLastLocatedPointLocal to the new daughter
1378 // coordinates
1379 //
1380 G4AffineTransform MotherToDaughterTransform=
1381 GetMotherToDaughterTransform( fBlockedPhysicalVolume,
1382 fBlockedReplicaNo,
1383 VolumeType(fBlockedPhysicalVolume) );
1384 G4ThreeVector daughterPointOwnLocal =
1385 MotherToDaughterTransform.TransformPoint( fLastStepEndPointLocal );
1386
1387 // OK if it is a parameterised volume
1388 //
1389 EInside inSideIt;
1390 G4bool onSurface;
1391 G4double safety = -1.0;
1392 currentSolid = candidateLogical->GetSolid();
1393 inSideIt = currentSolid->Inside(daughterPointOwnLocal);
1394 onSurface = (inSideIt == kSurface);
1395 if( !onSurface )
1396 {
1397 if( inSideIt == kOutside )
1398 {
1399 safety = (currentSolid->DistanceToIn(daughterPointOwnLocal));
1400 onSurface = safety < 100.0 * kCarTolerance;
1401 }
1402 else if (inSideIt == kInside )
1403 {
1404 safety = (currentSolid->DistanceToOut(daughterPointOwnLocal));
1405 onSurface = safety < 100.0 * kCarTolerance;
1406 }
1407 }
1408
1409 if( onSurface )
1410 {
1411 nextSolidExitNormal =
1412 currentSolid->SurfaceNormal(daughterPointOwnLocal);
1413
1414 // Entering the solid ==> opposite
1415 //
1416 // First flip ( ExitNormal = -nextSolidExitNormal; )
1417 // and then rotate the the normal to the frame of the mother (current volume)
1418 ExitNormal = MotherToDaughterTransform
1419 .InverseTransformAxis( -nextSolidExitNormal );
1420 fCalculatedExitNormal = true;
1421 }
1422 else
1423 {
1424#ifdef G4VERBOSE
1425 if(( fVerbose == 1 ) && ( fCheck ))
1426 {
1427 std::ostringstream message;
1428 message << "Point not on surface ! " << G4endl
1429 << " Point = "
1430 << daughterPointOwnLocal << G4endl
1431 << " Physical volume = "
1432 << fBlockedPhysicalVolume->GetName() << G4endl
1433 << " Logical volume = "
1434 << candidateLogical->GetName() << G4endl
1435 << " Solid = " << currentSolid->GetName()
1436 << " Type = "
1437 << currentSolid->GetEntityType() << G4endl
1438 << *currentSolid << G4endl;
1439 if( inSideIt == kOutside )
1440 {
1441 message << "Point is Outside. " << G4endl
1442 << " Safety (from outside) = " << safety << G4endl;
1443 }
1444 else // if( inSideIt == kInside )
1445 {
1446 message << "Point is Inside. " << G4endl
1447 << " Safety (from inside) = " << safety << G4endl;
1448 }
1449 G4Exception("G4Navigator::GetLocalExitNormal()", "GeomNav1001",
1450 JustWarning, message);
1451 }
1452#endif
1453 }
1454 *valid = onSurface; // was =true;
1455 }
1456 }
1457 }
1458 else if ( fExiting )
1459 {
1460 ExitNormal = fGrandMotherExitNormal;
1461 *valid = true;
1462 fCalculatedExitNormal = true; // Should be true already
1463 }
1464 else // i.e. ( fBlockedPhysicalVolume == 0 )
1465 {
1466 *valid = false;
1467 G4Exception("G4Navigator::GetLocalExitNormal()",
1468 "GeomNav0003", JustWarning,
1469 "Incorrect call to GetLocalSurfaceNormal." );
1470 }
1471 }
1472 else // ( ! fLastTriedStepComputation ) i.e. last call was to Locate
1473 {
1474 if ( EnteredDaughterVolume() )
1475 {
1476 G4VSolid* daughterSolid = fHistory.GetTopVolume()->GetLogicalVolume()
1477 ->GetSolid();
1478 ExitNormal = -(daughterSolid->SurfaceNormal(fLastLocatedPointLocal));
1479 if( std::fabs(ExitNormal.mag2()-1.0 ) > kToleranceNormalCheck )
1480 {
1482 desc << " Parameters of solid: " << *daughterSolid
1483 << " Point for surface = " << fLastLocatedPointLocal << std::endl;
1484 G4Exception("G4Navigator::GetLocalExitNormal()",
1485 "GeomNav0003", FatalException, desc,
1486 "Surface Normal returned by Solid is not a Unit Vector." );
1487 }
1488 fCalculatedExitNormal = true;
1489 *valid = true;
1490 }
1491 else
1492 {
1493 if( fExitedMother )
1494 {
1495 ExitNormal = fGrandMotherExitNormal;
1496 *valid = true;
1497 fCalculatedExitNormal = true;
1498 }
1499 else // We are not at a boundary. ExitNormal remains (0,0,0)
1500 {
1501 *valid = false;
1502 fCalculatedExitNormal = false;
1503 G4ExceptionDescription message;
1504 message << "Function called when *NOT* at a Boundary." << G4endl;
1505 message << "Exit Normal not calculated." << G4endl;
1506 G4Exception("G4Navigator::GetLocalExitNormal()",
1507 "GeomNav0003", JustWarning, message);
1508 }
1509 }
1510 }
1511 return ExitNormal;
1512}
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
const G4String & GetName() const
EVolume VolumeType(const G4VPhysicalVolume *pVol) const
G4AffineTransform GetMotherToDaughterTransform(G4VPhysicalVolume *dVolume, G4int dReplicaNo, EVolume dVolumeType)
G4bool EnteredDaughterVolume() const
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
EInside
Definition geomdefs.hh:67
@ kInside
Definition geomdefs.hh:70
@ kOutside
Definition geomdefs.hh:68
@ kSurface
Definition geomdefs.hh:69

Referenced by G4RayTrajectory::AppendStep(), G4MultiNavigator::GetLocalExitNormal(), GetLocalExitNormalAndCheck(), and G4VTransitionRadiation::PostStepDoIt().

◆ GetLocalExitNormalAndCheck()

G4ThreeVector G4Navigator::GetLocalExitNormalAndCheck ( const G4ThreeVector & point,
G4bool * valid )
virtual

Reimplemented in G4MultiNavigator.

Definition at line 1572 of file G4Navigator.cc.

1579{
1580#ifdef G4DEBUG_NAVIGATION
1581 // Check Current point against expected 'local' value
1582 //
1583 if ( fLastTriedStepComputation )
1584 {
1585 G4ThreeVector ExpectedBoundaryPointLocal;
1586
1587 const G4AffineTransform& GlobalToLocal = GetGlobalToLocalTransform();
1588 ExpectedBoundaryPointLocal =
1589 GlobalToLocal.TransformPoint( ExpectedBoundaryPointGlobal );
1590
1591 // Add here: Comparison against expected position,
1592 // i.e. the endpoint of ComputeStep
1593 }
1594#endif
1595
1596 return GetLocalExitNormal( pValid );
1597}
virtual G4ThreeVector GetLocalExitNormal(G4bool *valid)
const G4AffineTransform & GetGlobalToLocalTransform() const

Referenced by GetGlobalExitNormal().

◆ GetLocalToGlobalTransform()

const G4AffineTransform G4Navigator::GetLocalToGlobalTransform ( ) const
inline

◆ GetMotherToDaughterTransform()

G4AffineTransform G4Navigator::GetMotherToDaughterTransform ( G4VPhysicalVolume * dVolume,
G4int dReplicaNo,
EVolume dVolumeType )

Definition at line 1521 of file G4Navigator.cc.

1524{
1525 switch (enteringVolumeType)
1526 {
1527 case kNormal: // Nothing is needed to prepare the transformation
1528 break; // It is stored already in the physical volume (placement)
1529 case kReplica: // Sets the transform in the Replica - tbc
1530 G4Exception("G4Navigator::GetMotherToDaughterTransform()",
1531 "GeomNav0001", FatalException,
1532 "Method NOT Implemented yet for replica volumes.");
1533 break;
1534 case kParameterised:
1535 if( pEnteringPhysVol->GetRegularStructureId() == 0 )
1536 {
1537 G4VPVParameterisation *pParam =
1538 pEnteringPhysVol->GetParameterisation();
1539 G4VSolid* pSolid =
1540 pParam->ComputeSolid(enteringReplicaNo, pEnteringPhysVol);
1541 pSolid->ComputeDimensions(pParam, enteringReplicaNo, pEnteringPhysVol);
1542
1543 // Sets the transform in the Parameterisation
1544 //
1545 pParam->ComputeTransformation(enteringReplicaNo, pEnteringPhysVol);
1546
1547 // Set the correct solid and material in Logical Volume
1548 //
1549 G4LogicalVolume* pLogical = pEnteringPhysVol->GetLogicalVolume();
1550 pLogical->SetSolid( pSolid );
1551 }
1552 break;
1553 case kExternal:
1554 // Expect that nothing is needed to prepare the transformation.
1555 // It is stored already in the physical volume (placement)
1556 break;
1557 }
1558 return G4AffineTransform(pEnteringPhysVol->GetRotation(),
1559 pEnteringPhysVol->GetTranslation()).Invert();
1560}
G4AffineTransform & Invert()
void SetSolid(G4VSolid *pSolid)
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition G4VSolid.cc:137

Referenced by GetLocalExitNormal().

◆ GetVerboseLevel()

G4int G4Navigator::GetVerboseLevel ( ) const
inline

Referenced by GetGlobalExitNormal().

◆ GetVoxelNavigator()

G4VoxelNavigation & G4Navigator::GetVoxelNavigator ( )
inline

◆ GetWorldVolume()

◆ InformLastStep()

void G4Navigator::InformLastStep ( G4double lastStep,
G4bool entersDaughtVol,
G4bool exitsMotherVol )

Definition at line 2096 of file G4Navigator.cc.

2098{
2099 G4bool zeroStep = ( lastStep == 0.0 );
2100 fLocatedOnEdge = fLastStepWasZero && zeroStep;
2101 fLastStepWasZero = zeroStep;
2102
2103 fExiting = exitsMotherVol;
2104 fEntering = entersDaughtVol;
2105}

◆ IsActive()

G4bool G4Navigator::IsActive ( ) const
inline

◆ IsCheckModeActive()

G4bool G4Navigator::IsCheckModeActive ( ) const
inline

◆ LocateGlobalPointAndSetup()

G4VPhysicalVolume * G4Navigator::LocateGlobalPointAndSetup ( const G4ThreeVector & point,
const G4ThreeVector * direction = nullptr,
const G4bool pRelativeSearch = true,
const G4bool ignoreDirection = true )
virtual

Reimplemented in G4MultiNavigator.

Definition at line 132 of file G4Navigator.cc.

136{
137 G4bool notKnownContained = true, noResult;
138 G4VPhysicalVolume *targetPhysical;
139 G4LogicalVolume *targetLogical;
140 G4VSolid *targetSolid = nullptr;
141 G4ThreeVector localPoint, globalDirection;
142 EInside insideCode;
143
144 G4bool considerDirection = (pGlobalDirection != nullptr) && ((!ignoreDirection) || fLocatedOnEdge);
145
146 fLastTriedStepComputation = false;
147 fChangedGrandMotherRefFrame = false; // For local exit normal
148
149 if( considerDirection )
150 {
151 globalDirection=*pGlobalDirection;
152 }
153
154#ifdef G4VERBOSE
155 if( fVerbose > 2 )
156 {
157 G4long oldcoutPrec = G4cout.precision(8);
158 G4cout << "*** G4Navigator::LocateGlobalPointAndSetup: ***" << G4endl;
159 G4cout << " Called with arguments: " << G4endl
160 << " Globalpoint = " << globalPoint << G4endl
161 << " RelativeSearch = " << relativeSearch << G4endl;
162 if( fVerbose >= 4 )
163 {
164 G4cout << " ----- Upon entering:" << G4endl;
165 PrintState();
166 }
167 G4cout.precision(oldcoutPrec);
168 }
169#endif
170
171 G4int noLevelsExited = 0;
172
173 if ( !relativeSearch )
174 {
176 }
177 else
178 {
180 {
181 fWasLimitedByGeometry = false;
182 fEnteredDaughter = fEntering; // Remember
183 fExitedMother = fExiting; // Remember
184 if ( fExiting )
185 {
186 ++noLevelsExited; // count this first level entered too
187
188 if ( fHistory.GetDepth() != 0 )
189 {
190 fBlockedPhysicalVolume = fHistory.GetTopVolume();
191 fBlockedReplicaNo = fHistory.GetTopReplicaNo();
193 }
194 else
195 {
196 fLastLocatedPointLocal = localPoint;
197 fLocatedOutsideWorld = true;
198 fBlockedPhysicalVolume = nullptr; // to be sure
199 fBlockedReplicaNo = -1;
200 fEntering = false; // No longer
201 fEnteredDaughter = false;
202 fExitedMother = true; // ??
203
204 return nullptr; // Have exited world volume
205 }
206 // A fix for the case where a volume is "entered" at an edge
207 // and a coincident surface exists outside it.
208 // - This stops it from exiting further volumes and cycling
209 // - However ReplicaNavigator treats this case itself
210 //
211 // assert( fBlockedPhysicalVolume!=0 );
212
213 // Expect to be on edge => on surface
214 //
215 if ( fLocatedOnEdge && (VolumeType(fBlockedPhysicalVolume)!=kReplica ))
216 {
217 fExiting = false;
218 // Consider effect on Exit Normal !?
219 }
220 }
221 else
222 if ( fEntering )
223 {
224 switch (VolumeType(fBlockedPhysicalVolume))
225 {
226 case kNormal:
227 fHistory.NewLevel(fBlockedPhysicalVolume, kNormal,
228 fBlockedPhysicalVolume->GetCopyNo());
229 break;
230 case kReplica:
231 freplicaNav.ComputeTransformation(fBlockedReplicaNo,
232 fBlockedPhysicalVolume);
233 fHistory.NewLevel(fBlockedPhysicalVolume, kReplica,
234 fBlockedReplicaNo);
235 fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
236 break;
237 case kParameterised:
238 if( fBlockedPhysicalVolume->GetRegularStructureId() == 0 )
239 {
240 G4VSolid *pSolid;
241 G4VPVParameterisation *pParam;
242 G4TouchableHistory parentTouchable( fHistory );
243 pParam = fBlockedPhysicalVolume->GetParameterisation();
244 pSolid = pParam->ComputeSolid(fBlockedReplicaNo,
245 fBlockedPhysicalVolume);
246 pSolid->ComputeDimensions(pParam, fBlockedReplicaNo,
247 fBlockedPhysicalVolume);
248 pParam->ComputeTransformation(fBlockedReplicaNo,
249 fBlockedPhysicalVolume);
250 fHistory.NewLevel(fBlockedPhysicalVolume, kParameterised,
251 fBlockedReplicaNo);
252 fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
253 //
254 // Set the correct solid and material in Logical Volume
255 //
256 G4LogicalVolume *pLogical;
257 pLogical = fBlockedPhysicalVolume->GetLogicalVolume();
258 pLogical->SetSolid( pSolid );
259 pLogical->UpdateMaterial(pParam ->
260 ComputeMaterial(fBlockedReplicaNo,
261 fBlockedPhysicalVolume,
262 &parentTouchable));
263 }
264 break;
265 case kExternal:
266 G4Exception("G4Navigator::LocateGlobalPointAndSetup()",
267 "GeomNav0001", FatalException,
268 "Extra levels not applicable for external volumes.");
269 break;
270 }
271 fEntering = false;
272 fBlockedPhysicalVolume = nullptr;
273 localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
274 notKnownContained = false;
275 }
276 }
277 else
278 {
279 fBlockedPhysicalVolume = nullptr;
280 fEntering = false;
281 fEnteredDaughter = false; // Full Step was not taken, did not enter
282 fExiting = false;
283 fExitedMother = false; // Full Step was not taken, did not exit
284 }
285 }
286 //
287 // Search from top of history up through geometry until
288 // containing volume found:
289 // If on
290 // o OUTSIDE - Back up level, not/no longer exiting volumes
291 // o SURFACE and EXITING - Back up level, setting new blocking no.s
292 // else
293 // o containing volume found
294 //
295
296 while (notKnownContained) // Loop checking, 07.10.2016, J.Apostolakis
297 {
298 EVolume topVolumeType = fHistory.GetTopVolumeType();
299 if (topVolumeType!=kReplica && topVolumeType!=kExternal)
300 {
301 targetSolid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
302 localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
303 insideCode = targetSolid->Inside(localPoint);
304#ifdef G4VERBOSE
305 if(( fVerbose == 1 ) && ( fCheck ))
306 {
307 G4String solidResponse = "-kInside-";
308 if (insideCode == kOutside)
309 {
310 solidResponse = "-kOutside-";
311 }
312 else if (insideCode == kSurface)
313 {
314 solidResponse = "-kSurface-";
315 }
316 G4cout << "*** G4Navigator::LocateGlobalPointAndSetup(): ***" << G4endl
317 << " Invoked Inside() for solid: " << targetSolid->GetName()
318 << ". Solid replied: " << solidResponse << G4endl
319 << " For local point p: " << localPoint << G4endl;
320 }
321#endif
322 }
323 else
324 {
325 if( topVolumeType == kReplica )
326 {
327 insideCode = freplicaNav.BackLocate(fHistory, globalPoint, localPoint,
328 fExiting, notKnownContained);
329 // !CARE! if notKnownContained returns false then the point is within
330 // the containing placement volume of the replica(s). If insidecode
331 // will result in the history being backed up one level, then the
332 // local point returned is the point in the system of this new level
333 }
334 else
335 {
336 targetSolid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
337 localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
338 G4ThreeVector localDirection =
339 fHistory.GetTopTransform().TransformAxis(globalDirection);
340 insideCode = fpExternalNav->Inside(targetSolid, localPoint, localDirection);
341 }
342 }
343
344 // Point is inside current volume, break out of the loop
345 if ( insideCode == kInside ) { break; }
346
347 // Point is outside current volume, move up a level in the hierarchy
348 if ( insideCode == kOutside )
349 {
350 ++noLevelsExited;
351
352 // Exiting world volume
353 if ( fHistory.GetDepth() == 0 )
354 {
355 fLocatedOutsideWorld = true;
356 fLastLocatedPointLocal = localPoint;
357 return nullptr;
358 }
359
360 fBlockedPhysicalVolume = fHistory.GetTopVolume();
361 fBlockedReplicaNo = fHistory.GetTopReplicaNo();
363 fExiting = false;
364
365 if( noLevelsExited > 1 )
366 {
367 // The first transformation was done by the sub-navigator
368 //
369 if(const auto *mRot = fBlockedPhysicalVolume->GetRotation())
370 {
371 fGrandMotherExitNormal *= (*mRot).inverse();
372 fChangedGrandMotherRefFrame = true;
373 }
374 }
375 continue;
376 }
377
378 // Point is on the surface of a volume
379 G4bool isExiting = fExiting;
380 if( (!fExiting) && considerDirection )
381 {
382 // Figure out whether we are exiting this level's volume
383 // by using the direction
384 //
385 G4bool directionExiting = false;
386 G4ThreeVector localDirection =
387 fHistory.GetTopTransform().TransformAxis(globalDirection);
388
389 // Make sure localPoint in correct reference frame
390 // ( Was it already correct ? How ? )
391 //
392 localPoint= fHistory.GetTopTransform().TransformPoint(globalPoint);
394 {
395 G4ThreeVector normal = targetSolid->SurfaceNormal(localPoint);
396 directionExiting = normal.dot(localDirection) > 0.0;
397 isExiting = isExiting || directionExiting;
398 }
399 }
400
401 // Point is on a surface, but no longer exiting, break out of the loop
402 if ( !isExiting ) { break; }
403
404 ++noLevelsExited;
405
406 // Point is on the outer surface, leaving world volume
407 if ( fHistory.GetDepth() == 0 )
408 {
409 fLocatedOutsideWorld = true;
410 fLastLocatedPointLocal = localPoint;
411 return nullptr;
412 }
413
414 // Point is still on a surface, but exited a volume not necessarily convex
415 fValidExitNormal = false;
416 fBlockedPhysicalVolume = fHistory.GetTopVolume();
417 fBlockedReplicaNo = fHistory.GetTopReplicaNo();
419
420 if( noLevelsExited > 1 )
421 {
422 // The first transformation was done by the sub-navigator
423 //
424 const G4RotationMatrix* mRot =
425 fBlockedPhysicalVolume->GetRotation();
426 if( mRot != nullptr )
427 {
428 fGrandMotherExitNormal *= (*mRot).inverse();
429 fChangedGrandMotherRefFrame = true;
430 }
431 }
432 } // END while (notKnownContained)
433 //
434 // Search downwards until deepest containing volume found,
435 // blocking fBlockedPhysicalVolume/BlockedReplicaNum
436 //
437 // 3 Cases:
438 //
439 // o Parameterised daughters
440 // =>Must be one G4PVParameterised daughter & voxels
441 // o Positioned daughters & voxels
442 // o Positioned daughters & no voxels
443
444 noResult = true; // noResult should be renamed to
445 // something like enteredLevel, as that is its meaning.
446 do
447 {
448 // Determine `type' of current mother volume
449 //
450 targetPhysical = fHistory.GetTopVolume();
451 if (targetPhysical == nullptr) { break; }
452 targetLogical = targetPhysical->GetLogicalVolume();
453 switch( CharacteriseDaughters(targetLogical) )
454 {
455 case kNormal:
456 if ( targetLogical->GetVoxelHeader() != nullptr ) // use optimised navigation
457 {
459 fBlockedPhysicalVolume,
460 fBlockedReplicaNo,
461 globalPoint,
462 pGlobalDirection,
463 considerDirection,
464 localPoint);
465 }
466 else // do not use optimised navigation
467 {
468 noResult = fnormalNav.LevelLocate(fHistory,
469 fBlockedPhysicalVolume,
470 fBlockedReplicaNo,
471 globalPoint,
472 pGlobalDirection,
473 considerDirection,
474 localPoint);
475 }
476 break;
477 case kReplica:
478 noResult = freplicaNav.LevelLocate(fHistory,
479 fBlockedPhysicalVolume,
480 fBlockedReplicaNo,
481 globalPoint,
482 pGlobalDirection,
483 considerDirection,
484 localPoint);
485 break;
486 case kParameterised:
487 if( GetDaughtersRegularStructureId(targetLogical) != 1 )
488 {
489 noResult = fparamNav.LevelLocate(fHistory,
490 fBlockedPhysicalVolume,
491 fBlockedReplicaNo,
492 globalPoint,
493 pGlobalDirection,
494 considerDirection,
495 localPoint);
496 }
497 else // Regular structure
498 {
499 noResult = fregularNav.LevelLocate(fHistory,
500 fBlockedPhysicalVolume,
501 fBlockedReplicaNo,
502 globalPoint,
503 pGlobalDirection,
504 considerDirection,
505 localPoint);
506 }
507 break;
508 case kExternal:
509 noResult = fpExternalNav->LevelLocate(fHistory,
510 fBlockedPhysicalVolume,
511 fBlockedReplicaNo,
512 globalPoint,
513 pGlobalDirection,
514 considerDirection,
515 localPoint);
516 break;
517 }
518
519 // LevelLocate returns true if it finds a daughter volume
520 // in which globalPoint is inside (or on the surface).
521
522 if ( noResult )
523 {
524 // Entering a daughter after ascending
525 //
526 // The blocked volume is no longer valid - it was for another level
527 //
528 fBlockedPhysicalVolume = nullptr;
529 fBlockedReplicaNo = -1;
530
531 // fEntering should be false -- else blockedVolume is assumed good.
532 // fEnteredDaughter is used for ExitNormal
533 //
534 fEntering = false;
535 fEnteredDaughter = true;
536
537 if( fExitedMother )
538 {
539 G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
540 const G4RotationMatrix* mRot = enteredPhysical->GetRotation();
541 if( mRot != nullptr )
542 {
543 // Go deeper, i.e. move 'down' in the hierarchy
544 // Apply direct rotation, not inverse
545 //
546 fGrandMotherExitNormal *= (*mRot);
547 fChangedGrandMotherRefFrame= true;
548 }
549 }
550
551#ifdef G4DEBUG_NAVIGATION
552 if( fVerbose > 2 )
553 {
554 G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
555 G4cout << "*** G4Navigator::LocateGlobalPointAndSetup() ***" << G4endl;
556 G4cout << " Entering volume: " << enteredPhysical->GetName()
557 << G4endl;
558 }
559#endif
560 }
561 } while (noResult); // Loop checking, 07.10.2016, J.Apostolakis
562
563 fLastLocatedPointLocal = localPoint;
564
565#ifdef G4VERBOSE
566 if( fVerbose >= 4 )
567 {
568 G4long oldcoutPrec = G4cout.precision(8);
569 G4String curPhysVol_Name("None");
570 if (targetPhysical != nullptr) { curPhysVol_Name = targetPhysical->GetName(); }
571 G4cout << " Return value = new volume = " << curPhysVol_Name << G4endl;
572 G4cout << " ----- Upon exiting:" << G4endl;
573 PrintState();
574 if( fVerbose >= 5 )
575 {
576 G4cout << "Upon exiting LocateGlobalPointAndSetup():" << G4endl;
577 G4cout << " History = " << G4endl << fHistory << G4endl << G4endl;
578 }
579 G4cout.precision(oldcoutPrec);
580 }
581#endif
582
583 fLocatedOutsideWorld = false;
584
585 return targetPhysical;
586}
long G4long
Definition G4Types.hh:87
double dot(const Hep3Vector &) const
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
void UpdateMaterial(G4Material *pMaterial)
void NewLevel(G4VPhysicalVolume *pNewMother, EVolume vType=kNormal, G4int nReplica=-1)
G4int GetTopReplicaNo() const
G4bool fWasLimitedByGeometry
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) final
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) override
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) final
void ComputeTransformation(const G4int replicaNo, G4VPhysicalVolume *pVol, G4ThreeVector &point) const
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
EInside BackLocate(G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool &notKnownInside) const
virtual EInside Inside(const G4VSolid *solid, const G4ThreeVector &position, const G4ThreeVector &direction)
virtual G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)=0
virtual void SetCopyNo(G4int CopyNo)=0
virtual G4VPVParameterisation * GetParameterisation() const =0
virtual G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) override
EVolume
Definition geomdefs.hh:83

Referenced by G4AdjointPrimaryGenerator::ComputeAccumulatedDepthVectorAlongBackRay(), ComputeStep(), G4TheRayTracer::CreateBitMap(), G4VFieldModel::DescribeYourselfTo(), G4TrajectoryDrawByOriginVolume::Draw(), G4TrajectoryOriginVolumeFilter::Evaluate(), G4SafetyHelper::Locate(), G4VIntersectionLocator::LocateGlobalPointWithinVolumeAndCheck(), ResetHierarchyAndLocate(), and G4SteppingManager::SetInitialStep().

◆ LocateGlobalPointAndUpdateTouchable() [1/2]

void G4Navigator::LocateGlobalPointAndUpdateTouchable ( const G4ThreeVector & position,
const G4ThreeVector & direction,
G4VTouchable * touchableToUpdate,
const G4bool RelativeSearch = true )
inline

◆ LocateGlobalPointAndUpdateTouchable() [2/2]

void G4Navigator::LocateGlobalPointAndUpdateTouchable ( const G4ThreeVector & position,
G4VTouchable * touchableToUpdate,
const G4bool RelativeSearch = true )
inline

◆ LocateGlobalPointAndUpdateTouchableHandle()

void G4Navigator::LocateGlobalPointAndUpdateTouchableHandle ( const G4ThreeVector & position,
const G4ThreeVector & direction,
G4TouchableHandle & oldTouchableToUpdate,
const G4bool RelativeSearch = true )
inline

◆ LocateGlobalPointWithinVolume()

void G4Navigator::LocateGlobalPointWithinVolume ( const G4ThreeVector & position)
virtual

Reimplemented in G4MultiNavigator.

Definition at line 602 of file G4Navigator.cc.

603{
604#ifdef G4DEBUG_NAVIGATION
605 assert( !fWasLimitedByGeometry );
606 // Check: Either step was not limited by a boundary or
607 // else the full step is no longer being taken
608#endif
609
610 fLastLocatedPointLocal = ComputeLocalPoint(pGlobalpoint);
611 fLastTriedStepComputation = false;
612 fChangedGrandMotherRefFrame = false; // Frame for Exit Normal
613
614 // For the case of Voxel (or Parameterised) volume the respective
615 // Navigator must be messaged to update its voxel information etc
616
617 // Update the state of the Sub Navigators
618 // - in particular any voxel information they store/cache
619 //
620 G4VPhysicalVolume* motherPhysical = fHistory.GetTopVolume();
621 G4LogicalVolume* motherLogical = motherPhysical->GetLogicalVolume();
622
623 switch( CharacteriseDaughters(motherLogical) )
624 {
625 case kNormal:
626 GetVoxelNavigator().RelocateWithinVolume( motherPhysical, fLastLocatedPointLocal );
627 break;
628 case kParameterised:
629 fparamNav.RelocateWithinVolume( motherPhysical, fLastLocatedPointLocal );
630 break;
631 case kReplica:
632 // Nothing to do
633 break;
634 case kExternal:
635 fpExternalNav->RelocateWithinVolume( motherPhysical,
636 fLastLocatedPointLocal );
637 break;
638 }
639
640 // Reset the state variables
641 // - which would have been affected
642 // by the 'equivalent' call to LocateGlobalPointAndSetup
643 // - who's values have been invalidated by the 'move'.
644 //
645 fBlockedPhysicalVolume = nullptr;
646 fBlockedReplicaNo = -1;
647 fEntering = false;
648 fEnteredDaughter = false; // Boundary not encountered, did not enter
649 fExiting = false;
650 fExitedMother = false; // Boundary not encountered, did not exit
651}
void RelocateWithinVolume(G4VPhysicalVolume *motherPhysical, const G4ThreeVector &localPoint) override
virtual void RelocateWithinVolume(G4VPhysicalVolume *motherPhysical, const G4ThreeVector &localPoint)
virtual void RelocateWithinVolume(G4VPhysicalVolume *motherPhysical, const G4ThreeVector &localPoint) override

Referenced by G4VIntersectionLocator::AdjustmentOfFoundIntersection(), G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(), ComputeStep(), G4PropagatorInField::ComputeStep(), G4BrentLocator::EstimateIntersectionPoint(), G4MultiLevelLocator::EstimateIntersectionPoint(), G4SimpleLocator::EstimateIntersectionPoint(), G4VIntersectionLocator::LocateGlobalPointWithinVolumeAndCheck(), G4Transportation::PostStepDoIt(), and G4SafetyHelper::ReLocateWithinVolume().

◆ NetRotation()

G4RotationMatrix G4Navigator::NetRotation ( ) const
inline

◆ NetTranslation()

G4ThreeVector G4Navigator::NetTranslation ( ) const
inline

◆ operator=()

G4Navigator & G4Navigator::operator= ( const G4Navigator & )
delete

◆ PrintState()

void G4Navigator::PrintState ( ) const

Definition at line 1818 of file G4Navigator.cc.

1819{
1820 G4long oldcoutPrec = G4cout.precision(4);
1821 if( fVerbose >= 4 )
1822 {
1823 G4cout << "The current state of G4Navigator is: " << G4endl;
1824 G4cout << " ValidExitNormal= " << fValidExitNormal // << G4endl
1825 << " ExitNormal = " << fExitNormal // << G4endl
1826 << " Exiting = " << fExiting // << G4endl
1827 << " Entering = " << fEntering // << G4endl
1828 << " BlockedPhysicalVolume= " ;
1829 if (fBlockedPhysicalVolume==nullptr)
1830 {
1831 G4cout << "None";
1832 }
1833 else
1834 {
1835 G4cout << fBlockedPhysicalVolume->GetName();
1836 }
1837 G4cout << G4endl
1838 << " BlockedReplicaNo = " << fBlockedReplicaNo // << G4endl
1839 << " LastStepWasZero = " << fLastStepWasZero // << G4endl
1840 << G4endl;
1841 }
1842 if( ( 1 < fVerbose) && (fVerbose < 4) )
1843 {
1844 G4cout << G4endl; // Make sure to line up
1845 G4cout << std::setw(30) << " ExitNormal " << " "
1846 << std::setw( 5) << " Valid " << " "
1847 << std::setw( 9) << " Exiting " << " "
1848 << std::setw( 9) << " Entering" << " "
1849 << std::setw(15) << " Blocked:Volume " << " "
1850 << std::setw( 9) << " ReplicaNo" << " "
1851 << std::setw( 8) << " LastStepZero " << " "
1852 << G4endl;
1853 G4cout << "( " << std::setw(7) << fExitNormal.x()
1854 << ", " << std::setw(7) << fExitNormal.y()
1855 << ", " << std::setw(7) << fExitNormal.z() << " ) "
1856 << std::setw( 5) << fValidExitNormal << " "
1857 << std::setw( 9) << fExiting << " "
1858 << std::setw( 9) << fEntering << " ";
1859 if ( fBlockedPhysicalVolume == nullptr )
1860 { G4cout << std::setw(15) << "None"; }
1861 else
1862 { G4cout << std::setw(15)<< fBlockedPhysicalVolume->GetName(); }
1863 G4cout << std::setw( 9) << fBlockedReplicaNo << " "
1864 << std::setw( 8) << fLastStepWasZero << " "
1865 << G4endl;
1866 }
1867 if( fVerbose > 2 )
1868 {
1869 G4cout.precision(8);
1870 G4cout << " Current Localpoint = " << fLastLocatedPointLocal << G4endl;
1871 G4cout << " PreviousSftOrigin = " << fPreviousSftOrigin << G4endl;
1872 G4cout << " PreviousSafety = " << fPreviousSafety << G4endl;
1873 }
1874 G4cout.precision(oldcoutPrec);
1875}
#define fEntering
double z() const
double x() const
double y() const

Referenced by ComputeStep(), and LocateGlobalPointAndSetup().

◆ ResetHierarchyAndLocate()

G4VPhysicalVolume * G4Navigator::ResetHierarchyAndLocate ( const G4ThreeVector & point,
const G4ThreeVector & direction,
const G4TouchableHistory & h )
virtual

Reimplemented in G4MultiNavigator.

Definition at line 102 of file G4Navigator.cc.

105{
106 ResetState();
107 fHistory = *h.GetHistory();
109 fLastTriedStepComputation = false; // Redundant, but best
110 return LocateGlobalPointAndSetup(p, &direction, true, false);
111}
virtual void SetupHierarchy()
virtual void ResetState()
virtual const G4NavigationHistory * GetHistory() const

Referenced by G4MultiNavigator::ResetHierarchyAndLocate(), and G4SteppingManager::SetInitialStep().

◆ ResetStackAndState()

void G4Navigator::ResetStackAndState ( )
inline

◆ ResetState()

void G4Navigator::ResetState ( )
protectedvirtual

Reimplemented in G4MultiNavigator.

Definition at line 1259 of file G4Navigator.cc.

1260{
1261 fWasLimitedByGeometry = false;
1262 fEntering = false;
1263 fExiting = false;
1264 fLocatedOnEdge = false;
1265 fLastStepWasZero = false;
1266 fEnteredDaughter = false;
1267 fExitedMother = false;
1268 fPushed = false;
1269
1270 fValidExitNormal = false;
1271 fChangedGrandMotherRefFrame = false;
1272 fCalculatedExitNormal = false;
1273
1274 fExitNormal = G4ThreeVector(0,0,0);
1275 fGrandMotherExitNormal = G4ThreeVector(0,0,0);
1276 fExitNormalGlobalFrame = G4ThreeVector(0,0,0);
1277
1278 fPreviousSftOrigin = G4ThreeVector(0,0,0);
1279 fPreviousSafety = 0.0;
1280
1281 fNumberZeroSteps = 0;
1282
1283 fBlockedPhysicalVolume = nullptr;
1284 fBlockedReplicaNo = -1;
1285
1286 fLastLocatedPointLocal = G4ThreeVector( kInfinity, -kInfinity, 0.0 );
1287 fLocatedOutsideWorld = false;
1288
1289 fLastMotherPhys = nullptr;
1290}

Referenced by ResetHierarchyAndLocate().

◆ RestoreSavedState()

void G4Navigator::RestoreSavedState ( )
protected

Definition at line 695 of file G4Navigator.cc.

696{
697 fExitNormal = fSaveState.sExitNormal;
698 fValidExitNormal = fSaveState.sValidExitNormal;
699 fExiting = fSaveState.sExiting;
700 fEntering = fSaveState.sEntering;
701
702 fBlockedPhysicalVolume = fSaveState.spBlockedPhysicalVolume;
703 fBlockedReplicaNo = fSaveState.sBlockedReplicaNo;
704
705 fLastStepWasZero = (fSaveState.sLastStepWasZero != 0);
706
707 fLocatedOutsideWorld = fSaveState.sLocatedOutsideWorld;
708 fLastLocatedPointLocal = fSaveState.sLastLocatedPointLocal;
709 fEnteredDaughter = fSaveState.sEnteredDaughter;
710 fExitedMother = fSaveState.sExitedMother;
711 fWasLimitedByGeometry = fSaveState.sWasLimitedByGeometry;
712
713 // The 'expected' behaviour is to restore these too (fix 2014.05.26)
714 fPreviousSftOrigin = fSaveState.sPreviousSftOrigin;
715 fPreviousSafety = fSaveState.sPreviousSafety;
716}

Referenced by CheckNextStep().

◆ SetExternalNavigation()

void G4Navigator::SetExternalNavigation ( G4VExternalNavigation * externalNav)

Definition at line 2111 of file G4Navigator.cc.

2112{
2113 fpExternalNav = externalNav;
2114 fpSafetyCalculator->SetExternalNavigation(externalNav);
2115}

◆ SetGeometricallyLimitedStep()

void G4Navigator::SetGeometricallyLimitedStep ( )
inline

◆ SetPushVerbosity()

◆ SetSavedState()

void G4Navigator::SetSavedState ( )
protected

Definition at line 661 of file G4Navigator.cc.

662{
663 // Note: the state of dependent objects is not currently saved.
664 // ( This means that the full state is changed by calls between
665 // SetSavedState() and RestoreSavedState();
666
667 fSaveState.sExitNormal = fExitNormal;
668 fSaveState.sValidExitNormal = fValidExitNormal;
669 fSaveState.sExiting = fExiting;
670 fSaveState.sEntering = fEntering;
671
672 fSaveState.spBlockedPhysicalVolume = fBlockedPhysicalVolume;
673 fSaveState.sBlockedReplicaNo = fBlockedReplicaNo;
674
675 fSaveState.sLastStepWasZero = static_cast<G4int>(fLastStepWasZero);
676
677 fSaveState.sLocatedOutsideWorld = fLocatedOutsideWorld;
678 fSaveState.sLastLocatedPointLocal = fLastLocatedPointLocal;
679 fSaveState.sEnteredDaughter = fEnteredDaughter;
680 fSaveState.sExitedMother = fExitedMother;
681 fSaveState.sWasLimitedByGeometry = fWasLimitedByGeometry;
682
683 // Even the safety sphere - if you want to change it do it explicitly!
684 //
685 fSaveState.sPreviousSftOrigin = fPreviousSftOrigin;
686 fSaveState.sPreviousSafety = fPreviousSafety;
687}

Referenced by CheckNextStep().

◆ SetupHierarchy()

void G4Navigator::SetupHierarchy ( )
protectedvirtual

Reimplemented in G4MultiNavigator.

Definition at line 1300 of file G4Navigator.cc.

1301{
1302 const auto depth = (G4int)fHistory.GetDepth();
1303 for ( auto i = 1; i <= depth; ++i )
1304 {
1305 switch ( fHistory.GetVolumeType(i) )
1306 {
1307 case kNormal:
1308 case kExternal:
1309 break;
1310 case kReplica:
1312 break;
1313 case kParameterised:
1314 G4VPhysicalVolume* current = fHistory.GetVolume(i);
1315 G4int replicaNo = fHistory.GetReplicaNo(i);
1316 G4VPVParameterisation* pParam = current->GetParameterisation();
1317 G4VSolid* pSolid = pParam->ComputeSolid(replicaNo, current);
1318
1319 // Set up dimensions & transform in solid/physical volume
1320 //
1321 pSolid->ComputeDimensions(pParam, replicaNo, current);
1322 pParam->ComputeTransformation(replicaNo, current);
1323
1324 G4TouchableHistory* pTouchable = nullptr;
1325 if( pParam->IsNested() )
1326 {
1327 pTouchable= new G4TouchableHistory( fHistory );
1328 pTouchable->MoveUpHistory(); // Move up to the parent level
1329 // Adequate only if Nested at the Branch level (last)
1330 // To extend to other cases:
1331 // pTouchable->MoveUpHistory(cdepth-i-1);
1332 // Move to the parent level of *Current* level
1333 // Could replace this line and constructor with a revised
1334 // c-tor for History(levels to drop)
1335 }
1336 // Set up the correct solid and material in Logical Volume
1337 //
1338 G4LogicalVolume* pLogical = current->GetLogicalVolume();
1339 pLogical->SetSolid( pSolid );
1340 pLogical->UpdateMaterial( pParam ->
1341 ComputeMaterial(replicaNo, current, pTouchable) );
1342 delete pTouchable;
1343 break;
1344 }
1345 }
1346}
G4int GetReplicaNo(G4int n) const
G4VPhysicalVolume * GetVolume(G4int n) const
EVolume GetVolumeType(G4int n) const
virtual G4int MoveUpHistory(G4int num_levels=1)
virtual G4bool IsNested() const

Referenced by ResetHierarchyAndLocate().

◆ SetVerboseLevel()

void G4Navigator::SetVerboseLevel ( G4int level)
inline

Referenced by GetGlobalExitNormal().

◆ SetVoxelNavigation()

void G4Navigator::SetVoxelNavigation ( G4VoxelNavigation * voxelNav)

Definition at line 2086 of file G4Navigator.cc.

2087{
2088 delete fpvoxelNav;
2089 fpvoxelNav = voxelNav;
2090}

◆ SetWorldVolume()

◆ SeverityOfZeroStepping()

G4int G4Navigator::SeverityOfZeroStepping ( G4int * noZeroSteps) const
inline

◆ VolumeType()

EVolume G4Navigator::VolumeType ( const G4VPhysicalVolume * pVol) const
inlineprotected

Friends And Related Symbol Documentation

◆ operator<<

std::ostream & operator<< ( std::ostream & os,
const G4Navigator & n )
friend

Definition at line 2011 of file G4Navigator.cc.

2012{
2013 // Old version did only the following:
2014 // os << "Current History: " << G4endl << n.fHistory;
2015 // Old behaviour is recovered for fVerbose = 0
2016
2017 // Adapted from G4Navigator::PrintState() const
2018
2019 G4long oldcoutPrec = os.precision(4);
2020 if( n.fVerbose >= 4 )
2021 {
2022 os << "The current state of G4Navigator is: " << G4endl;
2023 os << " ValidExitNormal= " << n.fValidExitNormal << G4endl
2024 << " ExitNormal = " << n.fExitNormal << G4endl
2025 << " Exiting = " << n.fExiting << G4endl
2026 << " Entering = " << n.fEntering << G4endl
2027 << " BlockedPhysicalVolume= " ;
2028 if (n.fBlockedPhysicalVolume==nullptr)
2029 {
2030 os << "None";
2031 }
2032 else
2033 {
2034 os << n.fBlockedPhysicalVolume->GetName();
2035 }
2036 os << G4endl
2037 << " BlockedReplicaNo = " << n.fBlockedReplicaNo << G4endl
2038 << " LastStepWasZero = " << n.fLastStepWasZero << G4endl
2039 << G4endl;
2040 }
2041 if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )
2042 {
2043 os << G4endl; // Make sure to line up
2044 os << std::setw(30) << " ExitNormal " << " "
2045 << std::setw( 5) << " Valid " << " "
2046 << std::setw( 9) << " Exiting " << " "
2047 << std::setw( 9) << " Entering" << " "
2048 << std::setw(15) << " Blocked:Volume " << " "
2049 << std::setw( 9) << " ReplicaNo" << " "
2050 << std::setw( 8) << " LastStepZero " << " "
2051 << G4endl;
2052 os << "( " << std::setw(7) << n.fExitNormal.x()
2053 << ", " << std::setw(7) << n.fExitNormal.y()
2054 << ", " << std::setw(7) << n.fExitNormal.z() << " ) "
2055 << std::setw( 5) << n.fValidExitNormal << " "
2056 << std::setw( 9) << n.fExiting << " "
2057 << std::setw( 9) << n.fEntering << " ";
2058 if ( n.fBlockedPhysicalVolume==nullptr )
2059 { os << std::setw(15) << "None"; }
2060 else
2061 { os << std::setw(15)<< n.fBlockedPhysicalVolume->GetName(); }
2062 os << std::setw( 9) << n.fBlockedReplicaNo << " "
2063 << std::setw( 8) << n.fLastStepWasZero << " "
2064 << G4endl;
2065 }
2066 if( n.fVerbose > 2 )
2067 {
2068 os.precision(8);
2069 os << " Current Localpoint = " << n.fLastLocatedPointLocal << G4endl;
2070 os << " PreviousSftOrigin = " << n.fPreviousSftOrigin << G4endl;
2071 os << " PreviousSafety = " << n.fPreviousSafety << G4endl;
2072 }
2073 if( n.fVerbose > 3 || n.fVerbose == 0 )
2074 {
2075 os << "Current History: " << G4endl << n.fHistory;
2076 }
2077
2078 os.precision(oldcoutPrec);
2079 return os;
2080}

Member Data Documentation

◆ fEnteredDaughter

G4bool G4Navigator::fEnteredDaughter
protected

◆ fExitedMother

◆ fHistory

◆ fLastStepEndPointLocal

G4ThreeVector G4Navigator::fLastStepEndPointLocal
protected

Definition at line 380 of file G4Navigator.hh.

Referenced by ComputeStep(), G4Navigator(), and GetLocalExitNormal().

◆ fMinStep

G4double G4Navigator::fMinStep
protected

Definition at line 366 of file G4Navigator.hh.

Referenced by ComputeStep(), and G4Navigator().

◆ fSqTol

G4double G4Navigator::fSqTol
protected

Definition at line 366 of file G4Navigator.hh.

Referenced by ComputeStep(), G4Navigator(), and GetGlobalExitNormal().

◆ fStepEndPoint

G4ThreeVector G4Navigator::fStepEndPoint
protected

◆ fVerbose

◆ fWasLimitedByGeometry

◆ kCarTolerance

G4double G4Navigator::kCarTolerance
protected

The documentation for this class was generated from the following files: