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

Definition at line 48 of file G4ReplicaNavigation.cc.

References G4GeometryTolerance::GetAngularTolerance(), G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetRadialTolerance(), and G4GeometryTolerance::GetSurfaceTolerance().

00049 : fCheck(false), fVerbose(0)
00050 {
00051   kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00052   kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
00053   kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
00054 }

G4ReplicaNavigation::~G4ReplicaNavigation (  ) 

Definition at line 60 of file G4ReplicaNavigation.cc.

00061 {
00062 }


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(), Inside(), G4VSolid::Inside(), kInside, kOutside, kReplica, kSurface, and G4AffineTransform::TransformPoint().

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

01234 {
01235   G4VPhysicalVolume *pNRMother=0;
01236   G4VSolid *motherSolid;
01237   G4ThreeVector repPoint, goodPoint;
01238   G4int mdepth, depth, cdepth;
01239   EInside insideCode;
01240 
01241   cdepth = history.GetDepth();
01242   
01243   // Find non replicated mother
01244   //
01245   for ( mdepth=cdepth-1; mdepth>=0; mdepth-- )
01246   {
01247     if ( history.GetVolumeType(mdepth)!=kReplica )
01248     {
01249       pNRMother = history.GetVolume(mdepth);
01250       break;
01251     }
01252   }
01253 
01254   if( pNRMother==0 ) 
01255   {
01256     // All the tree of mother volumes were Replicas. 
01257     // This is an error, as the World volume must be a Placement
01258     //
01259     G4Exception("G4ReplicaNavigation::BackLocate()", "GeomNav0002",
01260                 FatalException, "The World volume must be a Placement!");
01261     return kInside;
01262   }
01263 
01264   motherSolid = pNRMother->GetLogicalVolume()->GetSolid();
01265   goodPoint = history.GetTransform(mdepth).TransformPoint(globalPoint);
01266   insideCode = motherSolid->Inside(goodPoint);
01267   if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
01268   {
01269     // Outside mother -> back up to mother level
01270     // Locate.. in Navigator will back up one more level
01271     // localPoint not required
01272     //
01273     history.BackLevel(cdepth-mdepth);
01274     //      localPoint = goodPoint;
01275   }
01276   else
01277   {
01278     notKnownInside = false;
01279 
01280     // Still within replications
01281     // Check down: if on outside stop at this level
01282     //
01283     for ( depth=mdepth+1; depth<cdepth; depth++)
01284     {
01285       repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
01286       insideCode = Inside(history.GetVolume(depth),
01287                           history.GetReplicaNo(depth),
01288                           repPoint);
01289       if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
01290       {
01291         localPoint = goodPoint;
01292         history.BackLevel(cdepth-depth);
01293         return insideCode;
01294       }
01295       else
01296       {
01297         goodPoint = repPoint;
01298       }
01299     }
01300     localPoint = history.GetTransform(depth).TransformPoint(globalPoint);
01301     insideCode = Inside(history.GetVolume(depth),
01302                         history.GetReplicaNo(depth),
01303                         localPoint);
01304     // If outside level, set localPoint = coordinates in reference system
01305     // of *previous* level - location code in navigator will back up one
01306     // level [And also manage blocking]
01307     //
01308     if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) )
01309     {
01310       localPoint = goodPoint;
01311     }
01312   }
01313   return insideCode;
01314 }

void G4ReplicaNavigation::CheckMode ( G4bool  mode  )  [inline]

Definition at line 219 of file G4ReplicaNavigation.icc.

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

00220 {
00221   fCheck = mode;
00222 }

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(), G4VSolid::DistanceToOut(), 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(), kReplica, and G4AffineTransform::TransformPoint().

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

