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 10.7.p1)


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