Geant4 11.2.2
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, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX) const
 
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 ( )
default

Member Function Documentation

◆ BackLocate()

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

Definition at line 1244 of file G4ReplicaNavigation.cc.

1249{
1250 G4VPhysicalVolume *pNRMother = nullptr;
1251 G4VSolid *motherSolid;
1252 G4ThreeVector repPoint, goodPoint;
1253 G4int mdepth, depth, cdepth;
1254 EInside insideCode;
1255
1256 cdepth = (G4int)history.GetDepth();
1257
1258 // Find non replicated mother
1259 //
1260 for ( mdepth=cdepth-1; mdepth>=0; mdepth-- )
1261 {
1262 if ( history.GetVolumeType(mdepth)!=kReplica )
1263 {
1264 pNRMother = history.GetVolume(mdepth);
1265 break;
1266 }
1267 }
1268
1269 if( pNRMother == nullptr )
1270 {
1271 // All the tree of mother volumes were Replicas.
1272 // This is an error, as the World volume must be a Placement
1273 //
1274 G4Exception("G4ReplicaNavigation::BackLocate()", "GeomNav0002",
1275 FatalException, "The World volume must be a Placement!");
1276 return kInside;
1277 }
1278
1279 motherSolid = pNRMother->GetLogicalVolume()->GetSolid();
1280 goodPoint = history.GetTransform(mdepth).TransformPoint(globalPoint);
1281 insideCode = motherSolid->Inside(goodPoint);
1282 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
1283 {
1284 // Outside mother -> back up to mother level
1285 // Locate.. in Navigator will back up one more level
1286 // localPoint not required
1287 //
1288 history.BackLevel(cdepth-mdepth);
1289 // localPoint = goodPoint;
1290 }
1291 else
1292 {
1293 notKnownInside = false;
1294
1295 // Still within replications
1296 // Check down: if on outside stop at this level
1297 //
1298 for ( depth=mdepth+1; depth<cdepth; ++depth)
1299 {
1300 repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1301 insideCode = Inside(history.GetVolume(depth),
1302 history.GetReplicaNo(depth),
1303 repPoint);
1304 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
1305 {
1306 localPoint = goodPoint;
1307 history.BackLevel(cdepth-depth);
1308 return insideCode;
1309 }
1310 goodPoint = repPoint;
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)
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,
const G4NavigationHistory & history,
const G4double pProposedMaxLength = DBL_MAX ) const

Definition at line 1155 of file G4ReplicaNavigation.cc.

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

◆ 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 747 of file G4ReplicaNavigation.cc.

762{
763 G4VPhysicalVolume *repPhysical, *motherPhysical;
764 G4VPhysicalVolume *samplePhysical, *blockedExitedVol = nullptr;
765 G4LogicalVolume *repLogical;
766 G4VSolid *motherSolid;
767 G4ThreeVector repPoint, repDirection, sampleDirection;
768 G4double ourStep=currentProposedStepLength;
769 G4double ourSafety=kInfinity;
770 G4double sampleStep, sampleSafety, motherStep, motherSafety;
771 G4long localNoDaughters, sampleNo;
772 G4int depth;
773 G4ExitNormal exitNormalStc;
774 // G4int depthDeterminingStep= -1; // Useful only for debugging - for now
775
776 calculatedExitNormal= false;
777
778 // Exiting normal optimisation
779 //
780 if ( exiting&&validExitNormal )
781 {
782 if ( localDirection.dot(exitNormalVector)>=kMinExitingNormalCosine )
783 {
784 // Block exited daughter volume
785 //
786 blockedExitedVol = *pBlockedPhysical;
787 ourSafety = 0;
788 }
789 }
790 exiting = false;
791 entering = false;
792
793 repPhysical = history.GetTopVolume();
794 repLogical = repPhysical->GetLogicalVolume();
795
796 //
797 // Compute intersection with replica boundaries & replica safety
798 //
799
800 sampleSafety = DistanceToOut(repPhysical,
801 history.GetTopReplicaNo(),
802 localPoint);
803 G4ExitNormal normalOutStc;
804 const auto topDepth= (G4int)history.GetDepth();
805
806 ourSafety = std::min( ourSafety, sampleSafety);
807
808 if ( sampleSafety<ourStep )
809 {
810
811 sampleStep = DistanceToOut(repPhysical,
812 history.GetTopReplicaNo(),
813 localPoint,
814 localDirection,
815 normalOutStc);
816 if ( sampleStep<ourStep )
817 {
818 ourStep = sampleStep;
819 exiting = true;
820 validExitNormal = normalOutStc.validConvex; // false; -> Old,Conservative
821
822 exitNormalStc = normalOutStc;
823 exitNormalStc.exitNormal =
824 history.GetTopTransform().InverseTransformAxis(normalOutStc.exitNormal);
825 calculatedExitNormal = true;
826 }
827 }
828 const G4int secondDepth = topDepth;
829 depth = secondDepth;
830
831 // Loop checking, 07.10.2016, JA -- Need to add: assert(depth>0)
832 while ( history.GetVolumeType(depth)==kReplica )
833 {
834 const G4AffineTransform& GlobalToLocal = history.GetTransform(depth);
835 repPoint = GlobalToLocal.TransformPoint(globalPoint);
836 // repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
837
838 sampleSafety = DistanceToOut(history.GetVolume(depth),
839 history.GetReplicaNo(depth),
840 repPoint);
841 if ( sampleSafety < ourSafety )
842 {
843 ourSafety = sampleSafety;
844 }
845 if ( sampleSafety < ourStep )
846 {
847 G4ThreeVector newLocalDirection =
848 GlobalToLocal.TransformAxis(globalDirection);
849 sampleStep = DistanceToOut(history.GetVolume(depth),
850 history.GetReplicaNo(depth),
851 repPoint,
852 newLocalDirection,
853 normalOutStc);
854 if ( sampleStep < ourStep )
855 {
856 ourStep = sampleStep;
857 exiting = true;
858
859 // As step is limited by this level, must set Exit Normal
860 //
861 G4ThreeVector localExitNorm = normalOutStc.exitNormal;
862 G4ThreeVector globalExitNorm =
863 GlobalToLocal.InverseTransformAxis(localExitNorm);
864
865 exitNormalStc = normalOutStc; // Normal, convex, calculated, side
866 exitNormalStc.exitNormal = globalExitNorm;
867 calculatedExitNormal = true;
868 }
869 }
870 depth--;
871 }
872
873 // Compute mother safety & intersection
874 //
875 G4ThreeVector exitVectorMother;
876 G4bool exitConvex = false; // Value obtained in DistanceToOut(p,v) call
877 G4ExitNormal motherNormalStc;
878
879 repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
880 motherPhysical = history.GetVolume(depth);
881 motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
882 motherSafety = motherSolid->DistanceToOut(repPoint);
883 repDirection = history.GetTransform(depth).TransformAxis(globalDirection);
884
885 motherStep = motherSolid->DistanceToOut(repPoint,repDirection,true,
886 &exitConvex,&exitVectorMother);
887 if( exitConvex )
888 {
889 motherNormalStc = G4ExitNormal( exitVectorMother, true, false,
891 calculatedExitNormal = true;
892 }
893 const G4AffineTransform& globalToLocalTop = history.GetTopTransform();
894
895 G4bool motherDeterminedStep = (motherStep<ourStep);
896
897 if( (!exitConvex) && motherDeterminedStep )
898 {
899 exitVectorMother = motherSolid->SurfaceNormal( repPoint );
900 motherNormalStc = G4ExitNormal( exitVectorMother, true, false,
902 // CalculatedExitNormal -> true;
903 // Convex -> false: do not know value
904 // ExitSide -> kMother (or kNull)
905
906 calculatedExitNormal = true;
907 }
908 if( motherDeterminedStep )
909 {
910 G4ThreeVector globalExitNormalTop =
911 globalToLocalTop.InverseTransformAxis(exitVectorMother);
912
913 exitNormalStc = motherNormalStc;
914 exitNormalStc.exitNormal = globalExitNormalTop;
915 }
916
917 // Push in principle no longer necessary. G4Navigator now takes care of ...
918 // Removing this however may cause additional almost-zero steps and generate
919 // warnings for pushed particles from G4Navigator, particularly for the case
920 // of 3D replicas (Cartesian or combined Radial/Phi cases).
921 // Requires further investigation and eventually reimplementation of
922 // LevelLocate() to take into account point and direction ...
923 //
924 if( ourStep<fMinStep )
925 {
926 ourStep = 2*kCarTolerance;
927 }
928
929 if ( motherSafety<ourSafety )
930 {
931 ourSafety = motherSafety;
932 }
933
934#ifdef G4VERBOSE
935 if ( fCheck )
936 {
937 if( motherSolid->Inside(localPoint)==kOutside )
938 {
939 std::ostringstream message;
940 message << "Point outside volume !" << G4endl
941 << " Point " << localPoint
942 << " is outside current volume " << motherPhysical->GetName()
943 << G4endl;
944 G4double estDistToSolid= motherSolid->DistanceToIn(localPoint);
945 message << " Estimated isotropic distance to solid (distToIn)= "
946 << estDistToSolid << G4endl;
947 if( estDistToSolid > 100.0 * kCarTolerance )
948 {
949 motherSolid->DumpInfo();
950 G4Exception("G4ReplicaNavigation::ComputeStep()",
951 "GeomNav0003", FatalException, message,
952 "Point is far outside Current Volume !" );
953 }
954 else
955 {
956 G4Exception("G4ReplicaNavigation::ComputeStep()",
957 "GeomNav1002", JustWarning, message,
958 "Point is a little outside Current Volume.");
959 }
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 != nullptr )
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 }
1104 message << " for this point !" << G4endl
1105 << " Point = " << intersectionPoint << G4endl;
1106 if ( insideIntPt != kInside ) {
1107 message << " DistanceToIn(p) = "
1108 << sampleSolid->DistanceToIn(intersectionPoint)
1109 << G4endl;
1110}
1111 if ( insideIntPt != kOutside ) {
1112 message << " DistanceToOut(p) = "
1113 << sampleSolid->DistanceToOut(intersectionPoint);
1114}
1115 G4Exception("G4ReplicaNavigation::ComputeStep()",
1116 "GeomNav1002", JustWarning, message);
1117 G4cout.precision(oldcoutPrec);
1118 }
1119 }
1120#endif
1121 }
1122 }
1123 }
1124 }
1125
1126 calculatedExitNormal &= (!daughterDeterminedStep);
1127
1128#ifdef DAUGHTER_NORMAL_ALSO
1129 if( daughterDeterminedStep )
1130 {
1131 // G4ThreeVector daughtNormGlobal =
1132 // GlobalToLastDepth.Inverse().TransformAxis(daughtNormRepCrd);
1133 // ==> Can calculate it, but have no way to transmit it to caller (for now)
1134
1135 exitNormalVector = globalToLocalTop.InverseTransformAxis(daughtNormGlobal);
1136 validExitNormal = false; // Entering daughter - never convex for parent
1137
1138 calculatedExitNormal = true;
1139 }
1140 // calculatedExitNormal= true; // Force it to true -- dubious
1141#endif
1142
1143 newSafety = ourSafety;
1144 return ourStep;
1145}
@ JustWarning
bool G4bool
Definition G4Types.hh:86
#define G4endl
Definition G4ios.hh:67
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 G4ITNavigator1::ComputeStep(), G4ITNavigator2::ComputeStep(), and G4Navigator::ComputeStep().