01146 {
01147   G4VPhysicalVolume *repPhysical, *motherPhysical;
01148   G4VPhysicalVolume *samplePhysical, *blockedExitedVol=0;
01149   G4LogicalVolume *repLogical;
01150   G4VSolid *motherSolid;
01151   G4ThreeVector repPoint;
01152   G4double ourSafety=kInfinity;
01153   G4double sampleSafety;
01154   G4int localNoDaughters, sampleNo;
01155   G4int depth;
01156 
01157   repPhysical = history.GetTopVolume();
01158   repLogical  = repPhysical->GetLogicalVolume();
01159 
01160   //
01161   // Compute intersection with replica boundaries & replica safety
01162   //
01163 
01164   sampleSafety = DistanceToOut(history.GetTopVolume(),
01165                                history.GetTopReplicaNo(),
01166                                localPoint);
01167   if ( sampleSafety<ourSafety )
01168   {
01169     ourSafety = sampleSafety;
01170   }
01171 
01172   depth = history.GetDepth()-1;
01173   while ( history.GetVolumeType(depth)==kReplica )
01174   {
01175     repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
01176     sampleSafety = DistanceToOut(history.GetVolume(depth),
01177                                  history.GetReplicaNo(depth),
01178                                  repPoint);
01179     if ( sampleSafety<ourSafety )
01180     {
01181       ourSafety = sampleSafety;
01182     }
01183     depth--;
01184   }
01185 
01186   // Compute mother safety & intersection
01187   //
01188   repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
01189   motherPhysical = history.GetVolume(depth);
01190   motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
01191   sampleSafety = motherSolid->DistanceToOut(repPoint);
01192 
01193   if ( sampleSafety<ourSafety )
01194   {
01195     ourSafety = sampleSafety;
01196   }
01197 
01198   // Compute daughter safeties & intersections
01199   //
01200   localNoDaughters = repLogical->GetNoDaughters();
01201   for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
01202   {
01203     samplePhysical = repLogical->GetDaughter(sampleNo);
01204     if ( samplePhysical!=blockedExitedVol )
01205     {
01206       G4AffineTransform sampleTf(samplePhysical->GetRotation(),
01207                                  samplePhysical->GetTranslation());
01208       sampleTf.Invert();
01209       const G4ThreeVector samplePoint =
01210                             sampleTf.TransformPoint(localPoint);
01211       const G4VSolid *sampleSolid =
01212                             samplePhysical->GetLogicalVolume()->GetSolid();
01213       const G4double sampleSafetyDistance =
01214                             sampleSolid->DistanceToIn(samplePoint);
01215       if ( sampleSafetyDistance<ourSafety )
01216       {
01217         ourSafety = sampleSafetyDistance;
01218       }
01219     }
01220   }
01221   return ourSafety;
01222 }

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(), G4VSolid::DistanceToOut(), DistanceToOut(), 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(), JustWarning, kInside, G4ExitNormal::kMother, kOutside, kReplica, kSurface, G4VSolid::SurfaceNormal(), G4AffineTransform::TransformAxis(), and G4AffineTransform::TransformPoint().

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

