Geant4  10.02.p03
G4ReplicaNavigation Class Reference

#include <G4ReplicaNavigation.hh>

Collaboration diagram for G4ReplicaNavigation:

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)
 

Private Member Functions

G4int VoxelLocate (const G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint, const G4int blocked=-1) const
 
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
 

Private Attributes

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

Detailed Description

Definition at line 82 of file G4ReplicaNavigation.hh.

Constructor & Destructor Documentation

◆ G4ReplicaNavigation()

G4ReplicaNavigation::G4ReplicaNavigation ( )

Definition at line 57 of file G4ReplicaNavigation.cc.

58 : fCheck(false), fVerbose(0)
59 {
66  fMinStep = 0.05*kCarTolerance;
67 }
G4double GetSurfaceTolerance() const
G4double GetRadialTolerance() const
G4double GetAngularTolerance() const
static G4GeometryTolerance * GetInstance()
Here is the call graph for this function:

◆ ~G4ReplicaNavigation()

G4ReplicaNavigation::~G4ReplicaNavigation ( )

Definition at line 73 of file G4ReplicaNavigation.cc.

74 {
75 }

Member Function Documentation

◆ BackLocate()

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

Definition at line 1247 of file G4ReplicaNavigation.cc.

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

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

1162 {
1163  G4VPhysicalVolume *repPhysical, *motherPhysical;
1164  G4VPhysicalVolume *samplePhysical, *blockedExitedVol=0;
1165  G4LogicalVolume *repLogical;
1166  G4VSolid *motherSolid;
1167  G4ThreeVector repPoint;
1168  G4double ourSafety=kInfinity;
1169  G4double sampleSafety;
1170  G4int localNoDaughters, sampleNo;
1171  G4int depth;
1172 
1173  repPhysical = history.GetTopVolume();
1174  repLogical = repPhysical->GetLogicalVolume();
1175 
1176  //
1177  // Compute intersection with replica boundaries & replica safety
1178  //
1179 
1180  sampleSafety = DistanceToOut(history.GetTopVolume(),
1181  history.GetTopReplicaNo(),
1182  localPoint);
1183  if ( sampleSafety<ourSafety )
1184  {
1185  ourSafety = sampleSafety;
1186  }
1187 
1188  depth = history.GetDepth()-1;
1189 
1190  // Loop checking, 07.10.2016, J.Apostolakis -- need to add: assert(depth>0)
1191  while ( history.GetVolumeType(depth)==kReplica )
1192  {
1193  repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1194  sampleSafety = DistanceToOut(history.GetVolume(depth),
1195  history.GetReplicaNo(depth),
1196  repPoint);
1197  if ( sampleSafety<ourSafety )
1198  {
1199  ourSafety = sampleSafety;
1200  }
1201  depth--;
1202  }
1203 
1204  // Compute mother safety & intersection
1205  //
1206  repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1207  motherPhysical = history.GetVolume(depth);
1208  motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
1209  sampleSafety = motherSolid->DistanceToOut(repPoint);
1210 
1211  if ( sampleSafety<ourSafety )
1212  {
1213  ourSafety = sampleSafety;
1214  }
1215 
1216  // Compute daughter safeties & intersections
1217  //
1218  localNoDaughters = repLogical->GetNoDaughters();
1219  for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1220  {
1221  samplePhysical = repLogical->GetDaughter(sampleNo);
1222  if ( samplePhysical!=blockedExitedVol )
1223  {
1224  G4AffineTransform sampleTf(samplePhysical->GetRotation(),
1225  samplePhysical->GetTranslation());
1226  sampleTf.Invert();
1227  const G4ThreeVector samplePoint =
1228  sampleTf.TransformPoint(localPoint);
1229  const G4VSolid *sampleSolid =
1230  samplePhysical->GetLogicalVolume()->GetSolid();
1231  const G4double sampleSafetyDistance =
1232  sampleSolid->DistanceToIn(samplePoint);
1233  if ( sampleSafetyDistance<ourSafety )
1234  {
1235  ourSafety = sampleSafetyDistance;
1236  }
1237  }
1238  }
1239  return ourSafety;
1240 }
G4int GetReplicaNo(G4int n) const
G4int GetTopReplicaNo() const
const G4AffineTransform & GetTransform(G4int n) const
static const G4double kInfinity
Definition: geomdefs.hh:42
const G4RotationMatrix * GetRotation() const
G4int GetNoDaughters() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
int G4int
Definition: G4Types.hh:78
EVolume GetVolumeType(G4int n) const
G4VPhysicalVolume * GetVolume(G4int n) const
G4AffineTransform & Invert()
G4double DistanceToOut(const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
G4VPhysicalVolume * GetTopVolume() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
double G4double
Definition: G4Types.hh:76
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
G4LogicalVolume * GetLogicalVolume() const
const G4ThreeVector & GetTranslation() const
G4VSolid * GetSolid() const
G4int GetDepth() const
Here is the call graph for this function:
Here is the caller graph for this function:

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

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

◆ ComputeTransformation() [1/2]

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

Definition at line 654 of file G4ReplicaNavigation.cc.

657 {
658  G4double val,cosv,sinv,tmpx,tmpy;
659 
660  // Replication data
661  //
662  EAxis axis;
663  G4int nReplicas;
664  G4double width,offset;
665  G4bool consuming;
666 
667  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
668 
669  switch (axis)
670  {
671  case kXAxis:
672  val = -width*0.5*(nReplicas-1)+width*replicaNo;
673  pVol->SetTranslation(G4ThreeVector(val,0,0));
674  point.setX(point.x()-val);
675  break;
676  case kYAxis:
677  val = -width*0.5*(nReplicas-1)+width*replicaNo;
678  pVol->SetTranslation(G4ThreeVector(0,val,0));
679  point.setY(point.y()-val);
680  break;
681  case kZAxis:
682  val = -width*0.5*(nReplicas-1)+width*replicaNo;
683  pVol->SetTranslation(G4ThreeVector(0,0,val));
684  point.setZ(point.z()-val);
685  break;
686  case kPhi:
687  val = -(offset+width*(replicaNo+0.5));
688  SetPhiTransformation(val,pVol);
689  cosv = std::cos(val);
690  sinv = std::sin(val);
691  tmpx = point.x()*cosv-point.y()*sinv;
692  tmpy = point.x()*sinv+point.y()*cosv;
693  point.setY(tmpy);
694  point.setX(tmpx);
695  break;
696  case kRho:
697  // No setup required for radial case
698  default:
699  break;
700  }
701 }
Definition: geomdefs.hh:54
CLHEP::Hep3Vector G4ThreeVector
#define width
int G4int
Definition: G4Types.hh:78
void setY(double)
void setZ(double)
void setX(double)
bool G4bool
Definition: G4Types.hh:79
void SetTranslation(const G4ThreeVector &v)
double x() const
double y() const
EAxis
Definition: geomdefs.hh:54
double z() const
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
void SetPhiTransformation(const G4double ang, G4VPhysicalVolume *pVol=0) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ComputeTransformation() [2/2]

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

Definition at line 710 of file G4ReplicaNavigation.cc.

712 {
713  G4double val;
714 
715  // Replication data
716  //
717  EAxis axis;
718  G4int nReplicas;
719  G4double width, offset;
720  G4bool consuming;
721 
722  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
723 
724  switch (axis)
725  {
726  case kXAxis:
727  val = -width*0.5*(nReplicas-1)+width*replicaNo;
728  pVol->SetTranslation(G4ThreeVector(val,0,0));
729  break;
730  case kYAxis:
731  val = -width*0.5*(nReplicas-1)+width*replicaNo;
732  pVol->SetTranslation(G4ThreeVector(0,val,0));
733  break;
734  case kZAxis:
735  val = -width*0.5*(nReplicas-1)+width*replicaNo;
736  pVol->SetTranslation(G4ThreeVector(0,0,val));
737  break;
738  case kPhi:
739  val = -(offset+width*(replicaNo+0.5));
740  SetPhiTransformation(val,pVol);
741  break;
742  case kRho:
743  // No setup required for radial case
744  default:
745  break;
746  }
747 }
Definition: geomdefs.hh:54
CLHEP::Hep3Vector G4ThreeVector
#define width
int G4int
Definition: G4Types.hh:78
bool G4bool
Definition: G4Types.hh:79
void SetTranslation(const G4ThreeVector &v)
EAxis
Definition: geomdefs.hh:54
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
void SetPhiTransformation(const G4double ang, G4VPhysicalVolume *pVol=0) const
Here is the call graph for this function:

◆ DistanceToOut() [1/2]

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

Definition at line 188 of file G4ReplicaNavigation.cc.

191 {
192  // Replication data
193  //
194  EAxis axis;
195  G4int nReplicas;
196  G4double width,offset;
197  G4bool consuming;
198 
199  G4double safety=0.;
200  G4double safe1,safe2;
201  G4double coord, rho, rmin, rmax;
202 
203  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
204  switch(axis)
205  {
206  case kXAxis:
207  case kYAxis:
208  case kZAxis:
209  coord = localPoint(axis);
210  safe1 = width*0.5-coord;
211  safe2 = width*0.5+coord;
212  safety = (safe1<=safe2) ? safe1 : safe2;
213  break;
214  case kPhi:
215  if ( localPoint.y()<=0 )
216  {
217  safety = localPoint.x()*std::sin(width*0.5)
218  + localPoint.y()*std::cos(width*0.5);
219  }
220  else
221  {
222  safety = localPoint.x()*std::sin(width*0.5)
223  - localPoint.y()*std::cos(width*0.5);
224  }
225  break;
226  case kRho:
227  rho = localPoint.perp();
228  rmax = width*(replicaNo+1)+offset;
229  if ( replicaNo||offset )
230  {
231  rmin = rmax-width;
232  safe1 = rho-rmin;
233  safe2 = rmax-rho;
234  safety = (safe1<=safe2) ? safe1 : safe2;
235  }
236  else
237  {
238  safety = rmax-rho;
239  }
240  break;
241  default:
242  G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
243  FatalException, "Unknown axis!");
244  break;
245  }
246  return (safety >= halfkCarTolerance) ? safety : 0;
247 }
Definition: geomdefs.hh:54
#define width
int G4int
Definition: G4Types.hh:78
bool G4bool
Definition: G4Types.hh:79
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
double x() const
double y() const
double perp() const
EAxis
Definition: geomdefs.hh:54
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DistanceToOut() [2/2]

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

