Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions
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 82 of file G4ReplicaNavigation.hh.

Constructor & Destructor Documentation

G4ReplicaNavigation::G4ReplicaNavigation ( )
G4ReplicaNavigation::~G4ReplicaNavigation ( )

Definition at line 60 of file G4ReplicaNavigation.cc.

61 {
62 }

Member Function Documentation

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

Definition at line 1229 of file G4ReplicaNavigation.cc.

References G4NavigationHistory::BackLevel(), FatalException, G4Exception(), G4NavigationHistory::GetDepth(), G4VPhysicalVolume::GetLogicalVolume(), G4NavigationHistory::GetReplicaNo(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTransform(), G4NavigationHistory::GetVolume(), G4NavigationHistory::GetVolumeType(), G4VSolid::Inside(), Inside(), kInside, kOutside, kReplica, kSurface, and G4AffineTransform::TransformPoint().

Referenced by G4Navigator::LocateGlobalPointAndSetup(), and G4ITNavigator::LocateGlobalPointAndSetup().

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

Definition at line 1142 of file G4ReplicaNavigation.cc.

References G4VSolid::DistanceToIn(), DistanceToOut(), G4VSolid::DistanceToOut(), G4LogicalVolume::GetDaughter(), G4NavigationHistory::GetDepth(), G4VPhysicalVolume::GetLogicalVolume(), G4LogicalVolume::GetNoDaughters(), G4NavigationHistory::GetReplicaNo(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopReplicaNo(), G4NavigationHistory::GetTopVolume(), G4NavigationHistory::GetTransform(), G4VPhysicalVolume::GetTranslation(), G4NavigationHistory::GetVolume(), G4NavigationHistory::GetVolumeType(), G4AffineTransform::Invert(), kReplica, and G4AffineTransform::TransformPoint().

Referenced by G4Navigator::ComputeSafety(), and G4ITNavigator::ComputeSafety().

1146 {
1147  G4VPhysicalVolume *repPhysical, *motherPhysical;
1148  G4VPhysicalVolume *samplePhysical, *blockedExitedVol=0;
1149  G4LogicalVolume *repLogical;
1150  G4VSolid *motherSolid;
1151  G4ThreeVector repPoint;
1152  G4double ourSafety=kInfinity;
1153  G4double sampleSafety;
1154  G4int localNoDaughters, sampleNo;
1155  G4int depth;
1156 
1157  repPhysical = history.GetTopVolume();
1158  repLogical = repPhysical->GetLogicalVolume();
1159 
1160  //
1161  // Compute intersection with replica boundaries & replica safety
1162  //
1163 
1164  sampleSafety = DistanceToOut(history.GetTopVolume(),
1165  history.GetTopReplicaNo(),
1166  localPoint);
1167  if ( sampleSafety<ourSafety )
1168  {
1169  ourSafety = sampleSafety;
1170  }
1171 
1172  depth = history.GetDepth()-1;
1173  while ( history.GetVolumeType(depth)==kReplica )
1174  {
1175  repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1176  sampleSafety = DistanceToOut(history.GetVolume(depth),
1177  history.GetReplicaNo(depth),
1178  repPoint);
1179  if ( sampleSafety<ourSafety )
1180  {
1181  ourSafety = sampleSafety;
1182  }
1183  depth--;
1184  }
1185 
1186  // Compute mother safety & intersection
1187  //
1188  repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
1189  motherPhysical = history.GetVolume(depth);
1190  motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
1191  sampleSafety = motherSolid->DistanceToOut(repPoint);
1192 
1193  if ( sampleSafety<ourSafety )
1194  {
1195  ourSafety = sampleSafety;
1196  }
1197 
1198  // Compute daughter safeties & intersections
1199  //
1200  localNoDaughters = repLogical->GetNoDaughters();
1201  for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1202  {
1203  samplePhysical = repLogical->GetDaughter(sampleNo);
1204  if ( samplePhysical!=blockedExitedVol )
1205  {
1206  G4AffineTransform sampleTf(samplePhysical->GetRotation(),
1207  samplePhysical->GetTranslation());
1208  sampleTf.Invert();
1209  const G4ThreeVector samplePoint =
1210  sampleTf.TransformPoint(localPoint);
1211  const G4VSolid *sampleSolid =
1212  samplePhysical->GetLogicalVolume()->GetSolid();
1213  const G4double sampleSafetyDistance =
1214  sampleSolid->DistanceToIn(samplePoint);
1215  if ( sampleSafetyDistance<ourSafety )
1216  {
1217  ourSafety = sampleSafetyDistance;
1218  }
1219  }
1220  }
1221  return ourSafety;
1222 }
G4VPhysicalVolume * GetTopVolume() const
const G4ThreeVector & GetTranslation() const
G4int GetDepth() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
EVolume GetVolumeType(G4int n) const
G4double DistanceToOut(const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const
int G4int
Definition: G4Types.hh:78
G4int GetTopReplicaNo() const
G4AffineTransform & Invert()
G4int GetReplicaNo(G4int n) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
G4int GetNoDaughters() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4LogicalVolume * GetLogicalVolume() const
const G4AffineTransform & GetTransform(G4int n) const
const G4RotationMatrix * GetRotation() const
double G4double
Definition: G4Types.hh:76
G4VPhysicalVolume * GetVolume(G4int n) const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
G4VSolid * GetSolid() const
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 740 of file G4ReplicaNavigation.cc.

References G4VSolid::DistanceToIn(), DistanceToOut(), G4VSolid::DistanceToOut(), CLHEP::Hep3Vector::dot(), G4VSolid::DumpInfo(), G4ExitNormal::exitNormal, FatalException, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4NavigationHistory::GetDepth(), G4VPhysicalVolume::GetLogicalVolume(), G4VSolid::GetName(), G4VPhysicalVolume::GetName(), G4LogicalVolume::GetNoDaughters(), G4NavigationHistory::GetReplicaNo(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopReplicaNo(), G4NavigationHistory::GetTopTransform(), G4NavigationHistory::GetTopVolume(), G4NavigationHistory::GetTransform(), G4VPhysicalVolume::GetTranslation(), G4NavigationHistory::GetVolume(), G4NavigationHistory::GetVolumeType(), G4VSolid::Inside(), G4AffineTransform::Inverse(), CLHEP::HepRotation::inverse(), G4AffineTransform::Invert(), JustWarning, kInside, G4ExitNormal::kMother, kOutside, kReplica, kSurface, G4VSolid::SurfaceNormal(), G4AffineTransform::TransformAxis(), and G4AffineTransform::TransformPoint().

Referenced by G4Navigator::ComputeStep(), and G4ITNavigator::ComputeStep().

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

Definition at line 640 of file G4ReplicaNavigation.cc.

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

Referenced by G4Navigator::LocateGlobalPointAndSetup(), G4ITNavigator::LocateGlobalPointAndSetup(), G4Navigator::SetupHierarchy(), and G4ITNavigator::SetupHierarchy().

643 {
644  G4double val,cosv,sinv,tmpx,tmpy;
645 
646  // Replication data
647  //
648  EAxis axis;
649  G4int nReplicas;
650  G4double width,offset;
651  G4bool consuming;
652 
653  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
654 
655  switch (axis)
656  {
657  case kXAxis:
658  val = -width*0.5*(nReplicas-1)+width*replicaNo;
659  pVol->SetTranslation(G4ThreeVector(val,0,0));
660  point.setX(point.x()-val);
661  break;
662  case kYAxis:
663  val = -width*0.5*(nReplicas-1)+width*replicaNo;
664  pVol->SetTranslation(G4ThreeVector(0,val,0));
665  point.setY(point.y()-val);
666  break;
667  case kZAxis:
668  val = -width*0.5*(nReplicas-1)+width*replicaNo;
669  pVol->SetTranslation(G4ThreeVector(0,0,val));
670  point.setZ(point.z()-val);
671  break;
672  case kPhi:
673  val = -(offset+width*(replicaNo+0.5));
674  SetPhiTransformation(val,pVol);
675  cosv = std::cos(val);
676  sinv = std::sin(val);
677  tmpx = point.x()*cosv-point.y()*sinv;
678  tmpy = point.x()*sinv+point.y()*cosv;
679  point.setY(tmpy);
680  point.setX(tmpx);
681  break;
682  case kRho:
683  // No setup required for radial case
684  default:
685  break;
686  }
687 }
Definition: geomdefs.hh:54
CLHEP::Hep3Vector G4ThreeVector
double x() const
#define width
int G4int
Definition: G4Types.hh:78
void setY(double)
double z() const
void setZ(double)
void setX(double)
bool G4bool
Definition: G4Types.hh:79
void SetTranslation(const G4ThreeVector &v)
EAxis
Definition: geomdefs.hh:54
double y() 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 G4ReplicaNavigation::ComputeTransformation ( const G4int  replicaNo,
G4VPhysicalVolume pVol 
) const

Definition at line 696 of file G4ReplicaNavigation.cc.

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

698 {
699  G4double val;
700 
701  // Replication data
702  //
703  EAxis axis;
704  G4int nReplicas;
705  G4double width, offset;
706  G4bool consuming;
707 
708  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
709 
710  switch (axis)
711  {
712  case kXAxis:
713  val = -width*0.5*(nReplicas-1)+width*replicaNo;
714  pVol->SetTranslation(G4ThreeVector(val,0,0));
715  break;
716  case kYAxis:
717  val = -width*0.5*(nReplicas-1)+width*replicaNo;
718  pVol->SetTranslation(G4ThreeVector(0,val,0));
719  break;
720  case kZAxis:
721  val = -width*0.5*(nReplicas-1)+width*replicaNo;
722  pVol->SetTranslation(G4ThreeVector(0,0,val));
723  break;
724  case kPhi:
725  val = -(offset+width*(replicaNo+0.5));
726  SetPhiTransformation(val,pVol);
727  break;
728  case kRho:
729  // No setup required for radial case
730  default:
731  break;
732  }
733 }
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
G4double G4ReplicaNavigation::DistanceToOut ( const G4VPhysicalVolume pVol,
const G4int  replicaNo,
const G4ThreeVector localPoint 
) const

Definition at line 175 of file G4ReplicaNavigation.cc.

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

Referenced by ComputeSafety(), and ComputeStep().

178 {
179  // Replication data
180  //
181  EAxis axis;
182  G4int nReplicas;
183  G4double width,offset;
184  G4bool consuming;
185 
186  G4double safety=0.;
187  G4double safe1,safe2;
188  G4double coord, rho, rmin, rmax;
189 
190  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
191  switch(axis)
192  {
193  case kXAxis:
194  case kYAxis:
195  case kZAxis:
196  coord = localPoint(axis);
197  safe1 = width*0.5-coord;
198  safe2 = width*0.5+coord;
199  safety = (safe1<=safe2) ? safe1 : safe2;
200  break;
201  case kPhi:
202  if ( localPoint.y()<=0 )
203  {
204  safety = localPoint.x()*std::sin(width*0.5)
205  + localPoint.y()*std::cos(width*0.5);
206  }
207  else
208  {
209  safety = localPoint.x()*std::sin(width*0.5)
210  - localPoint.y()*std::cos(width*0.5);
211  }
212  break;
213  case kRho:
214  rho = localPoint.perp();
215  rmax = width*(replicaNo+1)+offset;
216  if ( replicaNo||offset )
217  {
218  rmin = rmax-width;
219  safe1 = rho-rmin;
220  safe2 = rmax-rho;
221  safety = (safe1<=safe2) ? safe1 : safe2;
222  }
223  else
224  {
225  safety = rmax-rho;
226  }
227  break;
228  default:
229  G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
230  FatalException, "Unknown axis!");
231  break;
232  }
233  return (safety >= kCarTolerance) ? safety : 0;
234 }
Definition: geomdefs.hh:54
double x() const
#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
EAxis
Definition: geomdefs.hh:54
double y() 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
double perp() const
G4double G4ReplicaNavigation::DistanceToOut ( const G4VPhysicalVolume pVol,
const G4int  replicaNo,
const G4ThreeVector localPoint,
const G4ThreeVector localDirection,
G4ExitNormal candidateNormal 
) const

Definition at line 241 of file G4ReplicaNavigation.cc.

References G4ExitNormal::calculated, G4ExitNormal::exitNormal, G4ExitNormal::exitSide, FatalException, G4Exception(), G4ThreadLocal, G4VPhysicalVolume::GetReplicationData(), G4ExitNormal::kMX, G4ExitNormal::kMY, G4ExitNormal::kMZ, kPhi, G4ExitNormal::kPX, G4ExitNormal::kPY, G4ExitNormal::kPZ, kRho, kXAxis, kYAxis, kZAxis, G4ExitNormal::validConvex, and width.

246 {
247  // Replication data
248  //
249  EAxis axis;
250  G4int nReplicas;
251  G4double width, offset;
252  G4bool consuming;
253 
254  G4double Dist=kInfinity;
255  G4double coord, Comp, lindist;
256  G4double signC = 0.0;
257  G4ExitNormal candidateNormal;
258 
259  static const G4ThreeVector VecCartAxes[3]=
260  { G4ThreeVector(1.,0.,0.),G4ThreeVector(0.,1.,0.),G4ThreeVector(0.,0.,1.) };
261  static G4ThreadLocal G4ExitNormal::ESide *SideCartAxesPlus = 0 ; if (!SideCartAxesPlus) {SideCartAxesPlus = new G4ExitNormal::ESide [3] ;
262  SideCartAxesPlus[0]= G4ExitNormal::kPX;SideCartAxesPlus[1]= G4ExitNormal::kPY;SideCartAxesPlus[2]= G4ExitNormal::kPZ ;};
263  static G4ThreadLocal G4ExitNormal::ESide *SideCartAxesMinus = 0 ; if (!SideCartAxesMinus) {SideCartAxesMinus = new G4ExitNormal::ESide [3] ;
264  SideCartAxesMinus[0]= G4ExitNormal::kMX;SideCartAxesMinus[1]= G4ExitNormal::kMY;SideCartAxesMinus[2]= G4ExitNormal::kMZ ;};
265 
266  pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
267  switch(axis)
268  {
269  case kXAxis:
270  case kYAxis:
271  case kZAxis:
272  coord = localPoint(axis);
273  Comp = localDirection(axis);
274  if ( Comp>0 )
275  {
276  lindist = width*0.5-coord;
277  Dist = (lindist>0) ? lindist/Comp : 0;
278  signC= 1.0;
279  }
280  else if ( Comp<0 )
281  {
282  lindist = width*0.5+coord;
283  Dist = (lindist>0) ? -lindist/Comp : 0;
284  signC= -1.0;
285  }
286  else
287  {
288  Dist = kInfinity;
289  }
290  // signC = sign<G4double>(Comp)
291  candidateNormal.exitNormal = ( signC * VecCartAxes[axis]);
292  candidateNormal.calculated = true;
293  candidateNormal.validConvex = true;
294  candidateNormal.exitSide =
295  (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis];
296  break;
297  case kPhi:
298  Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal);
299  // candidateNormal set in call
300  break;
301  case kRho:
302  Dist = DistanceToOutRad(localPoint,localDirection,width,offset,
303  replicaNo,candidateNormal);
304  // candidateNormal set in call
305  break;
306  default:
307  G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
308  FatalException, "Unknown axis!");
309  break;
310  }
311 
312  arExitNormal= candidateNormal; // .exitNormal;
313 
314  return Dist;
315 }
Definition: geomdefs.hh:54
CLHEP::Hep3Vector G4ThreeVector
#define width
#define G4ThreadLocal
Definition: tls.hh:52
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
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
G4int G4ReplicaNavigation::GetVerboseLevel ( ) const
inline
EInside G4ReplicaNavigation::Inside ( const G4VPhysicalVolume pVol,
const G4int  replicaNo,
const G4ThreeVector localPoint 
) const

Definition at line 69 of file G4ReplicaNavigation.cc.

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

Referenced by BackLocate().

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

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