00755 {
00756   G4VPhysicalVolume *repPhysical, *motherPhysical;
00757   G4VPhysicalVolume *samplePhysical, *blockedExitedVol=0;
00758   G4LogicalVolume *repLogical;
00759   G4VSolid *motherSolid;
00760   G4ThreeVector repPoint, repDirection, sampleDirection;
00761   G4double ourStep=currentProposedStepLength;
00762   G4double ourSafety=kInfinity;
00763   G4double sampleStep, sampleSafety, motherStep, motherSafety;
00764   G4int localNoDaughters, sampleNo;
00765   G4int depth;
00766   G4ExitNormal exitNormalStc;
00767   // G4int depthDeterminingStep= -1; // Useful only for debugging - for now
00768 
00769   calculatedExitNormal= false;
00770   
00771   // Exiting normal optimisation
00772   //
00773   if ( exiting&&validExitNormal )
00774   {
00775     if ( localDirection.dot(exitNormalVector)>=kMinExitingNormalCosine )
00776     {
00777       // Block exited daughter volume
00778       //
00779       blockedExitedVol = *pBlockedPhysical;
00780       ourSafety = 0;
00781     }
00782   }
00783   exiting  = false;
00784   entering = false;
00785 
00786   repPhysical = history.GetTopVolume();
00787   repLogical  = repPhysical->GetLogicalVolume();
00788 
00789   //
00790   // Compute intersection with replica boundaries & replica safety
00791   //
00792 
00793   sampleSafety = DistanceToOut(repPhysical,
00794                                history.GetTopReplicaNo(),
00795                                localPoint);
00796   G4ExitNormal normalOutStc;
00797   const G4int topDepth= history.GetDepth();
00798 
00799   if ( sampleSafety<ourSafety )
00800   {
00801     ourSafety = sampleSafety;
00802   }
00803   if ( sampleSafety<ourStep )
00804   {
00805 
00806     sampleStep = DistanceToOut(repPhysical,
00807                                history.GetTopReplicaNo(),
00808                                localPoint,
00809                                localDirection,
00810                                normalOutStc);
00811     if ( sampleStep<ourStep )
00812     {
00813       ourStep = sampleStep;
00814       exiting = true;
00815       validExitNormal = normalOutStc.validConvex; // false; -> Old,Conservative
00816 
00817       exitNormalStc= normalOutStc;
00818       exitNormalStc.exitNormal= history.GetTopTransform().Inverse().
00819                                 TransformAxis(normalOutStc.exitNormal);
00820       calculatedExitNormal= true;
00821     }
00822   }
00823   const G4int secondDepth= topDepth;
00824   depth = secondDepth;
00825   
00826   while ( history.GetVolumeType(depth)==kReplica )
00827   {
00828     const G4AffineTransform& GlobalToLocal= history.GetTransform(depth);
00829     repPoint    = GlobalToLocal.TransformPoint(globalPoint);
00830     // repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
00831  
00832     sampleSafety = DistanceToOut(history.GetVolume(depth),
00833                                  history.GetReplicaNo(depth),
00834                                  repPoint);
00835     if ( sampleSafety < ourSafety )
00836     {
00837       ourSafety = sampleSafety;
00838     }
00839     if ( sampleSafety < ourStep )
00840     {
00841       G4ThreeVector newLocalDirection = GlobalToLocal.TransformAxis(globalDirection);
00842       sampleStep = DistanceToOut(history.GetVolume(depth),
00843                                  history.GetReplicaNo(depth),
00844                                  repPoint,
00845                                  newLocalDirection,
00846                                  normalOutStc);
00847       if ( sampleStep < ourStep )
00848       {
00849         ourStep = sampleStep;
00850         exiting = true;
00851        
00852         // As step is limited by this level, must set Exit Normal
00853         //
00854         G4ThreeVector localExitNorm= normalOutStc.exitNormal;
00855         G4ThreeVector globalExitNorm=
00856             GlobalToLocal.Inverse().TransformAxis(localExitNorm);
00857 
00858         exitNormalStc= normalOutStc; // Normal, convex, calculated, side
00859         exitNormalStc.exitNormal= globalExitNorm;
00860         calculatedExitNormal= true;
00861       }
00862     }
00863     depth--;
00864   }
00865  
00866   // Compute mother safety & intersection
00867   //
00868   G4ThreeVector exitVectorMother;
00869   G4bool        exitConvex= false; // Value obtained in DistanceToOut(p,v) call
00870   G4ExitNormal  motherNormalStc;
00871 
00872   repPoint = history.GetTransform(depth).TransformPoint(globalPoint);
00873   motherPhysical = history.GetVolume(depth);
00874   motherSolid = motherPhysical->GetLogicalVolume()->GetSolid();
00875   motherSafety = motherSolid->DistanceToOut(repPoint);
00876   repDirection = history.GetTransform(depth).TransformAxis(globalDirection);
00877 
00878   motherStep = motherSolid->DistanceToOut(repPoint,repDirection,true,
00879                                           &exitConvex,&exitVectorMother);
00880   if( exitConvex )
00881   {
00882      motherNormalStc = G4ExitNormal( exitVectorMother, true, false,
00883                                      G4ExitNormal::kMother);
00884      calculatedExitNormal= true;
00885   }
00886   const G4AffineTransform& globalToLocalTop = history.GetTopTransform();
00887 
00888   G4bool motherDeterminedStep= (motherStep<ourStep);
00889 
00890   if( (!exitConvex) && motherDeterminedStep )
00891   {
00892      exitVectorMother= motherSolid->SurfaceNormal( repPoint );
00893      motherNormalStc= G4ExitNormal( exitVectorMother, true, false,
00894                                     G4ExitNormal::kMother);
00895      // CalculatedExitNormal -> true;
00896      // Convex               -> false: do not know value
00897      // ExitSide             -> kMother (or kNull)
00898  
00899      calculatedExitNormal= true;
00900   }
00901   if( motherDeterminedStep)
00902   {
00903      G4ThreeVector globalExitNormalTop=
00904         globalToLocalTop.Inverse().TransformAxis(exitVectorMother);
00905      
00906      exitNormalStc= motherNormalStc;
00907      exitNormalStc.exitNormal= globalExitNormalTop;
00908   }
00909 
00910   // Push in principle no longer necessary. G4Navigator now takes care of ...
00911   // Removing this will however generate warnings for pushed particles from
00912   // G4Navigator, particularly for the case of 3D replicas (Cartesian or
00913   // combined Radial/Phi cases).
00914   // Requires further investigation and eventually reimplementation of
00915   // LevelLocate() to take into account point and direction ...
00916   //
00917   if  ( ( !ourStep && (sampleSafety<0.5*kCarTolerance) )
00918      && ( repLogical->GetSolid()->Inside(localPoint)==kSurface ) )
00919   {
00920     ourStep += kCarTolerance;
00921   }
00922 
00923   if ( motherSafety<ourSafety )
00924   {
00925     ourSafety = motherSafety;
00926   }
00927 
00928 #ifdef G4VERBOSE
00929   if ( fCheck )
00930   {
00931     if( motherSolid->Inside(localPoint)==kOutside )
00932     {
00933       std::ostringstream message;
00934       message << "Point outside volume !" << G4endl
00935               << "          Point " << localPoint
00936               << " is outside current volume " << motherPhysical->GetName()
00937               << G4endl;
00938       G4double estDistToSolid= motherSolid->DistanceToIn(localPoint); 
00939       message << "          Estimated isotropic distance to solid (distToIn)= " 
00940               << estDistToSolid << G4endl;
00941       if( estDistToSolid > 100.0 * kCarTolerance )
00942       {
00943         motherSolid->DumpInfo();
00944         G4Exception("G4ReplicaNavigation::ComputeStep()",
00945                     "GeomNav0003", FatalException, message,
00946                     "Point is far outside Current Volume !" ); 
00947       }
00948       else
00949         G4Exception("G4ReplicaNavigation::ComputeStep()",
00950                     "GeomNav1002", JustWarning, message,
00951                     "Point is a little outside Current Volume."); 
00952     }
00953   }
00954 #endif
00955 
00956   // Comparison of steps may need precision protection
00957   //
00958 #if 1
00959   if( motherDeterminedStep)
00960   {
00961     ourStep = motherStep;
00962     exiting = true;
00963   }
00964 
00965   // Transform it to the Grand-Mother Reference Frame (current convention)
00966   //
00967   if ( calculatedExitNormal )
00968   {
00969     if ( motherDeterminedStep )
00970     {
00971       exitNormalVector= motherNormalStc.exitNormal;
00972     }else{
00973       G4ThreeVector exitNormalGlobal= exitNormalStc.exitNormal;
00974       exitNormalVector= globalToLocalTop.TransformAxis(exitNormalGlobal);
00975       // exitNormalVector= globalToLocal2nd.TransformAxis(exitNormalGlobal);
00976       // Alt Make it in one go to Grand-Mother, avoiding transform below
00977     }
00978     // Transform to Grand-mother reference frame
00979     const G4RotationMatrix* rot = motherPhysical->GetRotation();
00980     if ( rot )
00981     {
00982       exitNormalVector *= rot->inverse();
00983     }
00984 
00985   }
00986   else
00987   {
00988     validExitNormal = false;
00989   }
00990 
00991 #else
00992   if ( motherSafety<=ourStep )
00993   {
00994     if ( motherStep<=ourStep )
00995     {
00996       ourStep = motherStep;
00997       exiting = true;
00998       if ( validExitNormal )
00999       {
01000         const G4RotationMatrix* rot = motherPhysical->GetRotation();
01001         if ( rot )
01002         {
01003           exitNormal *= rot->inverse();
01004         }
01005       }
01006     }
01007     else
01008     {
01009       validExitNormal = false;
01010       // calculatedExitNormal= false;
01011     }
01012   }
01013 #endif
01014 
01015 
01016   G4bool daughterDeterminedStep=false;
01017   G4ThreeVector daughtNormRepCrd;
01018      // Exit normal of daughter transformed to
01019      // the coordinate system of Replica (i.e. last depth)
01020 
01021   //
01022   // Compute daughter safeties & intersections
01023   //
01024   localNoDaughters = repLogical->GetNoDaughters();
01025   for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
01026   {
01027     samplePhysical = repLogical->GetDaughter(sampleNo);
01028     if ( samplePhysical!=blockedExitedVol )
01029     {
01030       G4ThreeVector localExitNorm;
01031       G4ThreeVector normReplicaCoord;
01032 
01033       G4AffineTransform sampleTf(samplePhysical->GetRotation(),
01034                                  samplePhysical->GetTranslation());
01035       sampleTf.Invert();
01036       const G4ThreeVector samplePoint =
01037                         sampleTf.TransformPoint(localPoint);
01038       const G4VSolid* sampleSolid =
01039                         samplePhysical->GetLogicalVolume()->GetSolid();
01040       const G4double sampleSafetyDistance =
01041                         sampleSolid->DistanceToIn(samplePoint);
01042       if ( sampleSafetyDistance<ourSafety )
01043       {
01044         ourSafety = sampleSafetyDistance;
01045       }
01046       if ( sampleSafetyDistance<=ourStep )
01047       {
01048         sampleDirection = sampleTf.TransformAxis(localDirection);
01049         const G4double sampleStepDistance =
01050                         sampleSolid->DistanceToIn(samplePoint,sampleDirection);
01051         if ( sampleStepDistance<=ourStep )
01052         {
01053           daughterDeterminedStep= true;
01054 
01055           ourStep  = sampleStepDistance;
01056           entering = true;
01057           exiting  = false;
01058           *pBlockedPhysical = samplePhysical;
01059           blockedReplicaNo  = -1;
01060 
01061 #ifdef DAUGHTER_NORMAL_ALSO
01062           // This norm can be calculated later, if needed daughter is available
01063           localExitNorm = sampleSolid->SurfaceNormal(samplePoint);
01064           daughtNormRepCrd = sampleTf.Inverse().TransformAxis(localExitNorm);
01065 #endif
01066           
01067 #ifdef G4VERBOSE
01068           // Check to see that the resulting point is indeed in/on volume.
01069           // This check could eventually be made only for successful candidate.
01070 
01071           if ( ( fCheck ) && ( sampleStepDistance < kInfinity ) )
01072           {
01073             G4ThreeVector intersectionPoint;
01074             intersectionPoint= samplePoint
01075                              + sampleStepDistance * sampleDirection;
01076             EInside insideIntPt= sampleSolid->Inside(intersectionPoint); 
01077             if ( insideIntPt != kSurface )
01078             {
01079               G4int oldcoutPrec = G4cout.precision(16); 
01080               std::ostringstream message;
01081               message << "Navigator gets conflicting response from Solid."
01082                       << G4endl
01083                       << "          Inaccurate DistanceToIn for solid "
01084                       << sampleSolid->GetName() << G4endl
01085                       << "          Solid gave DistanceToIn = "
01086                       << sampleStepDistance << " yet returns " ;
01087               if ( insideIntPt == kInside )
01088                 message << "-kInside-"; 
01089               else if ( insideIntPt == kOutside )
01090                 message << "-kOutside-";
01091               else
01092                 message << "-kSurface-"; 
01093               message << " for this point !" << G4endl
01094                       << "          Point = " << intersectionPoint << G4endl;
01095               if ( insideIntPt != kInside )
01096                 message << "        DistanceToIn(p) = " 
01097                        << sampleSolid->DistanceToIn(intersectionPoint)
01098                        << G4endl;
01099               if ( insideIntPt != kOutside ) 
01100                 message << "        DistanceToOut(p) = " 
01101                        << sampleSolid->DistanceToOut(intersectionPoint);
01102               G4Exception("G4ReplicaNavigation::ComputeStep()", 
01103                           "GeomNav1002", JustWarning, message); 
01104               G4cout.precision(oldcoutPrec);
01105             }
01106           }
01107 #endif
01108         }
01109       }
01110     }
01111   }
01112 
01113   calculatedExitNormal &= (!daughterDeterminedStep);
01114 
01115 #ifdef DAUGHTER_NORMAL_ALSO
01116   if( daughterDeterminedStep )
01117   {
01118     // G4ThreeVector daughtNormGlobal =
01119     //   GlobalToLastDepth.Inverse().TransformAxis(daughtNormRepCrd);
01120     // ==> Can calculate it, but have no way to transmit it to caller (for now)
01121 
01122     exitNormalVector=globalToLocalTop.Inverse().TransformAxis(daughtNormGlobal);
01123     validExitNormal= false; // Entering daughter - never convex for parent
01124 
01125     calculatedExitNormal= true;
01126   }
01127   // calculatedExitNormal= true;  // Force it to true -- dubious
01128 #endif
01129 
01130   newSafety = ourSafety;
01131   return ourStep;
01132 }

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, and G4VPhysicalVolume::SetTranslation().