Definition at line 254 of file G4ReplicaNavigation.cc.

259 {
260  // Replication data
261  //
262  EAxis axis;
263  G4int nReplicas;
264  G4double width, offset;
265  G4bool consuming;
266 
267  G4double Dist=kInfinity;
268  G4double coord, Comp, lindist;
269  G4double signC = 0.0;
270  G4ExitNormal candidateNormal;
271 
272  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
273  switch(axis)
274  {
275  case kXAxis:
276  case kYAxis:
277  case kZAxis:
278  coord = localPoint(axis);
279  Comp = localDirection(axis);
280  if ( Comp>0 )
281  {
282  lindist = width*0.5-coord;
283  Dist = (lindist>0) ? lindist/Comp : 0;
284  signC= 1.0;
285  }
286  else if ( Comp<0 )
287  {
288  lindist = width*0.5+coord;
289  Dist = (lindist>0) ? -lindist/Comp : 0;
290  signC= -1.0;
291  }
292  else
293  {
294  Dist = kInfinity;
295  }
296  // signC = sign<G4double>(Comp)
297  candidateNormal.exitNormal = ( signC * VecCartAxes[axis]);
298  candidateNormal.calculated = true;
299  candidateNormal.validConvex = true;
300  candidateNormal.exitSide =
301  (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis];
302  break;
303  case kPhi:
304  Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal);
305  // candidateNormal set in call
306  break;
307  case kRho:
308  Dist = DistanceToOutRad(localPoint,localDirection,width,offset,
309  replicaNo,candidateNormal);
310  // candidateNormal set in call
311  break;
312  default:
313  G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
314  FatalException, "Unknown axis!");
315  break;
316  }
317 
318  arExitNormal= candidateNormal; // .exitNormal;
319 
320  return Dist;
321 }
Definition: geomdefs.hh:54
static const G4double kInfinity
Definition: geomdefs.hh:42
#define width
G4double DistanceToOutRad(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double width, const G4double offset, const G4int replicaNo, G4ExitNormal &foundNormal) const
int G4int
Definition: G4Types.hh:78
G4ThreeVector exitNormal
bool G4bool
Definition: G4Types.hh:79
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
EAxis
Definition: geomdefs.hh:54
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
G4double DistanceToOutPhi(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double width, G4ExitNormal &foundNormal) const
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
Here is the call graph for this function:

◆ DistanceToOutPhi()

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

Definition at line 328 of file G4ReplicaNavigation.cc.

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

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

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

◆ GetVerboseLevel()

G4int G4ReplicaNavigation::GetVerboseLevel ( ) const
inline

◆ Inside()

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

Definition at line 82 of file G4ReplicaNavigation.cc.

85 {
87 
88  // Replication data
89  //
90  EAxis axis;
91  G4int nReplicas;
92  G4double width, offset;
93  G4bool consuming;
94 
95  G4double coord, rad2, rmin, tolRMax2, rmax, tolRMin2;
96 
97  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
98 
99  switch (axis)
100  {
101  case kXAxis:
102  case kYAxis:
103  case kZAxis:
104  coord = std::fabs(localPoint(axis))-width*0.5;
105  if ( coord<=-halfkCarTolerance )
106  {
107  in = kInside;
108  }
109  else if ( coord<=halfkCarTolerance )
110  {
111  in = kSurface;
112  }
113  break;
114  case kPhi:
115  if ( localPoint.y()||localPoint.x() )
116  {
117  coord = std::fabs(std::atan2(localPoint.y(),localPoint.x()))-width*0.5;
118  if ( coord<=-halfkAngTolerance )
119  {
120  in = kInside;
121  }
122  else if ( coord<=halfkAngTolerance )
123  {
124  in = kSurface;
125  }
126  }
127  else
128  {
129  in = kSurface;
130  }
131  break;
132  case kRho:
133  rad2 = localPoint.perp2();
134  rmax = (replicaNo+1)*width+offset;
135  tolRMax2 = rmax-halfkRadTolerance;
136  tolRMax2 *= tolRMax2;
137  if ( rad2>tolRMax2 )
138  {
139  tolRMax2 = rmax+halfkRadTolerance;
140  tolRMax2 *= tolRMax2;
141  if ( rad2<=tolRMax2 )
142  {
143  in = kSurface;
144  }
145  }
146  else
147  {
148  // Known to be inside outer radius
149  //
150  if ( replicaNo||offset )
151  {
152  rmin = rmax-width;
153  tolRMin2 = rmin-halfkRadTolerance;
154  tolRMin2 *= tolRMin2;
155  if ( rad2>tolRMin2 )
156  {
157  tolRMin2 = rmin+halfkRadTolerance;
158  tolRMin2 *= tolRMin2;
159  if ( rad2>=tolRMin2 )
160  {
161  in = kInside;
162  }
163  else
164  {
165  in = kSurface;
166  }
167  }
168  }
169  else
170  {
171  in = kInside;
172  }
173  }
174  break;
175  default:
176  G4Exception("G4ReplicaNavigation::Inside()", "GeomNav0002",
177  FatalException, "Unknown axis!");
178  break;
179  }
180  return in;
181 }
Definition: geomdefs.hh:54
ifstream in
Definition: comparison.C:7
#define width
int G4int
Definition: G4Types.hh:78
bool G4bool
Definition: G4Types.hh:79
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
double x() const
double perp2() const
double y() const
EInside
Definition: geomdefs.hh:58
EAxis
Definition: geomdefs.hh:54
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LevelLocate()

