G4VoxelNavigation Class Reference

#include <G4VoxelNavigation.hh>

Inheritance diagram for G4VoxelNavigation:

G4ParameterisedNavigation

Public Member Functions

 G4VoxelNavigation ()
virtual ~G4VoxelNavigation ()
G4SmartVoxelNodeVoxelLocate (G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
virtual G4bool LevelLocate (G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
virtual G4double ComputeStep (const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
virtual G4double ComputeSafety (const G4ThreeVector &globalpoint, const G4NavigationHistory &history, const G4double pMaxLength=DBL_MAX)
G4int GetVerboseLevel () const
void SetVerboseLevel (G4int level)
void CheckMode (G4bool mode)
void EnableBestSafety (G4bool flag=false)

Protected Member Functions

G4double ComputeVoxelSafety (const G4ThreeVector &localPoint) const
G4bool LocateNextVoxel (const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentStep)
G4SmartVoxelNodeVoxelLocateLight (G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint) const

Protected Attributes

G4BlockingList fBList
G4int fVoxelDepth
std::vector< EAxisfVoxelAxisStack
std::vector< G4intfVoxelNoSlicesStack
std::vector< G4doublefVoxelSliceWidthStack
std::vector< G4intfVoxelNodeNoStack
std::vector< G4SmartVoxelHeader * > fVoxelHeaderStack
G4SmartVoxelNodefVoxelNode
G4VoxelSafetyfpVoxelSafety
G4bool fCheck
G4bool fBestSafety
G4NavigationLoggerfLogger

Detailed Description

Definition at line 67 of file G4VoxelNavigation.hh.


Constructor & Destructor Documentation

G4VoxelNavigation::G4VoxelNavigation (  ) 

Definition at line 44 of file G4VoxelNavigation.cc.

References fLogger, and fpVoxelSafety.

00045   : fBList(), fVoxelDepth(-1),
00046     fVoxelAxisStack(kNavigatorVoxelStackMax,kXAxis),
00047     fVoxelNoSlicesStack(kNavigatorVoxelStackMax,0),
00048     fVoxelSliceWidthStack(kNavigatorVoxelStackMax,0.),
00049     fVoxelNodeNoStack(kNavigatorVoxelStackMax,0),
00050     fVoxelHeaderStack(kNavigatorVoxelStackMax,(G4SmartVoxelHeader*)0),
00051     fVoxelNode(0), fpVoxelSafety(0), fCheck(false), fBestSafety(false)
00052 {
00053   fLogger = new G4NavigationLogger("G4VoxelNavigation");
00054   fpVoxelSafety = new G4VoxelSafety (); 
00055 }

G4VoxelNavigation::~G4VoxelNavigation (  )  [virtual]

Definition at line 61 of file G4VoxelNavigation.cc.

References fLogger, and fpVoxelSafety.

00062 {
00063   delete fpVoxelSafety;
00064   delete fLogger;
00065 }


Member Function Documentation

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

Definition at line 178 of file G4VoxelNavigation.icc.

References fCheck.

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

00179 {
00180   fCheck = mode;
00181 }

G4double G4VoxelNavigation::ComputeSafety ( const G4ThreeVector globalpoint,
const G4NavigationHistory history,
const G4double  pMaxLength = DBL_MAX 
) [virtual]

Reimplemented in G4ParameterisedNavigation.

Definition at line 547 of file G4VoxelNavigation.cc.

References G4VoxelSafety::ComputeSafety(), G4NavigationLogger::ComputeSafetyLog(), ComputeVoxelSafety(), G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), fBestSafety, fCheck, fLogger, fpVoxelSafety, fVoxelNode, G4endl, G4Exception(), G4VPhysicalVolume::GetCopyNo(), G4LogicalVolume::GetDaughter(), G4VSolid::GetEntityType(), G4VPhysicalVolume::GetLogicalVolume(), G4VSolid::GetName(), G4VPhysicalVolume::GetName(), G4SmartVoxelNode::GetNoContained(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopVolume(), G4VPhysicalVolume::GetTranslation(), G4SmartVoxelNode::GetVolume(), G4VSolid::Inside(), JustWarning, kInside, and kOutside.

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

00550 {
00551   G4VPhysicalVolume *motherPhysical, *samplePhysical;
00552   G4LogicalVolume *motherLogical;
00553   G4VSolid *motherSolid;
00554   G4double motherSafety, ourSafety;
00555   G4int sampleNo;
00556   G4SmartVoxelNode *curVoxelNode;
00557   G4int curNoVolumes, contentNo;
00558   G4double voxelSafety;
00559 
00560   motherPhysical = history.GetTopVolume();
00561   motherLogical = motherPhysical->GetLogicalVolume();
00562   motherSolid = motherLogical->GetSolid();
00563 
00564   if( fBestSafety )
00565   { 
00566     return fpVoxelSafety->ComputeSafety( localPoint,*motherPhysical,maxLength );
00567   }
00568 
00569   //
00570   // Compute mother safety
00571   //
00572 
00573   motherSafety = motherSolid->DistanceToOut(localPoint);
00574   ourSafety = motherSafety;                 // Working isotropic safety
00575 
00576   if( motherSafety == 0.0 )
00577   {
00578 #ifdef G4DEBUG_NAVIGATION
00579     // Check that point is inside mother volume
00580     EInside  insideMother= motherSolid->Inside(localPoint);
00581 
00582     if( insideMother == kOutside )
00583     {
00584       G4ExceptionDescription message;
00585       message << "Safety method called for location outside current Volume." << G4endl
00586          << "Location for safety is Outside this volume. " << G4endl
00587          << "The approximate distance to the solid "
00588          << "(safety from outside) is: "
00589          << motherSolid->DistanceToIn( localPoint ) << G4endl;
00590       message << "  Problem occurred with physical volume: "
00591          << " Name: " << motherPhysical->GetName()
00592          << " Copy No: " << motherPhysical->GetCopyNo() << G4endl
00593          << "    Local Point = " << localPoint << G4endl;
00594       message << "  Description of solid: " << G4endl
00595             << *motherSolid << G4endl;
00596       G4Exception("G4VoxelNavigation::ComputeSafety()", "GeomNav0003",
00597                   JustWarning,  // FatalException,
00598                   message);
00599     }
00600 
00601     // Following check is NOT for an issue - it is only for information
00602     //  It is allowed that a solid gives approximate safety - even zero.
00603     //
00604     if( insideMother == kInside ) // && fVerbose )
00605     {
00606       G4ExceptionDescription messageIn;
00607       
00608       messageIn << " Point is Inside, but safety is Zero ."  << G4endl;
00609       messageIn << " Inexact safety for volume " << motherPhysical->GetName() << G4endl
00610              << "  Solid: Name= " << motherSolid->GetName()
00611              << "   Type= " << motherSolid->GetEntityType() << G4endl;
00612       messageIn << "  Local point= " << localPoint << G4endl;
00613       messageIn << "  Solid parameters: " << G4endl << *motherSolid << G4endl;
00614       G4Exception("G4VoxelNavigation::ComputeSafety()", "GeomNav0003",
00615                   JustWarning, messageIn);
00616     }
00617 #endif
00618     // if( insideMother != kInside )
00619     return 0.0;
00620   }
00621    
00622 #ifdef G4VERBOSE
00623   if( fCheck )
00624   {
00625     fLogger->ComputeSafetyLog (motherSolid, localPoint, motherSafety, true);
00626   }
00627 #endif
00628   //
00629   // Compute daughter safeties
00630   //
00631   // Look only inside the current Voxel only (in the first version).
00632   //
00633   curVoxelNode = fVoxelNode;
00634   curNoVolumes = curVoxelNode->GetNoContained();
00635 
00636   for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
00637   {
00638     sampleNo = curVoxelNode->GetVolume(contentNo);
00639     samplePhysical = motherLogical->GetDaughter(sampleNo);
00640 
00641     G4AffineTransform sampleTf(samplePhysical->GetRotation(),
00642                                samplePhysical->GetTranslation());
00643     sampleTf.Invert();
00644     const G4ThreeVector samplePoint =
00645                           sampleTf.TransformPoint(localPoint);
00646     const G4VSolid *sampleSolid     =
00647                           samplePhysical->GetLogicalVolume()->GetSolid();
00648     G4double sampleSafety = sampleSolid->DistanceToIn(samplePoint);
00649     if ( sampleSafety<ourSafety )
00650     {
00651       ourSafety = sampleSafety;
00652     }
00653 #ifdef G4VERBOSE
00654     if( fCheck )
00655     {
00656       fLogger->ComputeSafetyLog (sampleSolid,samplePoint,sampleSafety,false);
00657     }
00658 #endif
00659   }
00660   voxelSafety = ComputeVoxelSafety(localPoint);
00661   if ( voxelSafety<ourSafety )
00662   {
00663     ourSafety = voxelSafety;
00664   }
00665   return ourSafety;
00666 }

G4double G4VoxelNavigation::ComputeStep ( const G4ThreeVector globalPoint,
const G4ThreeVector globalDirection,
const G4double  currentProposedStepLength,
G4double newSafety,
G4NavigationHistory history,
G4bool validExitNormal,
G4ThreeVector exitNormal,
G4bool exiting,
G4bool entering,
G4VPhysicalVolume **  pBlockedPhysical,
G4int blockedReplicaNo 
) [virtual]

Reimplemented in G4ParameterisedNavigation.

Definition at line 72 of file G4VoxelNavigation.cc.

References G4NavigationLogger::AlongComputeStepLog(), G4BlockingList::BlockVolume(), ComputeVoxelSafety(), G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4BlockingList::Enlarge(), fBList, fCheck, fLogger, fVoxelNode, G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4SmartVoxelNode::GetNoContained(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopVolume(), G4VPhysicalVolume::GetTranslation(), G4SmartVoxelNode::GetVolume(), G4BlockingList::IsBlocked(), LocateNextVoxel(), G4NavigationLogger::PostComputeStepLog(), G4NavigationLogger::PreComputeStepLog(), G4NavigationLogger::PrintDaughterLog(), and G4BlockingList::Reset().

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

00083 {
00084   G4VPhysicalVolume *motherPhysical, *samplePhysical, *blockedExitedVol=0;
00085   G4LogicalVolume *motherLogical;
00086   G4VSolid *motherSolid;
00087   G4ThreeVector sampleDirection;
00088   G4double ourStep=currentProposedStepLength, motherSafety, ourSafety;
00089   G4int localNoDaughters, sampleNo;
00090 
00091   G4bool initialNode, noStep;
00092   G4SmartVoxelNode *curVoxelNode;
00093   G4int curNoVolumes, contentNo;
00094   G4double voxelSafety;
00095 
00096   motherPhysical = history.GetTopVolume();
00097   motherLogical = motherPhysical->GetLogicalVolume();
00098   motherSolid = motherLogical->GetSolid();
00099 
00100   //
00101   // Compute mother safety
00102   //
00103 
00104   motherSafety = motherSolid->DistanceToOut(localPoint);
00105   ourSafety = motherSafety;                 // Working isotropic safety
00106   
00107 #ifdef G4VERBOSE
00108   if ( fCheck )
00109   {
00110     fLogger->PreComputeStepLog (motherPhysical, motherSafety, localPoint);
00111   }
00112 #endif
00113 
00114   //
00115   // Compute daughter safeties & intersections
00116   //
00117 
00118   // Exiting normal optimisation
00119   //
00120   if ( exiting && validExitNormal )
00121   {
00122     if ( localDirection.dot(exitNormal)>=kMinExitingNormalCosine )
00123     {
00124       // Block exited daughter volume
00125       //
00126       blockedExitedVol = *pBlockedPhysical;
00127       ourSafety = 0;
00128     }
00129   }
00130   exiting = false;
00131   entering = false;
00132 
00133   localNoDaughters = motherLogical->GetNoDaughters();
00134 
00135   fBList.Enlarge(localNoDaughters);
00136   fBList.Reset();
00137 
00138   initialNode = true;
00139   noStep = true;
00140 
00141   while (noStep)
00142   {
00143     curVoxelNode = fVoxelNode;
00144     curNoVolumes = curVoxelNode->GetNoContained();
00145     for (contentNo=curNoVolumes-1; contentNo>=0; contentNo--)
00146     {
00147       sampleNo = curVoxelNode->GetVolume(contentNo);
00148       if ( !fBList.IsBlocked(sampleNo) )
00149       {
00150         fBList.BlockVolume(sampleNo);
00151         samplePhysical = motherLogical->GetDaughter(sampleNo);
00152         if ( samplePhysical!=blockedExitedVol )
00153         {
00154           G4AffineTransform sampleTf(samplePhysical->GetRotation(),
00155                                      samplePhysical->GetTranslation());
00156           sampleTf.Invert();
00157           const G4ThreeVector samplePoint =
00158                      sampleTf.TransformPoint(localPoint);
00159           const G4VSolid *sampleSolid     =
00160                      samplePhysical->GetLogicalVolume()->GetSolid();
00161           const G4double sampleSafety     =
00162                      sampleSolid->DistanceToIn(samplePoint);
00163 #ifdef G4VERBOSE
00164           if( fCheck )
00165           {
00166             fLogger->PrintDaughterLog(sampleSolid,samplePoint,sampleSafety,0);
00167           }
00168 #endif
00169           if ( sampleSafety<ourSafety )
00170           {
00171             ourSafety = sampleSafety;
00172           }
00173           if ( sampleSafety<=ourStep )
00174           {
00175             sampleDirection = sampleTf.TransformAxis(localDirection);
00176             G4double sampleStep =
00177                      sampleSolid->DistanceToIn(samplePoint, sampleDirection);
00178 #ifdef G4VERBOSE
00179             if( fCheck )
00180             {
00181               fLogger->PrintDaughterLog(sampleSolid, samplePoint,
00182                                         sampleSafety, sampleStep);
00183             }
00184 #endif
00185             if ( sampleStep<=ourStep )
00186             {
00187               ourStep = sampleStep;
00188               entering = true;
00189               exiting = false;
00190               *pBlockedPhysical = samplePhysical;
00191               blockedReplicaNo = -1;
00192 #ifdef G4VERBOSE
00193               // Check to see that the resulting point is indeed in/on volume.
00194               // This check could eventually be made only for successful
00195               // candidate.
00196 
00197               if ( fCheck )
00198               {
00199                 fLogger->AlongComputeStepLog (sampleSolid, samplePoint,
00200                   sampleDirection, localDirection, sampleSafety, sampleStep);
00201               }
00202 #endif
00203             }
00204           }
00205         }
00206       }
00207     }
00208     if (initialNode)
00209     {
00210       initialNode = false;
00211       voxelSafety = ComputeVoxelSafety(localPoint);
00212       if ( voxelSafety<ourSafety )
00213       {
00214         ourSafety = voxelSafety;
00215       }
00216       if ( currentProposedStepLength<ourSafety )
00217       {
00218         // Guaranteed physics limited
00219         //      
00220         noStep = false;
00221         entering = false;
00222         exiting = false;
00223         *pBlockedPhysical = 0;
00224         ourStep = kInfinity;
00225       }
00226       else
00227       {
00228         //
00229         // Compute mother intersection if required
00230         //
00231         if ( motherSafety<=ourStep )
00232         {
00233           G4double motherStep =
00234               motherSolid->DistanceToOut(localPoint,
00235                                          localDirection,
00236                                          true, &validExitNormal, &exitNormal);
00237 #ifdef G4VERBOSE
00238           if ( fCheck )
00239           {
00240             fLogger->PostComputeStepLog(motherSolid, localPoint, localDirection,
00241                                         motherStep, motherSafety);
00242           }
00243 #endif
00244           if ( motherStep<=ourStep )
00245           {
00246             ourStep = motherStep;
00247             exiting = true;
00248             entering = false;
00249             if ( validExitNormal )
00250             {
00251               const G4RotationMatrix *rot = motherPhysical->GetRotation();
00252               if (rot)
00253               {
00254                 exitNormal *= rot->inverse();
00255               }
00256             }  
00257           }
00258           else
00259           {
00260             validExitNormal = false;
00261           }
00262         }
00263       }
00264       newSafety = ourSafety;
00265     }
00266     if (noStep)
00267     {
00268       noStep = LocateNextVoxel(localPoint, localDirection, ourStep);
00269     }
00270   }  // end -while (noStep)- loop
00271 
00272   return ourStep;
00273 }

G4double G4VoxelNavigation::ComputeVoxelSafety ( const G4ThreeVector localPoint  )  const [protected]

Definition at line 285 of file G4VoxelNavigation.cc.

References fVoxelAxisStack, fVoxelDepth, fVoxelHeaderStack, fVoxelNode, fVoxelNodeNoStack, fVoxelSliceWidthStack, G4SmartVoxelNode::GetMaxEquivalentSliceNo(), G4SmartVoxelNode::GetMinEquivalentSliceNo(), and G4SmartVoxelHeader::GetMinExtent().

Referenced by ComputeSafety(), and ComputeStep().

00286 {
00287   G4SmartVoxelHeader *curHeader;
00288   G4double voxelSafety, curNodeWidth;
00289   G4double curNodeOffset, minCurCommonDelta, maxCurCommonDelta;
00290   G4int minCurNodeNoDelta, maxCurNodeNoDelta;
00291   G4int localVoxelDepth, curNodeNo;
00292   EAxis curHeaderAxis;
00293 
00294   localVoxelDepth = fVoxelDepth;
00295 
00296   curHeader = fVoxelHeaderStack[localVoxelDepth];
00297   curHeaderAxis = fVoxelAxisStack[localVoxelDepth];
00298   curNodeNo = fVoxelNodeNoStack[localVoxelDepth];
00299   curNodeWidth = fVoxelSliceWidthStack[localVoxelDepth];
00300   
00301   // Compute linear intersection distance to boundaries of max/min
00302   // to collected nodes at current level
00303   //
00304   curNodeOffset = curNodeNo*curNodeWidth;
00305   maxCurNodeNoDelta = fVoxelNode->GetMaxEquivalentSliceNo()-curNodeNo;
00306   minCurNodeNoDelta = curNodeNo-fVoxelNode->GetMinEquivalentSliceNo();
00307   minCurCommonDelta = localPoint(curHeaderAxis)
00308                       - curHeader->GetMinExtent() - curNodeOffset;
00309   maxCurCommonDelta = curNodeWidth-minCurCommonDelta;
00310 
00311   if ( minCurNodeNoDelta<maxCurNodeNoDelta )
00312   {
00313     voxelSafety = minCurNodeNoDelta*curNodeWidth;
00314     voxelSafety += minCurCommonDelta;
00315   }
00316   else if (maxCurNodeNoDelta < minCurNodeNoDelta)
00317   {
00318     voxelSafety = maxCurNodeNoDelta*curNodeWidth;
00319     voxelSafety += maxCurCommonDelta;
00320   }
00321   else    // (maxCurNodeNoDelta == minCurNodeNoDelta)
00322   {
00323     voxelSafety = minCurNodeNoDelta*curNodeWidth;
00324     voxelSafety += std::min(minCurCommonDelta,maxCurCommonDelta);
00325   }
00326 
00327   // Compute isotropic safety to boundaries of previous levels
00328   // [NOT to collected boundaries]
00329   //
00330   while ( (localVoxelDepth>0) && (voxelSafety>0) )
00331   {
00332     localVoxelDepth--;
00333     curHeader = fVoxelHeaderStack[localVoxelDepth];
00334     curHeaderAxis = fVoxelAxisStack[localVoxelDepth];
00335     curNodeNo = fVoxelNodeNoStack[localVoxelDepth];
00336     curNodeWidth = fVoxelSliceWidthStack[localVoxelDepth];
00337     curNodeOffset = curNodeNo*curNodeWidth;
00338     minCurCommonDelta = localPoint(curHeaderAxis)
00339                         - curHeader->GetMinExtent() - curNodeOffset;
00340     maxCurCommonDelta = curNodeWidth-minCurCommonDelta;
00341     
00342     if ( minCurCommonDelta<voxelSafety )
00343     {
00344       voxelSafety = minCurCommonDelta;
00345     }
00346     if ( maxCurCommonDelta<voxelSafety )
00347     {
00348       voxelSafety = maxCurCommonDelta;
00349     }
00350   }
00351   if ( voxelSafety<0 )
00352   {
00353     voxelSafety = 0;
00354   }
00355 
00356   return voxelSafety;
00357 }

void G4VoxelNavigation::EnableBestSafety ( G4bool  flag = false  )  [inline]

Definition at line 188 of file G4VoxelNavigation.icc.

References fBestSafety.

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

00189 {
00190   fBestSafety = flag;
00191 }

G4int G4VoxelNavigation::GetVerboseLevel (  )  const [inline]

Definition at line 168 of file G4VoxelNavigation.icc.

References fLogger, and G4NavigationLogger::GetVerboseLevel().

00169 {
00170   return fLogger->GetVerboseLevel();
00171 }

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

Reimplemented in G4ParameterisedNavigation.

Definition at line 100 of file G4VoxelNavigation.icc.

References G4NavigationHistory::BackLevel(), G4AuxiliaryNavServices::CheckPointOnSurface(), G4VPhysicalVolume::GetLogicalVolume(), G4SmartVoxelNode::GetNoContained(), G4NavigationHistory::GetTopTransform(), G4NavigationHistory::GetTopVolume(), G4SmartVoxelNode::GetVolume(), G4LogicalVolume::GetVoxelHeader(), kNormal, G4NavigationHistory::NewLevel(), G4AffineTransform::TransformPoint(), and VoxelLocate().

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

00107 {
00108   G4SmartVoxelHeader *targetVoxelHeader;
00109   G4SmartVoxelNode *targetVoxelNode;
00110   G4VPhysicalVolume *targetPhysical, *samplePhysical;
00111   G4LogicalVolume *targetLogical;
00112   G4VSolid *sampleSolid;
00113   G4ThreeVector samplePoint;
00114   G4int targetNoDaughters;
00115   
00116   targetPhysical = history.GetTopVolume();
00117   targetLogical = targetPhysical->GetLogicalVolume();
00118   targetVoxelHeader = targetLogical->GetVoxelHeader();
00119 
00120   // Find the voxel containing the point
00121   //
00122   targetVoxelNode = VoxelLocate(targetVoxelHeader,localPoint);
00123 
00124   targetNoDaughters=targetVoxelNode->GetNoContained();
00125   if ( targetNoDaughters==0 ) return false;
00126 
00127   //
00128   // Search daughters in volume
00129   //
00130 
00131   for ( register int sampleNo=targetNoDaughters-1; sampleNo>=0; sampleNo-- )
00132   {
00133     samplePhysical = targetLogical->
00134                      GetDaughter(targetVoxelNode->GetVolume(sampleNo));
00135     if ( samplePhysical!=blockedVol )
00136     {
00137       // Setup history
00138       //
00139       history.NewLevel(samplePhysical, kNormal, samplePhysical->GetCopyNo());
00140       sampleSolid = samplePhysical->GetLogicalVolume()->GetSolid();
00141       samplePoint = history.GetTopTransform().TransformPoint(globalPoint);
00142 
00143       if( G4AuxiliaryNavServices::CheckPointOnSurface(sampleSolid,
00144                                                       samplePoint,
00145                                                       globalDirection, 
00146                                                       history.GetTopTransform(),
00147                                                       pLocatedOnEdge) )
00148       {
00149         // Enter this daughter
00150         //
00151         localPoint = samplePoint;
00152         return true;
00153       }
00154       else
00155       {
00156         history.BackLevel();
00157       }
00158     }
00159   }
00160   return false;
00161 }

G4bool G4VoxelNavigation::LocateNextVoxel ( const G4ThreeVector localPoint,
const G4ThreeVector localDirection,
const G4double  currentStep 
) [protected]

Definition at line 373 of file G4VoxelNavigation.cc.

References fVoxelAxisStack, fVoxelDepth, fVoxelHeaderStack, fVoxelNode, fVoxelNodeNoStack, fVoxelNoSlicesStack, fVoxelSliceWidthStack, G4SmartVoxelHeader::GetAxis(), G4SmartVoxelProxy::GetHeader(), G4GeometryTolerance::GetInstance(), G4SmartVoxelNode::GetMaxEquivalentSliceNo(), G4SmartVoxelNode::GetMinEquivalentSliceNo(), G4SmartVoxelHeader::GetMinExtent(), G4SmartVoxelProxy::GetNode(), G4GeometryTolerance::GetSurfaceTolerance(), and G4SmartVoxelProxy::IsNode().

Referenced by ComputeStep().

00376 {
00377   G4SmartVoxelHeader *workHeader=0, *newHeader=0;
00378   G4SmartVoxelProxy *newProxy=0;
00379   G4SmartVoxelNode *newVoxelNode=0;
00380   G4ThreeVector targetPoint, voxelPoint;
00381   G4double workNodeWidth, workMinExtent, workCoord;
00382   G4double minVal, maxVal, newDistance=0.;
00383   G4double newHeaderMin, newHeaderNodeWidth;
00384   G4int depth=0, newDepth=0, workNodeNo=0, newNodeNo=0, newHeaderNoSlices=0;
00385   EAxis workHeaderAxis, newHeaderAxis;
00386   G4bool isNewVoxel=false;
00387   
00388   G4double currentDistance = currentStep;
00389   static const G4double sigma = 0.5*G4GeometryTolerance::GetInstance()
00390                                     ->GetSurfaceTolerance();
00391 
00392   // Determine if end of Step within current voxel
00393   //
00394   for (depth=0; depth<fVoxelDepth; depth++)
00395   {
00396     targetPoint = localPoint+localDirection*currentDistance;
00397     newDistance = currentDistance;
00398     workHeader = fVoxelHeaderStack[depth];
00399     workHeaderAxis = fVoxelAxisStack[depth];
00400     workNodeNo = fVoxelNodeNoStack[depth];
00401     workNodeWidth = fVoxelSliceWidthStack[depth];
00402     workMinExtent = workHeader->GetMinExtent();
00403     workCoord = targetPoint(workHeaderAxis);
00404     minVal = workMinExtent+workNodeNo*workNodeWidth;
00405 
00406     if ( minVal<=workCoord+sigma )
00407     {
00408       maxVal = minVal+workNodeWidth;
00409       if ( maxVal<=workCoord-sigma )
00410       {
00411         // Must consider next voxel
00412         //
00413         newNodeNo = workNodeNo+1;
00414         newHeader = workHeader;
00415         newDistance = (maxVal-localPoint(workHeaderAxis))
00416                     / localDirection(workHeaderAxis);
00417         isNewVoxel = true;
00418         newDepth = depth;
00419       }
00420     }
00421     else
00422     {
00423       newNodeNo = workNodeNo-1;
00424       newHeader = workHeader;
00425       newDistance = (minVal-localPoint(workHeaderAxis))
00426                   / localDirection(workHeaderAxis);
00427       isNewVoxel = true;
00428       newDepth = depth;
00429     }
00430     currentDistance = newDistance;
00431   }
00432   targetPoint = localPoint+localDirection*currentDistance;
00433 
00434   // Check if end of Step within collected boundaries of current voxel
00435   //
00436   depth = fVoxelDepth;
00437   {
00438     workHeader = fVoxelHeaderStack[depth];
00439     workHeaderAxis = fVoxelAxisStack[depth];
00440     workNodeNo = fVoxelNodeNoStack[depth];
00441     workNodeWidth = fVoxelSliceWidthStack[depth];
00442     workMinExtent = workHeader->GetMinExtent();
00443     workCoord = targetPoint(workHeaderAxis);
00444     minVal = workMinExtent+fVoxelNode->GetMinEquivalentSliceNo()*workNodeWidth;
00445 
00446     if ( minVal<=workCoord+sigma )
00447     {
00448       maxVal = workMinExtent+(fVoxelNode->GetMaxEquivalentSliceNo()+1)
00449                             *workNodeWidth;
00450       if ( maxVal<=workCoord-sigma )
00451       {
00452         newNodeNo = fVoxelNode->GetMaxEquivalentSliceNo()+1;
00453         newHeader = workHeader;
00454         newDistance = (maxVal-localPoint(workHeaderAxis))
00455                     / localDirection(workHeaderAxis);
00456         isNewVoxel = true;
00457         newDepth = depth;
00458       }
00459     }
00460     else
00461     {
00462       newNodeNo = fVoxelNode->GetMinEquivalentSliceNo()-1;
00463       newHeader = workHeader;
00464       newDistance = (minVal-localPoint(workHeaderAxis))
00465                   / localDirection(workHeaderAxis);
00466       isNewVoxel = true;
00467       newDepth = depth;
00468     }
00469     currentDistance = newDistance;
00470   }
00471   if (isNewVoxel)
00472   {
00473     // Compute new voxel & adjust voxel stack
00474     //
00475     // newNodeNo=Candidate node no at 
00476     // newDepth =refinement depth of crossed voxel boundary
00477     // newHeader=Header for crossed voxel
00478     // newDistance=distance to crossed voxel boundary (along the track)
00479     //
00480     if ( (newNodeNo<0) || (newNodeNo>=newHeader->GetNoSlices()))
00481     {
00482       // Leaving mother volume
00483       //
00484       isNewVoxel = false;
00485     }
00486     else
00487     {
00488       // Compute intersection point on the least refined
00489       // voxel boundary that is hit
00490       //
00491       voxelPoint = localPoint+localDirection*newDistance;
00492       fVoxelNodeNoStack[newDepth] = newNodeNo;
00493       fVoxelDepth = newDepth;
00494       newVoxelNode = 0;
00495       while ( !newVoxelNode )
00496       {
00497         newProxy = newHeader->GetSlice(newNodeNo);
00498         if (newProxy->IsNode())
00499         {
00500           newVoxelNode = newProxy->GetNode();
00501         }
00502         else
00503         {
00504           fVoxelDepth++;
00505           newHeader = newProxy->GetHeader();
00506           newHeaderAxis = newHeader->GetAxis();
00507           newHeaderNoSlices = newHeader->GetNoSlices();
00508           newHeaderMin = newHeader->GetMinExtent();
00509           newHeaderNodeWidth = (newHeader->GetMaxExtent()-newHeaderMin)
00510                              / newHeaderNoSlices;
00511           newNodeNo = G4int( (voxelPoint(newHeaderAxis)-newHeaderMin)
00512                              / newHeaderNodeWidth );
00513           // Rounding protection
00514           //
00515           if ( newNodeNo<0 )
00516           {
00517             newNodeNo=0;
00518           }
00519           else if ( newNodeNo>=newHeaderNoSlices )
00520                {
00521                  newNodeNo = newHeaderNoSlices-1;
00522                }
00523           // Stack info for stepping
00524           //
00525           fVoxelAxisStack[fVoxelDepth] = newHeaderAxis;
00526           fVoxelNoSlicesStack[fVoxelDepth] = newHeaderNoSlices;
00527           fVoxelSliceWidthStack[fVoxelDepth] = newHeaderNodeWidth;
00528           fVoxelNodeNoStack[fVoxelDepth] = newNodeNo;
00529           fVoxelHeaderStack[fVoxelDepth] = newHeader;
00530         }
00531       }
00532       fVoxelNode = newVoxelNode;
00533     }
00534   }
00535   return isNewVoxel;        
00536 }

void G4VoxelNavigation::SetVerboseLevel ( G4int  level  ) 

Definition at line 672 of file G4VoxelNavigation.cc.

References fLogger, fpVoxelSafety, G4VoxelSafety::SetVerboseLevel(), and G4NavigationLogger::SetVerboseLevel().

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

00673 {
00674   if( fLogger )       fLogger->SetVerboseLevel(level);
00675   if( fpVoxelSafety)  fpVoxelSafety->SetVerboseLevel( level ); 
00676 }

G4SmartVoxelNode * G4VoxelNavigation::VoxelLocate ( G4SmartVoxelHeader pHead,
const G4ThreeVector localPoint 
) [inline]

Definition at line 40 of file G4VoxelNavigation.icc.

References fVoxelAxisStack, fVoxelDepth, fVoxelHeaderStack, fVoxelNode, fVoxelNodeNoStack, fVoxelNoSlicesStack, fVoxelSliceWidthStack, G4SmartVoxelHeader::GetAxis(), G4SmartVoxelProxy::GetHeader(), G4SmartVoxelHeader::GetMaxExtent(), G4SmartVoxelHeader::GetMinExtent(), G4SmartVoxelProxy::GetNode(), G4SmartVoxelHeader::GetNoSlices(), G4SmartVoxelHeader::GetSlice(), and G4SmartVoxelProxy::IsNode().

Referenced by LevelLocate(), G4Navigator::LocateGlobalPointWithinVolume(), G4ITNavigator::LocateGlobalPointWithinVolume(), and G4ParameterisedNavigation::ParamVoxelLocate().

00042 {
00043   G4SmartVoxelHeader *targetVoxelHeader=pHead;
00044   G4SmartVoxelNode *targetVoxelNode=0;
00045   G4SmartVoxelProxy *sampleProxy;
00046   EAxis targetHeaderAxis;
00047   G4double targetHeaderMin, targetHeaderNodeWidth;
00048   G4int targetHeaderNoSlices, targetNodeNo;
00049 
00050   fVoxelDepth = 0;
00051 
00052   while ( !targetVoxelNode )
00053   {
00054     targetHeaderAxis = targetVoxelHeader->GetAxis();
00055     targetHeaderNoSlices = targetVoxelHeader->GetNoSlices();
00056     targetHeaderMin = targetVoxelHeader->GetMinExtent();
00057     targetHeaderNodeWidth = (targetVoxelHeader->GetMaxExtent()-targetHeaderMin)
00058                           / targetHeaderNoSlices;
00059     targetNodeNo = G4int( (localPoint(targetHeaderAxis)-targetHeaderMin)
00060                           / targetHeaderNodeWidth);
00061     // Rounding protection
00062     //
00063     if ( targetNodeNo<0 )
00064     {
00065       targetNodeNo = 0;
00066     }
00067     else if ( targetNodeNo>=targetHeaderNoSlices )
00068     {
00069       targetNodeNo = targetHeaderNoSlices-1;
00070     }
00071     // Stack info for stepping
00072     //
00073     fVoxelAxisStack[fVoxelDepth] = targetHeaderAxis;
00074     fVoxelNoSlicesStack[fVoxelDepth] = targetHeaderNoSlices;
00075     fVoxelSliceWidthStack[fVoxelDepth] = targetHeaderNodeWidth;
00076     fVoxelNodeNoStack[fVoxelDepth] = targetNodeNo;
00077     fVoxelHeaderStack[fVoxelDepth] = targetVoxelHeader;
00078     sampleProxy = targetVoxelHeader->GetSlice(targetNodeNo);
00079 
00080     if ( sampleProxy->IsNode() )
00081     {
00082       targetVoxelNode = sampleProxy->GetNode();
00083     }
00084     else
00085     {
00086       targetVoxelHeader = sampleProxy->GetHeader();
00087       fVoxelDepth++;
00088     }
00089   }
00090   fVoxelNode = targetVoxelNode;
00091   return targetVoxelNode;
00092 }

G4SmartVoxelNode* G4VoxelNavigation::VoxelLocateLight ( G4SmartVoxelHeader pHead,
const G4ThreeVector localPoint 
) const [protected]


Field Documentation

G4bool G4VoxelNavigation::fBestSafety [protected]

Definition at line 187 of file G4VoxelNavigation.hh.

Referenced by ComputeSafety(), and EnableBestSafety().

G4BlockingList G4VoxelNavigation::fBList [protected]

Definition at line 150 of file G4VoxelNavigation.hh.

Referenced by ComputeStep(), and G4ParameterisedNavigation::ComputeStep().

G4bool G4VoxelNavigation::fCheck [protected]

Definition at line 186 of file G4VoxelNavigation.hh.

Referenced by CheckMode(), ComputeSafety(), ComputeStep(), and G4ParameterisedNavigation::ComputeStep().

G4NavigationLogger* G4VoxelNavigation::fLogger [protected]

Definition at line 189 of file G4VoxelNavigation.hh.

Referenced by ComputeSafety(), ComputeStep(), G4VoxelNavigation(), GetVerboseLevel(), SetVerboseLevel(), and ~G4VoxelNavigation().

G4VoxelSafety* G4VoxelNavigation::fpVoxelSafety [protected]

Definition at line 183 of file G4VoxelNavigation.hh.

Referenced by ComputeSafety(), G4VoxelNavigation(), SetVerboseLevel(), and ~G4VoxelNavigation().

std::vector<EAxis> G4VoxelNavigation::fVoxelAxisStack [protected]

Definition at line 161 of file G4VoxelNavigation.hh.

Referenced by ComputeVoxelSafety(), LocateNextVoxel(), and VoxelLocate().

G4int G4VoxelNavigation::fVoxelDepth [protected]

Definition at line 157 of file G4VoxelNavigation.hh.

Referenced by ComputeVoxelSafety(), LocateNextVoxel(), and VoxelLocate().

std::vector<G4SmartVoxelHeader*> G4VoxelNavigation::fVoxelHeaderStack [protected]

Definition at line 173 of file G4VoxelNavigation.hh.

Referenced by ComputeVoxelSafety(), LocateNextVoxel(), and VoxelLocate().

G4SmartVoxelNode* G4VoxelNavigation::fVoxelNode [protected]

Definition at line 176 of file G4VoxelNavigation.hh.

Referenced by ComputeSafety(), G4ParameterisedNavigation::ComputeSafety(), ComputeStep(), G4ParameterisedNavigation::ComputeStep(), ComputeVoxelSafety(), LocateNextVoxel(), G4ParameterisedNavigation::ParamVoxelLocate(), and VoxelLocate().

std::vector<G4int> G4VoxelNavigation::fVoxelNodeNoStack [protected]

Definition at line 170 of file G4VoxelNavigation.hh.

Referenced by ComputeVoxelSafety(), LocateNextVoxel(), and VoxelLocate().

std::vector<G4int> G4VoxelNavigation::fVoxelNoSlicesStack [protected]

Definition at line 164 of file G4VoxelNavigation.hh.

Referenced by LocateNextVoxel(), and VoxelLocate().

std::vector<G4double> G4VoxelNavigation::fVoxelSliceWidthStack [protected]

Definition at line 167 of file G4VoxelNavigation.hh.

Referenced by ComputeVoxelSafety(), LocateNextVoxel(), and VoxelLocate().


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