00698 {
00699   G4double val;
00700 
00701   // Replication data
00702   //
00703   EAxis axis;
00704   G4int nReplicas;
00705   G4double width, offset;
00706   G4bool consuming;
00707 
00708   pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
00709 
00710   switch (axis)
00711   {
00712     case kXAxis:
00713       val = -width*0.5*(nReplicas-1)+width*replicaNo;
00714       pVol->SetTranslation(G4ThreeVector(val,0,0));
00715       break;
00716     case kYAxis:
00717       val = -width*0.5*(nReplicas-1)+width*replicaNo;
00718       pVol->SetTranslation(G4ThreeVector(0,val,0));
00719       break;
00720     case kZAxis:
00721       val = -width*0.5*(nReplicas-1)+width*replicaNo;
00722       pVol->SetTranslation(G4ThreeVector(0,0,val));
00723       break;
00724     case kPhi:
00725       val = -(offset+width*(replicaNo+0.5));
00726       SetPhiTransformation(val,pVol);
00727       break;
00728     case kRho:
00729       // No setup required for radial case
00730     default:
00731       break;
00732   }
00733 }

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, and G4VPhysicalVolume::SetTranslation().

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

00643 {
00644   G4double val,cosv,sinv,tmpx,tmpy;
00645 
00646   // Replication data
00647   //
00648   EAxis axis;
00649   G4int nReplicas;
00650   G4double width,offset;
00651   G4bool consuming;
00652 
00653   pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
00654 
00655   switch (axis)
00656   {
00657     case kXAxis:
00658       val = -width*0.5*(nReplicas-1)+width*replicaNo;
00659       pVol->SetTranslation(G4ThreeVector(val,0,0));
00660       point.setX(point.x()-val);
00661       break;
00662     case kYAxis:
00663       val = -width*0.5*(nReplicas-1)+width*replicaNo;
00664       pVol->SetTranslation(G4ThreeVector(0,val,0));
00665       point.setY(point.y()-val);
00666       break;
00667     case kZAxis:
00668       val = -width*0.5*(nReplicas-1)+width*replicaNo;
00669       pVol->SetTranslation(G4ThreeVector(0,0,val));
00670       point.setZ(point.z()-val);
00671       break;
00672     case kPhi:
00673       val = -(offset+width*(replicaNo+0.5));
00674       SetPhiTransformation(val,pVol);
00675       cosv = std::cos(val);
00676       sinv = std::sin(val);
00677       tmpx = point.x()*cosv-point.y()*sinv;
00678       tmpy = point.x()*sinv+point.y()*cosv;
00679       point.setY(tmpy);
00680       point.setX(tmpx);
00681       break;
00682     case kRho:
00683       // No setup required for radial case
00684     default:
00685       break;
00686   }
00687 }

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(), G4VPhysicalVolume::GetReplicationData(), G4ExitNormal::kMX, G4ExitNormal::kMY, G4ExitNormal::kMZ, kPhi, G4ExitNormal::kPX, G4ExitNormal::kPY, G4ExitNormal::kPZ, kRho, kXAxis, kYAxis, kZAxis, and G4ExitNormal::validConvex.

