Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/src/G4ITNavigator2.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 /processes/electromagnetic/dna/management/src/G4ITNavigator2.cc (Version 11.3.0) and /processes/electromagnetic/dna/management/src/G4ITNavigator2.cc (Version 10.6.p2)


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