Geant4-11
Public Member Functions | Private Member Functions | Private Attributes
G4ReplicaNavigation Class Reference

#include <G4ReplicaNavigation.hh>

Public Member Functions

EInside BackLocate (G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool &notKnownInside) const
 
void CheckMode (G4bool mode)
 
G4double ComputeSafety (const G4ThreeVector &globalPoint, const G4ThreeVector &localPoint, G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
 
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)
 
void ComputeTransformation (const G4int replicaNo, G4VPhysicalVolume *pVol) const
 
void ComputeTransformation (const G4int replicaNo, G4VPhysicalVolume *pVol, G4ThreeVector &point) const
 
G4double DistanceToOut (const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
 
G4double DistanceToOut (const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4ExitNormal &candidateNormal) const
 
 G4ReplicaNavigation ()
 
G4int GetVerboseLevel () const
 
EInside Inside (const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
 
G4bool LevelLocate (G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
 
void SetVerboseLevel (G4int level)
 
 ~G4ReplicaNavigation ()
 

Private Member Functions

G4double DistanceToOutPhi (const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double width, G4ExitNormal &foundNormal) const
 
G4double DistanceToOutRad (const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double width, const G4double offset, const G4int replicaNo, G4ExitNormal &foundNormal) const
 
void SetPhiTransformation (const G4double ang, G4VPhysicalVolume *pVol=0) const
 
G4int VoxelLocate (const G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint, const G4int blocked=-1) const
 

Private Attributes

G4bool fCheck = false
 
G4double fMinStep
 
G4int fVerbose = 0
 
G4double halfkAngTolerance
 
G4double halfkCarTolerance
 
G4double halfkRadTolerance
 
G4double kAngTolerance
 
G4double kCarTolerance
 
G4double kRadTolerance
 

Detailed Description

Definition at line 78 of file G4ReplicaNavigation.hh.

Constructor & Destructor Documentation

◆ G4ReplicaNavigation()

G4ReplicaNavigation::G4ReplicaNavigation ( )

Definition at line 53 of file G4ReplicaNavigation.cc.

54{
62}
G4double GetSurfaceTolerance() const
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const

References fMinStep, G4GeometryTolerance::GetAngularTolerance(), G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetRadialTolerance(), G4GeometryTolerance::GetSurfaceTolerance(), halfkAngTolerance, halfkCarTolerance, halfkRadTolerance, kAngTolerance, kCarTolerance, and kRadTolerance.

◆ ~G4ReplicaNavigation()

G4ReplicaNavigation::~G4ReplicaNavigation ( )

Definition at line 68 of file G4ReplicaNavigation.cc.

69{
70}

Member Function Documentation

◆ BackLocate()

EInside G4ReplicaNavigation::BackLocate ( G4NavigationHistory history,
const G4ThreeVector globalPoint,
G4ThreeVector localPoint,
const G4bool exiting,
G4bool notKnownInside 
) const

Definition at line 1241 of file G4ReplicaNavigation.cc.

1246{
1247 G4VPhysicalVolume *pNRMother = nullptr;
1248 G4VSolid *motherSolid;
1249 G4ThreeVector repPoint, goodPoint;
1250 G4int mdepth, depth, cdepth;
1251 EInside insideCode;
1252
1253 cdepth = history.GetDepth();
1254
1255 // Find non replicated mother
1256 //
1257 for ( mdepth=cdepth-1; mdepth>=0; mdepth-- )
1258 {
1259 if ( history.GetVolumeType(mdepth)!=kReplica )
1260 {
1261 pNRMother = history.GetVolume(mdepth);
1262 break;
1263 }
1264 }
1265
1266 if( pNRMother == nullptr )
1267 {
1268 // All the tree of mother volumes were Replicas.
1269 // This is an error, as the World volume must be a Placement
1270 //
1271 G4Exception("G4ReplicaNavigation::BackLocate()", "GeomNav0002",
1272 FatalException, "The World volume must be a Placement!");
1273 return kInside;
1274 }
1275
1276 motherSolid = pNRMother->GetLogicalVolume()->GetSolid();
1277 goodPoint = history.GetTransform(mdepth).TransformPoint(globalPoint);
1278 insideCode = motherSolid->Inside(goodPoint);
1279 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
1280 {
1281 // Outside mother -> back up to mother level
1282 // Locate.. in Navigator will back up one more level
1283 // localPoint not required
1284 //
1285 history.BackLevel(cdepth-mdepth);
1286 // localPoint = goodPoint;
1287 }
1288 else
1289 {
1290 notKnownInside = false;
1291
1292 // Still within replications
1293 // Check down: if on outside stop at this level
1294 //
1295 for ( depth=mdepth+1; depth<cdepth; ++depth)
1296 {
1297 repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1298 insideCode = Inside(history.GetVolume(depth),
1299 history.GetReplicaNo(depth),
1300 repPoint);
1301 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
1302 {
1303 localPoint = goodPoint;
1304 history.BackLevel(cdepth-depth);
1305 return insideCode;
1306 }
1307 else
1308 {
1309 goodPoint = repPoint;
1310 }
1311 }
1312 localPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1313 insideCode = Inside(history.GetVolume(depth),
1314 history.GetReplicaNo(depth),
1315 localPoint);
1316 // If outside level, set localPoint = coordinates in reference system
1317 // of *previous* level - location code in navigator will back up one
1318 // level [And also manage blocking]
1319 //
1320 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
1321 {
1322 localPoint = goodPoint;
1323 }
1324 }
1325 return insideCode;
1326}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
int G4int
Definition: G4Types.hh:85
G4VSolid * GetSolid() const
EInside Inside(const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
G4LogicalVolume * GetLogicalVolume() const
virtual EInside Inside(const G4ThreeVector &p) const =0
EInside
Definition: geomdefs.hh:67
@ kInside
Definition: geomdefs.hh:70
@ kOutside
Definition: geomdefs.hh:68
@ kSurface
Definition: geomdefs.hh:69
@ kReplica
Definition: geomdefs.hh:85
def history()
Definition: g4zmq.py:84

References FatalException, G4Exception(), G4VPhysicalVolume::GetLogicalVolume(), G4LogicalVolume::GetSolid(), g4zmq::history(), G4VSolid::Inside(), Inside(), kInside, kOutside, kReplica, and kSurface.

Referenced by G4ITNavigator1::LocateGlobalPointAndSetup(), G4ITNavigator2::LocateGlobalPointAndSetup(), and G4Navigator::LocateGlobalPointAndSetup().

◆ CheckMode()

void G4ReplicaNavigation::CheckMode ( G4bool  mode)
inline

◆ ComputeSafety()

G4double G4ReplicaNavigation::ComputeSafety ( const G4ThreeVector globalPoint,
const G4ThreeVector localPoint,
G4NavigationHistory history,
const G4double  pProposedMaxLength = DBL_MAX 
)

Definition at line 1152 of file G4ReplicaNavigation.cc.

1156{
1157 G4VPhysicalVolume *repPhysical, *motherPhysical;
1158 G4VPhysicalVolume *samplePhysical, *blockedExitedVol = nullptr;
1159 G4LogicalVolume *repLogical;
1160 G4VSolid *motherSolid;
1161 G4ThreeVector repPoint;
1162 G4double ourSafety = kInfinity;
1163 G4double sampleSafety;
1164 G4int localNoDaughters, sampleNo;
1165 G4int depth;
1166
1167 repPhysical = history.GetTopVolume();
1168 repLogical = repPhysical->GetLogicalVolume();
1169
1170 //
1171 // Compute intersection with replica boundaries & replica safety
1172 //
1173
1174 sampleSafety = DistanceToOut(history.GetTopVolume(),
1175 history.GetTopReplicaNo(),
1176 localPoint);
1177 if ( sampleSafety<ourSafety )
1178 {
1179 ourSafety = sampleSafety;
1180 }
1181
1182 depth = history.GetDepth()-1;
1183
1184 // Loop checking, 07.10.2016, JA -- need to add: assert(depth>0)
1185 while ( history.GetVolumeType(depth)==kReplica )
1186 {
1187 repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1188 sampleSafety = DistanceToOut(history.GetVolume(depth),
1189 history.GetReplicaNo(depth),
1190 repPoint);
1191 if ( sampleSafety<ourSafety )
1192 {
1193 ourSafety = sampleSafety;
1194 }
1195 depth--;
1196 }
1197
1198 // Compute mother safety & intersection
1199 //
1200 repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1201 motherPhysical = history.GetVolume(depth);
1202 motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
1203 sampleSafety = motherSolid->DistanceToOut(repPoint);
1204
1205 if ( sampleSafety<ourSafety )
1206 {
1207 ourSafety = sampleSafety;
1208 }
1209
1210 // Compute daughter safeties & intersections
1211 //
1212 localNoDaughters = repLogical->GetNoDaughters();
1213 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1214 {
1215 samplePhysical = repLogical->GetDaughter(sampleNo);
1216 if ( samplePhysical!=blockedExitedVol )
1217 {
1218 G4AffineTransform sampleTf(samplePhysical->GetRotation(),
1219 samplePhysical->GetTranslation());
1220 sampleTf.Invert();
1221 const G4ThreeVector samplePoint =
1222 sampleTf.TransformPoint(localPoint);
1223 const G4VSolid *sampleSolid =
1224 samplePhysical->GetLogicalVolume()->GetSolid();
1225 const G4double sampleSafetyDistance =
1226 sampleSolid->DistanceToIn(samplePoint);
1227 if ( sampleSafetyDistance<ourSafety )
1228 {
1229 ourSafety = sampleSafetyDistance;
1230 }
1231 }
1232 }
1233 return ourSafety;
1234}
double G4double
Definition: G4Types.hh:83
size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
G4double DistanceToOut(const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
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
static const G4double kInfinity
Definition: geomdefs.hh:41

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), DistanceToOut(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4VPhysicalVolume::GetTranslation(), g4zmq::history(), G4AffineTransform::Invert(), kInfinity, kReplica, and G4AffineTransform::TransformPoint().

Referenced by G4Navigator::ComputeSafety(), G4ITNavigator1::ComputeSafety(), and G4ITNavigator2::ComputeSafety().

◆ ComputeStep()

G4double G4ReplicaNavigation::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 
)

Definition at line 749 of file G4ReplicaNavigation.cc.

764{
765 G4VPhysicalVolume *repPhysical, *motherPhysical;
766 G4VPhysicalVolume *samplePhysical, *blockedExitedVol = nullptr;
767 G4LogicalVolume *repLogical;
768 G4VSolid *motherSolid;
769 G4ThreeVector repPoint, repDirection, sampleDirection;
770 G4double ourStep=currentProposedStepLength;
771 G4double ourSafety=kInfinity;
772 G4double sampleStep, sampleSafety, motherStep, motherSafety;
773 G4int localNoDaughters, sampleNo;
774 G4int depth;
775 G4ExitNormal exitNormalStc;
776 // G4int depthDeterminingStep= -1; // Useful only for debugging - for now
777
778 calculatedExitNormal= false;
779
780 // Exiting normal optimisation
781 //
782 if ( exiting&&validExitNormal )
783 {
784 if ( localDirection.dot(exitNormalVector)>=kMinExitingNormalCosine )
785 {
786 // Block exited daughter volume
787 //
788 blockedExitedVol = *pBlockedPhysical;
789 ourSafety = 0;
790 }
791 }
792 exiting = false;
793 entering = false;
794
795 repPhysical = history.GetTopVolume();
796 repLogical = repPhysical->GetLogicalVolume();
797
798 //
799 // Compute intersection with replica boundaries & replica safety
800 //
801
802 sampleSafety = DistanceToOut(repPhysical,
803 history.GetTopReplicaNo(),
804 localPoint);
805 G4ExitNormal normalOutStc;
806 const G4int topDepth= history.GetDepth();
807
808 ourSafety = std::min( ourSafety, sampleSafety);
809
810 if ( sampleSafety<ourStep )
811 {
812
813 sampleStep = DistanceToOut(repPhysical,
814 history.GetTopReplicaNo(),
815 localPoint,
816 localDirection,
817 normalOutStc);
818 if ( sampleStep<ourStep )
819 {
820 ourStep = sampleStep;
821 exiting = true;
822 validExitNormal = normalOutStc.validConvex; // false; -> Old,Conservative
823
824 exitNormalStc = normalOutStc;
825 exitNormalStc.exitNormal =
826 history.GetTopTransform().InverseTransformAxis(normalOutStc.exitNormal);
827 calculatedExitNormal = true;
828 }
829 }
830 const G4int secondDepth = topDepth;
831 depth = secondDepth;
832
833 // Loop checking, 07.10.2016, JA -- Need to add: assert(depth>0)
834 while ( history.GetVolumeType(depth)==kReplica )
835 {
836 const G4AffineTransform& GlobalToLocal = history.GetTransform(depth);
837 repPoint = GlobalToLocal.TransformPoint(globalPoint);
838 // repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
839
840 sampleSafety = DistanceToOut(history.GetVolume(depth),
841 history.GetReplicaNo(depth),
842 repPoint);
843 if ( sampleSafety < ourSafety )
844 {
845 ourSafety = sampleSafety;
846 }
847 if ( sampleSafety < ourStep )
848 {
849 G4ThreeVector newLocalDirection =
850 GlobalToLocal.TransformAxis(globalDirection);
851 sampleStep = DistanceToOut(history.GetVolume(depth),
852 history.GetReplicaNo(depth),
853 repPoint,
854 newLocalDirection,
855 normalOutStc);
856 if ( sampleStep < ourStep )
857 {
858 ourStep = sampleStep;
859 exiting = true;
860
861 // As step is limited by this level, must set Exit Normal
862 //
863 G4ThreeVector localExitNorm = normalOutStc.exitNormal;
864 G4ThreeVector globalExitNorm =
865 GlobalToLocal.InverseTransformAxis(localExitNorm);
866
867 exitNormalStc = normalOutStc; // Normal, convex, calculated, side
868 exitNormalStc.exitNormal = globalExitNorm;
869 calculatedExitNormal = true;
870 }
871 }
872 depth--;
873 }
874
875 // Compute mother safety & intersection
876 //
877 G4ThreeVector exitVectorMother;
878 G4bool exitConvex = false; // Value obtained in DistanceToOut(p,v) call
879 G4ExitNormal motherNormalStc;
880
881 repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
882 motherPhysical = history.GetVolume(depth);
883 motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
884 motherSafety = motherSolid->DistanceToOut(repPoint);
885 repDirection = history.GetTransform(depth).TransformAxis(globalDirection);
886
887 motherStep = motherSolid->DistanceToOut(repPoint,repDirection,true,
888 &exitConvex,&exitVectorMother);
889 if( exitConvex )
890 {
891 motherNormalStc = G4ExitNormal( exitVectorMother, true, false,
893 calculatedExitNormal = true;
894 }
895 const G4AffineTransform& globalToLocalTop = history.GetTopTransform();
896
897 G4bool motherDeterminedStep = (motherStep<ourStep);
898
899 if( (!exitConvex) && motherDeterminedStep )
900 {
901 exitVectorMother = motherSolid->SurfaceNormal( repPoint );
902 motherNormalStc = G4ExitNormal( exitVectorMother, true, false,
904 // CalculatedExitNormal -> true;
905 // Convex -> false: do not know value
906 // ExitSide -> kMother (or kNull)
907
908 calculatedExitNormal = true;
909 }
910 if( motherDeterminedStep )
911 {
912 G4ThreeVector globalExitNormalTop =
913 globalToLocalTop.InverseTransformAxis(exitVectorMother);
914
915 exitNormalStc = motherNormalStc;
916 exitNormalStc.exitNormal = globalExitNormalTop;
917 }
918
919 // Push in principle no longer necessary. G4Navigator now takes care of ...
920 // Removing this however may cause additional almost-zero steps and generate
921 // warnings for pushed particles from G4Navigator, particularly for the case
922 // of 3D replicas (Cartesian or combined Radial/Phi cases).
923 // Requires further investigation and eventually reimplementation of
924 // LevelLocate() to take into account point and direction ...
925 //
926 if( ourStep<fMinStep )
927 {
928 ourStep = 2*kCarTolerance;
929 }
930
931 if ( motherSafety<ourSafety )
932 {
933 ourSafety = motherSafety;
934 }
935
936#ifdef G4VERBOSE
937 if ( fCheck )
938 {
939 if( motherSolid->Inside(localPoint)==kOutside )
940 {
941 std::ostringstream message;
942 message << "Point outside volume !" << G4endl
943 << " Point " << localPoint
944 << " is outside current volume " << motherPhysical->GetName()
945 << G4endl;
946 G4double estDistToSolid= motherSolid->DistanceToIn(localPoint);
947 message << " Estimated isotropic distance to solid (distToIn)= "
948 << estDistToSolid << G4endl;
949 if( estDistToSolid > 100.0 * kCarTolerance )
950 {
951 motherSolid->DumpInfo();
952 G4Exception("G4ReplicaNavigation::ComputeStep()",
953 "GeomNav0003", FatalException, message,
954 "Point is far outside Current Volume !" );
955 }
956 else
957 G4Exception("G4ReplicaNavigation::ComputeStep()",
958 "GeomNav1002", JustWarning, message,
959 "Point is a little outside Current Volume.");
960 }
961 }
962#endif
963
964 // Comparison of steps may need precision protection
965 //
966#if 1
967 if( motherDeterminedStep )
968 {
969 ourStep = motherStep;
970 exiting = true;
971 }
972
973 // Transform it to the Grand-Mother Reference Frame (current convention)
974 //
975 if ( calculatedExitNormal )
976 {
977 if ( motherDeterminedStep )
978 {
979 exitNormalVector = motherNormalStc.exitNormal;
980 }
981 else
982 {
983 G4ThreeVector exitNormalGlobal = exitNormalStc.exitNormal;
984 exitNormalVector = globalToLocalTop.TransformAxis(exitNormalGlobal);
985 // exitNormalVector= globalToLocal2nd.TransformAxis(exitNormalGlobal);
986 // Alt Make it in one go to Grand-Mother, avoiding transform below
987 }
988 // Transform to Grand-mother reference frame
989 const G4RotationMatrix* rot = motherPhysical->GetRotation();
990 if ( rot )
991 {
992 exitNormalVector *= rot->inverse();
993 }
994
995 }
996 else
997 {
998 validExitNormal = false;
999 }
1000
1001#else
1002 if ( motherSafety<=ourStep )
1003 {
1004 if ( motherStep<=ourStep )
1005 {
1006 ourStep = motherStep;
1007 exiting = true;
1008 if ( validExitNormal )
1009 {
1010 const G4RotationMatrix* rot = motherPhysical->GetRotation();
1011 if ( rot )
1012 {
1013 exitNormal *= rot->inverse();
1014 }
1015 }
1016 }
1017 else
1018 {
1019 validExitNormal = false;
1020 // calculatedExitNormal= false;
1021 }
1022 }
1023#endif
1024
1025
1026 G4bool daughterDeterminedStep = false;
1027 G4ThreeVector daughtNormRepCrd;
1028 // Exit normal of daughter transformed to
1029 // the coordinate system of Replica (i.e. last depth)
1030
1031 //
1032 // Compute daughter safeties & intersections
1033 //
1034 localNoDaughters = repLogical->GetNoDaughters();
1035 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1036 {
1037 samplePhysical = repLogical->GetDaughter(sampleNo);
1038 if ( samplePhysical!=blockedExitedVol )
1039 {
1040 G4ThreeVector localExitNorm;
1041 G4ThreeVector normReplicaCoord;
1042
1043 G4AffineTransform sampleTf(samplePhysical->GetRotation(),
1044 samplePhysical->GetTranslation());
1045 sampleTf.Invert();
1046 const G4ThreeVector samplePoint =
1047 sampleTf.TransformPoint(localPoint);
1048 const G4VSolid* sampleSolid =
1049 samplePhysical->GetLogicalVolume()->GetSolid();
1050 const G4double sampleSafetyDistance =
1051 sampleSolid->DistanceToIn(samplePoint);
1052 if ( sampleSafetyDistance<ourSafety )
1053 {
1054 ourSafety = sampleSafetyDistance;
1055 }
1056 if ( sampleSafetyDistance<=ourStep )
1057 {
1058 sampleDirection = sampleTf.TransformAxis(localDirection);
1059 const G4double sampleStepDistance =
1060 sampleSolid->DistanceToIn(samplePoint,sampleDirection);
1061 if ( sampleStepDistance<=ourStep )
1062 {
1063 daughterDeterminedStep = true;
1064
1065 ourStep = sampleStepDistance;
1066 entering = true;
1067 exiting = false;
1068 *pBlockedPhysical = samplePhysical;
1069 blockedReplicaNo = sampleNo;
1070
1071#ifdef DAUGHTER_NORMAL_ALSO
1072 // This norm can be calculated later, if needed daughter is available
1073 localExitNorm = sampleSolid->SurfaceNormal(samplePoint);
1074 daughtNormRepCrd = sampleTf.InverseTransformAxis(localExitNorm);
1075#endif
1076
1077#ifdef G4VERBOSE
1078 // Check to see that the resulting point is indeed in/on volume.
1079 // This check could eventually be made only for successful candidate.
1080
1081 if ( ( fCheck ) && ( sampleStepDistance < kInfinity ) )
1082 {
1083 G4ThreeVector intersectionPoint;
1084 intersectionPoint = samplePoint
1085 + sampleStepDistance * sampleDirection;
1086 EInside insideIntPt = sampleSolid->Inside(intersectionPoint);
1087 if ( insideIntPt != kSurface )
1088 {
1089 G4int oldcoutPrec = G4cout.precision(16);
1090 std::ostringstream message;
1091 message << "Navigator gets conflicting response from Solid."
1092 << G4endl
1093 << " Inaccurate DistanceToIn for solid "
1094 << sampleSolid->GetName() << G4endl
1095 << " Solid gave DistanceToIn = "
1096 << sampleStepDistance << " yet returns " ;
1097 if ( insideIntPt == kInside )
1098 message << "-kInside-";
1099 else if ( insideIntPt == kOutside )
1100 message << "-kOutside-";
1101 else
1102 message << "-kSurface-";
1103 message << " for this point !" << G4endl
1104 << " Point = " << intersectionPoint << G4endl;
1105 if ( insideIntPt != kInside )
1106 message << " DistanceToIn(p) = "
1107 << sampleSolid->DistanceToIn(intersectionPoint)
1108 << G4endl;
1109 if ( insideIntPt != kOutside )
1110 message << " DistanceToOut(p) = "
1111 << sampleSolid->DistanceToOut(intersectionPoint);
1112 G4Exception("G4ReplicaNavigation::ComputeStep()",
1113 "GeomNav1002", JustWarning, message);
1114 G4cout.precision(oldcoutPrec);
1115 }
1116 }
1117#endif
1118 }
1119 }
1120 }
1121 }
1122
1123 calculatedExitNormal &= (!daughterDeterminedStep);
1124
1125#ifdef DAUGHTER_NORMAL_ALSO
1126 if( daughterDeterminedStep )
1127 {
1128 // G4ThreeVector daughtNormGlobal =
1129 // GlobalToLastDepth.Inverse().TransformAxis(daughtNormRepCrd);
1130 // ==> Can calculate it, but have no way to transmit it to caller (for now)
1131
1132 exitNormalVector = globalToLocalTop.InverseTransformAxis(daughtNormGlobal);
1133 validExitNormal = false; // Entering daughter - never convex for parent
1134
1135 calculatedExitNormal = true;
1136 }
1137 // calculatedExitNormal= true; // Force it to true -- dubious
1138#endif
1139
1140 newSafety = ourSafety;
1141 return ourStep;
1142}
@ JustWarning
bool G4bool
Definition: G4Types.hh:86
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
HepRotation inverse() const
G4ThreeVector InverseTransformAxis(const G4ThreeVector &axis) const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
const G4String & GetName() const
G4String GetName() const
void DumpInfo() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
static const double kMinExitingNormalCosine
Definition: geomdefs.hh:45
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4ThreeVector exitNormal

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), DistanceToOut(), CLHEP::Hep3Vector::dot(), G4VSolid::DumpInfo(), G4ExitNormal::exitNormal, FatalException, fCheck, fMinStep, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4VPhysicalVolume::GetName(), G4VSolid::GetName(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4VPhysicalVolume::GetTranslation(), g4zmq::history(), G4VSolid::Inside(), CLHEP::HepRotation::inverse(), G4AffineTransform::InverseTransformAxis(), G4AffineTransform::Invert(), JustWarning, kCarTolerance, kInfinity, kInside, kMinExitingNormalCosine, G4ExitNormal::kMother, kOutside, kReplica, kSurface, G4INCL::Math::min(), G4VSolid::SurfaceNormal(), G4AffineTransform::TransformAxis(), G4AffineTransform::TransformPoint(), and G4ExitNormal::validConvex.

Referenced by G4Navigator::ComputeStep(), G4ITNavigator1::ComputeStep(), and G4ITNavigator2::ComputeStep().

◆ ComputeTransformation() [1/2]

void G4ReplicaNavigation::ComputeTransformation ( const G4int  replicaNo,
G4VPhysicalVolume pVol 
) const

Definition at line 705 of file G4ReplicaNavigation.cc.

707{
708 G4double val;
709
710 // Replication data
711 //
712 EAxis axis;
713 G4int nReplicas;
714 G4double width, offset;
715 G4bool consuming;
716
717 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
718
719 switch (axis)
720 {
721 case kXAxis:
722 val = -width*0.5*(nReplicas-1)+width*replicaNo;
723 pVol->SetTranslation(G4ThreeVector(val,0,0));
724 break;
725 case kYAxis:
726 val = -width*0.5*(nReplicas-1)+width*replicaNo;
727 pVol->SetTranslation(G4ThreeVector(0,val,0));
728 break;
729 case kZAxis:
730 val = -width*0.5*(nReplicas-1)+width*replicaNo;
731 pVol->SetTranslation(G4ThreeVector(0,0,val));
732 break;
733 case kPhi:
734 val = -(offset+width*(replicaNo+0.5));
735 SetPhiTransformation(val,pVol);
736 break;
737 case kRho:
738 // No setup required for radial case
739 default:
740 break;
741 }
742}
CLHEP::Hep3Vector G4ThreeVector
void SetPhiTransformation(const G4double ang, G4VPhysicalVolume *pVol=0) const
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
void SetTranslation(const G4ThreeVector &v)
EAxis
Definition: geomdefs.hh:54
@ kPhi
Definition: geomdefs.hh:60
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57
@ kRho
Definition: geomdefs.hh:58

References G4VPhysicalVolume::GetReplicationData(), kPhi, kRho, kXAxis, kYAxis, kZAxis, SetPhiTransformation(), and G4VPhysicalVolume::SetTranslation().

◆ ComputeTransformation() [2/2]

void G4ReplicaNavigation::ComputeTransformation ( const G4int  replicaNo,
G4VPhysicalVolume pVol,
G4ThreeVector point 
) const

Definition at line 649 of file G4ReplicaNavigation.cc.

652{
653 G4double val,cosv,sinv,tmpx,tmpy;
654
655 // Replication data
656 //
657 EAxis axis;
658 G4int nReplicas;
659 G4double width,offset;
660 G4bool consuming;
661
662 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
663
664 switch (axis)
665 {
666 case kXAxis:
667 val = -width*0.5*(nReplicas-1)+width*replicaNo;
668 pVol->SetTranslation(G4ThreeVector(val,0,0));
669 point.setX(point.x()-val);
670 break;
671 case kYAxis:
672 val = -width*0.5*(nReplicas-1)+width*replicaNo;
673 pVol->SetTranslation(G4ThreeVector(0,val,0));
674 point.setY(point.y()-val);
675 break;
676 case kZAxis:
677 val = -width*0.5*(nReplicas-1)+width*replicaNo;
678 pVol->SetTranslation(G4ThreeVector(0,0,val));
679 point.setZ(point.z()-val);
680 break;
681 case kPhi:
682 val = -(offset+width*(replicaNo+0.5));
683 SetPhiTransformation(val,pVol);
684 cosv = std::cos(val);
685 sinv = std::sin(val);
686 tmpx = point.x()*cosv-point.y()*sinv;
687 tmpy = point.x()*sinv+point.y()*cosv;
688 point.setY(tmpy);
689 point.setX(tmpx);
690 break;
691 case kRho:
692 // No setup required for radial case
693 default:
694 break;
695 }
696}
double z() const
double x() const
void setY(double)
double y() const
void setZ(double)
void setX(double)

References G4VPhysicalVolume::GetReplicationData(), kPhi, kRho, kXAxis, kYAxis, kZAxis, SetPhiTransformation(), G4VPhysicalVolume::SetTranslation(), CLHEP::Hep3Vector::setX(), CLHEP::Hep3Vector::setY(), CLHEP::Hep3Vector::setZ(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4ITNavigator1::LocateGlobalPointAndSetup(), G4ITNavigator2::LocateGlobalPointAndSetup(), G4Navigator::LocateGlobalPointAndSetup(), G4Navigator::SetupHierarchy(), G4ITNavigator1::SetupHierarchy(), and G4ITNavigator2::SetupHierarchy().

◆ DistanceToOut() [1/2]

G4double G4ReplicaNavigation::DistanceToOut ( const G4VPhysicalVolume pVol,
const G4int  replicaNo,
const G4ThreeVector localPoint 
) const

Definition at line 183 of file G4ReplicaNavigation.cc.

186{
187 // Replication data
188 //
189 EAxis axis;
190 G4int nReplicas;
191 G4double width,offset;
192 G4bool consuming;
193
194 G4double safety = 0.;
195 G4double safe1,safe2;
196 G4double coord, rho, rmin, rmax;
197
198 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
199 switch(axis)
200 {
201 case kXAxis:
202 case kYAxis:
203 case kZAxis:
204 coord = localPoint(axis);
205 safe1 = width*0.5-coord;
206 safe2 = width*0.5+coord;
207 safety = (safe1<=safe2) ? safe1 : safe2;
208 break;
209 case kPhi:
210 if ( localPoint.y()<=0 )
211 {
212 safety = localPoint.x()*std::sin(width*0.5)
213 + localPoint.y()*std::cos(width*0.5);
214 }
215 else
216 {
217 safety = localPoint.x()*std::sin(width*0.5)
218 - localPoint.y()*std::cos(width*0.5);
219 }
220 break;
221 case kRho:
222 rho = localPoint.perp();
223 rmax = width*(replicaNo+1)+offset;
224 if ( replicaNo||offset )
225 {
226 rmin = rmax-width;
227 safe1 = rho-rmin;
228 safe2 = rmax-rho;
229 safety = (safe1<=safe2) ? safe1 : safe2;
230 }
231 else
232 {
233 safety = rmax-rho;
234 }
235 break;
236 default:
237 G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
238 FatalException, "Unknown axis!");
239 break;
240 }
241 return (safety >= halfkCarTolerance) ? safety : 0;
242}
double perp() const

References FatalException, G4Exception(), G4VPhysicalVolume::GetReplicationData(), halfkCarTolerance, kPhi, kRho, kXAxis, kYAxis, kZAxis, CLHEP::Hep3Vector::perp(), CLHEP::Hep3Vector::x(), and CLHEP::Hep3Vector::y().

Referenced by ComputeSafety(), and ComputeStep().

◆ DistanceToOut() [2/2]

G4double G4ReplicaNavigation::DistanceToOut ( const G4VPhysicalVolume pVol,
const G4int  replicaNo,
const G4ThreeVector localPoint,
const G4ThreeVector localDirection,
G4ExitNormal candidateNormal 
) const

Definition at line 249 of file G4ReplicaNavigation.cc.

254{
255 // Replication data
256 //
257 EAxis axis;
258 G4int nReplicas;
259 G4double width, offset;
260 G4bool consuming;
261
262 G4double Dist=kInfinity;
263 G4double coord, Comp, lindist;
264 G4double signC = 0.0;
265 G4ExitNormal candidateNormal;
266
267 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
268 switch(axis)
269 {
270 case kXAxis:
271 case kYAxis:
272 case kZAxis:
273 coord = localPoint(axis);
274 Comp = localDirection(axis);
275 if ( Comp>0 )
276 {
277 lindist = width*0.5-coord;
278 Dist = (lindist>0) ? lindist/Comp : 0;
279 signC= 1.0;
280 }
281 else if ( Comp<0 )
282 {
283 lindist = width*0.5+coord;
284 Dist = (lindist>0) ? -lindist/Comp : 0;
285 signC= -1.0;
286 }
287 else
288 {
289 Dist = kInfinity;
290 }
291 // signC = sign<G4double>(Comp)
292 candidateNormal.exitNormal = ( signC * VecCartAxes[axis]);
293 candidateNormal.calculated = true;
294 candidateNormal.validConvex = true;
295 candidateNormal.exitSide =
296 (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis];
297 break;
298 case kPhi:
299 Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal);
300 // candidateNormal set in call
301 break;
302 case kRho:
303 Dist = DistanceToOutRad(localPoint,localDirection,width,offset,
304 replicaNo,candidateNormal);
305 // candidateNormal set in call
306 break;
307 default:
308 G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
309 FatalException, "Unknown axis!");
310 break;
311 }
312
313 arExitNormal= candidateNormal; // .exitNormal;
314
315 return Dist;
316}
G4double DistanceToOutPhi(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double width, G4ExitNormal &foundNormal) const
G4double DistanceToOutRad(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double width, const G4double offset, const G4int replicaNo, G4ExitNormal &foundNormal) const
const G4ExitNormal::ESide SideCartAxesMinus[3]

References G4ExitNormal::calculated, DistanceToOutPhi(), DistanceToOutRad(), G4ExitNormal::exitNormal, G4ExitNormal::exitSide, FatalException, G4Exception(), G4VPhysicalVolume::GetReplicationData(), kInfinity, kPhi, kRho, kXAxis, kYAxis, kZAxis, anonymous_namespace{G4ReplicaNavigation.cc}::SideCartAxesMinus, anonymous_namespace{G4ReplicaNavigation.cc}::SideCartAxesPlus, G4ExitNormal::validConvex, and anonymous_namespace{G4ReplicaNavigation.cc}::VecCartAxes.

◆ DistanceToOutPhi()

G4double G4ReplicaNavigation::DistanceToOutPhi ( const G4ThreeVector localPoint,
const G4ThreeVector localDirection,
const G4double  width,
G4ExitNormal foundNormal 
) const
private

Definition at line 323 of file G4ReplicaNavigation.cc.

327{
328 // Phi Intersection
329 // NOTE: width<=pi by definition
330 //
331 G4double sinSPhi = -2.0, cosSPhi = -2.0;
332 G4double pDistS, pDistE, compS, compE, Dist, dist2, yi;
334 G4ThreeVector candidateNormal;
335
336 if ( (localPoint.x()!=0.0) || (localPoint.y()!=0.0) )
337 {
338 sinSPhi = std::sin(-width*0.5); // SIN of starting phi plane
339 cosSPhi = std::cos(width*0.5); // COS of starting phi plane
340
341 // pDist -ve when inside
342 //
343 pDistS = localPoint.x()*sinSPhi-localPoint.y()*cosSPhi;
344 // Start plane at phi= -S
345 pDistE = localPoint.x()*sinSPhi+localPoint.y()*cosSPhi;
346 // End plane at phi= +S
347
348 // Comp -ve when in direction of outwards normal
349 //
350 compS = -sinSPhi*localDirection.x()+cosSPhi*localDirection.y();
351 compE = -sinSPhi*localDirection.x()-cosSPhi*localDirection.y();
352
353 if ( (pDistS<=halfkCarTolerance)&&(pDistE<=halfkCarTolerance) )
354 {
355 // Inside both phi *full* planes
356 //
357 if ( compS<0 )
358 {
359 dist2 = pDistS/compS;
360 yi = localPoint.y()+dist2*localDirection.y();
361
362 // Check intersecting with correct half-plane (no -> no intersect)
363 //
364 if ( yi<=0 )
365 {
366 Dist = (pDistS<=-halfkCarTolerance) ? dist2 : 0;
367 sidePhi= G4ExitNormal::kSPhi; // tbc
368 }
369 else
370 {
371 Dist = kInfinity;
372 }
373 }
374 else
375 {
376 Dist = kInfinity;
377 }
378 if ( compE<0 )
379 {
380 dist2 = pDistE/compE;
381
382 // Only check further if < starting phi intersection
383 //
384 if ( dist2<Dist )
385 {
386 yi = localPoint.y()+dist2*localDirection.y();
387
388 // Check intersecting with correct half-plane
389 //
390 if ( yi>=0 )
391 {
392 // Leaving via ending phi
393 //
394 Dist = (pDistE<=-halfkCarTolerance) ? dist2 : 0;
395 sidePhi = G4ExitNormal::kEPhi;
396 }
397 }
398 }
399 }
400 else if ( (pDistS>halfkCarTolerance)&&(pDistE>halfkCarTolerance) )
401 {
402 // Outside both *full* phi planes
403 // if towards both >=0 then once inside will remain inside
404 //
405 Dist = ((compS>=0)&&(compE>=0)) ? kInfinity : 0;
406 }
407 else if ( (pDistS>halfkCarTolerance)&&(pDistE<=halfkCarTolerance) )
408 {
409 // Outside full starting plane, inside full ending plane
410 //
411 if ( compE<0 )
412 {
413 dist2 = pDistE/compE;
414 yi = localPoint.y()+dist2*localDirection.y();
415
416 // Check intersection in correct half-plane
417 // (if not -> remain in extent)
418 //
419 Dist = (yi>0) ? dist2 : kInfinity;
420 if( yi> 0 ) { sidePhi = G4ExitNormal::kEPhi; }
421 }
422 else // Leaving immediately by starting phi
423 {
424 Dist = kInfinity;
425 }
426 }
427 else
428 {
429 // Must be (pDistS<=halfkCarTolerance)&&(pDistE>halfkCarTolerance)
430 // Inside full starting plane, outside full ending plane
431 //
432 if ( compE>=0 )
433 {
434 if ( compS<0 )
435 {
436 dist2 = pDistS/compS;
437 yi = localPoint.y()+dist2*localDirection.y();
438
439 // Check intersection in correct half-plane
440 // (if not -> remain in extent)
441 //
442 Dist = (yi<0) ? dist2 : kInfinity;
443 if(yi<0) { sidePhi = G4ExitNormal::kSPhi; }
444 }
445 else
446 {
447 Dist = kInfinity;
448 }
449 }
450 else
451 {
452 // Leaving immediately by ending phi
453 //
454 Dist = 0.;
455 sidePhi = G4ExitNormal::kEPhi;
456 }
457 }
458 }
459 else
460 {
461 // On z axis + travel not || to z axis -> use direction vector
462 //
463 if( (std::fabs(localDirection.phi())<=width*0.5) )
464 {
465 Dist = kInfinity;
466 }
467 else
468 {
469 Dist = 0.;
470 sidePhi = G4ExitNormal::kMY;
471 }
472 }
473
474 if(sidePhi == G4ExitNormal::kSPhi )
475 {
476 candidateNormal = G4ThreeVector(sinSPhi,-cosSPhi,0.) ;
477 }
478 else if (sidePhi == G4ExitNormal::kEPhi)
479 {
480 candidateNormal = G4ThreeVector(sinSPhi,cosSPhi,0.) ;
481 }
482 else if (sidePhi == G4ExitNormal::kMY )
483 {
484 candidateNormal = G4ThreeVector(0., -1.0, 0.); // Split -S and +S 'phi'
485 }
486 foundNormal.calculated= (sidePhi != G4ExitNormal::kNull );
487 foundNormal.exitNormal= candidateNormal;
488
489 return Dist;
490}
double phi() const

References G4ExitNormal::calculated, G4ExitNormal::exitNormal, halfkCarTolerance, G4ExitNormal::kEPhi, kInfinity, G4ExitNormal::kMY, G4ExitNormal::kNull, G4ExitNormal::kSPhi, CLHEP::Hep3Vector::phi(), CLHEP::Hep3Vector::x(), and CLHEP::Hep3Vector::y().

Referenced by DistanceToOut().

◆ DistanceToOutRad()

G4double G4ReplicaNavigation::DistanceToOutRad ( const G4ThreeVector localPoint,
const G4ThreeVector localDirection,
const G4double  width,
const G4double  offset,
const G4int  replicaNo,
G4ExitNormal foundNormal 
) const
private

Definition at line 497 of file G4ReplicaNavigation.cc.

503{
504 G4double rmin, rmax, t1, t2, t3, deltaR;
505 G4double b, c, d2, srd;
507
508 //
509 // Radial Intersections
510 //
511
512 // Find intersction with cylinders at rmax/rmin
513 // Intersection point (xi,yi,zi) on line
514 // x=localPoint.x+t*localDirection.x etc.
515 //
516 // Intersects with x^2+y^2=R^2
517 //
518 // Hence (localDirection.x^2+localDirection.y^2)t^2+
519 // 2t(localPoint.x*localDirection.x+localPoint.y*localDirection.y)+
520 // localPoint.x^2+localPoint.y^2-R^2=0
521 //
522 // t1 t2 t3
523
524 rmin = replicaNo*width+offset;
525 rmax = (replicaNo+1)*width+offset;
526
527 t1 = 1.0-localDirection.z()*localDirection.z(); // since v normalised
528 t2 = localPoint.x()*localDirection.x()+localPoint.y()*localDirection.y();
529 t3 = localPoint.x()*localPoint.x()+localPoint.y()*localPoint.y();
530
531 if ( t1>0 ) // Check not parallel
532 {
533 // Calculate srd, r exit distance
534 //
535 if ( t2>=0 )
536 {
537 // Delta r not negative => leaving via rmax
538 //
539 deltaR = t3-rmax*rmax;
540
541 // NOTE: Should use
542 // rho-rmax<-halfkRadTolerance - [no sqrts for efficiency]
543 //
544 if ( deltaR<-halfkRadTolerance )
545 {
546 b = t2/t1;
547 c = deltaR/t1;
548 srd = -b+std::sqrt(b*b-c);
549 sideR = G4ExitNormal::kRMax;
550 }
551 else
552 {
553 // On tolerant boundary & heading outwards (or locally
554 // perpendicular to) outer radial surface -> leaving immediately
555 //
556 srd = 0;
557 sideR = G4ExitNormal::kRMax;
558 }
559 }
560 else
561 {
562 // Possible rmin intersection
563 //
564 if (rmin)
565 {
566 deltaR = t3-rmin*rmin;
567 b = t2/t1;
568 c = deltaR/t1;
569 d2 = b*b-c;
570 if ( d2>=0 )
571 {
572 // Leaving via rmin
573 // NOTE: Should use
574 // rho-rmin>halfkRadTolerance - [no sqrts for efficiency]
575 //
576 srd = (deltaR>halfkRadTolerance) ? -b-std::sqrt(d2) : 0.0;
577 // Is the following more accurate ?
578 // srd = (deltaR>halfkRadTolerance) ? c/( -b - std::sqrt(d2)) : 0.0;
579 sideR = G4ExitNormal::kRMin;
580 }
581 else
582 {
583 // No rmin intersect -> must be rmax intersect
584 //
585 deltaR = t3-rmax*rmax;
586 c = deltaR/t1;
587 d2 = b*b-c;
588 srd = (d2 < 0.) ? 0.0 : -b+std::sqrt(d2);
589 sideR = G4ExitNormal::kRMax;
590 }
591 }
592 else
593 {
594 // No rmin intersect -> must be rmax intersect
595 //
596 deltaR = t3-rmax*rmax;
597 b = t2/t1;
598 c = deltaR/t1;
599 d2 = b*b-c;
600 srd = (d2 < 0.) ? 0.0 : -b+std::sqrt(d2);
601 sideR= G4ExitNormal::kRMax;
602 }
603 }
604 }
605 else
606 {
607 srd =kInfinity;
608 sideR = G4ExitNormal::kNull;
609 }
610
611 if( sideR != G4ExitNormal::kNull ) // if ((side == kRMax) || (side==kRMin))
612 {
613 // Note: returned vector not explicitly normalised
614 // (divided by fRMax for unit vector)
615
616 G4double xi, yi;
617 xi = localPoint.x() + srd*localDirection.x();
618 yi = localPoint.y() + srd*localDirection.y();
619 G4ThreeVector normalR = G4ThreeVector(xi,yi,0.0);
620
621 if( sideR == G4ExitNormal::kRMax )
622 {
623 normalR *= 1.0/rmax;
624 }
625 else
626 {
627 normalR *= (-1.0)/rmin;
628 }
629 foundNormal.exitNormal= normalR;
630 foundNormal.calculated= true;
631 foundNormal.validConvex = (sideR == G4ExitNormal::kRMax);
632 foundNormal.exitSide = sideR;
633 }
634 else
635 {
636 foundNormal.calculated = false;
637 }
638
639 return srd;
640}
static const G4double d2

References G4ExitNormal::calculated, d2, G4ExitNormal::exitNormal, G4ExitNormal::exitSide, halfkRadTolerance, kInfinity, G4ExitNormal::kNull, G4ExitNormal::kRMax, G4ExitNormal::kRMin, G4ExitNormal::validConvex, CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by DistanceToOut().

◆ GetVerboseLevel()

G4int G4ReplicaNavigation::GetVerboseLevel ( ) const
inline

◆ Inside()

EInside G4ReplicaNavigation::Inside ( const G4VPhysicalVolume pVol,
const G4int  replicaNo,
const G4ThreeVector localPoint 
) const

Definition at line 77 of file G4ReplicaNavigation.cc.

80{
81 EInside in = kOutside;
82
83 // Replication data
84 //
85 EAxis axis;
86 G4int nReplicas;
87 G4double width, offset;
88 G4bool consuming;
89
90 G4double coord, rad2, rmin, tolRMax2, rmax, tolRMin2;
91
92 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
93
94 switch (axis)
95 {
96 case kXAxis:
97 case kYAxis:
98 case kZAxis:
99 coord = std::fabs(localPoint(axis))-width*0.5;
100 if ( coord<=-halfkCarTolerance )
101 {
102 in = kInside;
103 }
104 else if ( coord<=halfkCarTolerance )
105 {
106 in = kSurface;
107 }
108 break;
109 case kPhi:
110 if ( localPoint.y()||localPoint.x() )
111 {
112 coord = std::fabs(std::atan2(localPoint.y(),localPoint.x()))-width*0.5;
113 if ( coord<=-halfkAngTolerance )
114 {
115 in = kInside;
116 }
117 else if ( coord<=halfkAngTolerance )
118 {
119 in = kSurface;
120 }
121 }
122 else
123 {
124 in = kSurface;
125 }
126 break;
127 case kRho:
128 rad2 = localPoint.perp2();
129 rmax = (replicaNo+1)*width+offset;
130 tolRMax2 = rmax-halfkRadTolerance;
131 tolRMax2 *= tolRMax2;
132 if ( rad2>tolRMax2 )
133 {
134 tolRMax2 = rmax+halfkRadTolerance;
135 tolRMax2 *= tolRMax2;
136 if ( rad2<=tolRMax2 )
137 {
138 in = kSurface;
139 }
140 }
141 else
142 {
143 // Known to be inside outer radius
144 //
145 if ( replicaNo||offset )
146 {
147 rmin = rmax-width;
148 tolRMin2 = rmin-halfkRadTolerance;
149 tolRMin2 *= tolRMin2;
150 if ( rad2>tolRMin2 )
151 {
152 tolRMin2 = rmin+halfkRadTolerance;
153 tolRMin2 *= tolRMin2;
154 if ( rad2>=tolRMin2 )
155 {
156 in = kInside;
157 }
158 else
159 {
160 in = kSurface;
161 }
162 }
163 }
164 else
165 {
166 in = kInside;
167 }
168 }
169 break;
170 default:
171 G4Exception("G4ReplicaNavigation::Inside()", "GeomNav0002",
172 FatalException, "Unknown axis!");
173 break;
174 }
175 return in;
176}
double perp2() const

References FatalException, G4Exception(), G4VPhysicalVolume::GetReplicationData(), halfkAngTolerance, halfkCarTolerance, halfkRadTolerance, kInside, kOutside, kPhi, kRho, kSurface, kXAxis, kYAxis, kZAxis, CLHEP::Hep3Vector::perp2(), CLHEP::Hep3Vector::x(), and CLHEP::Hep3Vector::y().

Referenced by BackLocate().

◆ LevelLocate()

G4bool G4ReplicaNavigation::LevelLocate ( G4NavigationHistory history,
const G4VPhysicalVolume blockedVol,
const G4int  blockedNum,
const G4ThreeVector globalPoint,
const G4ThreeVector globalDirection,
const G4bool  pLocatedOnEdge,
G4ThreeVector localPoint 
)
inline

◆ SetPhiTransformation()

void G4ReplicaNavigation::SetPhiTransformation ( const G4double  ang,
G4VPhysicalVolume pVol = 0 
) const
inlineprivate

Referenced by ComputeTransformation().

◆ SetVerboseLevel()

void G4ReplicaNavigation::SetVerboseLevel ( G4int  level)
inline

◆ VoxelLocate()

G4int G4ReplicaNavigation::VoxelLocate ( const G4SmartVoxelHeader pHead,
const G4ThreeVector localPoint,
const G4int  blocked = -1 
) const
inlineprivate

Field Documentation

◆ fCheck

G4bool G4ReplicaNavigation::fCheck = false
private

Definition at line 171 of file G4ReplicaNavigation.hh.

Referenced by ComputeStep().

◆ fMinStep

G4double G4ReplicaNavigation::fMinStep
private

Definition at line 177 of file G4ReplicaNavigation.hh.

Referenced by ComputeStep(), and G4ReplicaNavigation().

◆ fVerbose

G4int G4ReplicaNavigation::fVerbose = 0
private

Definition at line 172 of file G4ReplicaNavigation.hh.

◆ halfkAngTolerance

G4double G4ReplicaNavigation::halfkAngTolerance
private

Definition at line 176 of file G4ReplicaNavigation.hh.

Referenced by G4ReplicaNavigation(), and Inside().

◆ halfkCarTolerance

G4double G4ReplicaNavigation::halfkCarTolerance
private

◆ halfkRadTolerance

G4double G4ReplicaNavigation::halfkRadTolerance
private

Definition at line 176 of file G4ReplicaNavigation.hh.

Referenced by DistanceToOutRad(), G4ReplicaNavigation(), and Inside().

◆ kAngTolerance

G4double G4ReplicaNavigation::kAngTolerance
private

Definition at line 175 of file G4ReplicaNavigation.hh.

Referenced by G4ReplicaNavigation().

◆ kCarTolerance

G4double G4ReplicaNavigation::kCarTolerance
private

Definition at line 175 of file G4ReplicaNavigation.hh.

Referenced by ComputeStep(), and G4ReplicaNavigation().

◆ kRadTolerance

G4double G4ReplicaNavigation::kRadTolerance
private

Definition at line 175 of file G4ReplicaNavigation.hh.

Referenced by G4ReplicaNavigation().


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