00246 {
00247   // Replication data
00248   //
00249   EAxis axis;
00250   G4int nReplicas;
00251   G4double width, offset;
00252   G4bool consuming;
00253 
00254   G4double Dist=kInfinity;
00255   G4double coord, Comp, lindist;
00256   G4double signC = 0.0;
00257   G4ExitNormal candidateNormal; 
00258    
00259   static const G4ThreeVector VecCartAxes[3]=
00260    { G4ThreeVector(1.,0.,0.),G4ThreeVector(0.,1.,0.),G4ThreeVector(0.,0.,1.) };
00261   static G4ExitNormal::ESide SideCartAxesPlus [3]=
00262    { G4ExitNormal::kPX, G4ExitNormal::kPY, G4ExitNormal::kPZ };
00263   static G4ExitNormal::ESide SideCartAxesMinus[3]=
00264    { G4ExitNormal::kMX, G4ExitNormal::kMY, G4ExitNormal::kMZ };
00265 
00266   pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
00267   switch(axis)
00268   {
00269     case kXAxis:
00270     case kYAxis:
00271     case kZAxis:
00272       coord = localPoint(axis);
00273       Comp = localDirection(axis);
00274       if ( Comp>0 )
00275       {
00276         lindist = width*0.5-coord;
00277         Dist = (lindist>0) ? lindist/Comp : 0;
00278         signC= 1.0;
00279       }
00280       else if ( Comp<0 )
00281       {
00282         lindist = width*0.5+coord;
00283         Dist = (lindist>0) ? -lindist/Comp : 0;
00284         signC= -1.0;
00285       }
00286       else
00287       {
00288         Dist = kInfinity;
00289       }
00290       // signC = sign<G4double>(Comp)
00291       candidateNormal.exitNormal = ( signC * VecCartAxes[axis]);
00292       candidateNormal.calculated = true;
00293       candidateNormal.validConvex = true;
00294       candidateNormal.exitSide =
00295         (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis];
00296       break;
00297     case kPhi:
00298       Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal);
00299         // candidateNormal set in call
00300       break;
00301     case kRho:
00302       Dist = DistanceToOutRad(localPoint,localDirection,width,offset,
00303                               replicaNo,candidateNormal);
00304         // candidateNormal set in call
00305       break;
00306     default:
00307      G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
00308                  FatalException, "Unknown axis!");
00309      break;
00310   }
00311 
00312   arExitNormal= candidateNormal; // .exitNormal;
00313 
00314   return Dist;
00315 }

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, and kZAxis.

