Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/navigation/src/G4Navigator.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/navigation/src/G4Navigator.cc (Version 11.3.0) and /geometry/navigation/src/G4Navigator.cc (Version 9.6)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
                                                   >>  25 //
                                                   >>  26 //
                                                   >>  27 // $Id: G4Navigator.cc 2012-11-01 japost Exp $
                                                   >>  28 // GEANT4 tag $ Name:  $
 25 //                                                 29 // 
 26 // G4Navigator class Implementation            <<  30 // class G4Navigator Implementation
 27 //                                                 31 //
 28 // Original author: Paul Kent, July 95/96          32 // Original author: Paul Kent, July 95/96
 29 // Responsible 1996-present: John Apostolakis, <<  33 // Responsible 1996-present: John Apostolakis
                                                   >>  34 // Co-maintainer:            Gabriele Cosmo
 30 // Additional revisions by: Pedro Arce, Vladim     35 // Additional revisions by: Pedro Arce, Vladimir Grichine
 31 // -------------------------------------------     36 // --------------------------------------------------------------------
 32                                                    37 
 33 #include <iomanip>                                 38 #include <iomanip>
 34                                                    39 
 35 #include "G4Navigator.hh"                          40 #include "G4Navigator.hh"
 36 #include "G4ios.hh"                                41 #include "G4ios.hh"
 37 #include "G4SystemOfUnits.hh"                      42 #include "G4SystemOfUnits.hh"
 38 #include "G4GeometryTolerance.hh"                  43 #include "G4GeometryTolerance.hh"
 39 #include "G4VPhysicalVolume.hh"                    44 #include "G4VPhysicalVolume.hh"
 40                                                    45 
 41 #include "G4VoxelSafety.hh"                        46 #include "G4VoxelSafety.hh"
 42 #include "G4SafetyCalculator.hh"               << 
 43                                                << 
 44 // Constant determining how precise normals sh << 
 45 // vectors). If exceeded, warnings will be iss << 
 46 // Can be CLHEP::perMillion (its old default)  << 
 47 //                                             << 
 48 static const G4double kToleranceNormalCheck =  << 
 49                                                    47 
 50 // *******************************************     48 // ********************************************************************
 51 // Constructor                                     49 // Constructor
 52 // *******************************************     50 // ********************************************************************
 53 //                                                 51 //
 54 G4Navigator::G4Navigator()                         52 G4Navigator::G4Navigator()
                                                   >>  53   : fWasLimitedByGeometry(false), fVerbose(0),
                                                   >>  54     fTopPhysical(0), fCheck(false), fPushed(false), fWarnPush(true)
 55 {                                                  55 {
                                                   >>  56   fActive= false; 
                                                   >>  57   fLastTriedStepComputation= false;
                                                   >>  58 
 56   ResetStackAndState();                            59   ResetStackAndState();
 57     // Initialises also all                        60     // Initialises also all 
 58     // - exit / entry flags                        61     // - exit / entry flags
 59     // - flags & variables for exit normals        62     // - flags & variables for exit normals
 60     // - zero step counters                        63     // - zero step counters
 61     // - blocked volume                            64     // - blocked volume 
 62                                                    65 
 63   if( fVerbose > 2 )                           <<  66   fActionThreshold_NoZeroSteps  = 10; 
 64   {                                            <<  67   fAbandonThreshold_NoZeroSteps = 25; 
 65     G4cout << " G4Navigator parameters: Action << 
 66            << fActionThreshold_NoZeroSteps     << 
 67            << "  Abandon Threshold (No Zero St << 
 68            << fAbandonThreshold_NoZeroSteps << << 
 69   }                                            << 
 70   kCarTolerance = G4GeometryTolerance::GetInst << 
 71   fMinStep = 0.05*kCarTolerance;               << 
 72   fSqTol = sqr(kCarTolerance);                 << 
 73                                                    68 
                                                   >>  69   kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
 74   fregularNav.SetNormalNavigation( &fnormalNav     70   fregularNav.SetNormalNavigation( &fnormalNav );
 75                                                    71 
 76   fStepEndPoint = G4ThreeVector( kInfinity, kI     72   fStepEndPoint = G4ThreeVector( kInfinity, kInfinity, kInfinity ); 
 77   fLastStepEndPointLocal = G4ThreeVector( kInf     73   fLastStepEndPointLocal = G4ThreeVector( kInfinity, kInfinity, kInfinity ); 
 78                                                << 
 79   fpVoxelSafety = new G4VoxelSafety();         << 
 80   fpvoxelNav    = new G4VoxelNavigation();     << 
 81   fpSafetyCalculator = new G4SafetyCalculator( << 
 82   fpSafetyCalculator->SetExternalNavigation(fp << 
 83 }                                                  74 }
 84                                                    75 
 85 // *******************************************     76 // ********************************************************************
 86 // Destructor                                      77 // Destructor
 87 // *******************************************     78 // ********************************************************************
 88 //                                                 79 //
 89 G4Navigator::~G4Navigator()                        80 G4Navigator::~G4Navigator()
 90 {                                              <<  81 {;}
 91   delete fpVoxelSafety;                        << 
 92   delete fpExternalNav;                        << 
 93   delete fpvoxelNav;                           << 
 94   delete fpSafetyCalculator;                   << 
 95 }                                              << 
 96                                                    82 
 97 // *******************************************     83 // ********************************************************************
 98 // ResetHierarchyAndLocate                         84 // ResetHierarchyAndLocate
 99 // *******************************************     85 // ********************************************************************
100 //                                                 86 //
101 G4VPhysicalVolume*                                 87 G4VPhysicalVolume*
102 G4Navigator::ResetHierarchyAndLocate(const G4T <<  88 G4Navigator::ResetHierarchyAndLocate(const G4ThreeVector &p,
103                                      const G4T <<  89                                      const G4ThreeVector &direction,
104                                      const G4T <<  90                                      const G4TouchableHistory &h)
105 {                                                  91 {
106   ResetState();                                    92   ResetState();
107   fHistory = *h.GetHistory();                      93   fHistory = *h.GetHistory();
108   SetupHierarchy();                                94   SetupHierarchy();
109   fLastTriedStepComputation = false;  // Redun <<  95   fLastTriedStepComputation= false;  // Redundant, but best
110   return LocateGlobalPointAndSetup(p, &directi     96   return LocateGlobalPointAndSetup(p, &direction, true, false);
111 }                                                  97 }
112                                                    98 
113 // *******************************************     99 // ********************************************************************
114 // LocateGlobalPointAndSetup                      100 // LocateGlobalPointAndSetup
115 //                                                101 //
116 // Locate the point in the hierarchy return 0     102 // Locate the point in the hierarchy return 0 if outside
117 // The direction is required                      103 // The direction is required 
118 //    - if on an edge shared by more than two     104 //    - if on an edge shared by more than two surfaces 
119 //      (to resolve likely looping in tracking    105 //      (to resolve likely looping in tracking)
120 //    - at initial location of a particle         106 //    - at initial location of a particle
121 //      (to resolve potential ambiguity at bou    107 //      (to resolve potential ambiguity at boundary)
122 //                                                108 // 
123 // Flags on exit: (comments to be completed)      109 // Flags on exit: (comments to be completed)
124 // fEntering         - True if entering `daugh    110 // fEntering         - True if entering `daughter' volume (or replica)
125 //                     whether daughter of las    111 //                     whether daughter of last mother directly 
126 //                     or daughter of that vol    112 //                     or daughter of that volume's ancestor.
127 // fExiting          - True if exited 'mother' << 
128 //                     (always ? - how about i << 
129 // *******************************************    113 // ********************************************************************
130 //                                                114 //
131 G4VPhysicalVolume*                                115 G4VPhysicalVolume* 
132 G4Navigator::LocateGlobalPointAndSetup( const     116 G4Navigator::LocateGlobalPointAndSetup( const G4ThreeVector& globalPoint,
133                                         const     117                                         const G4ThreeVector* pGlobalDirection,
134                                         const     118                                         const G4bool relativeSearch,
135                                         const     119                                         const G4bool ignoreDirection )
136 {                                                 120 {
137   G4bool notKnownContained = true, noResult;   << 121   G4bool notKnownContained=true, noResult;
138   G4VPhysicalVolume *targetPhysical;              122   G4VPhysicalVolume *targetPhysical;
139   G4LogicalVolume *targetLogical;                 123   G4LogicalVolume *targetLogical;
140   G4VSolid *targetSolid = nullptr;             << 124   G4VSolid *targetSolid=0;
141   G4ThreeVector localPoint, globalDirection;      125   G4ThreeVector localPoint, globalDirection;
142   EInside insideCode;                             126   EInside insideCode;
                                                   >> 127   
                                                   >> 128   G4bool considerDirection = (!ignoreDirection) || fLocatedOnEdge;
143                                                   129 
144   G4bool considerDirection = (pGlobalDirection << 130   fLastTriedStepComputation=   false;   
145                                                << 131   fChangedGrandMotherRefFrame= false;  // For local exit normal
146   fLastTriedStepComputation = false;           << 
147   fChangedGrandMotherRefFrame = false;  // For << 
148                                                   132    
149   if( considerDirection )                      << 133   if( considerDirection && pGlobalDirection != 0 )
150   {                                               134   {
151     globalDirection=*pGlobalDirection;            135     globalDirection=*pGlobalDirection;
152   }                                               136   }
153                                                   137 
                                                   >> 138 
154 #ifdef G4VERBOSE                                  139 #ifdef G4VERBOSE
155   if( fVerbose > 2 )                              140   if( fVerbose > 2 )
156   {                                               141   {
157     G4long oldcoutPrec = G4cout.precision(8);  << 142     G4int oldcoutPrec = G4cout.precision(8);
158     G4cout << "*** G4Navigator::LocateGlobalPo    143     G4cout << "*** G4Navigator::LocateGlobalPointAndSetup: ***" << G4endl; 
159     G4cout << "    Called with arguments: " <<    144     G4cout << "    Called with arguments: " << G4endl
160            << "        Globalpoint = " << glob << 145            << "    Globalpoint = " << globalPoint << G4endl
161            << "        RelativeSearch = " << r << 146            << "    RelativeSearch = " << relativeSearch  << G4endl;
162     if( fVerbose >= 4 )                        << 147     if( fVerbose == 4 )
163     {                                             148     {
164       G4cout << "    ----- Upon entering:" <<     149       G4cout << "    ----- Upon entering:" << G4endl;
165       PrintState();                               150       PrintState();
166     }                                             151     }
167     G4cout.precision(oldcoutPrec);                152     G4cout.precision(oldcoutPrec);
168   }                                               153   }
169 #endif                                            154 #endif
170                                                   155 
171   G4int noLevelsExited = 0;                    << 
172                                                << 
173   if ( !relativeSearch )                          156   if ( !relativeSearch )
174   {                                               157   {
175     ResetStackAndState();                         158     ResetStackAndState();
176   }                                               159   }
177   else                                            160   else
178   {                                               161   {
179     if ( fWasLimitedByGeometry )                  162     if ( fWasLimitedByGeometry )
180     {                                             163     {
181       fWasLimitedByGeometry = false;              164       fWasLimitedByGeometry = false;
182       fEnteredDaughter = fEntering;   // Remem    165       fEnteredDaughter = fEntering;   // Remember
183       fExitedMother = fExiting;       // Remem    166       fExitedMother = fExiting;       // Remember
184       if ( fExiting )                             167       if ( fExiting )
185       {                                           168       {
186         ++noLevelsExited;  // count this first << 169         if ( fHistory.GetDepth() )
187                                                << 
188         if ( fHistory.GetDepth() != 0 )        << 
189         {                                         170         {
190           fBlockedPhysicalVolume = fHistory.Ge    171           fBlockedPhysicalVolume = fHistory.GetTopVolume();
191           fBlockedReplicaNo = fHistory.GetTopR    172           fBlockedReplicaNo = fHistory.GetTopReplicaNo();
192           fHistory.BackLevel();                   173           fHistory.BackLevel();
193         }                                         174         }
194         else                                      175         else
195         {                                         176         {
196           fLastLocatedPointLocal = localPoint;    177           fLastLocatedPointLocal = localPoint;
197           fLocatedOutsideWorld = true;            178           fLocatedOutsideWorld = true;
198           fBlockedPhysicalVolume = nullptr;    << 179           return 0;           // Have exited world volume
199           fBlockedReplicaNo = -1;              << 
200           fEntering = false;            // No  << 
201           fEnteredDaughter = false;            << 
202           fExitedMother = true;      // ??     << 
203                                                << 
204           return nullptr;           // Have ex << 
205         }                                         180         }
206         // A fix for the case where a volume i    181         // A fix for the case where a volume is "entered" at an edge
207         // and a coincident surface exists out    182         // and a coincident surface exists outside it.
208         //  - This stops it from exiting furth    183         //  - This stops it from exiting further volumes and cycling
209         //  - However ReplicaNavigator treats     184         //  - However ReplicaNavigator treats this case itself
210         //                                        185         //
211         // assert( fBlockedPhysicalVolume!=0 ) << 
212                                                << 
213         // Expect to be on edge => on surface  << 
214         //                                     << 
215         if ( fLocatedOnEdge && (VolumeType(fBl    186         if ( fLocatedOnEdge && (VolumeType(fBlockedPhysicalVolume)!=kReplica ))
216         {                                         187         { 
217           fExiting = false;                    << 188           fExiting= false;
218           // Consider effect on Exit Normal !? << 
219         }                                         189         }
220       }                                           190       }
221       else                                        191       else
222         if ( fEntering )                          192         if ( fEntering )
223         {                                         193         {
224           switch (VolumeType(fBlockedPhysicalV    194           switch (VolumeType(fBlockedPhysicalVolume))
225           {                                       195           {
226             case kNormal:                         196             case kNormal:
227               fHistory.NewLevel(fBlockedPhysic    197               fHistory.NewLevel(fBlockedPhysicalVolume, kNormal,
228                                 fBlockedPhysic    198                                 fBlockedPhysicalVolume->GetCopyNo());
229               break;                              199               break;
230             case kReplica:                        200             case kReplica:
231               freplicaNav.ComputeTransformatio    201               freplicaNav.ComputeTransformation(fBlockedReplicaNo,
232                                                   202                                                 fBlockedPhysicalVolume);
233               fHistory.NewLevel(fBlockedPhysic    203               fHistory.NewLevel(fBlockedPhysicalVolume, kReplica,
234                                 fBlockedReplic    204                                 fBlockedReplicaNo);
235               fBlockedPhysicalVolume->SetCopyN    205               fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
236               break;                              206               break;
237             case kParameterised:                  207             case kParameterised:
238               if( fBlockedPhysicalVolume->GetR    208               if( fBlockedPhysicalVolume->GetRegularStructureId() == 0 )
239               {                                   209               {
240                 G4VSolid *pSolid;                 210                 G4VSolid *pSolid;
241                 G4VPVParameterisation *pParam;    211                 G4VPVParameterisation *pParam;
242                 G4TouchableHistory parentTouch    212                 G4TouchableHistory parentTouchable( fHistory );
243                 pParam = fBlockedPhysicalVolum    213                 pParam = fBlockedPhysicalVolume->GetParameterisation();
244                 pSolid = pParam->ComputeSolid(    214                 pSolid = pParam->ComputeSolid(fBlockedReplicaNo,
245                                                   215                                               fBlockedPhysicalVolume);
246                 pSolid->ComputeDimensions(pPar    216                 pSolid->ComputeDimensions(pParam, fBlockedReplicaNo,
247                                           fBlo    217                                           fBlockedPhysicalVolume);
248                 pParam->ComputeTransformation(    218                 pParam->ComputeTransformation(fBlockedReplicaNo,
249                                                   219                                               fBlockedPhysicalVolume);
250                 fHistory.NewLevel(fBlockedPhys    220                 fHistory.NewLevel(fBlockedPhysicalVolume, kParameterised,
251                                   fBlockedRepl    221                                   fBlockedReplicaNo);
252                 fBlockedPhysicalVolume->SetCop    222                 fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
253                 //                                223                 //
254                 // Set the correct solid and m    224                 // Set the correct solid and material in Logical Volume
255                 //                                225                 //
256                 G4LogicalVolume *pLogical;        226                 G4LogicalVolume *pLogical;
257                 pLogical = fBlockedPhysicalVol    227                 pLogical = fBlockedPhysicalVolume->GetLogicalVolume();
258                 pLogical->SetSolid( pSolid );     228                 pLogical->SetSolid( pSolid );
259                 pLogical->UpdateMaterial(pPara    229                 pLogical->UpdateMaterial(pParam ->
260                   ComputeMaterial(fBlockedRepl    230                   ComputeMaterial(fBlockedReplicaNo,
261                                   fBlockedPhys    231                                   fBlockedPhysicalVolume, 
262                                   &parentTouch    232                                   &parentTouchable));
263               }                                   233               }
264               break;                              234               break;
265             case kExternal:                    << 
266               G4Exception("G4Navigator::Locate << 
267                           "GeomNav0001", Fatal << 
268                           "Extra levels not ap << 
269               break;                           << 
270           }                                       235           }
271           fEntering = false;                      236           fEntering = false;
272           fBlockedPhysicalVolume = nullptr;    << 237           fBlockedPhysicalVolume = 0;
273           localPoint = fHistory.GetTopTransfor    238           localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
274           notKnownContained = false;              239           notKnownContained = false;
275         }                                         240         }
276     }                                             241     }
277     else                                          242     else
278     {                                             243     {
279       fBlockedPhysicalVolume = nullptr;        << 244       fBlockedPhysicalVolume = 0;
280       fEntering = false;                          245       fEntering = false;
281       fEnteredDaughter = false;  // Full Step     246       fEnteredDaughter = false;  // Full Step was not taken, did not enter
282       fExiting = false;                           247       fExiting = false;
283       fExitedMother = false;     // Full Step     248       fExitedMother = false;     // Full Step was not taken, did not exit
284     }                                             249     }
285   }                                               250   }
286   //                                              251   //
287   // Search from top of history up through geo    252   // Search from top of history up through geometry until
288   // containing volume found:                     253   // containing volume found:
289   // If on                                        254   // If on 
290   // o OUTSIDE - Back up level, not/no longer     255   // o OUTSIDE - Back up level, not/no longer exiting volumes
291   // o SURFACE and EXITING - Back up level, se    256   // o SURFACE and EXITING - Back up level, setting new blocking no.s
292   // else                                         257   // else
293   // o containing volume found                    258   // o containing volume found
294   //                                              259   //
                                                   >> 260   G4int noLevelsExited=0 ;
295                                                   261 
296   while (notKnownContained)  // Loop checking, << 262   while (notKnownContained)
297   {                                               263   {
298     EVolume topVolumeType = fHistory.GetTopVol << 264     if ( fHistory.GetTopVolumeType()!=kReplica )
299     if (topVolumeType!=kReplica && topVolumeTy << 
300     {                                             265     {
301       targetSolid = fHistory.GetTopVolume()->G    266       targetSolid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
302       localPoint = fHistory.GetTopTransform().    267       localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
303       insideCode = targetSolid->Inside(localPo    268       insideCode = targetSolid->Inside(localPoint);
304 #ifdef G4VERBOSE                                  269 #ifdef G4VERBOSE
305       if(( fVerbose == 1 ) && ( fCheck ))         270       if(( fVerbose == 1 ) && ( fCheck ))
306       {                                           271       {
307         G4String solidResponse = "-kInside-";  << 272          G4String solidResponse = "-kInside-";
308         if (insideCode == kOutside)            << 273          if (insideCode == kOutside)
309         {                                      << 274            solidResponse = "-kOutside-";
310           solidResponse = "-kOutside-";        << 275          else if (insideCode == kSurface)
311         }                                      << 276            solidResponse = "-kSurface-";
312         else if (insideCode == kSurface)       << 277          G4cout << "*** G4Navigator::LocateGlobalPointAndSetup(): ***" << G4endl
313         {                                      << 278                 << "    Invoked Inside() for solid: " << targetSolid->GetName()
314           solidResponse = "-kSurface-";        << 279                 << ". Solid replied: " << solidResponse << G4endl
315         }                                      << 280                 << "    For local point p: " << localPoint << G4endl;
316         G4cout << "*** G4Navigator::LocateGlob << 
317                << "    Invoked Inside() for so << 
318                << ". Solid replied: " << solid << 
319                << "    For local point p: " << << 
320       }                                           281       }
321 #endif                                            282 #endif
322     }                                             283     }
323     else                                          284     else
324     {                                             285     {
325        if( topVolumeType == kReplica )         << 286       insideCode = freplicaNav.BackLocate(fHistory, globalPoint, localPoint,
326        {                                       << 287                                           fExiting, notKnownContained);
327           insideCode = freplicaNav.BackLocate( << 288       // !CARE! if notKnownContained returns false then the point is within
328                                                << 289       // the containing placement volume of the replica(s). If insidecode
329           // !CARE! if notKnownContained retur << 290       // will result in the history being backed up one level, then the
330           // the containing placement volume o << 291       // local point returned is the point in the system of this new level
331           // will result in the history being  << 
332           // local point returned is the point << 
333        }                                       << 
334        else                                    << 
335        {                                       << 
336           targetSolid = fHistory.GetTopVolume( << 
337           localPoint = fHistory.GetTopTransfor << 
338           G4ThreeVector localDirection =       << 
339              fHistory.GetTopTransform().Transf << 
340           insideCode = fpExternalNav->Inside(t << 
341        }                                       << 
342     }                                             292     }
343                                                   293 
344     // Point is inside current volume, break o << 
345     if ( insideCode == kInside ) { break; }    << 
346                                                   294 
347     // Point is outside current volume, move u << 295     if ( insideCode==kOutside )
348     if ( insideCode == kOutside )              << 
349     {                                             296     {
350       ++noLevelsExited;                        << 297       noLevelsExited++; 
351                                                << 298       if ( fHistory.GetDepth() )
352       // Exiting world volume                  << 
353       if ( fHistory.GetDepth() == 0 )          << 
354       {                                           299       {
355         fLocatedOutsideWorld = true;           << 300         fBlockedPhysicalVolume = fHistory.GetTopVolume();
356         fLastLocatedPointLocal = localPoint;   << 301         fBlockedReplicaNo = fHistory.GetTopReplicaNo();
357         return nullptr;                        << 302         fHistory.BackLevel();
358       }                                        << 303         fExiting = false;
359                                                << 
360       fBlockedPhysicalVolume = fHistory.GetTop << 
361       fBlockedReplicaNo = fHistory.GetTopRepli << 
362       fHistory.BackLevel();                    << 
363       fExiting = false;                        << 
364                                                   304 
365       if( noLevelsExited > 1 )                 << 305         if( noLevelsExited > 1 )
366       {                                        << 
367         // The first transformation was done b << 
368         //                                     << 
369         if(const auto *mRot = fBlockedPhysical << 
370         {                                         306         {
371           fGrandMotherExitNormal *= (*mRot).in << 307           // The first transformation was done by the sub-navigator
372           fChangedGrandMotherRefFrame = true;  << 308           //
                                                   >> 309           const G4RotationMatrix* mRot = fBlockedPhysicalVolume->GetRotation();
                                                   >> 310           if( mRot )
                                                   >> 311           { 
                                                   >> 312             fGrandMotherExitNormal *= (*mRot).inverse();
                                                   >> 313             fChangedGrandMotherRefFrame= true;
                                                   >> 314           }
373         }                                         315         }
374       }                                           316       }
375       continue;                                << 317       else
376     }                                          << 
377                                                << 
378     // Point is on the surface of a volume     << 
379     G4bool isExiting = fExiting;               << 
380     if( (!fExiting) && considerDirection )     << 
381     {                                          << 
382       // Figure out whether we are exiting thi << 
383       // by using the direction                << 
384       //                                       << 
385       G4bool directionExiting = false;         << 
386       G4ThreeVector localDirection =           << 
387         fHistory.GetTopTransform().TransformAx << 
388                                                << 
389       // Make sure localPoint in correct refer << 
390       //     ( Was it already correct ? How ?  << 
391       //                                       << 
392       localPoint= fHistory.GetTopTransform().T << 
393       if ( fHistory.GetTopVolumeType() != kRep << 
394       {                                           318       {
395         G4ThreeVector normal = targetSolid->Su << 319         fLastLocatedPointLocal = localPoint;
396         directionExiting = normal.dot(localDir << 320         fLocatedOutsideWorld = true;
397         isExiting = isExiting || directionExit << 321           // No extra transformation for ExitNormal - is in frame of Top Volume
                                                   >> 322         return 0;         // Have exited world volume
398       }                                           323       }
399     }                                             324     }
                                                   >> 325     else
                                                   >> 326       if ( insideCode==kSurface )
                                                   >> 327       {
                                                   >> 328         G4bool isExiting = fExiting;
                                                   >> 329         if( (!fExiting)&&considerDirection )
                                                   >> 330         {
                                                   >> 331           // Figure out whether we are exiting this level's volume
                                                   >> 332           // by using the direction
                                                   >> 333           //
                                                   >> 334           G4bool directionExiting = false;
                                                   >> 335           G4ThreeVector localDirection =
                                                   >> 336               fHistory.GetTopTransform().TransformAxis(globalDirection);
400                                                   337 
401     // Point is on a surface, but no longer ex << 338           // Make sure localPoint in correct reference frame
402     if ( !isExiting ) { break; }               << 339           //     ( Was it already correct ? How ? )
403                                                << 340           //
404     ++noLevelsExited;                          << 341           localPoint= fHistory.GetTopTransform().TransformPoint(globalPoint);
405                                                << 342           if ( fHistory.GetTopVolumeType()!=kReplica )
406     // Point is on the outer surface, leaving  << 343           {
407     if ( fHistory.GetDepth() == 0 )            << 344             G4ThreeVector normal = targetSolid->SurfaceNormal(localPoint);
408     {                                          << 345             directionExiting = normal.dot(localDirection) > 0.0;
409       fLocatedOutsideWorld = true;             << 346             isExiting = isExiting || directionExiting;
410       fLastLocatedPointLocal = localPoint;     << 347           }
411       return nullptr;                          << 348         }
412     }                                          << 349         if( isExiting )
413                                                << 350         {
414     // Point is still on a surface, but exited << 351           noLevelsExited++; 
415     fValidExitNormal = false;                  << 352           if ( fHistory.GetDepth() )
416     fBlockedPhysicalVolume = fHistory.GetTopVo << 353           {
417     fBlockedReplicaNo = fHistory.GetTopReplica << 354             fBlockedPhysicalVolume = fHistory.GetTopVolume();
418     fHistory.BackLevel();                      << 355             fBlockedReplicaNo = fHistory.GetTopReplicaNo();
                                                   >> 356             fHistory.BackLevel();
                                                   >> 357             //
                                                   >> 358             // Still on surface but exited volume not necessarily convex
                                                   >> 359             //
                                                   >> 360             fValidExitNormal = false;
419                                                   361 
420     if( noLevelsExited > 1 )                   << 362             if( noLevelsExited > 1 )
421     {                                          << 363             {
422       // The first transformation was done by  << 364               // The first transformation was done by the sub-navigator
423       //                                       << 365               //
424       const G4RotationMatrix* mRot =           << 366               const G4RotationMatrix* mRot=fBlockedPhysicalVolume->GetRotation();
425         fBlockedPhysicalVolume->GetRotation(); << 367               if( mRot )
426       if( mRot != nullptr )                    << 368               { 
                                                   >> 369                 fGrandMotherExitNormal *= (*mRot).inverse();
                                                   >> 370                 fChangedGrandMotherRefFrame= true;
                                                   >> 371               }
                                                   >> 372             }
                                                   >> 373           } 
                                                   >> 374           else
                                                   >> 375           {
                                                   >> 376             fLastLocatedPointLocal = localPoint;
                                                   >> 377             fLocatedOutsideWorld = true;
                                                   >> 378               // No extra transformation for ExitNormal, is in frame of Top Vol
                                                   >> 379             return 0;          // Have exited world volume
                                                   >> 380           }
                                                   >> 381         }
                                                   >> 382         else
                                                   >> 383         {
                                                   >> 384           notKnownContained=false;
                                                   >> 385         }
                                                   >> 386       }
                                                   >> 387       else
427       {                                           388       {
428         fGrandMotherExitNormal *= (*mRot).inve << 389         notKnownContained=false;
429         fChangedGrandMotherRefFrame = true;    << 
430       }                                           390       }
431     }                                          << 
432   }  // END while (notKnownContained)             391   }  // END while (notKnownContained)
433   //                                              392   //
434   // Search downwards until deepest containing    393   // Search downwards until deepest containing volume found,
435   // blocking fBlockedPhysicalVolume/BlockedRe    394   // blocking fBlockedPhysicalVolume/BlockedReplicaNum
436   //                                              395   //
437   // 3 Cases:                                     396   // 3 Cases:
438   //                                              397   //
439   // o Parameterised daughters                    398   // o Parameterised daughters
440   //   =>Must be one G4PVParameterised daughte    399   //   =>Must be one G4PVParameterised daughter & voxels
441   // o Positioned daughters & voxels              400   // o Positioned daughters & voxels
442   // o Positioned daughters & no voxels           401   // o Positioned daughters & no voxels
443                                                   402 
444   noResult = true;  // noResult should be rena << 403   noResult = true;  // noResult should be renamed to 
445                     // something like enteredL    404                     // something like enteredLevel, as that is its meaning.
446   do                                              405   do
447   {                                               406   {
448     // Determine `type' of current mother volu    407     // Determine `type' of current mother volume
449     //                                            408     //
450     targetPhysical = fHistory.GetTopVolume();     409     targetPhysical = fHistory.GetTopVolume();
451     if (targetPhysical == nullptr) { break; }  << 410     if (!targetPhysical) { break; }
452     targetLogical = targetPhysical->GetLogical    411     targetLogical = targetPhysical->GetLogicalVolume();
453     switch( CharacteriseDaughters(targetLogica    412     switch( CharacteriseDaughters(targetLogical) )
454     {                                             413     {
455       case kNormal:                               414       case kNormal:
456         if ( targetLogical->GetVoxelHeader() ! << 415         if ( targetLogical->GetVoxelHeader() )  // use optimised navigation
457         {                                         416         {
458           noResult = GetVoxelNavigator().Level << 417           noResult = fvoxelNav.LevelLocate(fHistory,
459                                            fBl    418                                            fBlockedPhysicalVolume,
460                                            fBl    419                                            fBlockedReplicaNo,
461                                            glo    420                                            globalPoint,
462                                            pGl    421                                            pGlobalDirection,
463                                            con    422                                            considerDirection,
464                                            loc    423                                            localPoint);
465         }                                         424         }
466         else                       // do not u    425         else                       // do not use optimised navigation
467         {                                         426         {
468           noResult = fnormalNav.LevelLocate(fH    427           noResult = fnormalNav.LevelLocate(fHistory,
469                                             fB    428                                             fBlockedPhysicalVolume,
470                                             fB    429                                             fBlockedReplicaNo,
471                                             gl    430                                             globalPoint,
472                                             pG    431                                             pGlobalDirection,
473                                             co    432                                             considerDirection,
474                                             lo    433                                             localPoint);
475         }                                         434         }
476         break;                                    435         break;
477       case kReplica:                              436       case kReplica:
478         noResult = freplicaNav.LevelLocate(fHi    437         noResult = freplicaNav.LevelLocate(fHistory,
479                                            fBl    438                                            fBlockedPhysicalVolume,
480                                            fBl    439                                            fBlockedReplicaNo,
481                                            glo    440                                            globalPoint,
482                                            pGl    441                                            pGlobalDirection,
483                                            con    442                                            considerDirection,
484                                            loc    443                                            localPoint);
485         break;                                    444         break;
486       case kParameterised:                        445       case kParameterised:
487         if( GetDaughtersRegularStructureId(tar    446         if( GetDaughtersRegularStructureId(targetLogical) != 1 )
488         {                                         447         {
489           noResult = fparamNav.LevelLocate(fHi    448           noResult = fparamNav.LevelLocate(fHistory,
490                                            fBl    449                                            fBlockedPhysicalVolume,
491                                            fBl    450                                            fBlockedReplicaNo,
492                                            glo    451                                            globalPoint,
493                                            pGl    452                                            pGlobalDirection,
494                                            con    453                                            considerDirection,
495                                            loc    454                                            localPoint);
496         }                                         455         }
497         else  // Regular structure                456         else  // Regular structure
498         {                                         457         {
499           noResult = fregularNav.LevelLocate(f    458           noResult = fregularNav.LevelLocate(fHistory,
500                                              f    459                                              fBlockedPhysicalVolume,
501                                              f    460                                              fBlockedReplicaNo,
502                                              g    461                                              globalPoint,
503                                              p    462                                              pGlobalDirection,
504                                              c    463                                              considerDirection,
505                                              l    464                                              localPoint);
506         }                                         465         }
507         break;                                    466         break;
508       case kExternal:                          << 
509         noResult = fpExternalNav->LevelLocate( << 
510                                                << 
511                                                << 
512                                                << 
513                                                << 
514                                                << 
515                                                << 
516         break;                                 << 
517     }                                             467     }
518                                                   468 
519     // LevelLocate returns true if it finds a     469     // LevelLocate returns true if it finds a daughter volume 
520     // in which globalPoint is inside (or on t    470     // in which globalPoint is inside (or on the surface).
521                                                   471 
522     if ( noResult )                               472     if ( noResult )
523     {                                             473     {
524       // Entering a daughter after ascending      474       // Entering a daughter after ascending
525       //                                          475       //
526       // The blocked volume is no longer valid    476       // The blocked volume is no longer valid - it was for another level
527       //                                          477       //
528       fBlockedPhysicalVolume = nullptr;        << 478       fBlockedPhysicalVolume = 0;
529       fBlockedReplicaNo = -1;                     479       fBlockedReplicaNo = -1;
530                                                   480 
531       // fEntering should be false -- else blo    481       // fEntering should be false -- else blockedVolume is assumed good.
532       // fEnteredDaughter is used for ExitNorm    482       // fEnteredDaughter is used for ExitNormal
533       //                                          483       //
534       fEntering = false;                          484       fEntering = false;
535       fEnteredDaughter = true;                    485       fEnteredDaughter = true;
536                                                   486 
537       if( fExitedMother )                         487       if( fExitedMother )
538       {                                           488       {
539         G4VPhysicalVolume* enteredPhysical = f    489         G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
540         const G4RotationMatrix* mRot = entered    490         const G4RotationMatrix* mRot = enteredPhysical->GetRotation();
541         if( mRot != nullptr )                  << 491         if( mRot )
542         {                                         492         { 
543           // Go deeper, i.e. move 'down' in th << 493           fGrandMotherExitNormal *= (*mRot).inverse();
544           // Apply direct rotation, not invers << 
545           //                                   << 
546           fGrandMotherExitNormal *= (*mRot);   << 
547           fChangedGrandMotherRefFrame= true;   << 
548         }                                         494         }
549       }                                           495       }
550                                                   496 
551 #ifdef G4DEBUG_NAVIGATION                         497 #ifdef G4DEBUG_NAVIGATION
552       if( fVerbose > 2 )                          498       if( fVerbose > 2 )
553       {                                           499       { 
554          G4VPhysicalVolume* enteredPhysical =     500          G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
555          G4cout << "*** G4Navigator::LocateGlo    501          G4cout << "*** G4Navigator::LocateGlobalPointAndSetup() ***" << G4endl;
556          G4cout << "    Entering volume: " <<     502          G4cout << "    Entering volume: " << enteredPhysical->GetName()
557                 << G4endl;                        503                 << G4endl;
558       }                                           504       }
559 #endif                                            505 #endif
560     }                                             506     }
561   } while (noResult);  // Loop checking, 07.10 << 507   } while (noResult);
562                                                   508 
563   fLastLocatedPointLocal = localPoint;            509   fLastLocatedPointLocal = localPoint;
564                                                   510 
565 #ifdef G4VERBOSE                                  511 #ifdef G4VERBOSE
566   if( fVerbose >= 4 )                             512   if( fVerbose >= 4 )
567   {                                               513   {
568     G4long oldcoutPrec = G4cout.precision(8);  << 514     G4int oldcoutPrec = G4cout.precision(8);
569     G4String curPhysVol_Name("None");             515     G4String curPhysVol_Name("None");
570     if (targetPhysical != nullptr)  { curPhysV << 516     if (targetPhysical)  { curPhysVol_Name = targetPhysical->GetName(); }
571     G4cout << "    Return value = new volume =    517     G4cout << "    Return value = new volume = " << curPhysVol_Name << G4endl;
572     G4cout << "    ----- Upon exiting:" << G4e    518     G4cout << "    ----- Upon exiting:" << G4endl;
573     PrintState();                                 519     PrintState();
574     if( fVerbose >= 5 )                        << 520     if( fVerbose == 5 )
575     {                                             521     {
576       G4cout << "Upon exiting LocateGlobalPoin    522       G4cout << "Upon exiting LocateGlobalPointAndSetup():" << G4endl;
577       G4cout << "    History = " << G4endl <<     523       G4cout << "    History = " << G4endl << fHistory << G4endl << G4endl;
578     }                                             524     }
579     G4cout.precision(oldcoutPrec);                525     G4cout.precision(oldcoutPrec);
580   }                                               526   }
581 #endif                                            527 #endif
582                                                   528 
583   fLocatedOutsideWorld = false;                << 529   fLocatedOutsideWorld= false;
584                                                   530 
585   return targetPhysical;                          531   return targetPhysical;
586 }                                                 532 }
587                                                   533 
588 // *******************************************    534 // ********************************************************************
589 // LocateGlobalPointWithinVolume                  535 // LocateGlobalPointWithinVolume
590 //                                                536 //
591 // -> the state information of this Navigator     537 // -> the state information of this Navigator and its subNavigators
592 //    is updated in order to start the next st    538 //    is updated in order to start the next step at pGlobalpoint
593 // -> no check is performed whether pGlobalpoi    539 // -> no check is performed whether pGlobalpoint is inside the 
594 //    original volume (this must be the case).    540 //    original volume (this must be the case).
595 //                                                541 //
596 // Note: a direction could be added to the arg    542 // Note: a direction could be added to the arguments, to aid in future
597 //       optional checking (via the old code b    543 //       optional checking (via the old code below, flagged by OLD_LOCATE). 
598 //       [ This would be done only in verbose     544 //       [ This would be done only in verbose mode ]
599 // *******************************************    545 // ********************************************************************
600 //                                                546 //
601 void                                              547 void
602 G4Navigator::LocateGlobalPointWithinVolume(con    548 G4Navigator::LocateGlobalPointWithinVolume(const G4ThreeVector& pGlobalpoint)
603 {                                              << 549 {  
                                                   >> 550    fLastLocatedPointLocal = ComputeLocalPoint(pGlobalpoint);
                                                   >> 551    fLastTriedStepComputation= false;
                                                   >> 552    fChangedGrandMotherRefFrame= false;  //  Frame for Exit Normal
                                                   >> 553 
604 #ifdef G4DEBUG_NAVIGATION                         554 #ifdef G4DEBUG_NAVIGATION
605    assert( !fWasLimitedByGeometry );           << 555    if( fVerbose > 2 )
606    // Check: Either step was not limited by a  << 556    { 
607    //          else the full step is no longer << 557      G4cout << "Entering LocateGlobalWithinVolume(): History = " << G4endl;
                                                   >> 558      G4cout << fHistory << G4endl;
                                                   >> 559    }
608 #endif                                            560 #endif
609                                                << 
610    fLastLocatedPointLocal = ComputeLocalPoint( << 
611    fLastTriedStepComputation = false;          << 
612    fChangedGrandMotherRefFrame = false;  //  F << 
613                                                   561 
614    // For the case of Voxel (or Parameterised)    562    // For the case of Voxel (or Parameterised) volume the respective 
615    // Navigator must be messaged to update its    563    // Navigator must be messaged to update its voxel information etc
616                                                   564 
617    // Update the state of the Sub Navigators      565    // Update the state of the Sub Navigators 
618    // - in particular any voxel information th    566    // - in particular any voxel information they store/cache
619    //                                             567    //
620    G4VPhysicalVolume*  motherPhysical = fHisto    568    G4VPhysicalVolume*  motherPhysical = fHistory.GetTopVolume();
621    G4LogicalVolume*    motherLogical  = mother    569    G4LogicalVolume*    motherLogical  = motherPhysical->GetLogicalVolume();
                                                   >> 570    G4SmartVoxelHeader* pVoxelHeader   = motherLogical->GetVoxelHeader();
622                                                   571 
623    switch( CharacteriseDaughters(motherLogical << 572    if ( fHistory.GetTopVolumeType()!=kReplica )
624    {                                              573    {
                                                   >> 574      switch( CharacteriseDaughters(motherLogical) )
                                                   >> 575      {
625        case kNormal:                              576        case kNormal:
626          GetVoxelNavigator().RelocateWithinVol << 577          if ( pVoxelHeader )
                                                   >> 578          {
                                                   >> 579            fvoxelNav.VoxelLocate( pVoxelHeader, fLastLocatedPointLocal );
                                                   >> 580          }
627          break;                                   581          break;
628        case kParameterised:                       582        case kParameterised:
629          fparamNav.RelocateWithinVolume( mothe << 583          if( GetDaughtersRegularStructureId(motherLogical) != 1 )
                                                   >> 584          {
                                                   >> 585            // Resets state & returns voxel node
                                                   >> 586            //
                                                   >> 587            fparamNav.ParamVoxelLocate( pVoxelHeader, fLastLocatedPointLocal );
                                                   >> 588          }
630          break;                                   589          break;
631        case kReplica:                             590        case kReplica:
632          // Nothing to do                      << 591          G4Exception("G4Navigator::LocateGlobalPointWithinVolume()",
633          break;                                << 592                      "GeomNav0001", FatalException,
634        case kExternal:                         << 593                      "Not applicable for replicated volumes.");
635          fpExternalNav->RelocateWithinVolume(  << 
636                                                << 
637          break;                                   594          break;
                                                   >> 595      }
638    }                                              596    }
639                                                   597 
640    // Reset the state variables                   598    // Reset the state variables 
641    //   - which would have been affected          599    //   - which would have been affected
642    //     by the 'equivalent' call to LocateGl    600    //     by the 'equivalent' call to LocateGlobalPointAndSetup
643    //   - who's values have been invalidated b    601    //   - who's values have been invalidated by the 'move'.
644    //                                             602    //
645    fBlockedPhysicalVolume = nullptr;           << 603    fBlockedPhysicalVolume = 0; 
646    fBlockedReplicaNo = -1;                        604    fBlockedReplicaNo = -1;
647    fEntering = false;                             605    fEntering = false;
648    fEnteredDaughter = false;  // Boundary not     606    fEnteredDaughter = false;  // Boundary not encountered, did not enter
649    fExiting = false;                              607    fExiting = false;
650    fExitedMother = false;     // Boundary not     608    fExitedMother = false;     // Boundary not encountered, did not exit
651 }                                                 609 }
652                                                   610 
653 // *******************************************    611 // ********************************************************************
654 // SetSavedState                                  612 // SetSavedState
655 //                                                613 //
656 // Save the state, in case this is a parasitic    614 // Save the state, in case this is a parasitic call
657 // Save fValidExitNormal, fExitNormal, fExitin    615 // Save fValidExitNormal, fExitNormal, fExiting, fEntering, 
658 //      fBlockedPhysicalVolume, fBlockedReplic    616 //      fBlockedPhysicalVolume, fBlockedReplicaNo, fLastStepWasZero; 
659 // *******************************************    617 // ********************************************************************
660 //                                                618 //
661 void G4Navigator::SetSavedState()                 619 void G4Navigator::SetSavedState()
662 {                                                 620 {
663   // Note: the state of dependent objects is n << 
664   //   ( This means that the full state is cha << 
665   //     SetSavedState() and RestoreSavedState << 
666                                                << 
667   fSaveState.sExitNormal = fExitNormal;           621   fSaveState.sExitNormal = fExitNormal;
668   fSaveState.sValidExitNormal = fValidExitNorm    622   fSaveState.sValidExitNormal = fValidExitNormal;
669   fSaveState.sExiting = fExiting;                 623   fSaveState.sExiting = fExiting;
670   fSaveState.sEntering = fEntering;               624   fSaveState.sEntering = fEntering;
671                                                   625 
672   fSaveState.spBlockedPhysicalVolume = fBlocke    626   fSaveState.spBlockedPhysicalVolume = fBlockedPhysicalVolume;
673   fSaveState.sBlockedReplicaNo = fBlockedRepli << 627   fSaveState.sBlockedReplicaNo = fBlockedReplicaNo, 
674                                                   628 
675   fSaveState.sLastStepWasZero = static_cast<G4 << 629   fSaveState.sLastStepWasZero = fLastStepWasZero;
676                                                   630   
677   fSaveState.sLocatedOutsideWorld = fLocatedOu    631   fSaveState.sLocatedOutsideWorld = fLocatedOutsideWorld;
678   fSaveState.sLastLocatedPointLocal = fLastLoc << 632   fSaveState.sLastLocatedPointLocal= fLastLocatedPointLocal;
679   fSaveState.sEnteredDaughter = fEnteredDaught << 633   fSaveState.sEnteredDaughter= fEnteredDaughter;
680   fSaveState.sExitedMother = fExitedMother;    << 634   fSaveState.sExitedMother= fExitedMother;
681   fSaveState.sWasLimitedByGeometry = fWasLimit << 
682                                                   635 
683   // Even the safety sphere - if you want to c    636   // Even the safety sphere - if you want to change it do it explicitly!
684   //                                              637   //
685   fSaveState.sPreviousSftOrigin = fPreviousSft << 638   fSaveState.sPreviousSftOrigin= fPreviousSftOrigin;
686   fSaveState.sPreviousSafety = fPreviousSafety << 639   fSaveState.sPreviousSafety= fPreviousSafety;
687 }                                                 640 }
688                                                   641 
689 // *******************************************    642 // ********************************************************************
690 // RestoreSavedState                              643 // RestoreSavedState
691 //                                                644 //
692 // Restore the state (in Compute Step), in cas    645 // Restore the state (in Compute Step), in case this is a parasitic call
693 // *******************************************    646 // ********************************************************************
694 //                                                647 //
695 void G4Navigator::RestoreSavedState()             648 void G4Navigator::RestoreSavedState()
696 {                                                 649 {
697   fExitNormal = fSaveState.sExitNormal;           650   fExitNormal = fSaveState.sExitNormal;
698   fValidExitNormal = fSaveState.sValidExitNorm    651   fValidExitNormal = fSaveState.sValidExitNormal;
699   fExiting = fSaveState.sExiting;                 652   fExiting = fSaveState.sExiting;
700   fEntering = fSaveState.sEntering;               653   fEntering = fSaveState.sEntering;
701                                                   654 
702   fBlockedPhysicalVolume = fSaveState.spBlocke    655   fBlockedPhysicalVolume = fSaveState.spBlockedPhysicalVolume;
703   fBlockedReplicaNo = fSaveState.sBlockedRepli << 656   fBlockedReplicaNo = fSaveState.sBlockedReplicaNo, 
704                                                   657 
705   fLastStepWasZero = (fSaveState.sLastStepWasZ << 658   fLastStepWasZero = fSaveState.sLastStepWasZero;
706                                                   659   
707   fLocatedOutsideWorld = fSaveState.sLocatedOu    660   fLocatedOutsideWorld = fSaveState.sLocatedOutsideWorld;
708   fLastLocatedPointLocal = fSaveState.sLastLoc << 661   fLastLocatedPointLocal= fSaveState.sLastLocatedPointLocal;
709   fEnteredDaughter = fSaveState.sEnteredDaught << 662   fEnteredDaughter= fSaveState.sEnteredDaughter;
710   fExitedMother = fSaveState.sExitedMother;    << 663   fExitedMother= fSaveState.sExitedMother;
711   fWasLimitedByGeometry = fSaveState.sWasLimit << 664   fSaveState.sPreviousSftOrigin= fPreviousSftOrigin;
712                                                << 665   fSaveState.sPreviousSafety= fPreviousSafety;
713   // The 'expected' behaviour is to restore th << 
714   fPreviousSftOrigin = fSaveState.sPreviousSft << 
715   fPreviousSafety = fSaveState.sPreviousSafety << 
716 }                                                 666 }
717                                                   667 
718 // *******************************************    668 // ********************************************************************
719 // ComputeStep                                    669 // ComputeStep
720 //                                                670 //
721 // Computes the next geometric Step: intersect    671 // Computes the next geometric Step: intersections with current
722 // mother and `daughter' volumes.                 672 // mother and `daughter' volumes.
723 //                                                673 //
724 // NOTE:                                          674 // NOTE:
725 //                                                675 //
726 // Flags on entry:                                676 // Flags on entry:
727 // --------------                                 677 // --------------
728 // fValidExitNormal  - Normal of exited volume    678 // fValidExitNormal  - Normal of exited volume is valid (convex, not a 
729 //                     coincident boundary)       679 //                     coincident boundary)
730 // fExitNormal       - Surface normal of exite    680 // fExitNormal       - Surface normal of exited volume
731 // fExiting          - True if have exited sol    681 // fExiting          - True if have exited solid
732 //                                                682 //
733 // fBlockedPhysicalVolume - Ptr to exited volu    683 // fBlockedPhysicalVolume - Ptr to exited volume (or 0)
734 // fBlockedReplicaNo - Replication no of exite    684 // fBlockedReplicaNo - Replication no of exited volume
735 // fLastStepWasZero  - True if last Step size  << 685 // fLastStepWasZero  - True if last Step size was zero.
736 //                                                686 //
737 // Flags on exit:                                 687 // Flags on exit:
738 // -------------                                  688 // -------------
739 // fValidExitNormal  - True if surface normal     689 // fValidExitNormal  - True if surface normal of exited volume is valid
740 // fExitNormal       - Surface normal of exite    690 // fExitNormal       - Surface normal of exited volume rotated to mothers
741 //                    reference system            691 //                    reference system
742 // fExiting          - True if exiting mother     692 // fExiting          - True if exiting mother
743 // fEntering         - True if entering `daugh    693 // fEntering         - True if entering `daughter' volume (or replica)
744 // fBlockedPhysicalVolume - Ptr to candidate (    694 // fBlockedPhysicalVolume - Ptr to candidate (entered) volume
745 // fBlockedReplicaNo - Replication no of candi    695 // fBlockedReplicaNo - Replication no of candidate (entered) volume
746 // fLastStepWasZero  - True if this Step size  << 696 // fLastStepWasZero  - True if this Step size was zero.
747 // *******************************************    697 // ********************************************************************
748 //                                                698 //
749 G4double G4Navigator::ComputeStep( const G4Thr << 699 G4double G4Navigator::ComputeStep( const G4ThreeVector &pGlobalpoint,
750                                    const G4Thr << 700                                    const G4ThreeVector &pDirection,
751                                    const G4dou    701                                    const G4double pCurrentProposedStepLength,
752                                          G4dou << 702                                          G4double &pNewSafety)
753 {                                                 703 {
754 #ifdef G4DEBUG_NAVIGATION                      << 
755   static G4ThreadLocal G4int sNavCScalls = 0;  << 
756   ++sNavCScalls;                               << 
757 #endif                                         << 
758                                                << 
759   G4ThreeVector localDirection = ComputeLocalA    704   G4ThreeVector localDirection = ComputeLocalAxis(pDirection);
760   G4double Step = kInfinity;                      705   G4double Step = kInfinity;
761   G4VPhysicalVolume  *motherPhysical = fHistor    706   G4VPhysicalVolume  *motherPhysical = fHistory.GetTopVolume();
762   G4LogicalVolume *motherLogical = motherPhysi    707   G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
763                                                   708 
764   // All state relating to exiting normals mus    709   // All state relating to exiting normals must be reset
765   //                                              710   //
766   fExitNormalGlobalFrame = G4ThreeVector( 0.,  << 711   fExitNormalGlobalFrame= G4ThreeVector( 0., 0., 0.);
767     // Reset value - to erase its memory          712     // Reset value - to erase its memory
768   fChangedGrandMotherRefFrame = false;         << 713   fChangedGrandMotherRefFrame= false;
769     // Reset - used for local exit normal         714     // Reset - used for local exit normal
770   fGrandMotherExitNormal = G4ThreeVector( 0.,  << 715   fGrandMotherExitNormal= G4ThreeVector( 0., 0., 0.); 
771   fCalculatedExitNormal = false;               << 716   fCalculatedExitNormal  = false;
772     // Reset for new step                         717     // Reset for new step
773                                                   718 
                                                   >> 719   static G4int sNavCScalls=0;
                                                   >> 720   sNavCScalls++;
                                                   >> 721 
                                                   >> 722   fLastTriedStepComputation= true; 
                                                   >> 723 
774 #ifdef G4VERBOSE                                  724 #ifdef G4VERBOSE
775   if( fVerbose > 0 )                              725   if( fVerbose > 0 )
776   {                                               726   {
777     G4cout << "*** G4Navigator::ComputeStep: *    727     G4cout << "*** G4Navigator::ComputeStep: ***" << G4endl; 
778     G4cout << "    Volume = " << motherPhysica    728     G4cout << "    Volume = " << motherPhysical->GetName() 
779            << " - Proposed step length = " <<     729            << " - Proposed step length = " << pCurrentProposedStepLength
780            << G4endl;                             730            << G4endl; 
781 #ifdef G4DEBUG_NAVIGATION                         731 #ifdef G4DEBUG_NAVIGATION
782     if( fVerbose >= 2 )                           732     if( fVerbose >= 2 )
783     {                                             733     {
784       G4cout << "  Called with the arguments:     734       G4cout << "  Called with the arguments: " << G4endl
785              << "  Globalpoint = " << std::set    735              << "  Globalpoint = " << std::setw(25) << pGlobalpoint << G4endl
786              << "  Direction   = " << std::set    736              << "  Direction   = " << std::setw(25) << pDirection << G4endl;
787       if( fVerbose >= 4 )                         737       if( fVerbose >= 4 )
788       {                                           738       {
789         G4cout << "  ---- Upon entering : Stat    739         G4cout << "  ---- Upon entering : State" << G4endl;
790         PrintState();                             740         PrintState();
791       }                                           741       }
792     }                                             742     }
793 #endif                                            743 #endif
794   }                                               744   }
795 #endif                                            745 #endif
796                                                   746 
797   G4ThreeVector newLocalPoint = ComputeLocalPo    747   G4ThreeVector newLocalPoint = ComputeLocalPoint(pGlobalpoint);
798                                                << 
799   if( newLocalPoint != fLastLocatedPointLocal     748   if( newLocalPoint != fLastLocatedPointLocal )
800   {                                               749   {
801     // Check whether the relocation is within     750     // Check whether the relocation is within safety
802     //                                            751     //
803     G4ThreeVector oldLocalPoint = fLastLocated    752     G4ThreeVector oldLocalPoint = fLastLocatedPointLocal;
804     G4double moveLenSq = (newLocalPoint-oldLoc    753     G4double moveLenSq = (newLocalPoint-oldLocalPoint).mag2();
805                                                   754 
806     if ( moveLenSq >= fSqTol )                 << 755     if ( moveLenSq >= kCarTolerance*kCarTolerance )
807     {                                             756     {
808 #ifdef G4VERBOSE                                  757 #ifdef G4VERBOSE
809       ComputeStepLog(pGlobalpoint, moveLenSq);    758       ComputeStepLog(pGlobalpoint, moveLenSq);
810 #endif                                            759 #endif
811       // Relocate the point within the same vo    760       // Relocate the point within the same volume
812       //                                          761       //
813       LocateGlobalPointWithinVolume( pGlobalpo    762       LocateGlobalPointWithinVolume( pGlobalpoint );
                                                   >> 763       fLastTriedStepComputation= true;     // Ensure that this is set again !!
814     }                                             764     }
815   }                                               765   }
816   if ( fHistory.GetTopVolumeType()!=kReplica )    766   if ( fHistory.GetTopVolumeType()!=kReplica )
817   {                                               767   {
818     switch( CharacteriseDaughters(motherLogica    768     switch( CharacteriseDaughters(motherLogical) )
819     {                                             769     {
820       case kNormal:                               770       case kNormal:
821         if ( motherLogical->GetVoxelHeader() ! << 771         if ( motherLogical->GetVoxelHeader() )
822         {                                         772         {
823           Step = GetVoxelNavigator().ComputeSt << 773           Step = fvoxelNav.ComputeStep(fLastLocatedPointLocal,
824                                        localDi    774                                        localDirection,
825                                        pCurren    775                                        pCurrentProposedStepLength,
826                                        pNewSaf    776                                        pNewSafety,
827                                        fHistor    777                                        fHistory,
828                                        fValidE    778                                        fValidExitNormal,
829                                        fExitNo    779                                        fExitNormal,
830                                        fExitin    780                                        fExiting,
831                                        fEnteri    781                                        fEntering,
832                                        &fBlock    782                                        &fBlockedPhysicalVolume,
833                                        fBlocke    783                                        fBlockedReplicaNo);
834                                                   784       
835         }                                         785         }
836         else                                      786         else
837         {                                         787         {
838           if( motherPhysical->GetRegularStruct    788           if( motherPhysical->GetRegularStructureId() == 0 )
839           {                                       789           {
840             Step = fnormalNav.ComputeStep(fLas    790             Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
841                                           loca    791                                           localDirection,
842                                           pCur    792                                           pCurrentProposedStepLength,
843                                           pNew    793                                           pNewSafety,
844                                           fHis    794                                           fHistory,
845                                           fVal    795                                           fValidExitNormal,
846                                           fExi    796                                           fExitNormal,
847                                           fExi    797                                           fExiting,
848                                           fEnt    798                                           fEntering,
849                                           &fBl    799                                           &fBlockedPhysicalVolume,
850                                           fBlo    800                                           fBlockedReplicaNo);
851           }                                       801           }
852           else  // Regular (non-voxelised) str    802           else  // Regular (non-voxelised) structure
853           {                                       803           {
854             LocateGlobalPointAndSetup( pGlobal    804             LocateGlobalPointAndSetup( pGlobalpoint, &pDirection, true, true );
                                                   >> 805             fLastTriedStepComputation= true; // Ensure that this is set again !!
855             //                                    806             //
856             // if physical process limits the     807             // if physical process limits the step, the voxel will not be the
857             // one given by ComputeStepSkippin    808             // one given by ComputeStepSkippingEqualMaterials() and the local
858             // point will be wrongly calculate    809             // point will be wrongly calculated.
859                                                   810 
860             // There is a problem: when msc li    811             // There is a problem: when msc limits the step and the point is
861             // assigned wrongly to phantom in     812             // assigned wrongly to phantom in previous step (while it is out
862             // of the container volume). Then     813             // of the container volume). Then LocateGlobalPointAndSetup() has
863             // reset the history topvolume to     814             // reset the history topvolume to world.
864             //                                    815             //
865             if(fHistory.GetTopVolume()->GetReg    816             if(fHistory.GetTopVolume()->GetRegularStructureId() == 0 )
866             {                                     817             { 
867               G4Exception("G4Navigator::Comput    818               G4Exception("G4Navigator::ComputeStep()",
868                           "GeomNav1001", JustW    819                           "GeomNav1001", JustWarning,
869                 "Point is relocated in voxels,    820                 "Point is relocated in voxels, while it should be outside!");
870               Step = fnormalNav.ComputeStep(fL    821               Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
871                                             lo    822                                             localDirection,
872                                             pC    823                                             pCurrentProposedStepLength,
873                                             pN    824                                             pNewSafety,
874                                             fH    825                                             fHistory,
875                                             fV    826                                             fValidExitNormal,
876                                             fE    827                                             fExitNormal,
877                                             fE    828                                             fExiting,
878                                             fE    829                                             fEntering,
879                                             &f    830                                             &fBlockedPhysicalVolume,
880                                             fB    831                                             fBlockedReplicaNo);
881             }                                     832             }
882             else                                  833             else
883             {                                     834             {
884               Step = fregularNav.                 835               Step = fregularNav.
885                    ComputeStepSkippingEqualMat    836                    ComputeStepSkippingEqualMaterials(fLastLocatedPointLocal,
886                                                   837                                                      localDirection,
887                                                   838                                                      pCurrentProposedStepLength,
888                                                   839                                                      pNewSafety,
889                                                   840                                                      fHistory,
890                                                   841                                                      fValidExitNormal,
891                                                   842                                                      fExitNormal,
892                                                   843                                                      fExiting,
893                                                   844                                                      fEntering,
894                                                   845                                                      &fBlockedPhysicalVolume,
895                                                   846                                                      fBlockedReplicaNo,
896                                                   847                                                      motherPhysical);
897             }                                     848             }
898           }                                       849           }
899         }                                         850         }
900         break;                                    851         break;
901       case kParameterised:                        852       case kParameterised:
902         if( GetDaughtersRegularStructureId(mot    853         if( GetDaughtersRegularStructureId(motherLogical) != 1 )
903         {                                         854         {
904           Step = fparamNav.ComputeStep(fLastLo    855           Step = fparamNav.ComputeStep(fLastLocatedPointLocal,
905                                        localDi    856                                        localDirection,
906                                        pCurren    857                                        pCurrentProposedStepLength,
907                                        pNewSaf    858                                        pNewSafety,
908                                        fHistor    859                                        fHistory,
909                                        fValidE    860                                        fValidExitNormal,
910                                        fExitNo    861                                        fExitNormal,
911                                        fExitin    862                                        fExiting,
912                                        fEnteri    863                                        fEntering,
913                                        &fBlock    864                                        &fBlockedPhysicalVolume,
914                                        fBlocke    865                                        fBlockedReplicaNo);
915         }                                         866         }
916         else  // Regular structure                867         else  // Regular structure
917         {                                         868         {
918           Step = fregularNav.ComputeStep(fLast    869           Step = fregularNav.ComputeStep(fLastLocatedPointLocal,
919                                          local    870                                          localDirection,
920                                          pCurr    871                                          pCurrentProposedStepLength,
921                                          pNewS    872                                          pNewSafety,
922                                          fHist    873                                          fHistory,
923                                          fVali    874                                          fValidExitNormal,
924                                          fExit    875                                          fExitNormal,
925                                          fExit    876                                          fExiting,
926                                          fEnte    877                                          fEntering,
927                                          &fBlo    878                                          &fBlockedPhysicalVolume,
928                                          fBloc    879                                          fBlockedReplicaNo);
929         }                                         880         }
930         break;                                    881         break;
931       case kReplica:                              882       case kReplica:
932         G4Exception("G4Navigator::ComputeStep(    883         G4Exception("G4Navigator::ComputeStep()", "GeomNav0001",
933                     FatalException, "Not appli    884                     FatalException, "Not applicable for replicated volumes.");
934         break;                                    885         break;
935       case kExternal:                          << 
936         Step = fpExternalNav->ComputeStep(fLas << 
937                                           loca << 
938                                           pCur << 
939                                           pNew << 
940                                           fHis << 
941                                           fVal << 
942                                           fExi << 
943                                           fExi << 
944                                           fEnt << 
945                                           &fBl << 
946                                           fBlo << 
947         break;                                 << 
948     }                                             886     }
949   }                                               887   }
950   else                                            888   else
951   {                                               889   {
952     // In the case of a replica, it must handl    890     // In the case of a replica, it must handle the exiting
953     // edge/corner problem by itself              891     // edge/corner problem by itself
954     //                                            892     //
955     fExiting = fExitedMother;                  << 893     G4bool exitingReplica = fExitedMother;
                                                   >> 894     G4bool calculatedExitNormal;
956     Step = freplicaNav.ComputeStep(pGlobalpoin    895     Step = freplicaNav.ComputeStep(pGlobalpoint,
957                                    pDirection,    896                                    pDirection,
958                                    fLastLocate    897                                    fLastLocatedPointLocal,
959                                    localDirect    898                                    localDirection,
960                                    pCurrentPro    899                                    pCurrentProposedStepLength,
961                                    pNewSafety,    900                                    pNewSafety,
962                                    fHistory,      901                                    fHistory,
963                                    fValidExitN    902                                    fValidExitNormal,
964                                    fCalculated << 903                                    calculatedExitNormal,
965                                    fExitNormal    904                                    fExitNormal,
966                                    fExiting,   << 905                                    exitingReplica,
967                                    fEntering,     906                                    fEntering,
968                                    &fBlockedPh    907                                    &fBlockedPhysicalVolume,
969                                    fBlockedRep    908                                    fBlockedReplicaNo);
                                                   >> 909     fExiting= exitingReplica;                          
                                                   >> 910     fCalculatedExitNormal= calculatedExitNormal;
970   }                                               911   }
971                                                   912 
972   // Remember last safety origin & value.         913   // Remember last safety origin & value.
973   //                                              914   //
974   fPreviousSftOrigin = pGlobalpoint;              915   fPreviousSftOrigin = pGlobalpoint;
975   fPreviousSafety = pNewSafety;                   916   fPreviousSafety = pNewSafety; 
976                                                   917 
977   // Count zero steps - one can occur due to c    918   // Count zero steps - one can occur due to changing momentum at a boundary
978   //                  - one, two (or a few) ca    919   //                  - one, two (or a few) can occur at common edges between
979   //                    volumes                   920   //                    volumes
980   //                  - more than two is likel    921   //                  - more than two is likely a problem in the geometry
981   //                    description or the Nav    922   //                    description or the Navigation 
982                                                   923 
983   // Rule of thumb: likely at an Edge if two c    924   // Rule of thumb: likely at an Edge if two consecutive steps are zero,
984   //                because at least two candi    925   //                because at least two candidate volumes must have been
985   //                checked                       926   //                checked
986   //                                              927   //
987   fLocatedOnEdge   = fLastStepWasZero && (Step    928   fLocatedOnEdge   = fLastStepWasZero && (Step==0.0);
988   fLastStepWasZero = (Step<fMinStep);          << 929   fLastStepWasZero = (Step==0.0);
989   if (fPushed)  { fPushed = fLastStepWasZero;     930   if (fPushed)  { fPushed = fLastStepWasZero; }
990                                                   931 
991   // Handle large number of consecutive zero s    932   // Handle large number of consecutive zero steps
992   //                                              933   //
993   if ( fLastStepWasZero )                         934   if ( fLastStepWasZero )
994   {                                               935   {
995     ++fNumberZeroSteps;                        << 936     fNumberZeroSteps++;
996                                                << 
997     G4bool act     = fNumberZeroSteps >= fActi << 
998     G4bool actAndReport = false;               << 
999     G4bool abandon = fNumberZeroSteps >= fAban << 
1000     G4bool inform  = false;                   << 
1001 #ifdef G4VERBOSE                              << 
1002     actAndReport = act && (!fPushed) && fWarn << 
1003 #endif                                        << 
1004 #ifdef G4DEBUG_NAVIGATION                        937 #ifdef G4DEBUG_NAVIGATION
1005     inform = fNumberZeroSteps > 1;            << 938     if( fNumberZeroSteps > 1 )
1006 #endif                                        << 
1007                                               << 
1008     if ( act || inform )                      << 
1009     {                                            939     {
1010       if( act && !abandon )                   << 940        G4cout << "G4Navigator::ComputeStep(): another zero step, # "
1011       {                                       << 941               << fNumberZeroSteps
1012         // Act to recover this stuck track. P << 942               << " at " << pGlobalpoint
1013         //                                    << 943               << " in volume " << motherPhysical->GetName()
1014         Step += 100*kCarTolerance;            << 944               << " nav-comp-step calls # " << sNavCScalls
1015         fPushed = true;                       << 945               << G4endl;
1016       }                                       << 946     }
1017                                               << 
1018       if( actAndReport || abandon || inform ) << 
1019       {                                       << 
1020         std::ostringstream message;           << 
1021                                               << 
1022         message.precision(16);                << 
1023         message << "Stuck Track: potential ge << 
1024                 << G4endl;                    << 
1025         message << "  Track stuck, not moving << 
1026                 << fNumberZeroSteps << " step << 
1027                 << "  Current  phys volume: ' << 
1028                 << "'" << G4endl              << 
1029                 << "   - at position : " << p << 
1030                 << "     in direction: " << p << 
1031                 << "    (local position: " << << 
1032                 << "    (local direction: " < << 
1033                 << "  Previous phys volume: ' << 
1034                 << ( fLastMotherPhys != nullp << 
1035                 << "'" << G4endl << G4endl;   << 
1036         if( actAndReport || abandon )         << 
1037         {                                     << 
1038            message << "  Likely geometry over << 
1039                    << G4endl;                 << 
1040         }                                     << 
1041         if( abandon ) // i.e. fNumberZeroStep << 
1042         {                                     << 
1043           // Must kill this stuck track       << 
1044 #ifdef G4VERBOSE                              << 
1045           if ( fWarnPush ) { CheckOverlapsIte << 
1046 #endif                                           947 #endif
1047           message << " Track *abandoned* due  << 948     if( fNumberZeroSteps > fActionThreshold_NoZeroSteps-1 )
1048                   << " Event aborted. " << G4 << 949     {
1049           G4Exception("G4Navigator::ComputeSt << 950        // Act to recover this stuck track. Pushing it along direction
1050                       EventMustBeAborted, mes << 951        //
1051         }                                     << 952        Step += 100*kCarTolerance;
1052         else                                  << 
1053         {                                     << 
1054 #ifdef G4VERBOSE                                 953 #ifdef G4VERBOSE
1055           if ( actAndReport )  // (!fPushed = << 954        if ((!fPushed) && (fWarnPush))
1056           {                                   << 955        {
1057              message << "   *** Trying to get << 956          std::ostringstream message;
1058                      << " - expanding step to << 957          message << "Track stuck or not moving." << G4endl
1059                      << "       Potential ove << 958                  << "          Track stuck, not moving for " 
1060              G4Exception("G4Navigator::Comput << 959                  << fNumberZeroSteps << " steps" << G4endl
1061                          JustWarning, message << 960                  << "          in volume -" << motherPhysical->GetName()
1062           }                                   << 961                  << "- at point " << pGlobalpoint << G4endl
1063 #endif                                        << 962                  << "          direction: " << pDirection << "." << G4endl
1064 #ifdef G4DEBUG_NAVIGATION                     << 963                  << "          Potential geometry or navigation problem !"
1065           else                                << 964                  << G4endl
1066           {                                   << 965                  << "          Trying pushing it of " << Step << " mm ...";
1067             if( fNumberZeroSteps > 1 )        << 966          G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
1068             {                                 << 967                      JustWarning, message, "Potential overlap in geometry!");
1069                message << ", nav-comp-step ca << 968        }
1070                        << ", Step= " << Step  << 
1071                G4cout << message.str();       << 
1072             }                                 << 
1073           }                                   << 
1074 #endif                                           969 #endif
1075         } // end of else if ( abandon )       << 970        fPushed = true;
1076       } // end of if( actAndReport || abandon << 971     }
1077     } // end of if ( act || inform )          << 972     if( fNumberZeroSteps > fAbandonThreshold_NoZeroSteps-1 )
                                                   >> 973     {
                                                   >> 974       // Must kill this stuck track
                                                   >> 975       //
                                                   >> 976       std::ostringstream message;
                                                   >> 977       message << "Stuck Track: potential geometry or navigation problem."
                                                   >> 978               << G4endl
                                                   >> 979               << "        Track stuck, not moving for " 
                                                   >> 980               << fNumberZeroSteps << " steps" << G4endl
                                                   >> 981               << "        in volume -" << motherPhysical->GetName()
                                                   >> 982               << "- at point " << pGlobalpoint << G4endl
                                                   >> 983               << "        direction: " << pDirection << ".";
                                                   >> 984       motherPhysical->CheckOverlaps(5000, false);
                                                   >> 985       G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
                                                   >> 986                   EventMustBeAborted, message);
                                                   >> 987     }
1078   }                                              988   }
1079   else                                           989   else
1080   {                                              990   {
1081     if (!fPushed)  { fNumberZeroSteps = 0; }  << 991     if (!fPushed)  fNumberZeroSteps = 0;
1082   }                                              992   }
1083   fLastMotherPhys = motherPhysical;           << 
1084                                                  993 
1085   fEnteredDaughter = fEntering;   // I expect    994   fEnteredDaughter = fEntering;   // I expect to enter a volume in this Step
1086   fExitedMother = fExiting;                      995   fExitedMother = fExiting;
1087                                                  996 
1088   fStepEndPoint = pGlobalpoint                << 997   fStepEndPoint = pGlobalpoint + Step * pDirection; 
1089                 + std::min(Step,pCurrentPropo << 
1090   fLastStepEndPointLocal = fLastLocatedPointL    998   fLastStepEndPointLocal = fLastLocatedPointLocal + Step * localDirection; 
1091                                                  999 
1092   if( fExiting )                                 1000   if( fExiting )
1093   {                                              1001   {
1094 #ifdef G4DEBUG_NAVIGATION                        1002 #ifdef G4DEBUG_NAVIGATION
1095     if( fVerbose > 2 )                           1003     if( fVerbose > 2 )
1096     {                                            1004     { 
1097       G4cout << " At G4Nav CompStep End - if( << 1005       G4cout << " At G4Nav CompStep End - if(exiting) - fExiting= " << fExiting 
1098              << " fValidExitNormal = " << fVa    1006              << " fValidExitNormal = " << fValidExitNormal  << G4endl;
1099       G4cout << " fExitNormal= " << fExitNorm    1007       G4cout << " fExitNormal= " << fExitNormal << G4endl;
1100     }                                            1008     }
1101 #endif                                           1009 #endif
1102                                                  1010 
1103     if ( fValidExitNormal || fCalculatedExitN << 1011     if(fValidExitNormal || fCalculatedExitNormal)
1104     {                                            1012     {
1105       // Convention: fExitNormal is in the 'g << 1013       if (  fHistory.GetTopVolumeType()!=kReplica )
1106       fGrandMotherExitNormal = fExitNormal;   << 1014       {
                                                   >> 1015         // Convention: fExitNormal is in the 'grand-mother' coordinate system
                                                   >> 1016         //
                                                   >> 1017         fGrandMotherExitNormal= fExitNormal;
                                                   >> 1018         fCalculatedExitNormal= true;
                                                   >> 1019       }
                                                   >> 1020       else
                                                   >> 1021       {
                                                   >> 1022         fGrandMotherExitNormal = fExitNormal;
                                                   >> 1023       }
1107     }                                            1024     }
1108     else                                         1025     else
1109     {                                            1026     {  
1110       // We must calculate the normal anyway     1027       // We must calculate the normal anyway (in order to have it if requested)
1111       //                                         1028       //
1112       G4ThreeVector finalLocalPoint = fLastLo << 1029       G4ThreeVector finalLocalPoint =
1113                                     + localDi << 1030             fLastLocatedPointLocal + localDirection*Step;
1114                                                  1031 
1115       if (  fHistory.GetTopVolumeType() != kR << 1032       if (  fHistory.GetTopVolumeType()!=kReplica )
1116       {                                          1033       {
1117         // Find normal in the 'mother' coordi    1034         // Find normal in the 'mother' coordinate system
1118         //                                       1035         //
1119         G4ThreeVector exitNormalMotherFrame=     1036         G4ThreeVector exitNormalMotherFrame=
1120            motherLogical->GetSolid()->Surface    1037            motherLogical->GetSolid()->SurfaceNormal(finalLocalPoint);
1121                                                  1038         
1122         // Transform it to the 'grand-mother'    1039         // Transform it to the 'grand-mother' coordinate system
1123         //                                       1040         //
1124         const G4RotationMatrix* mRot = mother    1041         const G4RotationMatrix* mRot = motherPhysical->GetRotation();
1125         if( mRot != nullptr )                 << 1042         if( mRot )
1126         {                                        1043         {
1127           fChangedGrandMotherRefFrame = true; << 1044           fChangedGrandMotherRefFrame= true;           
1128           fGrandMotherExitNormal = (*mRot).in    1045           fGrandMotherExitNormal = (*mRot).inverse() * exitNormalMotherFrame;
1129         }                                        1046         }
1130         else                                     1047         else
1131         {                                        1048         {
1132           fGrandMotherExitNormal = exitNormal    1049           fGrandMotherExitNormal = exitNormalMotherFrame;
1133         }                                        1050         }
1134                                                  1051 
1135         // Do not set fValidExitNormal -- thi    1052         // Do not set fValidExitNormal -- this signifies
1136         // that the solid is convex!             1053         // that the solid is convex!
                                                   >> 1054         //
                                                   >> 1055         fCalculatedExitNormal= true;
1137       }                                          1056       }
1138       else                                       1057       else
1139       {                                          1058       {
1140         fCalculatedExitNormal = false;           1059         fCalculatedExitNormal = false;
1141         //                                       1060         //
1142         // Nothing can be done at this stage     1061         // Nothing can be done at this stage currently - to solve this
1143         // Replica Navigation must have calcu    1062         // Replica Navigation must have calculated the normal for this case
1144         // already.                              1063         // already.
1145         // Cases: mother is not convex, and e    1064         // Cases: mother is not convex, and exit is at previous replica level
1146                                                  1065 
1147 #ifdef G4DEBUG_NAVIGATION                        1066 #ifdef G4DEBUG_NAVIGATION
1148         G4ExceptionDescription desc;             1067         G4ExceptionDescription desc;
1149                                                  1068 
1150         desc << "Problem in ComputeStep:  Rep    1069         desc << "Problem in ComputeStep:  Replica Navigation did not provide"
1151              << " valid exit Normal. " << G4e    1070              << " valid exit Normal. " << G4endl;
1152         desc << " Do not know how calculate i    1071         desc << " Do not know how calculate it in this case." << G4endl;
1153         desc << "  Location    = " << finalLo    1072         desc << "  Location    = " << finalLocalPoint << G4endl;
1154         desc << "  Volume name = " << motherP    1073         desc << "  Volume name = " << motherPhysical->GetName()
1155              << "  copy/replica No = " << mot    1074              << "  copy/replica No = " << motherPhysical->GetCopyNo() << G4endl;
1156         G4Exception("G4Navigator::ComputeStep    1075         G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
1157                     JustWarning, desc, "Norma    1076                     JustWarning, desc, "Normal not available for exiting.");
1158 #endif                                           1077 #endif
1159       }                                          1078       }
1160     }                                            1079     }
1161                                                  1080 
1162     if ( fHistory.GetTopVolumeType() != kRepl << 
1163     {                                         << 
1164       fCalculatedExitNormal = true;           << 
1165     }                                         << 
1166                                               << 
1167     // Now transform it to the global referen    1081     // Now transform it to the global reference frame !!
1168     //                                           1082     //
1169     if( fValidExitNormal || fCalculatedExitNo    1083     if( fValidExitNormal || fCalculatedExitNormal )
1170     {                                            1084     {
1171       auto  depth = (G4int)fHistory.GetDepth( << 1085       G4int depth= fHistory.GetDepth();
1172       if( depth > 0 )                            1086       if( depth > 0 )
1173       {                                          1087       {
1174         fExitNormalGlobalFrame = fHistory.Get << 1088         G4AffineTransform GrandMotherToGlobalTransf =
1175                                 .InverseTrans << 1089           fHistory.GetTransform(depth-1).Inverse();
                                                   >> 1090         fExitNormalGlobalFrame =
                                                   >> 1091           GrandMotherToGlobalTransf.TransformAxis( fGrandMotherExitNormal );
1176       }                                          1092       }
1177       else                                       1093       else
1178       {                                          1094       {
1179         fExitNormalGlobalFrame = fGrandMother << 1095         fExitNormalGlobalFrame= fGrandMotherExitNormal;
1180       }                                          1096       }
1181     }                                            1097     }
1182     else                                         1098     else
1183     {                                            1099     {
1184       fExitNormalGlobalFrame = G4ThreeVector( << 1100       fExitNormalGlobalFrame= G4ThreeVector( 0., 0., 0.);
1185     }                                            1101     }
1186   }                                              1102   }
                                                   >> 1103   fStepEndPoint= pGlobalpoint+Step*pDirection; 
1187                                                  1104 
1188   if( (Step == pCurrentProposedStepLength) &&    1105   if( (Step == pCurrentProposedStepLength) && (!fExiting) && (!fEntering) )
1189   {                                              1106   {
1190     // This if Step is not really limited by     1107     // This if Step is not really limited by the geometry.
1191     // The Navigator is obliged to return "in    1108     // The Navigator is obliged to return "infinity"
1192     //                                           1109     //
1193     Step = kInfinity;                            1110     Step = kInfinity;
1194   }                                              1111   }
1195                                                  1112 
1196 #ifdef G4VERBOSE                                 1113 #ifdef G4VERBOSE
1197   if( fVerbose > 1 )                             1114   if( fVerbose > 1 )
1198   {                                              1115   {
1199     if( fVerbose >= 4 )                          1116     if( fVerbose >= 4 )
1200     {                                            1117     {
1201       G4cout << "    ----- Upon exiting :" <<    1118       G4cout << "    ----- Upon exiting :" << G4endl;
1202       PrintState();                              1119       PrintState();
1203     }                                            1120     }
1204     G4cout << "  Returned step= " << Step;       1121     G4cout << "  Returned step= " << Step;
1205     if( fVerbose > 5 )  { G4cout << G4endl; } << 1122     if( fVerbose > 5 )   G4cout << G4endl;
1206     if( Step == kInfinity )                      1123     if( Step == kInfinity )
1207     {                                            1124     {
1208        G4cout << " Requested step= " << pCurr    1125        G4cout << " Requested step= " << pCurrentProposedStepLength ;
1209        if( fVerbose > 5)  { G4cout << G4endl; << 1126        if( fVerbose > 5) G4cout << G4endl;
1210     }                                            1127     }
1211     G4cout << "  Safety = " << pNewSafety <<     1128     G4cout << "  Safety = " << pNewSafety << G4endl;
1212   }                                              1129   }
1213 #endif                                           1130 #endif
1214                                                  1131 
1215   fLastTriedStepComputation = true;           << 
1216                                               << 
1217   return Step;                                   1132   return Step;
1218 }                                                1133 }
1219                                                  1134 
1220 // ******************************************    1135 // ********************************************************************
1221 // CheckNextStep                                 1136 // CheckNextStep
1222 //                                               1137 //
1223 // Compute the step without altering the navi    1138 // Compute the step without altering the navigator state
1224 // ******************************************    1139 // ********************************************************************
1225 //                                               1140 //
1226 G4double G4Navigator::CheckNextStep( const G4    1141 G4double G4Navigator::CheckNextStep( const G4ThreeVector& pGlobalpoint,
1227                                      const G4    1142                                      const G4ThreeVector& pDirection,
1228                                      const G4    1143                                      const G4double pCurrentProposedStepLength,
1229                                            G4    1144                                            G4double& pNewSafety)
1230 {                                                1145 {
1231   G4double step;                                 1146   G4double step;
1232                                                  1147 
1233   // Save the state, for this parasitic call     1148   // Save the state, for this parasitic call
1234   //                                             1149   //
1235   SetSavedState();                               1150   SetSavedState();
1236                                                  1151 
1237   step = ComputeStep ( pGlobalpoint,             1152   step = ComputeStep ( pGlobalpoint, 
1238                        pDirection,               1153                        pDirection,
1239                        pCurrentProposedStepLe    1154                        pCurrentProposedStepLength, 
1240                        pNewSafety );             1155                        pNewSafety ); 
1241                                                  1156 
1242   // It is a parasitic call, so attempt to re << 1157   // If a parasitic call, then attempt to restore the key parts of the state
1243   //                                             1158   //
1244   RestoreSavedState();                           1159   RestoreSavedState(); 
1245   // NOTE: the state of the current subnaviga << 1160 
1246   // ***> TODO: restore subnavigator state    << 
1247   //            if( last_located)       Need  << 
1248   //            if( last_computed step) Need  << 
1249                                               << 
1250   return step;                                   1161   return step; 
1251 }                                                1162 }
1252                                                  1163 
1253 // ******************************************    1164 // ********************************************************************
1254 // ResetState                                    1165 // ResetState
1255 //                                               1166 //
1256 // Resets stack and minimum of navigator stat    1167 // Resets stack and minimum of navigator state `machine'
1257 // ******************************************    1168 // ********************************************************************
1258 //                                               1169 //
1259 void G4Navigator::ResetState()                   1170 void G4Navigator::ResetState()
1260 {                                                1171 {
1261   fWasLimitedByGeometry  = false;                1172   fWasLimitedByGeometry  = false;
1262   fEntering              = false;                1173   fEntering              = false;
1263   fExiting               = false;                1174   fExiting               = false;
1264   fLocatedOnEdge         = false;                1175   fLocatedOnEdge         = false;
1265   fLastStepWasZero       = false;                1176   fLastStepWasZero       = false;
1266   fEnteredDaughter       = false;                1177   fEnteredDaughter       = false;
1267   fExitedMother          = false;                1178   fExitedMother          = false;
1268   fPushed                = false;                1179   fPushed                = false;
1269                                                  1180 
1270   fValidExitNormal       = false;                1181   fValidExitNormal       = false;
1271   fChangedGrandMotherRefFrame = false;        << 1182   fChangedGrandMotherRefFrame= false;
1272   fCalculatedExitNormal  = false;                1183   fCalculatedExitNormal  = false;
1273                                                  1184 
1274   fExitNormal            = G4ThreeVector(0,0,    1185   fExitNormal            = G4ThreeVector(0,0,0);
1275   fGrandMotherExitNormal = G4ThreeVector(0,0,    1186   fGrandMotherExitNormal = G4ThreeVector(0,0,0);
1276   fExitNormalGlobalFrame = G4ThreeVector(0,0,    1187   fExitNormalGlobalFrame = G4ThreeVector(0,0,0);
1277                                                  1188 
1278   fPreviousSftOrigin     = G4ThreeVector(0,0,    1189   fPreviousSftOrigin     = G4ThreeVector(0,0,0);
1279   fPreviousSafety        = 0.0;                  1190   fPreviousSafety        = 0.0; 
1280                                                  1191 
1281   fNumberZeroSteps       = 0;                    1192   fNumberZeroSteps       = 0;
1282                                               << 1193     
1283   fBlockedPhysicalVolume = nullptr;           << 1194   fBlockedPhysicalVolume = 0;
1284   fBlockedReplicaNo      = -1;                   1195   fBlockedReplicaNo      = -1;
1285                                                  1196 
1286   fLastLocatedPointLocal = G4ThreeVector( kIn    1197   fLastLocatedPointLocal = G4ThreeVector( kInfinity, -kInfinity, 0.0 ); 
1287   fLocatedOutsideWorld   = false;                1198   fLocatedOutsideWorld   = false;
1288                                               << 
1289   fLastMotherPhys = nullptr;                  << 
1290 }                                                1199 }
1291                                                  1200 
1292 // ******************************************    1201 // ********************************************************************
1293 // SetupHierarchy                                1202 // SetupHierarchy
1294 //                                               1203 //
1295 // Renavigates & resets hierarchy described b    1204 // Renavigates & resets hierarchy described by current history
1296 // o Reset volumes                               1205 // o Reset volumes
1297 // o Recompute transforms and/or solids of re    1206 // o Recompute transforms and/or solids of replicated/parameterised volumes
1298 // ******************************************    1207 // ********************************************************************
1299 //                                               1208 //
1300 void G4Navigator::SetupHierarchy()               1209 void G4Navigator::SetupHierarchy()
1301 {                                                1210 {
1302   const auto  depth = (G4int)fHistory.GetDept << 1211   G4int i;
1303   for ( auto i = 1; i <= depth; ++i )         << 1212   const G4int cdepth = fHistory.GetDepth();
                                                   >> 1213   G4VPhysicalVolume *current;
                                                   >> 1214   G4VSolid *pSolid;
                                                   >> 1215   G4VPVParameterisation *pParam;
                                                   >> 1216 
                                                   >> 1217   for ( i=1; i<=cdepth; i++ )
1304   {                                              1218   {
                                                   >> 1219     current = fHistory.GetVolume(i);
1305     switch ( fHistory.GetVolumeType(i) )         1220     switch ( fHistory.GetVolumeType(i) )
1306     {                                            1221     {
1307       case kNormal:                              1222       case kNormal:
1308       case kExternal:                         << 
1309         break;                                   1223         break;
1310       case kReplica:                             1224       case kReplica:
1311         freplicaNav.ComputeTransformation(fHi << 1225         freplicaNav.ComputeTransformation(fHistory.GetReplicaNo(i), current);
1312         break;                                   1226         break;
1313       case kParameterised:                       1227       case kParameterised:
1314         G4VPhysicalVolume* current = fHistory << 1228         G4int replicaNo;
1315         G4int replicaNo = fHistory.GetReplica << 1229         pParam = current->GetParameterisation();
1316         G4VPVParameterisation* pParam = curre << 1230         replicaNo = fHistory.GetReplicaNo(i);
1317         G4VSolid* pSolid = pParam->ComputeSol << 1231         pSolid = pParam->ComputeSolid(replicaNo, current);
1318                                                  1232 
1319         // Set up dimensions & transform in s    1233         // Set up dimensions & transform in solid/physical volume
1320         //                                       1234         //
1321         pSolid->ComputeDimensions(pParam, rep    1235         pSolid->ComputeDimensions(pParam, replicaNo, current);
1322         pParam->ComputeTransformation(replica    1236         pParam->ComputeTransformation(replicaNo, current);
1323                                                  1237 
1324         G4TouchableHistory* pTouchable = null << 1238         G4TouchableHistory touchable( fHistory );
1325         if( pParam->IsNested() )              << 1239         touchable.MoveUpHistory();  // move up to the parent level
1326         {                                     << 1240       
1327           pTouchable= new G4TouchableHistory( << 
1328           pTouchable->MoveUpHistory(); // Mov << 
1329             // Adequate only if Nested at the << 
1330             // To extend to other cases:      << 
1331             // pTouchable->MoveUpHistory(cdep << 
1332             // Move to the parent level of *C << 
1333             // Could replace this line and co << 
1334             // c-tor for History(levels to dr << 
1335         }                                     << 
1336         // Set up the correct solid and mater    1241         // Set up the correct solid and material in Logical Volume
1337         //                                       1242         //
1338         G4LogicalVolume* pLogical = current-> << 1243         G4LogicalVolume *pLogical = current->GetLogicalVolume();
1339         pLogical->SetSolid( pSolid );            1244         pLogical->SetSolid( pSolid );
1340         pLogical->UpdateMaterial( pParam ->      1245         pLogical->UpdateMaterial( pParam ->
1341           ComputeMaterial(replicaNo, current, << 1246           ComputeMaterial(replicaNo, current, &touchable) );
1342         delete pTouchable;                    << 
1343         break;                                   1247         break;
1344     }                                            1248     }
1345   }                                              1249   }
1346 }                                                1250 }
1347                                                  1251 
1348 // ******************************************    1252 // ********************************************************************
1349 // GetLocalExitNormal                            1253 // GetLocalExitNormal
1350 //                                               1254 //
1351 // Obtains the Normal vector to a surface (in    1255 // Obtains the Normal vector to a surface (in local coordinates)
1352 // pointing out of previous volume and into c    1256 // pointing out of previous volume and into current volume
1353 // ******************************************    1257 // ********************************************************************
1354 //                                               1258 //
1355 G4ThreeVector G4Navigator::GetLocalExitNormal    1259 G4ThreeVector G4Navigator::GetLocalExitNormal( G4bool* valid )
1356 {                                                1260 {
1357   G4ThreeVector    ExitNormal(0.,0.,0.);         1261   G4ThreeVector    ExitNormal(0.,0.,0.);
1358   G4VSolid* currentSolid = nullptr;           << 1262   G4VSolid        *currentSolid=0;
1359   G4LogicalVolume* candidateLogical;          << 1263   G4LogicalVolume *candidateLogical;
1360                                               << 
1361   if ( fLastTriedStepComputation )               1264   if ( fLastTriedStepComputation ) 
1362   {                                              1265   {
1363     // use fLastLocatedPointLocal and next ca    1266     // use fLastLocatedPointLocal and next candidate volume
1364     //                                           1267     //
1365     G4ThreeVector nextSolidExitNormal(0.,0.,0    1268     G4ThreeVector nextSolidExitNormal(0.,0.,0.);
1366                                                  1269 
1367     if( fEntering && (fBlockedPhysicalVolume! << 1270     if( fEntering && (fBlockedPhysicalVolume!=0) ) 
1368     {                                            1271     { 
1369       candidateLogical = fBlockedPhysicalVolu << 1272       candidateLogical= fBlockedPhysicalVolume->GetLogicalVolume();
1370       if( candidateLogical != nullptr )       << 1273       if( candidateLogical ) 
1371       {                                          1274       {
1372         // fLastStepEndPointLocal is in the c    1275         // fLastStepEndPointLocal is in the coordinates of the mother
1373         // we need it in the daughter's coord    1276         // we need it in the daughter's coordinate system.
1374                                                  1277 
1375         // The following code should also wor    1278         // The following code should also work in case of Replica
1376         {                                        1279         {
1377           // First transform fLastLocatedPoin    1280           // First transform fLastLocatedPointLocal to the new daughter
1378           // coordinates                         1281           // coordinates
1379           //                                     1282           //
1380           G4AffineTransform MotherToDaughterT    1283           G4AffineTransform MotherToDaughterTransform=
1381             GetMotherToDaughterTransform( fBl    1284             GetMotherToDaughterTransform( fBlockedPhysicalVolume, 
1382                                           fBl    1285                                           fBlockedReplicaNo,
1383                                           Vol    1286                                           VolumeType(fBlockedPhysicalVolume) ); 
1384           G4ThreeVector daughterPointOwnLocal << 1287           G4ThreeVector daughterPointOwnLocal= 
1385             MotherToDaughterTransform.Transfo    1288             MotherToDaughterTransform.TransformPoint( fLastStepEndPointLocal ); 
1386                                                  1289 
1387           // OK if it is a parameterised volu    1290           // OK if it is a parameterised volume
1388           //                                     1291           //
1389           EInside inSideIt;                   << 1292           EInside  inSideIt; 
1390           G4bool onSurface;                   << 1293           G4bool   onSurface;
1391           G4double safety = -1.0;             << 1294           G4double safety= -1.0; 
1392           currentSolid = candidateLogical->Ge << 1295           currentSolid= candidateLogical->GetSolid(); 
1393           inSideIt = currentSolid->Inside(dau << 1296           inSideIt  =  currentSolid->Inside(daughterPointOwnLocal); 
1394           onSurface = (inSideIt == kSurface); << 1297           onSurface =  (inSideIt == kSurface); 
1395           if( !onSurface )                    << 1298           if( ! onSurface ) 
1396           {                                      1299           {
1397             if( inSideIt == kOutside )           1300             if( inSideIt == kOutside )
1398             {                                    1301             {
1399               safety = (currentSolid->Distanc    1302               safety = (currentSolid->DistanceToIn(daughterPointOwnLocal)); 
1400               onSurface = safety < 100.0 * kC    1303               onSurface = safety < 100.0 * kCarTolerance; 
1401             }                                    1304             }
1402             else if (inSideIt == kInside )       1305             else if (inSideIt == kInside )
1403             {                                    1306             {
1404               safety = (currentSolid->Distanc    1307               safety = (currentSolid->DistanceToOut(daughterPointOwnLocal)); 
1405               onSurface = safety < 100.0 * kC    1308               onSurface = safety < 100.0 * kCarTolerance; 
1406             }                                    1309             }
1407           }                                      1310           }
1408                                                  1311 
1409           if( onSurface )                        1312           if( onSurface ) 
1410           {                                      1313           {
1411             nextSolidExitNormal =                1314             nextSolidExitNormal =
1412               currentSolid->SurfaceNormal(dau << 1315               currentSolid->SurfaceNormal(daughterPointOwnLocal); 
1413                                                  1316  
1414             // Entering the solid ==> opposit    1317             // Entering the solid ==> opposite
1415             //                                   1318             //
1416             // First flip ( ExitNormal = -nex << 1319             ExitNormal = -nextSolidExitNormal;
1417             //  and then rotate the the norma << 1320             fCalculatedExitNormal= true;
1418             ExitNormal = MotherToDaughterTran << 
1419                         .InverseTransformAxis << 
1420             fCalculatedExitNormal = true;     << 
1421           }                                      1321           }
1422           else                                   1322           else
1423           {                                      1323           {
1424 #ifdef G4VERBOSE                                 1324 #ifdef G4VERBOSE
1425             if(( fVerbose == 1 ) && ( fCheck     1325             if(( fVerbose == 1 ) && ( fCheck ))
1426             {                                    1326             {
1427               std::ostringstream message;        1327               std::ostringstream message;
1428               message << "Point not on surfac    1328               message << "Point not on surface ! " << G4endl
1429                       << "  Point           =    1329                       << "  Point           = "
1430                       << daughterPointOwnLoca    1330                       << daughterPointOwnLocal << G4endl 
1431                       << "  Physical volume =    1331                       << "  Physical volume = "
1432                       << fBlockedPhysicalVolu    1332                       << fBlockedPhysicalVolume->GetName() << G4endl
1433                       << "  Logical volume  =    1333                       << "  Logical volume  = "
1434                       << candidateLogical->Ge    1334                       << candidateLogical->GetName() << G4endl
1435                       << "  Solid           =    1335                       << "  Solid           = " << currentSolid->GetName() 
1436                       << "  Type            =    1336                       << "  Type            = "
1437                       << currentSolid->GetEnt    1337                       << currentSolid->GetEntityType() << G4endl
1438                       << *currentSolid << G4e    1338                       << *currentSolid << G4endl;
1439               if( inSideIt == kOutside )         1339               if( inSideIt == kOutside )
1440               {                                  1340               { 
1441                 message << "Point is Outside.    1341                 message << "Point is Outside. " << G4endl
1442                         << "  Safety (from ou    1342                         << "  Safety (from outside) = " << safety << G4endl;
1443               }                                  1343               }
1444               else // if( inSideIt == kInside    1344               else // if( inSideIt == kInside ) 
1445               {                                  1345               {
1446                 message << "Point is Inside.     1346                 message << "Point is Inside. " << G4endl
1447                         << "  Safety (from in << 1347                         << "  Safety (from inside) = " << safety << G4endl;              
1448               }                                  1348               }
1449               G4Exception("G4Navigator::GetLo    1349               G4Exception("G4Navigator::GetLocalExitNormal()", "GeomNav1001",
1450                           JustWarning, messag    1350                           JustWarning, message);
1451             }                                    1351             }
1452 #endif                                           1352 #endif
1453           }                                      1353           }
1454           *valid = onSurface;   //   was =tru    1354           *valid = onSurface;   //   was =true;
1455         }                                        1355         }
1456       }                                          1356       }
1457     }                                            1357     }
1458     else if ( fExiting )                         1358     else if ( fExiting ) 
1459     {                                            1359     {
1460       ExitNormal = fGrandMotherExitNormal;       1360       ExitNormal = fGrandMotherExitNormal;
1461       *valid = true;                             1361       *valid = true;
1462       fCalculatedExitNormal = true;  // Shoul << 1362       fCalculatedExitNormal= true;  // Should be true already
1463     }                                            1363     }
1464     else  // i.e.  ( fBlockedPhysicalVolume =    1364     else  // i.e.  ( fBlockedPhysicalVolume == 0 )
1465     {                                            1365     {
1466       *valid = false;                            1366       *valid = false;
1467       G4Exception("G4Navigator::GetLocalExitN    1367       G4Exception("G4Navigator::GetLocalExitNormal()",
1468                   "GeomNav0003", JustWarning,    1368                   "GeomNav0003", JustWarning, 
1469                   "Incorrect call to GetLocal    1369                   "Incorrect call to GetLocalSurfaceNormal." );
1470     }                                            1370     }
1471   }                                              1371   }
1472   else //  ( ! fLastTriedStepComputation ) i. << 1372   else //  ( ! fLastTriedStepComputation ) ie. last call was to Locate
1473   {                                              1373   {
1474     if ( EnteredDaughterVolume() )               1374     if ( EnteredDaughterVolume() )
1475     {                                            1375     {
1476       G4VSolid* daughterSolid = fHistory.GetT << 1376       G4VSolid* daughterSolid =fHistory.GetTopVolume()->GetLogicalVolume()
1477                                               << 1377                                                       ->GetSolid();
1478       ExitNormal = -(daughterSolid->SurfaceNo << 1378       ExitNormal= -(daughterSolid->SurfaceNormal(fLastLocatedPointLocal));
1479       if( std::fabs(ExitNormal.mag2()-1.0 ) > << 1379       if( std::fabs(ExitNormal.mag2()-1.0 ) > CLHEP::perMillion )
1480       {                                          1380       {
1481         G4ExceptionDescription desc;             1381         G4ExceptionDescription desc;
1482         desc << " Parameters of solid: " << *    1382         desc << " Parameters of solid: " << *daughterSolid
1483              << " Point for surface = " << fL    1383              << " Point for surface = " << fLastLocatedPointLocal << std::endl;
1484         G4Exception("G4Navigator::GetLocalExi    1384         G4Exception("G4Navigator::GetLocalExitNormal()",
1485                     "GeomNav0003", FatalExcep    1385                     "GeomNav0003", FatalException, desc,
1486                     "Surface Normal returned     1386                     "Surface Normal returned by Solid is not a Unit Vector." );
1487       }                                          1387       }
1488       fCalculatedExitNormal = true;           << 1388       fCalculatedExitNormal= true;
1489       *valid = true;                             1389       *valid = true;
1490     }                                            1390     }
1491     else                                         1391     else
1492     {                                            1392     {
1493       if( fExitedMother )                        1393       if( fExitedMother )
1494       {                                          1394       {
1495         ExitNormal = fGrandMotherExitNormal;     1395         ExitNormal = fGrandMotherExitNormal;
1496         *valid = true;                           1396         *valid = true;
1497         fCalculatedExitNormal = true;         << 1397         fCalculatedExitNormal= true;
1498       }                                          1398       }
1499       else  // We are not at a boundary. Exit    1399       else  // We are not at a boundary. ExitNormal remains (0,0,0)
1500       {                                          1400       { 
1501         *valid = false;                          1401         *valid = false;
1502         fCalculatedExitNormal = false;        << 1402         fCalculatedExitNormal= false; 
1503         G4ExceptionDescription message;          1403         G4ExceptionDescription message; 
1504         message << "Function called when *NOT    1404         message << "Function called when *NOT* at a Boundary." << G4endl;
1505         message << "Exit Normal not calculate << 
1506         G4Exception("G4Navigator::GetLocalExi    1405         G4Exception("G4Navigator::GetLocalExitNormal()",
1507                     "GeomNav0003", JustWarnin    1406                     "GeomNav0003", JustWarning, message); 
1508       }                                          1407       }
1509     }                                            1408     }
1510   }                                              1409   }
1511   return ExitNormal;                             1410   return ExitNormal;
1512 }                                                1411 }
1513                                                  1412 
1514 // ******************************************    1413 // ********************************************************************
1515 // GetMotherToDaughterTransform                  1414 // GetMotherToDaughterTransform
1516 //                                               1415 //
1517 // Obtains the mother to daughter affine tran    1416 // Obtains the mother to daughter affine transformation
1518 // ******************************************    1417 // ********************************************************************
1519 //                                               1418 //
1520 G4AffineTransform                                1419 G4AffineTransform
1521 G4Navigator::GetMotherToDaughterTransform( G4 << 1420 G4Navigator::GetMotherToDaughterTransform( G4VPhysicalVolume *pEnteringPhysVol,
1522                                            G4 << 1421                                            G4int   enteringReplicaNo,
1523                                            EV    1422                                            EVolume enteringVolumeType ) 
1524 {                                                1423 {
1525   switch (enteringVolumeType)                    1424   switch (enteringVolumeType)
1526   {                                              1425   {
1527     case kNormal:  // Nothing is needed to pr    1426     case kNormal:  // Nothing is needed to prepare the transformation
1528       break;       // It is stored already in    1427       break;       // It is stored already in the physical volume (placement)
1529     case kReplica: // Sets the transform in t    1428     case kReplica: // Sets the transform in the Replica - tbc
1530       G4Exception("G4Navigator::GetMotherToDa    1429       G4Exception("G4Navigator::GetMotherToDaughterTransform()",
1531                   "GeomNav0001", FatalExcepti    1430                   "GeomNav0001", FatalException,
1532                   "Method NOT Implemented yet    1431                   "Method NOT Implemented yet for replica volumes.");
1533       break;                                     1432       break;
1534     case kParameterised:                         1433     case kParameterised:
1535       if( pEnteringPhysVol->GetRegularStructu    1434       if( pEnteringPhysVol->GetRegularStructureId() == 0 )
1536       {                                          1435       {
1537         G4VPVParameterisation *pParam =          1436         G4VPVParameterisation *pParam =
1538           pEnteringPhysVol->GetParameterisati    1437           pEnteringPhysVol->GetParameterisation();
1539         G4VSolid* pSolid =                       1438         G4VSolid* pSolid =
1540           pParam->ComputeSolid(enteringReplic    1439           pParam->ComputeSolid(enteringReplicaNo, pEnteringPhysVol);
1541         pSolid->ComputeDimensions(pParam, ent    1440         pSolid->ComputeDimensions(pParam, enteringReplicaNo, pEnteringPhysVol);
1542                                                  1441 
1543         // Sets the transform in the Paramete    1442         // Sets the transform in the Parameterisation
1544         //                                       1443         //
1545         pParam->ComputeTransformation(enterin    1444         pParam->ComputeTransformation(enteringReplicaNo, pEnteringPhysVol);
1546                                                  1445 
1547         // Set the correct solid and material    1446         // Set the correct solid and material in Logical Volume
1548         //                                       1447         //
1549         G4LogicalVolume* pLogical = pEntering    1448         G4LogicalVolume* pLogical = pEnteringPhysVol->GetLogicalVolume();
1550         pLogical->SetSolid( pSolid );            1449         pLogical->SetSolid( pSolid );
1551       }                                          1450       }
1552       break;                                     1451       break;
1553     case kExternal:                           << 
1554       // Expect that nothing is needed to pre << 
1555       // It is stored already in the physical << 
1556       break;                                  << 
1557   }                                              1452   }
1558   return G4AffineTransform(pEnteringPhysVol->    1453   return G4AffineTransform(pEnteringPhysVol->GetRotation(), 
1559                            pEnteringPhysVol->    1454                            pEnteringPhysVol->GetTranslation()).Invert(); 
1560 }                                                1455 }
1561                                                  1456 
1562                                               << 
1563 // ******************************************    1457 // ********************************************************************
1564 // GetLocalExitNormalAndCheck                    1458 // GetLocalExitNormalAndCheck
1565 //                                               1459 //
1566 // Obtains the Normal vector to a surface (in    1460 // Obtains the Normal vector to a surface (in local coordinates)
1567 // pointing out of previous volume and into c    1461 // pointing out of previous volume and into current volume, and
1568 // checks the current point against expected     1462 // checks the current point against expected 'local' value.
1569 // ******************************************    1463 // ********************************************************************
1570 //                                               1464 //
1571 G4ThreeVector                                 << 1465 G4ThreeVector G4Navigator::
1572 G4Navigator::GetLocalExitNormalAndCheck(      << 1466 GetLocalExitNormalAndCheck( 
1573 #ifdef G4DEBUG_NAVIGATION                        1467 #ifdef G4DEBUG_NAVIGATION
1574                            const G4ThreeVecto    1468                            const G4ThreeVector& ExpectedBoundaryPointGlobal,
1575 #else                                            1469 #else
1576                            const G4ThreeVecto    1470                            const G4ThreeVector&,
1577 #endif                                           1471 #endif
1578                                  G4bool* pVal << 1472                                  G4bool*        pValid)
1579 {                                                1473 {
1580 #ifdef G4DEBUG_NAVIGATION                        1474 #ifdef G4DEBUG_NAVIGATION
1581   // Check Current point against expected 'lo    1475   // Check Current point against expected 'local' value
1582   //                                             1476   //
1583   if ( fLastTriedStepComputation )               1477   if ( fLastTriedStepComputation ) 
1584   {                                              1478   {
1585     G4ThreeVector ExpectedBoundaryPointLocal;    1479     G4ThreeVector ExpectedBoundaryPointLocal;
1586                                                  1480 
1587     const G4AffineTransform& GlobalToLocal =  << 1481     const G4AffineTransform& GlobalToLocal= GetGlobalToLocalTransform(); 
1588     ExpectedBoundaryPointLocal =                 1482     ExpectedBoundaryPointLocal =
1589       GlobalToLocal.TransformPoint( ExpectedB    1483       GlobalToLocal.TransformPoint( ExpectedBoundaryPointGlobal ); 
1590                                                  1484 
1591     // Add here:  Comparison against expected    1485     // Add here:  Comparison against expected position,
1592     //            i.e. the endpoint of Comput    1486     //            i.e. the endpoint of ComputeStep
1593   }                                              1487   }
1594 #endif                                           1488 #endif
1595                                                  1489   
1596   return GetLocalExitNormal( pValid );        << 1490   return GetLocalExitNormal( pValid); 
1597 }                                                1491 }
1598                                                  1492 
1599 // ******************************************    1493 // ********************************************************************
1600 // GetGlobalExitNormal                           1494 // GetGlobalExitNormal
1601 //                                               1495 //
1602 // Obtains the Normal vector to a surface (in    1496 // Obtains the Normal vector to a surface (in global coordinates)
1603 // pointing out of previous volume and into c    1497 // pointing out of previous volume and into current volume
1604 // ******************************************    1498 // ********************************************************************
1605 //                                               1499 //
1606 G4ThreeVector                                    1500 G4ThreeVector 
1607 G4Navigator::GetGlobalExitNormal(const G4Thre    1501 G4Navigator::GetGlobalExitNormal(const G4ThreeVector& IntersectPointGlobal,
1608                                        G4bool    1502                                        G4bool*        pNormalCalculated)
1609 {                                                1503 {
1610   G4bool         validNormal;                    1504   G4bool         validNormal;
1611   G4ThreeVector  localNormal, globalNormal;      1505   G4ThreeVector  localNormal, globalNormal;
1612                                               << 1506 
1613   G4bool usingStored = fCalculatedExitNormal  << 1507   if( fLastTriedStepComputation && fExiting )  
1614        ( fLastTriedStepComputation && fExitin << 
1615        ||                                     << 
1616        ( !fLastTriedStepComputation           << 
1617           && (IntersectPointGlobal-fStepEndPo << 
1618            // Calculated it 'just' before & t << 
1619            // but it did not move position    << 
1620                                               << 
1621   if( usingStored )                           << 
1622   {                                              1508   {
1623     // This was computed in last call to Comp << 1509     // This was computed in ComputeStep -- and only on arrival at boundary
1624     // and only if it arrived at boundary     << 
1625     //                                           1510     //
1626     globalNormal = fExitNormalGlobalFrame;       1511     globalNormal = fExitNormalGlobalFrame; 
1627     G4double  normMag2 = globalNormal.mag2(); << 1512     *pNormalCalculated = true; // ComputeStep always computes it if Exiting
1628     if( std::fabs ( normMag2 - 1.0 ) < perTho << 1513                                // (fExiting==true)
1629     {                                         << 
1630        *pNormalCalculated = true; // ComputeS << 
1631                                   // (fExitin << 
1632     }                                         << 
1633     else                                      << 
1634     {                                         << 
1635        G4ExceptionDescription message;        << 
1636        message.precision(10);                 << 
1637        message << " WARNING> Expected normal- << 
1638                << " i.e. a unit vector!" << G << 
1639                << "  - but |normal|   = "  << << 
1640                << "  - and |normal|^2 = "  << << 
1641                << " which differs from 1.0 by << 
1642                << "   n = " << fExitNormalGlo << 
1643                << " Global point: " << Inters << 
1644                << " Volume: " << fHistory.Get << 
1645 #ifdef G4VERBOSE                              << 
1646        G4LogicalVolume* candLog = fHistory.Ge << 
1647        if ( candLog != nullptr )              << 
1648        {                                      << 
1649          message << " Solid: " << candLog->Ge << 
1650                  << ", Type: " << candLog->Ge << 
1651                  << *candLog->GetSolid() << G << 
1652        }                                      << 
1653 #endif                                        << 
1654        message << "========================== << 
1655                << G4endl;                     << 
1656        G4int oldVerbose = fVerbose;           << 
1657        fVerbose = 4;                          << 
1658        message << "   State of Navigator: " < << 
1659        message << *this << G4endl;            << 
1660        fVerbose = oldVerbose;                 << 
1661        message << "========================== << 
1662                << G4endl;                     << 
1663                                               << 
1664        G4Exception("G4Navigator::GetGlobalExi << 
1665                    "GeomNav0003",JustWarning, << 
1666               "Value obtained from stored glo << 
1667                                               << 
1668        // (Re)Compute it now -- as either it  << 
1669        //                                     << 
1670        localNormal = GetLocalExitNormalAndChe << 
1671                                               << 
1672        *pNormalCalculated = fCalculatedExitNo << 
1673        globalNormal = fHistory.GetTopTransfor << 
1674                      .InverseTransformAxis(lo << 
1675     }                                         << 
1676   }                                              1514   }
1677   else                                           1515   else
1678   {                                              1516   {
1679     localNormal = GetLocalExitNormalAndCheck(    1517     localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,&validNormal);
1680     *pNormalCalculated = fCalculatedExitNorma    1518     *pNormalCalculated = fCalculatedExitNormal;
1681                                                  1519 
1682 #ifdef G4DEBUG_NAVIGATION                        1520 #ifdef G4DEBUG_NAVIGATION
1683     usingStored = false;                      << 1521     if( (!validNormal) && !fCalculatedExitNormal)
1684                                               << 
1685     if( (!validNormal) && !fCalculatedExitNor << 
1686     {                                            1522     {
1687       G4ExceptionDescription edN;                1523       G4ExceptionDescription edN;
1688       edN << "  Calculated = " << fCalculated    1524       edN << "  Calculated = " << fCalculatedExitNormal << G4endl;
1689       edN << "   Entering= "  << fEntering <<    1525       edN << "   Entering= "  << fEntering << G4endl;
1690       G4int oldVerbose = this->GetVerboseLeve << 1526       G4int oldVerbose= this->GetVerboseLevel();
1691       this->SetVerboseLevel(4);                  1527       this->SetVerboseLevel(4);
1692       edN << "   State of Navigator: " << G4e    1528       edN << "   State of Navigator: " << G4endl;
1693       edN << *this << G4endl;                    1529       edN << *this << G4endl;
1694       this->SetVerboseLevel( oldVerbose );       1530       this->SetVerboseLevel( oldVerbose );
1695                                                  1531        
1696       G4Exception("G4Navigator::GetGlobalExit    1532       G4Exception("G4Navigator::GetGlobalExitNormal()",
1697                   "GeomNav0003", JustWarning,    1533                   "GeomNav0003", JustWarning, edN,
1698                   "LocalExitNormalAndCheck()     1534                   "LocalExitNormalAndCheck() did not calculate Normal.");
1699      }                                           1535      }
1700 #endif                                           1536 #endif
1701                                                  1537      
1702      G4double localMag2 = localNormal.mag2(); << 1538      G4double localMag2= localNormal.mag2();
1703      if( validNormal && (std::fabs(localMag2- << 1539      if( validNormal && (std::fabs(localMag2-1.0)) > CLHEP::perMillion )
1704      {                                           1540      {
1705        G4ExceptionDescription edN;               1541        G4ExceptionDescription edN;
1706        edN.precision(10);                     << 1542 
1707        edN << "G4Navigator::GetGlobalExitNorm    1543        edN << "G4Navigator::GetGlobalExitNormal: "
1708            << "  Using Local Normal - from ca    1544            << "  Using Local Normal - from call to GetLocalExitNormalAndCheck. "
1709            << G4endl                             1545            << G4endl
1710            << "  Local  Exit Normal : " << "  << 1546            << "  Local  Exit Normal = " << localNormal  << " || = "
1711            << " vec = " << localNormal << G4e << 1547            << std::sqrt(localMag2) << G4endl
1712            << "  Global Exit Normal : " << "  << 1548            << "  Global Exit Normal = " << globalNormal << " || = "
1713            << " vec = " << globalNormal << G4 << 1549            << globalNormal.mag() << G4endl;
1714            << "  Global point: " << Intersect << 1550        edN << "  Calculated It      = " << fCalculatedExitNormal << G4endl;
1715        edN << "  Calculated It      = " << fC << 1551 
1716            << "  Volume: " << fHistory.GetTop << 
1717 #ifdef G4VERBOSE                              << 
1718        G4LogicalVolume* candLog = fHistory.Ge << 
1719        if ( candLog != nullptr )              << 
1720        {                                      << 
1721          edN << "  Solid: " << candLog->GetSo << 
1722              << ", Type: " << candLog->GetSol << 
1723              << *candLog->GetSolid();         << 
1724        }                                      << 
1725 #endif                                        << 
1726        G4Exception("G4Navigator::GetGlobalExi    1552        G4Exception("G4Navigator::GetGlobalExitNormal()",
1727                    "GeomNav0003",JustWarning,    1553                    "GeomNav0003",JustWarning, edN,
1728                    "Value obtained from new l    1554                    "Value obtained from new local *solid* is incorrect.");
1729        localNormal = localNormal.unit(); // S    1555        localNormal = localNormal.unit(); // Should we correct it ??
1730      }                                           1556      }
1731      globalNormal = fHistory.GetTopTransform( << 1557      G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1732                    .InverseTransformAxis(loca << 1558      globalNormal = localToGlobal.TransformAxis( localNormal );
1733   }                                              1559   }
1734                                                  1560 
1735 #ifdef G4DEBUG_NAVIGATION                        1561 #ifdef G4DEBUG_NAVIGATION
1736   if( usingStored )                           << 1562   // Temporary extra checks
                                                   >> 1563   if( fLastTriedStepComputation && fExiting)
1737   {                                              1564   {
1738     G4ThreeVector globalNormAgn;              << 1565     localNormal = GetLocalExitNormalAndCheck( IntersectPointGlobal, &validNormal);
                                                   >> 1566     *pNormalCalculated = fCalculatedExitNormal;
1739                                                  1567 
1740     localNormal = GetLocalExitNormalAndCheck( << 1568     G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1741                                               << 1569     globalNormal = localToGlobal.TransformAxis( localNormal );
1742     globalNormAgn = fHistory.GetTopTransform( << 
1743                    .InverseTransformAxis(loca << 
1744                                                  1570     
1745     // Check the value computed against fExit    1571     // Check the value computed against fExitNormalGlobalFrame
1746     G4ThreeVector diffNorm = globalNormAgn -  << 1572     G4ThreeVector diffNorm = globalNormal - fExitNormalGlobalFrame;
1747     if( diffNorm.mag2() > kToleranceNormalChe << 1573     if( diffNorm.mag2() > perMillion*CLHEP::perMillion)
1748     {                                            1574     {
1749       G4ExceptionDescription edDfn;              1575       G4ExceptionDescription edDfn;
1750       edDfn << "Found difference in normals i    1576       edDfn << "Found difference in normals in case of exiting mother "
1751             << "- when Get is called after Co    1577             << "- when Get is called after ComputingStep " << G4endl;
1752       edDfn << "  Magnitude of diff =      "     1578       edDfn << "  Magnitude of diff =      " << diffNorm.mag() << G4endl;
1753       edDfn << "  Normal stored (Global)         1579       edDfn << "  Normal stored (Global)     = " << fExitNormalGlobalFrame
1754             << G4endl;                           1580             << G4endl;
1755       edDfn << "  Global Computed from Local  << 1581       edDfn << "  Global Computed from Local = " << globalNormal << G4endl;
1756       G4Exception("G4Navigator::GetGlobalExit    1582       G4Exception("G4Navigator::GetGlobalExitNormal()", "GeomNav0003",
1757                   JustWarning, edDfn);           1583                   JustWarning, edDfn);
1758     }                                            1584     }
1759   }                                              1585   }
1760 #endif                                           1586 #endif
1761                                               << 1587    
1762   // Synchronise stored global exit normal as << 
1763   //                                          << 
1764   fExitNormalGlobalFrame = globalNormal;      << 
1765                                               << 
1766   return globalNormal;                           1588   return globalNormal;
1767 }                                                1589 }
1768                                                  1590 
                                                   >> 1591 // To make the new Voxel Safety the default, uncomment the next line
                                                   >> 1592 // #define  G4NEW_SAFETY  1
                                                   >> 1593 
1769 // ******************************************    1594 // ********************************************************************
1770 // ComputeSafety                                 1595 // ComputeSafety
1771 //                                               1596 //
1772 // It assumes that it will be                    1597 // It assumes that it will be 
1773 //  i) called at the Point in the same volume    1598 //  i) called at the Point in the same volume as the EndPoint of the
1774 //     ComputeStep.                              1599 //     ComputeStep.
1775 // ii) after (or at the end of) ComputeStep O    1600 // ii) after (or at the end of) ComputeStep OR after the relocation.
1776 // ******************************************    1601 // ********************************************************************
1777 //                                               1602 //
1778 G4double G4Navigator::ComputeSafety( const G4 << 1603 G4double G4Navigator::ComputeSafety( const G4ThreeVector &pGlobalpoint,
1779                                      const G4    1604                                      const G4double pMaxLength,
1780                                      const G4 << 1605                                      const G4bool keepState)
1781 {                                                1606 {
1782   G4VPhysicalVolume  *motherPhysical = fHisto << 1607   G4double newSafety = 0.0;
1783   G4double safety = 0.0;                      << 1608 
                                                   >> 1609 #ifdef G4DEBUG_NAVIGATION
                                                   >> 1610   G4int oldcoutPrec = G4cout.precision(8);
                                                   >> 1611   if( fVerbose > 0 )
                                                   >> 1612   {
                                                   >> 1613     G4cout << "*** G4Navigator::ComputeSafety: ***" << G4endl
                                                   >> 1614            << "    Called at point: " << pGlobalpoint << G4endl;
                                                   >> 1615 
                                                   >> 1616     G4VPhysicalVolume  *motherPhysical = fHistory.GetTopVolume();
                                                   >> 1617     G4cout << "    Volume = " << motherPhysical->GetName() 
                                                   >> 1618            << " - Maximum length = " << pMaxLength << G4endl; 
                                                   >> 1619     if( fVerbose >= 4 )
                                                   >> 1620     {
                                                   >> 1621        G4cout << "    ----- Upon entering Compute Safety:" << G4endl;
                                                   >> 1622        PrintState();
                                                   >> 1623     }
                                                   >> 1624   }
                                                   >> 1625 #endif
                                                   >> 1626 
                                                   >> 1627   if (keepState)  { SetSavedState(); }
1784                                                  1628 
1785   G4double distEndpointSq = (pGlobalpoint-fSt    1629   G4double distEndpointSq = (pGlobalpoint-fStepEndPoint).mag2(); 
1786   G4bool stayedOnEndpoint = distEndpointSq <  << 1630   G4bool   stayedOnEndpoint  = distEndpointSq < kCarTolerance*kCarTolerance; 
1787   G4bool endpointOnSurface = fEnteredDaughter << 1631   G4bool   endpointOnSurface = fEnteredDaughter || fExitedMother;
1788                                                  1632 
1789   G4bool onSurface = endpointOnSurface && sta << 1633   if( !(endpointOnSurface && stayedOnEndpoint) )
1790   if( ! onSurface )                           << 
1791   {                                              1634   {
1792     safety= fpSafetyCalculator->SafetyInCurre << 1635     // Pseudo-relocate to this point (updates voxel information only)
1793     // offload to G4SafetyCalculator - avoids << 
1794                                               << 
1795     // Remember last safety origin & value    << 
1796     //                                           1636     //
1797     fPreviousSftOrigin = pGlobalpoint;        << 1637     LocateGlobalPointWithinVolume( pGlobalpoint ); 
1798     fPreviousSafety =    safety;              << 1638       // --->> DANGER: Side effects on sub-navigator voxel information <<---
1799     // We overwrite the Safety 'sphere' - kee << 1639       //       Could be replaced again by 'granular' calls to sub-navigator
                                                   >> 1640       //       locates (similar side-effects, but faster.  
                                                   >> 1641       //       Solutions:
                                                   >> 1642       //        1) Re-locate (to where?)
                                                   >> 1643       //        2) Insure that the methods using (G4ComputeStep?)
                                                   >> 1644       //           does a relocation (if information is disturbed only ?)
                                                   >> 1645 
                                                   >> 1646 #ifdef G4DEBUG_NAVIGATION
                                                   >> 1647     if( fVerbose >= 2 )
                                                   >> 1648     {
                                                   >> 1649       G4cout << "  G4Navigator::ComputeSafety() relocates-in-volume to point: "
                                                   >> 1650              << pGlobalpoint << G4endl;
                                                   >> 1651     }
                                                   >> 1652 #endif 
                                                   >> 1653     G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
                                                   >> 1654     G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
                                                   >> 1655     G4SmartVoxelHeader* pVoxelHeader = motherLogical->GetVoxelHeader();
                                                   >> 1656     G4ThreeVector localPoint = ComputeLocalPoint(pGlobalpoint);
                                                   >> 1657 
                                                   >> 1658     if ( fHistory.GetTopVolumeType()!=kReplica )
                                                   >> 1659     {
                                                   >> 1660       switch(CharacteriseDaughters(motherLogical))
                                                   >> 1661       {
                                                   >> 1662         case kNormal:
                                                   >> 1663           if ( pVoxelHeader )
                                                   >> 1664           {
                                                   >> 1665 #ifdef G4NEW_SAFETY
                                                   >> 1666             static G4VoxelSafety sfVoxelSafety;
                                                   >> 1667             G4double safetyTwo = sfVoxelSafety.ComputeSafety(localPoint,
                                                   >> 1668                                            *motherPhysical, pMaxLength);
                                                   >> 1669 #ifdef G4DEBUG_NAVIGATION
                                                   >> 1670             G4double safetyNormal=
                                                   >> 1671                fnormalNav.ComputeSafety(localPoint, fHistory, pMaxLength);
                                                   >> 1672 
                                                   >> 1673             G4double diffSafety= (safetyTwo - safetyNormal);
                                                   >> 1674             if( std::fabs(diffSafety) > CLHEP::perMillion
                                                   >> 1675                                       * std::fabs(safetyNormal) )
                                                   >> 1676             {
                                                   >> 1677               G4ExceptionDescription exd;
                                                   >> 1678               exd << " ERROR in G4Navigator::ComputeStep " << G4endl;
                                                   >> 1679               exd << "  Error>  DIFFERENCE in Safety from G4VoxelSafety "
                                                   >> 1680                   << " - compared to value from Normal.  Diff = " << diffSafety << G4endl;
                                                   >> 1681               exd << "  New Voxel Safety= " << safetyTwo
                                                   >> 1682                   << "  Value from Normal= " << safetyNormal << G4endl;
                                                   >> 1683               exd << "  Location:  Local coordinates = " << localPoint
                                                   >> 1684                   << "  mother Volume= " << *motherPhysical->GetName()
                                                   >> 1685                   << "  Copy# = " << motherPhysical->GetCopyNo() << G4endl;
                                                   >> 1686               exd << "          : Global coordinates = " << pGlobalpoint
                                                   >> 1687                   << G4endl;
                                                   >> 1688               G4Exception("G4Navigator::ComputeSafety()",
                                                   >> 1689                           "GeomNav0003", JustWarning, exd);
                                                   >> 1690             }
                                                   >> 1691             G4double safetyOldVoxel;
                                                   >> 1692             safetyOldVoxel =
                                                   >> 1693               fvoxelNav.ComputeSafety(localPoint,fHistory,pMaxLength);
                                                   >> 1694 
                                                   >> 1695             G4double diffBetterToApprox= safetyTwo - safetyOldVoxel;
                                                   >> 1696             if( diffBetterToApprox < 0.0 )
                                                   >> 1697             {
                                                   >> 1698               G4ExceptionDescription exd;
                                                   >> 1699               exd << "SMALLER Safety from call G4VoxelSafety compared to value "
                                                   >> 1700                   << " from Normal.  Diff = " << diffSafety << G4endl;
                                                   >> 1701               exd << " New Voxel Safety= " << safetyTwo
                                                   >> 1702                   << "  Old value from Normal= " << newSafety << G4endl;
                                                   >> 1703               exd << "  Location:  Local coordinates = " << localPoint
                                                   >> 1704                   << "  mother Volume= " << *motherPhysical->GetName()
                                                   >> 1705                   << "  Copy# = " << motherPhysical->GetCopyNo() << G4endl;
                                                   >> 1706               exd << "          : Global coordinates = " << pGlobalpoint
                                                   >> 1707                   << G4endl;
                                                   >> 1708               G4Exception("G4Navigator::ComputeSafety()",
                                                   >> 1709                           "GeomNav0003", JustWarning, exd);
                                                   >> 1710             }
                                                   >> 1711 #endif
                                                   >> 1712 
                                                   >> 1713             // newSafety= safetyOldVoxel;
                                                   >> 1714             newSafety= safetyTwo;   // Faster and best available
                                                   >> 1715 #else
                                                   >> 1716             G4double safetyOldVoxel;
                                                   >> 1717             safetyOldVoxel =
                                                   >> 1718               fvoxelNav.ComputeSafety(localPoint,fHistory,pMaxLength);
                                                   >> 1719             newSafety= safetyOldVoxel;
                                                   >> 1720 #endif
                                                   >> 1721           }
                                                   >> 1722           else
                                                   >> 1723           {
                                                   >> 1724             newSafety=fnormalNav.ComputeSafety(localPoint,fHistory,pMaxLength);
                                                   >> 1725           }
                                                   >> 1726           break;
                                                   >> 1727         case kParameterised:
                                                   >> 1728           if( GetDaughtersRegularStructureId(motherLogical) != 1 )
                                                   >> 1729           {
                                                   >> 1730             newSafety=fparamNav.ComputeSafety(localPoint,fHistory,pMaxLength);
                                                   >> 1731           }
                                                   >> 1732           else  // Regular structure
                                                   >> 1733           {
                                                   >> 1734             newSafety=fregularNav.ComputeSafety(localPoint,fHistory,pMaxLength);
                                                   >> 1735           }
                                                   >> 1736           break;
                                                   >> 1737         case kReplica:
                                                   >> 1738           G4Exception("G4Navigator::ComputeSafety()", "GeomNav0001",
                                                   >> 1739                       FatalException, "Not applicable for replicated volumes.");
                                                   >> 1740           break;
                                                   >> 1741       }
                                                   >> 1742     }
                                                   >> 1743     else
                                                   >> 1744     {
                                                   >> 1745       newSafety = freplicaNav.ComputeSafety(pGlobalpoint, localPoint,
                                                   >> 1746                                             fHistory, pMaxLength);
                                                   >> 1747     }
                                                   >> 1748   }
                                                   >> 1749   else // if( endpointOnSurface && stayedOnEndpoint )
                                                   >> 1750   {
                                                   >> 1751 #ifdef G4DEBUG_NAVIGATION
                                                   >> 1752     if( fVerbose >= 2 )
                                                   >> 1753     {
                                                   >> 1754       G4cout << "    G4Navigator::ComputeSafety() finds that point - " 
                                                   >> 1755              << pGlobalpoint << " - is on surface " << G4endl; 
                                                   >> 1756       if( fEnteredDaughter ) { G4cout << "   entered new daughter volume"; }
                                                   >> 1757       if( fExitedMother )    { G4cout << "   and exited previous volume."; }
                                                   >> 1758       G4cout << G4endl;
                                                   >> 1759       G4cout << " EndPoint was = " << fStepEndPoint << G4endl;
                                                   >> 1760     } 
                                                   >> 1761 #endif
                                                   >> 1762     newSafety = 0.0; 
1800   }                                              1763   }
1801                                                  1764 
1802   return safety;                              << 1765   // Remember last safety origin & value
                                                   >> 1766   //
                                                   >> 1767   fPreviousSftOrigin = pGlobalpoint;
                                                   >> 1768   fPreviousSafety = newSafety; 
                                                   >> 1769 
                                                   >> 1770   if (keepState)  { RestoreSavedState(); }
                                                   >> 1771 
                                                   >> 1772 #ifdef G4DEBUG_NAVIGATION
                                                   >> 1773   if( fVerbose > 1 )
                                                   >> 1774   {
                                                   >> 1775     G4cout << "   ---- Exiting ComputeSafety  " << G4endl;
                                                   >> 1776     if( fVerbose > 2 )  { PrintState(); }
                                                   >> 1777     G4cout << "    Returned value of Safety = " << newSafety << G4endl;
                                                   >> 1778   }
                                                   >> 1779   G4cout.precision(oldcoutPrec);
                                                   >> 1780 #endif
                                                   >> 1781 
                                                   >> 1782   return newSafety;
1803 }                                                1783 }
1804                                                  1784 
1805 // ******************************************    1785 // ********************************************************************
1806 // CreateTouchableHistoryHandle                  1786 // CreateTouchableHistoryHandle
1807 // ******************************************    1787 // ********************************************************************
1808 //                                               1788 //
1809 G4TouchableHandle G4Navigator::CreateTouchabl << 1789 G4TouchableHistoryHandle G4Navigator::CreateTouchableHistoryHandle() const
1810 {                                                1790 {
1811   return G4TouchableHandle( CreateTouchableHi << 1791   return G4TouchableHistoryHandle( CreateTouchableHistory() );
1812 }                                                1792 }
1813                                                  1793 
1814 // ******************************************    1794 // ********************************************************************
1815 // PrintState                                    1795 // PrintState
1816 // ******************************************    1796 // ********************************************************************
1817 //                                               1797 //
1818 void  G4Navigator::PrintState() const            1798 void  G4Navigator::PrintState() const
1819 {                                                1799 {
1820   G4long oldcoutPrec = G4cout.precision(4);   << 1800   G4int oldcoutPrec = G4cout.precision(4);
1821   if( fVerbose >= 4 )                         << 1801   if( fVerbose == 4 )
1822   {                                              1802   {
1823     G4cout << "The current state of G4Navigat    1803     G4cout << "The current state of G4Navigator is: " << G4endl;
1824     G4cout << "  ValidExitNormal= " << fValid << 1804     G4cout << "  ValidExitNormal= " << fValidExitNormal << G4endl
1825            << "  ExitNormal     = " << fExitN << 1805            << "  ExitNormal     = " << fExitNormal      << G4endl
1826            << "  Exiting        = " << fExiti << 1806            << "  Exiting        = " << fExiting         << G4endl
1827            << "  Entering       = " << fEnter << 1807            << "  Entering       = " << fEntering        << G4endl
1828            << "  BlockedPhysicalVolume= " ;      1808            << "  BlockedPhysicalVolume= " ;
1829     if (fBlockedPhysicalVolume==nullptr)      << 1809     if (fBlockedPhysicalVolume==0)
1830     {                                         << 
1831       G4cout << "None";                          1810       G4cout << "None";
1832     }                                         << 
1833     else                                         1811     else
1834     {                                         << 
1835       G4cout << fBlockedPhysicalVolume->GetNa    1812       G4cout << fBlockedPhysicalVolume->GetName();
1836     }                                         << 
1837     G4cout << G4endl                             1813     G4cout << G4endl
1838            << "  BlockedReplicaNo     = " <<  << 1814            << "  BlockedReplicaNo     = " <<  fBlockedReplicaNo       << G4endl
1839            << "  LastStepWasZero      = " <<  << 1815            << "  LastStepWasZero      = " <<   fLastStepWasZero       << G4endl
1840            << G4endl;                            1816            << G4endl;   
1841   }                                              1817   }
1842   if( ( 1 < fVerbose) && (fVerbose < 4) )        1818   if( ( 1 < fVerbose) && (fVerbose < 4) )
1843   {                                              1819   {
1844     G4cout << G4endl; // Make sure to line up    1820     G4cout << G4endl; // Make sure to line up
1845     G4cout << std::setw(30) << " ExitNormal "    1821     G4cout << std::setw(30) << " ExitNormal "  << " "
1846            << std::setw( 5) << " Valid "         1822            << std::setw( 5) << " Valid "       << " "     
1847            << std::setw( 9) << " Exiting "       1823            << std::setw( 9) << " Exiting "     << " "      
1848            << std::setw( 9) << " Entering"       1824            << std::setw( 9) << " Entering"     << " " 
1849            << std::setw(15) << " Blocked:Volu    1825            << std::setw(15) << " Blocked:Volume "  << " "   
1850            << std::setw( 9) << " ReplicaNo"      1826            << std::setw( 9) << " ReplicaNo"        << " "  
1851            << std::setw( 8) << " LastStepZero    1827            << std::setw( 8) << " LastStepZero  "   << " "   
1852            << G4endl;                            1828            << G4endl;   
1853     G4cout << "( " << std::setw(7) << fExitNo    1829     G4cout << "( " << std::setw(7) << fExitNormal.x() 
1854            << ", " << std::setw(7) << fExitNo    1830            << ", " << std::setw(7) << fExitNormal.y()
1855            << ", " << std::setw(7) << fExitNo    1831            << ", " << std::setw(7) << fExitNormal.z() << " ) "
1856            << std::setw( 5)  << fValidExitNor    1832            << std::setw( 5)  << fValidExitNormal  << " "   
1857            << std::setw( 9)  << fExiting         1833            << std::setw( 9)  << fExiting          << " "
1858            << std::setw( 9)  << fEntering        1834            << std::setw( 9)  << fEntering         << " ";
1859     if ( fBlockedPhysicalVolume == nullptr )  << 1835     if ( fBlockedPhysicalVolume==0 )
1860     { G4cout << std::setw(15) << "None"; }    << 1836       G4cout << std::setw(15) << "None";
1861     else                                         1837     else
1862     { G4cout << std::setw(15)<< fBlockedPhysi << 1838       G4cout << std::setw(15)<< fBlockedPhysicalVolume->GetName();
1863     G4cout << std::setw( 9)  << fBlockedRepli << 1839       G4cout << std::setw( 9)  << fBlockedReplicaNo  << " "
1864            << std::setw( 8)  << fLastStepWasZ << 1840              << std::setw( 8)  << fLastStepWasZero   << " "
1865            << G4endl;                         << 1841              << G4endl;   
1866   }                                              1842   }
1867   if( fVerbose > 2 )                             1843   if( fVerbose > 2 ) 
1868   {                                              1844   {
1869     G4cout.precision(8);                         1845     G4cout.precision(8);
1870     G4cout << " Current Localpoint = " << fLa    1846     G4cout << " Current Localpoint = " << fLastLocatedPointLocal << G4endl;
1871     G4cout << " PreviousSftOrigin  = " << fPr    1847     G4cout << " PreviousSftOrigin  = " << fPreviousSftOrigin << G4endl;
1872     G4cout << " PreviousSafety     = " << fPr    1848     G4cout << " PreviousSafety     = " << fPreviousSafety << G4endl; 
1873   }                                              1849   }
1874   G4cout.precision(oldcoutPrec);                 1850   G4cout.precision(oldcoutPrec);
1875 }                                                1851 }
1876                                                  1852 
1877 // ******************************************    1853 // ********************************************************************
1878 // ComputeStepLog                                1854 // ComputeStepLog
1879 // ******************************************    1855 // ********************************************************************
1880 //                                               1856 //
1881 void G4Navigator::ComputeStepLog(const G4Thre    1857 void G4Navigator::ComputeStepLog(const G4ThreeVector& pGlobalpoint,
1882                                        G4doub    1858                                        G4double moveLenSq) const
1883 {                                                1859 {
1884   //  The following checks only make sense if    1860   //  The following checks only make sense if the move is larger
1885   //  than the tolerance.                        1861   //  than the tolerance.
1886                                                  1862 
1887   const G4double fAccuracyForWarning   = kCar << 1863   static const G4double fAccuracyForWarning   = kCarTolerance,
1888                  fAccuracyForException = 1000 << 1864                         fAccuracyForException = 1000*kCarTolerance;
1889                                                  1865 
1890   G4ThreeVector OriginalGlobalpoint = fHistor << 1866   G4ThreeVector OriginalGlobalpoint = fHistory.GetTopTransform().Inverse().
1891                                InverseTransfo << 1867                                       TransformPoint(fLastLocatedPointLocal); 
1892                                                  1868 
1893   G4double shiftOriginSafSq = (fPreviousSftOr    1869   G4double shiftOriginSafSq = (fPreviousSftOrigin-pGlobalpoint).mag2();
1894                                                  1870 
1895   // Check that the starting point of this st    1871   // Check that the starting point of this step is 
1896   // within the isotropic safety sphere of th    1872   // within the isotropic safety sphere of the last point
1897   // to a accuracy/precision  given by fAccur    1873   // to a accuracy/precision  given by fAccuracyForWarning.
1898   //   If so give warning.                       1874   //   If so give warning.
1899   //   If it fails by more than fAccuracyForE    1875   //   If it fails by more than fAccuracyForException exit with error.
1900   //                                             1876   //
1901   if( shiftOriginSafSq >= sqr(fPreviousSafety    1877   if( shiftOriginSafSq >= sqr(fPreviousSafety) )
1902   {                                              1878   {
1903     G4double shiftOrigin = std::sqrt(shiftOri    1879     G4double shiftOrigin = std::sqrt(shiftOriginSafSq);
1904     G4double diffShiftSaf = shiftOrigin - fPr    1880     G4double diffShiftSaf = shiftOrigin - fPreviousSafety;
1905                                                  1881 
1906     if( diffShiftSaf > fAccuracyForWarning )     1882     if( diffShiftSaf > fAccuracyForWarning )
1907     {                                            1883     {
1908       G4long oldcoutPrec = G4cout.precision(8 << 1884       G4int oldcoutPrec= G4cout.precision(8);
1909       G4long oldcerrPrec = G4cerr.precision(1 << 1885       G4int oldcerrPrec= G4cerr.precision(10);
1910       std::ostringstream message, suggestion;    1886       std::ostringstream message, suggestion;
1911       message << "Accuracy error or slightly     1887       message << "Accuracy error or slightly inaccurate position shift."
1912               << G4endl                          1888               << G4endl
1913               << "     The Step's starting po    1889               << "     The Step's starting point has moved " 
1914               << std::sqrt(moveLenSq)/mm << "    1890               << std::sqrt(moveLenSq)/mm << " mm " << G4endl
1915               << "     since the last call to    1891               << "     since the last call to a Locate method." << G4endl
1916               << "     This has resulted in m    1892               << "     This has resulted in moving " 
1917               << shiftOrigin/mm << " mm "        1893               << shiftOrigin/mm << " mm " 
1918               << " from the last point at whi    1894               << " from the last point at which the safety " 
1919               << "     was calculated " << G4    1895               << "     was calculated " << G4endl
1920               << "     which is more than the    1896               << "     which is more than the computed safety= " 
1921               << fPreviousSafety/mm << " mm      1897               << fPreviousSafety/mm << " mm  at that point." << G4endl
1922               << "     This difference is "      1898               << "     This difference is " 
1923               << diffShiftSaf/mm << " mm." <<    1899               << diffShiftSaf/mm << " mm." << G4endl
1924               << "     The tolerated accuracy    1900               << "     The tolerated accuracy is "
1925               << fAccuracyForException/mm <<     1901               << fAccuracyForException/mm << " mm.";
1926                                                  1902 
1927       suggestion << " ";                         1903       suggestion << " ";
1928       static G4ThreadLocal G4int warnNow = 0; << 1904       static G4int warnNow = 0;
1929       if( ((++warnNow % 100) == 1) )             1905       if( ((++warnNow % 100) == 1) )
1930       {                                          1906       {
1931         message << G4endl                        1907         message << G4endl
1932                << "  This problem can be due     1908                << "  This problem can be due to either " << G4endl
1933                << "    - a process that has p    1909                << "    - a process that has proposed a displacement"
1934                << " larger than the current s    1910                << " larger than the current safety , or" << G4endl
1935                << "    - inaccuracy in the co    1911                << "    - inaccuracy in the computation of the safety";
1936         suggestion << "We suggest that you "     1912         suggestion << "We suggest that you " << G4endl
1937                    << "   - find i) what part    1913                    << "   - find i) what particle is being tracked, and "
1938                    << " ii) through what part    1914                    << " ii) through what part of your geometry " << G4endl
1939                    << "      for example by r    1915                    << "      for example by re-running this event with "
1940                    << G4endl                     1916                    << G4endl
1941                    << "         /tracking/ver    1917                    << "         /tracking/verbose 1 "  << G4endl
1942                    << "    - check which proc    1918                    << "    - check which processes you declare for"
1943                    << " this particle (and lo    1919                    << " this particle (and look at non-standard ones)"
1944                    << G4endl                     1920                    << G4endl
1945                    << "   - in case, create a    1921                    << "   - in case, create a detailed logfile"
1946                    << " of this event using:"    1922                    << " of this event using:" << G4endl
1947                    << "         /tracking/ver    1923                    << "         /tracking/verbose 6 ";
1948       }                                          1924       }
1949       G4Exception("G4Navigator::ComputeStep()    1925       G4Exception("G4Navigator::ComputeStep()",
1950                   "GeomNav1002", JustWarning,    1926                   "GeomNav1002", JustWarning,
1951                   message, G4String(suggestio    1927                   message, G4String(suggestion.str()));
1952       G4cout.precision(oldcoutPrec);             1928       G4cout.precision(oldcoutPrec);
1953       G4cerr.precision(oldcerrPrec);             1929       G4cerr.precision(oldcerrPrec);
1954     }                                            1930     }
1955 #ifdef G4DEBUG_NAVIGATION                        1931 #ifdef G4DEBUG_NAVIGATION
1956     else                                         1932     else
1957     {                                            1933     {
1958       G4cerr << "WARNING - G4Navigator::Compu    1934       G4cerr << "WARNING - G4Navigator::ComputeStep()" << G4endl
1959              << "          The Step's startin    1935              << "          The Step's starting point has moved "
1960              << std::sqrt(moveLenSq) << "," <    1936              << std::sqrt(moveLenSq) << "," << G4endl
1961              << "          which has taken it    1937              << "          which has taken it to the limit of"
1962              << " the current safety. " << G4    1938              << " the current safety. " << G4endl;
1963     }                                            1939     }
1964 #endif                                           1940 #endif
1965   }                                              1941   }
1966   G4double safetyPlus = fPreviousSafety + fAc    1942   G4double safetyPlus = fPreviousSafety + fAccuracyForException;
1967   if ( shiftOriginSafSq > sqr(safetyPlus) )      1943   if ( shiftOriginSafSq > sqr(safetyPlus) )
1968   {                                              1944   {
1969     std::ostringstream message;                  1945     std::ostringstream message;
1970     message << "May lead to a crash or unreli    1946     message << "May lead to a crash or unreliable results." << G4endl
1971             << "        Position has shifted     1947             << "        Position has shifted considerably without"
1972             << " notifying the navigator !" <    1948             << " notifying the navigator !" << G4endl
1973             << "        Tolerated safety: " <    1949             << "        Tolerated safety: " << safetyPlus << G4endl
1974             << "        Computed shift  : " <    1950             << "        Computed shift  : " << shiftOriginSafSq;
1975     G4Exception("G4Navigator::ComputeStep()",    1951     G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
1976                 JustWarning, message);           1952                 JustWarning, message);
1977   }                                              1953   }
1978 }                                                1954 }
1979                                                  1955 
1980 // ******************************************    1956 // ********************************************************************
1981 // CheckOverlapsIterative                     << 
1982 // ****************************************** << 
1983 //                                            << 
1984 G4bool G4Navigator::CheckOverlapsIterative(G4 << 
1985 {                                             << 
1986   // Check and report overlaps                << 
1987   //                                          << 
1988   G4bool foundOverlap = false;                << 
1989   G4int  nPoints = 300000,  ntrials = 9, numO << 
1990   G4double  trialLength = 1.0 * CLHEP::centim << 
1991   while ( ntrials-- > 0 && !foundOverlap )    << 
1992   {                                           << 
1993     if ( fVerbose > 1 )                       << 
1994     {                                         << 
1995        G4cout << " ** Running overlap checks  << 
1996               <<  vol->GetName()              << 
1997               << " with length = " << trialLe << 
1998     }                                         << 
1999     foundOverlap = vol->CheckOverlaps(nPoints << 
2000                                       fVerbos << 
2001     trialLength *= 0.1;                       << 
2002     if ( trialLength <= 1.0e-5 ) { numOverlap << 
2003   }                                           << 
2004   return foundOverlap;                        << 
2005 }                                             << 
2006                                               << 
2007 // ****************************************** << 
2008 // Operator <<                                   1957 // Operator <<
2009 // ******************************************    1958 // ********************************************************************
2010 //                                               1959 //
2011 std::ostream& operator << (std::ostream &os,c    1960 std::ostream& operator << (std::ostream &os,const G4Navigator &n)
2012 {                                                1961 {
2013   //  Old version did only the following:        1962   //  Old version did only the following:
2014   // os << "Current History: " << G4endl << n    1963   // os << "Current History: " << G4endl << n.fHistory;
2015   //  Old behaviour is recovered for fVerbose    1964   //  Old behaviour is recovered for fVerbose = 0
2016                                                  1965   
2017   // Adapted from G4Navigator::PrintState() c    1966   // Adapted from G4Navigator::PrintState() const
2018                                                  1967 
2019   G4long oldcoutPrec = os.precision(4);       << 1968   G4int oldcoutPrec = os.precision(4);
2020   if( n.fVerbose >= 4 )                          1969   if( n.fVerbose >= 4 )
2021   {                                              1970   {
2022     os << "The current state of G4Navigator i    1971     os << "The current state of G4Navigator is: " << G4endl;
2023     os << "  ValidExitNormal= " << n.fValidEx    1972     os << "  ValidExitNormal= " << n.fValidExitNormal << G4endl
2024     << "  ExitNormal     = " << n.fExitNormal    1973     << "  ExitNormal     = " << n.fExitNormal      << G4endl
2025     << "  Exiting        = " << n.fExiting       1974     << "  Exiting        = " << n.fExiting         << G4endl
2026     << "  Entering       = " << n.fEntering      1975     << "  Entering       = " << n.fEntering        << G4endl
2027     << "  BlockedPhysicalVolume= " ;             1976     << "  BlockedPhysicalVolume= " ;
2028     if (n.fBlockedPhysicalVolume==nullptr)    << 1977     if (n.fBlockedPhysicalVolume==0)
2029     {                                         << 
2030       os << "None";                              1978       os << "None";
2031     }                                         << 
2032     else                                         1979     else
2033     {                                         << 
2034       os << n.fBlockedPhysicalVolume->GetName    1980       os << n.fBlockedPhysicalVolume->GetName();
2035     }                                         << 
2036     os << G4endl                                 1981     os << G4endl
2037     << "  BlockedReplicaNo     = " <<  n.fBlo    1982     << "  BlockedReplicaNo     = " <<  n.fBlockedReplicaNo       << G4endl
2038     << "  LastStepWasZero      = " <<   n.fLa    1983     << "  LastStepWasZero      = " <<   n.fLastStepWasZero       << G4endl
2039     << G4endl;                                   1984     << G4endl;
2040   }                                              1985   }
2041   if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )    1986   if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )
2042   {                                              1987   {
2043     os << G4endl; // Make sure to line up        1988     os << G4endl; // Make sure to line up
2044     os << std::setw(30) << " ExitNormal "  <<    1989     os << std::setw(30) << " ExitNormal "  << " "
2045     << std::setw( 5) << " Valid "       << "     1990     << std::setw( 5) << " Valid "       << " "
2046     << std::setw( 9) << " Exiting "     << "     1991     << std::setw( 9) << " Exiting "     << " "
2047     << std::setw( 9) << " Entering"     << "     1992     << std::setw( 9) << " Entering"     << " "
2048     << std::setw(15) << " Blocked:Volume "  <    1993     << std::setw(15) << " Blocked:Volume "  << " "
2049     << std::setw( 9) << " ReplicaNo"        <    1994     << std::setw( 9) << " ReplicaNo"        << " "
2050     << std::setw( 8) << " LastStepZero  "   <    1995     << std::setw( 8) << " LastStepZero  "   << " "
2051     << G4endl;                                   1996     << G4endl;
2052     os << "( " << std::setw(7) << n.fExitNorm    1997     os << "( " << std::setw(7) << n.fExitNormal.x()
2053     << ", " << std::setw(7) << n.fExitNormal.    1998     << ", " << std::setw(7) << n.fExitNormal.y()
2054     << ", " << std::setw(7) << n.fExitNormal.    1999     << ", " << std::setw(7) << n.fExitNormal.z() << " ) "
2055     << std::setw( 5)  << n.fValidExitNormal      2000     << std::setw( 5)  << n.fValidExitNormal  << " "
2056     << std::setw( 9)  << n.fExiting              2001     << std::setw( 9)  << n.fExiting          << " "
2057     << std::setw( 9)  << n.fEntering             2002     << std::setw( 9)  << n.fEntering         << " ";
2058     if ( n.fBlockedPhysicalVolume==nullptr )  << 2003     if ( n.fBlockedPhysicalVolume==0 )
2059       { os << std::setw(15) << "None"; }         2004       { os << std::setw(15) << "None"; }
2060     else                                         2005     else
2061       { os << std::setw(15)<< n.fBlockedPhysi    2006       { os << std::setw(15)<< n.fBlockedPhysicalVolume->GetName(); }
2062     os << std::setw( 9)  << n.fBlockedReplica    2007     os << std::setw( 9)  << n.fBlockedReplicaNo  << " "
2063     << std::setw( 8)  << n.fLastStepWasZero      2008     << std::setw( 8)  << n.fLastStepWasZero   << " "
2064     << G4endl;                                   2009     << G4endl;
2065   }                                              2010   }
2066   if( n.fVerbose > 2 )                           2011   if( n.fVerbose > 2 )
2067   {                                              2012   {
2068     os.precision(8);                             2013     os.precision(8);
2069     os << " Current Localpoint = " << n.fLast    2014     os << " Current Localpoint = " << n.fLastLocatedPointLocal << G4endl;
2070     os << " PreviousSftOrigin  = " << n.fPrev    2015     os << " PreviousSftOrigin  = " << n.fPreviousSftOrigin << G4endl;
2071     os << " PreviousSafety     = " << n.fPrev    2016     os << " PreviousSafety     = " << n.fPreviousSafety << G4endl;
2072   }                                              2017   }
2073   if( n.fVerbose > 3 || n.fVerbose == 0 )        2018   if( n.fVerbose > 3 || n.fVerbose == 0 )
2074   {                                              2019   {
2075     os << "Current History: " << G4endl << n.    2020     os << "Current History: " << G4endl << n.fHistory;
2076   }                                              2021   }
2077                                                  2022     
2078   os.precision(oldcoutPrec);                     2023   os.precision(oldcoutPrec);
2079   return os;                                     2024   return os;
2080 }                                             << 
2081                                               << 
2082 // ****************************************** << 
2083 // SetVoxelNavigation: alternative navigator  << 
2084 // ****************************************** << 
2085 //                                            << 
2086 void G4Navigator::SetVoxelNavigation(G4VoxelN << 
2087 {                                             << 
2088   delete fpvoxelNav;                          << 
2089   fpvoxelNav = voxelNav;                      << 
2090 }                                             << 
2091                                               << 
2092 // ****************************************** << 
2093 // InformLastStep: derived navigators can inf << 
2094 //                 used to update fLastStepWa << 
2095 // ****************************************** << 
2096 void  G4Navigator::InformLastStep(G4double la << 
2097                                   G4bool exit << 
2098 {                                             << 
2099   G4bool zeroStep = ( lastStep == 0.0 );      << 
2100   fLocatedOnEdge   = fLastStepWasZero && zero << 
2101   fLastStepWasZero = zeroStep;                << 
2102                                               << 
2103   fExiting = exitsMotherVol;                  << 
2104   fEntering = entersDaughtVol;                << 
2105 }                                             << 
2106                                               << 
2107 // ****************************************** << 
2108 // SetExternalNavigation                      << 
2109 // ****************************************** << 
2110 //                                            << 
2111 void G4Navigator::SetExternalNavigation(G4VEx << 
2112 {                                             << 
2113   fpExternalNav = externalNav;                << 
2114   fpSafetyCalculator->SetExternalNavigation(e << 
2115 }                                                2025 }
2116                                                  2026