Geant4 Cross Reference

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