Referenced by ComputeSafety(), and ComputeStep().

00178 {
00179   // Replication data
00180   //
00181   EAxis axis;
00182   G4int nReplicas;
00183   G4double width,offset;
00184   G4bool consuming;
00185   
00186   G4double safety=0.;
00187   G4double safe1,safe2;
00188   G4double coord, rho, rmin, rmax;
00189 
00190   pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
00191   switch(axis)
00192   {
00193     case kXAxis:
00194     case kYAxis:
00195     case kZAxis:
00196        coord = localPoint(axis);
00197        safe1 = width*0.5-coord;
00198        safe2 = width*0.5+coord;
00199        safety = (safe1<=safe2) ? safe1 : safe2;
00200        break;
00201     case kPhi:
00202       if ( localPoint.y()<=0 )
00203       {
00204         safety = localPoint.x()*std::sin(width*0.5)
00205                + localPoint.y()*std::cos(width*0.5);
00206       }
00207       else
00208       {
00209         safety = localPoint.x()*std::sin(width*0.5)
00210                - localPoint.y()*std::cos(width*0.5);
00211       }
00212       break;
00213     case kRho:
00214       rho = localPoint.perp();
00215       rmax = width*(replicaNo+1)+offset;
00216       if ( replicaNo||offset )
00217       {
00218         rmin  = rmax-width;
00219         safe1 = rho-rmin;
00220         safe2 = rmax-rho;
00221         safety = (safe1<=safe2) ? safe1 : safe2;
00222       }
00223       else
00224       {
00225         safety = rmax-rho;
00226       }
00227       break;
00228     default:
00229      G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002",
00230                  FatalException, "Unknown axis!");
00231      break;
00232   }
00233   return (safety >= kCarTolerance) ? safety : 0;
00234 }