◆ ComputeTransformation() [1/2]

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

Definition at line 703 of file G4ReplicaNavigation.cc.

705{
706 G4double val;
707
708 // Replication data
709 //
710 EAxis axis;
711 G4int nReplicas;
712 G4double width, offset;
713 G4bool consuming;
714
715 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
716
717 switch (axis)
718 {
719 case kXAxis:
720 val = -width*0.5*(nReplicas-1)+width*replicaNo;
721 pVol->SetTranslation(G4ThreeVector(val,0,0));
722 break;
723 case kYAxis:
724 val = -width*0.5*(nReplicas-1)+width*replicaNo;
725 pVol->SetTranslation(G4ThreeVector(0,val,0));
726 break;
727 case kZAxis:
728 val = -width*0.5*(nReplicas-1)+width*replicaNo;
729 pVol->SetTranslation(G4ThreeVector(0,0,val));
730 break;
731 case kPhi:
732 val = -(offset+width*(replicaNo+0.5));
733 SetPhiTransformation(val,pVol);
734 break;
735 case kRho:
736 // No setup required for radial case
737 default:
738 break;
739 }
740}
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 647 of file G4ReplicaNavigation.cc.

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

◆ DistanceToOut() [1/2]

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

Definition at line 181 of file G4ReplicaNavigation.cc.

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

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

◆ GetVerboseLevel()

G4int G4ReplicaNavigation::GetVerboseLevel ( ) const
inline

◆ Inside()

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

Definition at line 75 of file G4ReplicaNavigation.cc.

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