G4bool G4ReplicaNavigation::LevelLocate ( G4NavigationHistory history,
const G4VPhysicalVolume blockedVol,
const G4int  blockedNum,
const G4ThreeVector globalPoint,
const G4ThreeVector globalDirection,
const G4bool  pLocatedOnEdge,
G4ThreeVector localPoint 
)
inline
Here is the caller graph for this function:

◆ SetPhiTransformation()

void G4ReplicaNavigation::SetPhiTransformation ( const G4double  ang,
G4VPhysicalVolume pVol = 0 
) const
inlineprivate
Here is the caller graph for this function:

◆ SetVerboseLevel()

void G4ReplicaNavigation::SetVerboseLevel ( G4int  level)
inline

◆ VoxelLocate()

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

Member Data Documentation

◆ fCheck

G4bool G4ReplicaNavigation::fCheck
private

Definition at line 175 of file G4ReplicaNavigation.hh.

◆ fMinStep

G4double G4ReplicaNavigation::fMinStep
private

Definition at line 179 of file G4ReplicaNavigation.hh.

◆ fVerbose

G4int G4ReplicaNavigation::fVerbose
private

Definition at line 176 of file G4ReplicaNavigation.hh.

◆ halfkAngTolerance

G4double G4ReplicaNavigation::halfkAngTolerance
private

Definition at line 179 of file G4ReplicaNavigation.hh.

◆ halfkCarTolerance

G4double G4ReplicaNavigation::halfkCarTolerance
private

Definition at line 179 of file G4ReplicaNavigation.hh.

◆ halfkRadTolerance

G4double G4ReplicaNavigation::halfkRadTolerance
private

Definition at line 179 of file G4ReplicaNavigation.hh.

◆ kAngTolerance

G4double G4ReplicaNavigation::kAngTolerance
private

Definition at line 179 of file G4ReplicaNavigation.hh.

◆ kCarTolerance

G4double G4ReplicaNavigation::kCarTolerance
private

Definition at line 179 of file G4ReplicaNavigation.hh.

◆ kRadTolerance

G4double G4ReplicaNavigation::kRadTolerance
private

Definition at line 179 of file G4ReplicaNavigation.hh.


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