G4int G4ReplicaNavigation::GetVerboseLevel (  )  const [inline]

Definition at line 199 of file G4ReplicaNavigation.icc.

00200 {
00201   return fVerbose;
00202 }

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, and kZAxis.

Referenced by BackLocate().

00072 {
00073   EInside in = kOutside;
00074 
00075   // Replication data
00076   //
00077   EAxis axis;
00078   G4int nReplicas;
00079   G4double width, offset;
00080   G4bool consuming;
00081   
00082   G4double coord, rad2, rmin, tolRMax2, rmax, tolRMin2;
00083 
00084   pVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
00085 
00086   switch (axis)
00087   {
00088     case kXAxis:
00089     case kYAxis:
00090     case kZAxis:
00091       coord = std::fabs(localPoint(axis))-width*0.5;
00092       if ( coord<=-kCarTolerance*0.5 )
00093       {
00094         in = kInside;
00095       }
00096       else if ( coord<=kCarTolerance*0.5 )
00097       {
00098         in = kSurface;
00099       }
00100       break;
00101     case kPhi:
00102       if ( localPoint.y()||localPoint.x() )
00103       {
00104         coord = std::fabs(std::atan2(localPoint.y(),localPoint.x()))-width*0.5;
00105         if ( coord<=-kAngTolerance*0.5 )
00106         {
00107           in = kInside;
00108         }
00109         else if ( coord<=kAngTolerance*0.5 )
00110         {
00111           in = kSurface;
00112         }
00113       }
00114       else
00115       {
00116         in = kSurface;
00117       }
00118       break;
00119     case kRho:
00120       rad2 = localPoint.perp2();
00121       rmax = (replicaNo+1)*width+offset;
00122       tolRMax2  = rmax-kRadTolerance*0.5;
00123       tolRMax2 *= tolRMax2;
00124       if ( rad2>tolRMax2 )
00125       {
00126         tolRMax2 = rmax+kRadTolerance*0.5;
00127         tolRMax2 *= tolRMax2;
00128         if ( rad2<=tolRMax2 )
00129         {
00130           in = kSurface;
00131         }
00132       }
00133       else
00134       {
00135         // Known to be inside outer radius
00136         //
00137         if ( replicaNo||offset )
00138         {
00139           rmin = rmax-width;
00140           tolRMin2 = rmin-kRadTolerance*0.5;
00141           tolRMin2 *= tolRMin2;
00142           if ( rad2>tolRMin2 )
00143           {
00144             tolRMin2 = rmin+kRadTolerance*0.5;
00145             tolRMin2 *= tolRMin2;
00146             if ( rad2>=tolRMin2 )
00147             {
00148               in = kInside;
00149             }
00150             else
00151             {
00152               in = kSurface;
00153             }
00154           }
00155         }
00156         else
00157         {
00158           in = kInside;
00159         }
00160       }
00161       break;
00162     default:
00163       G4Exception("G4ReplicaNavigation::Inside()", "GeomNav0002",
00164                   FatalException, "Unknown axis!");
00165       break;
00166   }
00167   return in;
00168 }

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

