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

#include <G4ReplicaNavigation.hh>

Public Member Functions

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

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{
58 halfkCarTolerance = kCarTolerance*0.5;
59 halfkRadTolerance = kRadTolerance*0.5;
60 halfkAngTolerance = kAngTolerance*0.5;
61 fMinStep = 0.05*kCarTolerance;
62}
G4double GetSurfaceTolerance() const
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const

◆ ~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 = (G4int)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:59
int G4int
Definition: G4Types.hh:85
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4VSolid * GetSolid() const
G4int GetReplicaNo(G4int n) const
G4VPhysicalVolume * GetVolume(G4int n) const
std::size_t GetDepth() const
EVolume GetVolumeType(G4int n) const
const G4AffineTransform & GetTransform(G4int n) 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

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 G4long 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 = (G4int)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((G4int)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
long G4long
Definition: G4Types.hh:87
std::size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
G4int GetTopReplicaNo() const
G4VPhysicalVolume * GetTopVolume() 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

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 G4long 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= (G4int)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((G4int)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 = (G4int)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 G4long 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 TransformAxis(const G4ThreeVector &axis) const
const G4AffineTransform & GetTopTransform() const
const G4String & GetName() const
G4String GetName() const
void DumpInfo() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
G4ThreeVector exitNormal

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
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

◆ 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)

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

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}

◆ 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

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

◆ SetVerboseLevel()

void G4ReplicaNavigation::SetVerboseLevel ( G4int  level)
inline

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