Geant4 Cross Reference

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

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

Diff markup

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


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