Definition at line 145 of file G4ReplicaNavigation.icc.

References ComputeTransformation(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4NavigationHistory::GetTopVolume(), G4LogicalVolume::GetVoxelHeader(), kReplica, G4NavigationHistory::NewLevel(), and G4VPhysicalVolume::SetCopyNo().

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

00152 {
00153   G4VPhysicalVolume *motherPhysical, *pPhysical;
00154   G4LogicalVolume *motherLogical;
00155   G4SmartVoxelHeader *motherVoxelHeader;
00156   G4int nodeNo;
00157 
00158   motherPhysical = history.GetTopVolume();
00159   motherLogical = motherPhysical->GetLogicalVolume();
00160   motherVoxelHeader = motherLogical->GetVoxelHeader();
00161   pPhysical = motherLogical->GetDaughter(0);
00162 
00163   if ( blockedVol==pPhysical )
00164   {
00165     nodeNo = VoxelLocate(motherVoxelHeader, localPoint, blockedNum);
00166   }
00167   else
00168   {
00169     nodeNo = VoxelLocate(motherVoxelHeader, localPoint);
00170   }
00171 
00172   ComputeTransformation(nodeNo, pPhysical, localPoint);
00173   history.NewLevel(pPhysical, kReplica, nodeNo);
00174   pPhysical->SetCopyNo(nodeNo); 
00175 
00176   return true;
00177 }

void G4ReplicaNavigation::SetVerboseLevel ( G4int  level  )  [inline]

Definition at line 209 of file G4ReplicaNavigation.icc.

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

00210 {
00211   fVerbose = level;
00212 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:17 2013 for Geant4 by  doxygen 1.4.7