Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/navigation/src/G4PathFinder.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/G4PathFinder.cc (Version 11.3.0) and /geometry/navigation/src/G4PathFinder.cc (Version 1.1)


  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 // G4PathFinder Implementation                    
 27 //                                                
 28 // Original author: John Apostolakis, April 20    
 29 // -------------------------------------------    
 30                                                   
 31 #include <iomanip>                                
 32                                                   
 33 #include "G4PathFinder.hh"                        
 34                                                   
 35 #include "G4SystemOfUnits.hh"                     
 36 #include "G4GeometryTolerance.hh"                 
 37 #include "G4Navigator.hh"                         
 38 #include "G4PropagatorInField.hh"                 
 39 #include "G4TransportationManager.hh"             
 40 #include "G4MultiNavigator.hh"                    
 41 #include "G4SafetyHelper.hh"                      
 42                                                   
 43 // Initialise the static instance of the singl    
 44 //                                                
 45 G4ThreadLocal G4PathFinder* G4PathFinder::fpPa    
 46                                                   
 47 // -------------------------------------------    
 48 // GetInstance()                                  
 49 //                                                
 50 // Retrieve the static instance of the singlet    
 51 //                                                
 52 G4PathFinder* G4PathFinder::GetInstance()         
 53 {                                                 
 54    if( fpPathFinder == nullptr )                  
 55    {                                              
 56      fpPathFinder = new G4PathFinder;             
 57    }                                              
 58    return fpPathFinder;                           
 59 }                                                 
 60                                                   
 61 // -------------------------------------------    
 62 // GetInstanceIfExist()                           
 63 //                                                
 64 // Retrieve the static instance pointer of the    
 65 //                                                
 66 G4PathFinder* G4PathFinder::GetInstanceIfExist    
 67 {                                                 
 68    return fpPathFinder;                           
 69 }                                                 
 70                                                   
 71 // -------------------------------------------    
 72 // Constructor                                    
 73 //                                                
 74 G4PathFinder::G4PathFinder()                      
 75   : fEndState( G4ThreeVector(), G4ThreeVector(    
 76 {                                                 
 77    fpMultiNavigator = new G4MultiNavigator();     
 78                                                   
 79    fpTransportManager= G4TransportationManager    
 80    fpFieldPropagator = fpTransportManager->Get    
 81                                                   
 82    kCarTolerance = G4GeometryTolerance::GetIns    
 83                                                   
 84    G4ThreeVector  Big3Vector( kInfinity, kInfi    
 85    fLastLocatedPosition= Big3Vector;              
 86    fSafetyLocation= Big3Vector;                   
 87    fPreSafetyLocation= Big3Vector;                
 88    fPreStepLocation= Big3Vector;                  
 89                                                   
 90    for( auto num=0; num<fMaxNav; ++num )          
 91    {                                              
 92       fpNavigator[num] = nullptr;                 
 93       fLimitTruth[num] = false;                   
 94       fLimitedStep[num] = kUndefLimited;          
 95       fCurrentStepSize[num] = -1.0;               
 96       fLocatedVolume[num] = nullptr;              
 97       fPreSafetyValues[num]= -1.0;                
 98       fCurrentPreStepSafety[num] = -1.0;          
 99       fNewSafetyComputed[num]= -1.0;              
100    }                                              
101 }                                                 
102                                                   
103 // -------------------------------------------    
104 // Destructor                                     
105 //                                                
106 G4PathFinder::~G4PathFinder()                     
107 {                                                 
108    delete fpMultiNavigator;                       
109    fpPathFinder = nullptr;                        
110 }                                                 
111                                                   
112 // -------------------------------------------    
113 //                                                
114 void                                              
115 G4PathFinder::EnableParallelNavigation(G4bool     
116 {                                                 
117    G4Navigator *navigatorForPropagation = null    
118                                                   
119    massNavigator = fpTransportManager->GetNavi    
120    if( enableChoice )                             
121    {                                              
122       navigatorForPropagation = fpMultiNavigat    
123                                                   
124       // Enable SafetyHelper to use PF            
125       //                                          
126       fpTransportManager->GetSafetyHelper()->E    
127    }                                              
128    else                                           
129    {                                              
130       navigatorForPropagation = massNavigator;    
131                                                   
132       // Disable SafetyHelper to use PF           
133       //                                          
134       fpTransportManager->GetSafetyHelper()->E    
135    }                                              
136    fpFieldPropagator->SetNavigatorForPropagati    
137 }                                                 
138                                                   
139 // -------------------------------------------    
140 //                                                
141 G4double                                          
142 G4PathFinder::ComputeStep( const G4FieldTrack&    
143                                  G4double         
144                                  G4int            
145                                  G4int            
146                                  G4double&        
147                                  ELimited&        
148                                  G4FieldTrack&    
149                                  G4VPhysicalVo    
150 {                                                 
151   G4double possibleStep = -1.0;                   
152                                                   
153 #ifdef G4DEBUG_PATHFINDER                         
154   if( fVerboseLevel > 2 )                         
155   {                                               
156     G4cout << " -------------------------" <<     
157     G4cout << " G4PathFinder::ComputeStep - en    
158     G4cout << "   - stepNo = "  << std::setw(4    
159            << " navigatorId = " << std::setw(2    
160            << " proposed step len = " << propo    
161     G4cout << " PF::ComputeStep requested step    
162            << " from " << InitialFieldTrack.Ge    
163            << " dir  " << InitialFieldTrack.Ge    
164   }                                               
165 #endif                                            
166 #ifdef G4VERBOSE                                  
167   if( navigatorNo >= fNoActiveNavigators )        
168   {                                               
169     std::ostringstream message;                   
170     message << "Bad Navigator ID !" << G4endl     
171             << "        Requested Navigator ID    
172             << "        Number of active navig    
173     G4Exception("G4PathFinder::ComputeStep()",    
174                 FatalException, message);         
175   }                                               
176 #endif                                            
177                                                   
178   if( fNewTrack || (stepNo != fLastStepNo)  )     
179   {                                               
180     // This is a new track or a new step, so w    
181     // ( else we can simply retrieve its resul    
182                                                   
183     G4FieldTrack currentState = InitialFieldTr    
184                                                   
185     fCurrentStepNo = stepNo;                      
186                                                   
187     // Check whether a process shifted the pos    
188     // since the last step -- by physics proce    
189     //                                            
190     G4ThreeVector newPosition = InitialFieldTr    
191     G4ThreeVector moveVector = newPosition - f    
192     G4double moveLenSq = moveVector.mag2();       
193     if( moveLenSq > sqr(kCarTolerance) )          
194     {                                             
195        G4ThreeVector newDirection = InitialFie    
196 #ifdef G4DEBUG_PATHFINDER                         
197        if( fVerboseLevel > 2 )                    
198        {                                          
199           G4double moveLen= std::sqrt( moveLen    
200           G4cout << " G4PathFinder::ComputeSte    
201                  << " -- at step # = " << step    
202                  << " by " << moveLen  << " to    
203        }                                          
204 #endif                                            
205        MovePoint();  // Unintentional changed     
206                                                   
207        // Relocate to cope with this move -- e    
208        //                                         
209        Locate( newPosition, newDirection );       
210     }                                             
211                                                   
212     // Check whether the particle have an (EM)    
213     //                                            
214     G4double particleCharge = currentState.Get    
215                                                   
216     G4FieldManager* fieldMgr = nullptr;           
217     G4bool          fieldExertsForce = false ;    
218     if( particleCharge != 0.0 )                   
219     {                                             
220         fieldMgr = fpFieldPropagator->FindAndS    
221                                                   
222         // Protect for case where field manage    
223         //                                        
224         fieldExertsForce = (fieldMgr != nullpt    
225                         && (fieldMgr->GetDetec    
226     }                                             
227     fFieldExertedForce = fieldExertsForce;  //    
228                                             //    
229                                                   
230     fNoGeometriesLimiting = -1;  // At start o    
231     if( fieldExertsForce )                        
232     {                                             
233        DoNextCurvedStep( currentState, propose    
234        //--------------                           
235     }else{                                        
236        DoNextLinearStep( currentState, propose    
237        //--------------                           
238     }                                             
239     fLastStepNo = stepNo;                         
240     fRelocatedPoint = false;                      
241                                                   
242 #ifdef  G4DEBUG_PATHFINDER                        
243     if ( (fNoGeometriesLimiting < 0)              
244       || (fNoGeometriesLimiting > fNoActiveNav    
245     {                                             
246       std::ostringstream message;                 
247       message << "Number of geometries limitin    
248               << "        Number of geometries    
249               << fNoGeometriesLimiting;           
250       G4Exception("G4PathFinder::ComputeStep()    
251                   "GeomNav0002", FatalExceptio    
252     }                                             
253 #endif                                            
254   }                                               
255 #ifdef G4DEBUG_PATHFINDER                         
256   else                                            
257   {                                               
258      const G4double checkTolerance = 1.0e-9;      
259      if( proposedStepLength < fTrueMinStep * (    
260      {                                            
261        std::ostringstream message;                
262        message.precision( 12 );                   
263        message << "Problem in step size reques    
264                << "        Being requested to     
265                << " than the minimum Step " <<    
266                << "        already computed fo    
267                << " this tracking-step: " << G    
268                << "        This could happen d    
269                << G4endl                          
270                << "        Check that all phys    
271                << "        before all processe    
272                << G4endl                          
273                << "        If using pre-packag    
274                << "        functionality, plea    
275                << G4endl << G4endl                
276                << "        Additional informat    
277                << "        Steps request/propo    
278                << G4endl                          
279                << "        MinimumStep (true)     
280                << G4endl                          
281                << "        MinimumStep (navraw    
282                << G4endl                          
283                << "        Navigator raw retur    
284                << "        Requested step now     
285                << G4endl                          
286                << "        Difference min-req     
287                << fTrueMinStep-proposedStepLen    
288                << "        Relative (to max of    
289                << (fTrueMinStep-proposedStepLe    
290                   / std::max(proposedStepLengt    
291                << "     -- Step info> stepNo=     
292                << " last= " << fLastStepNo        
293                << " newTr= " << fNewTrack << G    
294         G4Exception("G4PathFinder::ComputeStep    
295                     "GeomNav0003", FatalExcept    
296      }                                            
297      else                                         
298      {                                            
299         // This is neither a new track nor a n    
300         // client accessing information for th    
301         // We will simply retrieve the results    
302         // stepping for this Navigator Id belo    
303         //                                        
304         if( fVerboseLevel > 1 )                   
305         {                                         
306            G4cout << " G4P::CS -> Not calling     
307                   << " stepNo= " << stepNo <<     
308                   << " new= " << fNewTrack <<     
309         }                                         
310      }                                            
311   }                                               
312 #endif                                            
313                                                   
314   fNewTrack = false;                              
315                                                   
316   // Prepare the information to return            
317                                                   
318   pNewSafety  = fCurrentPreStepSafety[ navigat    
319   limitedStep = fLimitedStep[ navigatorNo ];      
320                                                   
321   possibleStep = std::min(proposedStepLength,     
322   EndState = fEndState;  //  now corrected for    
323                                                   
324 #ifdef G4DEBUG_PATHFINDER                         
325   if( fVerboseLevel > 0 )                         
326   {                                               
327     G4cout << " G4PathFinder::ComputeStep retu    
328            << fCurrentStepSize[ navigatorNo ]     
329            << " for Navigator " << navigatorNo    
330            << " Limited step = " << limitedSte    
331            << " Safety(mm) = " << pNewSafety /    
332            << G4endl;                             
333   }                                               
334 #endif                                            
335                                                   
336   return possibleStep;                            
337 }                                                 
338                                                   
339 // -------------------------------------------    
340                                                   
341 void                                              
342 G4PathFinder::PrepareNewTrack( const G4ThreeVe    
343                                const G4ThreeVe    
344                                G4VPhysicalVolu    
345 {                                                 
346   // Key purposes:                                
347   //   - Check and cache set of active navigat    
348   //   - Reset state for new track                
349                                                   
350   G4int num=0;                                    
351                                                   
352   EnableParallelNavigation(true);                 
353     // Switch PropagatorInField to use MultiNa    
354                                                   
355   fpTransportManager->GetSafetyHelper()->Initi    
356     // Reinitialise state of safety helper --     
357                                                   
358   fNewTrack = true;                               
359   this->MovePoint();   // Signal further that     
360                                                   
361   fpFieldPropagator->PrepareNewTrack(); // Inf    
362                                                   
363   // Message the G4NavigatorPanel / Dispatcher    
364   //                                              
365   std::vector<G4Navigator*>::iterator pNavigat    
366                                                   
367   fNoActiveNavigators = (G4int)fpTransportMana    
368   if( fNoActiveNavigators > fMaxNav )             
369   {                                               
370     std::ostringstream message;                   
371     message << "Too many active Navigators / w    
372             << "        Transportation Manager    
373             << fNoActiveNavigators << " active    
374             << "        This is more than the     
375             << fMaxNav << " !";                   
376     G4Exception("G4PathFinder::PrepareNewTrack    
377                 FatalException, message);         
378   }                                               
379                                                   
380   fpMultiNavigator->PrepareNavigators();          
381   //------------------------------------          
382                                                   
383   pNavigatorIter = fpTransportManager->GetActi    
384   for( num=0; num< fNoActiveNavigators; ++pNav    
385   {                                               
386      // Keep information in C-array ... for cr    
387      //                                           
388      fpNavigator[num] = *pNavigatorIter;          
389      fLimitTruth[num] = false;                    
390      fLimitedStep[num] = kDoNot;                  
391      fCurrentStepSize[num] = 0.0;                 
392      fLocatedVolume[num] = nullptr;               
393   }                                               
394   fNoGeometriesLimiting = 0;  // At start of t    
395                                                   
396   // In case of one geometry, the tracking wil    
397                                                   
398   if( fNoActiveNavigators > 1 )                   
399   {                                               
400      Locate( position, direction, false );        
401   }                                               
402   else                                            
403   {                                               
404      // Update state -- depending on the track    
405                                                   
406      fLastLocatedPosition = position;             
407      fLocatedVolume[0] = massStartVol; // This    
408                                        // by t    
409      fLimitedStep[0] = kDoNot;                    
410      fCurrentStepSize[0] = 0.0;                   
411   }                                               
412                                                   
413   // Reset Safety Information -- as in case of    
414   // inconsistencies ...                          
415   //                                              
416   fMinSafety_PreStepPt = fPreSafetyMinValue =     
417                                                   
418   for( num=0; num<fNoActiveNavigators; ++num )    
419   {                                               
420      fPreSafetyValues[num] = 0.0;                 
421      fNewSafetyComputed[num] = 0.0;               
422      fCurrentPreStepSafety[num] = 0.0;            
423   }                                               
424                                                   
425   // The first location for each Navigator mus    
426   // or else call ResetStackAndState() for eac    
427                                                   
428   fRelocatedPoint = false;                        
429 }                                                 
430                                                   
431                                                   
432 void G4PathFinder::EndTrack()                     
433   // Signal end of tracking of current track.     
434   // Reset TransportationManager to use 'ordin    
435   // Reset internal state, if needed              
436 {                                                 
437   EnableParallelNavigation(false);  // Else it    
438 }                                                 
439                                                   
440 void G4PathFinder::ReportMove( const G4ThreeVe    
441                                const G4ThreeVe    
442                                const G4String&    
443 {                                                 
444     G4ThreeVector moveVec = ( NewVector - OldV    
445                                                   
446     std::ostringstream message;                   
447     message.precision(16);                        
448     message << "Endpoint moved between value r    
449             << " and call to Locate(). " << G4    
450             << "          Change of " << Quant    
451             << moveVec.mag() / mm << " mm long    
452             << "          and its vector is "     
453             << (1.0/mm) * moveVec << " mm " <<    
454             << "          Endpoint of ComputeS    
455             << G4endl                             
456             << "          and current position    
457     G4Exception("G4PathFinder::ReportMove()",     
458                 JustWarning, message);            
459 }                                                 
460                                                   
461 void G4PathFinder::Locate( const G4ThreeVector    
462                            const G4ThreeVector    
463                                  G4bool relati    
464 {                                                 
465   // Locate the point in each geometry            
466                                                   
467   auto pNavIter = fpTransportManager->GetActiv    
468                                                   
469   G4ThreeVector lastEndPosition = fRelocatedPo    
470                                 ? fLastLocated    
471                                 : fEndState.Ge    
472   fLastLocatedPosition = position;                
473                                                   
474 #ifdef G4DEBUG_PATHFINDER                         
475   static const G4double movLenTol = 10*sqr(kCa    
476                                                   
477   G4ThreeVector moveVec = ( position - lastEnd    
478   G4double      moveLenSq = moveVec.mag2();       
479   if( (!fNewTrack) && ( moveLenSq > movLenTol     
480   {                                               
481      ReportMove( lastEndPosition, position,       
482                  " (End) Position / G4PathFind    
483   }                                               
484                                                   
485   if( fVerboseLevel > 2 )                         
486   {                                               
487     G4cout << G4endl;                             
488     G4cout << " G4PathFinder::Locate : entered    
489     G4cout << " --------------------   -------    
490     G4cout << "   Locating at position " << po    
491            << "  with direction " << direction    
492            << "  relative= " << relative << G4    
493     if ( (fVerboseLevel > 1) || ( moveLenSq >     
494     {                                             
495        G4cout << "  lastEndPosition = " << las    
496               << "  moveVec = " << moveVec        
497               << "  newTr = " << fNewTrack        
498               << "  relocated = " << fRelocate    
499     }                                             
500                                                   
501     G4cout << " Located at " << position ;        
502     if( fNoActiveNavigators > 1 )  { G4cout <<    
503   }                                               
504 #endif                                            
505                                                   
506   for ( auto num=0; num<fNoActiveNavigators ;     
507   {                                               
508      //  ... who limited the step ....            
509                                                   
510      if( fLimitTruth[num] ) { (*pNavIter)->Set    
511                                                   
512      G4VPhysicalVolume *pLocated=                 
513      (*pNavIter)->LocateGlobalPointAndSetup( p    
514                                              r    
515                                              f    
516      // Set the state related to the location     
517      //                                           
518      fLocatedVolume[num] = pLocated;              
519                                                   
520      // Clear state related to the step           
521      //                                           
522      fLimitedStep[num] = kDoNot;                  
523      fCurrentStepSize[num] = 0.0;                 
524                                                   
525 #ifdef G4DEBUG_PATHFINDER                         
526      if( fVerboseLevel > 2 )                      
527      {                                            
528        G4cout << " - In world " << num << " ge    
529               << "  gives volume= " << pLocate    
530        if( pLocated )                             
531        {                                          
532          G4cout << "  name = '" << pLocated->G    
533          G4cout << " - CopyNo= " << pLocated->    
534        }                                          
535        G4cout  << G4endl;                         
536      }                                            
537 #endif                                            
538   }                                               
539                                                   
540   fRelocatedPoint = false;                        
541 }                                                 
542                                                   
543 void G4PathFinder::ReLocate( const G4ThreeVect    
544 {                                                 
545   // Locate the point in each geometry            
546                                                   
547   auto pNavIter = fpTransportManager->GetActiv    
548                                                   
549 #ifdef G4DEBUG_PATHFINDER                         
550                                                   
551   // Check that this relocation does not viola    
552   //   - at endpoint (computed from start poin    
553   //   - at last safety location  (likely just    
554                                                   
555   G4ThreeVector lastEndPosition = fEndState.Ge    
556                                                   
557   // Calculate end-point safety ...               
558   //                                              
559   G4double DistanceStartEnd = (lastEndPosition    
560   G4double endPointSafety_raw = fMinSafety_Pre    
561   G4double endPointSafety_Est1 = std::max( 0.0    
562                                                   
563   // ... and check move from endpoint against     
564   //                                              
565   G4ThreeVector moveVecEndPos  = position - la    
566   G4double      moveLenEndPosSq = moveVecEndPo    
567                                                   
568   // Check that move from endpoint of last ste    
569   // -- or check against last location or relo    
570   //                                              
571   G4ThreeVector moveVecSafety = position - fSa    
572   G4double      moveLenSafSq = moveVecSafety.m    
573                                                   
574   G4double distCheckEnd_sq = ( moveLenEndPosSq    
575                                                   
576   G4double distCheckSaf_sq = ( moveLenSafSq -     
577                                              *    
578                                                   
579   G4bool longMoveEnd = distCheckEnd_sq > 0.0;     
580   G4bool longMoveSaf = distCheckSaf_sq > 0.0;     
581                                                   
582   G4double revisedSafety = 0.0;                   
583                                                   
584   if( (!fNewTrack) && ( longMoveEnd && longMov    
585   {                                               
586      // Recompute ComputeSafety for end positi    
587      //                                           
588      revisedSafety = ComputeSafety(lastEndPosi    
589                                                   
590      const G4double kRadTolerance =               
591            G4GeometryTolerance::GetInstance()-    
592      const G4double cErrorTolerance = 1e-12;      
593        // Maximum relative error from roundoff    
594                                                   
595      G4double distCheckRevisedEnd = moveLenEnd    
596                                                   
597      G4bool  longMoveRevisedEnd = ( distCheckR    
598                                                   
599      G4double moveMinusSafety = 0.0;              
600      G4double moveLenEndPosition = std::sqrt(     
601      moveMinusSafety = moveLenEndPosition - re    
602                                                   
603      if ( longMoveRevisedEnd && ( moveMinusSaf    
604                              && ( revisedSafet    
605      {                                            
606         // Take into account possibility of ro    
607         // this apparent move further than saf    
608                                                   
609         if( fVerboseLevel > 0 )                   
610         {                                         
611            G4cout << " G4PF:Relocate> Ratio to    
612                   << std::fabs(moveMinusSafety    
613         }                                         
614                                                   
615         G4double absMoveMinusSafety = std::fab    
616         G4bool smallRatio = absMoveMinusSafety    
617         G4double maxCoordPos = std::max(          
618                                       std::max    
619                                                   
620                                       std::fab    
621         G4bool smallValue= absMoveMinusSafety     
622         if( !(smallRatio || smallValue) )         
623         {                                         
624            G4cout << " G4PF:Relocate> Ratio to    
625                   << std::fabs(moveMinusSafety    
626            G4cout << " Difference of move and     
627                   << G4endl;                      
628         }                                         
629         else                                      
630         {                                         
631           moveMinusSafety = 0.0;                  
632           longMoveRevisedEnd = false;   // Num    
633                                                   
634           G4cout << " Difference of move & saf    
635                  << absMoveMinusSafety << G4en    
636           if( smallRatio )                        
637           {                                       
638             G4cout << " ratio to safety " << r    
639                    << " is " <<  absMoveMinusS    
640                    << "smaller than " << kRadT    
641           }                                       
642           else                                    
643           {                                       
644             G4cout << " as fraction " << absMo    
645                    << " of position vector max    
646                    << " smaller than " << cErr    
647           }                                       
648           G4cout << " -- reset moveMinusSafety    
649                  << moveMinusSafety << G4endl;    
650         }                                         
651      }                                            
652                                                   
653      if ( longMoveEnd && longMoveSaf              
654        && longMoveRevisedEnd && (moveMinusSafe    
655      {                                            
656         std::ostringstream message;               
657         message.precision(9);                     
658         message << "ReLocation is further than    
659                 << " Moved from last endpoint     
660                 << " compared to end safety (f    
661                 << endPointSafety_Est1 << G4en    
662                 << "  --> last PreSafety Locat    
663                 << G4endl                         
664                 << "       safety value =  " <    
665                 << "  --> last PreStep Locatio    
666                 << G4endl                         
667                 << "       safety value =  " <    
668                 << "  --> last EndStep Locatio    
669                 << G4endl                         
670                 << "       safety value =  " <    
671                 << " raw-value = " << endPoint    
672                 << "  --> Calling again at thi    
673                 <<  revisedSafety << " as safe    
674                 << "  --> last position for sa    
675                 << G4endl                         
676                 << "       its safety value =     
677                 << G4endl                         
678                 << "       move from safety lo    
679                 << std::sqrt(moveLenSafSq) <<     
680                 << "         again= " << moveV    
681                 << "       safety - Move-from-    
682                 << revisedSafety - moveLenEndP    
683                 << " (negative is Bad.)" << G4    
684                 << " Debug:  distCheckRevisedE    
685                 << distCheckRevisedEnd;           
686         ReportMove( lastEndPosition, position,    
687         G4Exception("G4PathFinder::ReLocate",     
688                     FatalException, message);     
689     }                                             
690   }                                               
691                                                   
692   if( fVerboseLevel > 2 )                         
693   {                                               
694     G4cout << G4endl;                             
695     G4cout << " G4PathFinder::ReLocate : enter    
696     G4cout << " ----------------------   -----    
697     G4cout << "  *Re*Locating at position " <<    
698     if ( (fVerboseLevel > -1) || ( moveLenEndP    
699     {                                             
700        G4cout << "  lastEndPosition = " << las    
701               << "  moveVec from step-end = "     
702               << "  is new Track = " << fNewTr    
703               << "  relocated = " << fRelocate    
704     }                                             
705   }                                               
706 #endif // G4DEBUG_PATHFINDER                      
707                                                   
708   for ( auto num=0; num< fNoActiveNavigators ;    
709   {                                               
710      //  ... none limited the step                
711                                                   
712      (*pNavIter)->LocateGlobalPointWithinVolum    
713                                                   
714      // Clear state related to the step           
715      //                                           
716      fLimitedStep[num] = kDoNot;                  
717      fCurrentStepSize[num] = 0.0;                 
718      fLimitTruth[num] = false;                    
719   }                                               
720                                                   
721   fLastLocatedPosition = position;                
722   fRelocatedPoint = true;                         
723                                                   
724 #ifdef G4DEBUG_PATHFINDER                         
725   if( fVerboseLevel > 2 )                         
726   {                                               
727     G4cout << " G4PathFinder::ReLocate : exiti    
728            << "  at position " << fLastLocated    
729   }                                               
730 #endif                                            
731 }                                                 
732                                                   
733 // -------------------------------------------    
734                                                   
735 G4double  G4PathFinder::ComputeSafety( const G    
736 {                                                 
737     // Recompute safety for the relevant point    
738                                                   
739    G4double minSafety = kInfinity;                
740                                                   
741    std::vector<G4Navigator*>::iterator pNaviga    
742    pNavigatorIter = fpTransportManager->GetAct    
743                                                   
744    for( auto num=0; num<fNoActiveNavigators; +    
745    {                                              
746       G4double safety = (*pNavigatorIter)->Com    
747       if( safety < minSafety ) { minSafety = s    
748       fNewSafetyComputed[num] = safety;           
749    }                                              
750                                                   
751    fSafetyLocation = position;                    
752    fMinSafety_atSafLocation = minSafety;          
753                                                   
754 #ifdef G4DEBUG_PATHFINDER                         
755    if( fVerboseLevel > 1 )                        
756    {                                              
757      G4cout << " G4PathFinder::ComputeSafety -    
758             << minSafety << " at location " <<    
759    }                                              
760 #endif                                            
761    return minSafety;                              
762 }                                                 
763                                                   
764                                                   
765 // -------------------------------------------    
766                                                   
767 G4TouchableHandle                                 
768 G4PathFinder::CreateTouchableHandle( G4int nav    
769 {                                                 
770 #ifdef G4DEBUG_PATHFINDER                         
771   if( fVerboseLevel > 2 )                         
772   {                                               
773     G4cout << "G4PathFinder::CreateTouchableHa    
774            << navId << " -- " << GetNavigator(    
775   }                                               
776 #endif                                            
777                                                   
778   G4TouchableHistory* touchHist;                  
779   touchHist = GetNavigator(navId)->CreateTouch    
780                                                   
781   G4VPhysicalVolume* locatedVolume = fLocatedV    
782   if( locatedVolume == nullptr )                  
783   {                                               
784      // Workaround to ensure that the touchabl    
785                                                   
786      touchHist->UpdateYourself( locatedVolume,    
787   }                                               
788                                                   
789 #ifdef G4DEBUG_PATHFINDER                         
790   if( fVerboseLevel > 2 )                         
791   {                                               
792     G4String VolumeName("None");                  
793     if( locatedVolume ) { VolumeName = located    
794     G4cout << " Touchable History created at a    
795            << "; volume = " << locatedVolume <    
796            << G4endl;                             
797   }                                               
798 #endif                                            
799                                                   
800   return {touchHist};                             
801 }                                                 
802                                                   
803 G4double                                          
804 G4PathFinder::DoNextLinearStep( const G4FieldT    
805                                       G4double    
806 {                                                 
807   std::vector<G4Navigator*>::iterator pNavigat    
808   G4double safety = 0.0, step =0.0;               
809   G4double minSafety = kInfinity, minStep = kI    
810                                                   
811   const G4int IdTransport = 0;  // Id of Mass     
812   G4int num = 0;                                  
813                                                   
814 #ifdef G4DEBUG_PATHFINDER                         
815   if( fVerboseLevel > 2 )                         
816   {                                               
817     G4cout << " G4PathFinder::DoNextLinearStep    
818     G4cout << "   Input field track= " << init    
819     G4cout << "   Requested step= " << propose    
820   }                                               
821 #endif                                            
822                                                   
823   G4ThreeVector initialPosition = initialState    
824   G4ThreeVector initialDirection = initialStat    
825                                                   
826   G4ThreeVector OriginShift = initialPosition     
827   G4double      MagSqShift  = OriginShift.mag2    
828   G4double      MagShift;  // Only given value    
829                                                   
830   // Potential optimisation using Maximum Valu    
831   // if( MagSqShift >= sqr(fPreSafetyMaxValue     
832   //   MagShift= kInfinity;   // Not a useful     
833   // else                                         
834   //  MagShift= std::sqrt(MagSqShift) ;           
835                                                   
836   MagShift= std::sqrt(MagSqShift) ;               
837                                                   
838 #ifdef G4PATHFINDER_OPTIMISATION                  
839                                                   
840   G4double fullSafety;  // For all geometries,    
841                                                   
842   if( MagSqShift >= sqr(fPreSafetyMinValue) )     
843   {                                               
844      fullSafety = 0.0 ;                           
845   }                                               
846   else                                            
847   {                                               
848      fullSafety = fPreSafetyMinValue - MagShif    
849   }                                               
850   if( proposedStepLength < fullSafety )           
851   {                                               
852      // Move is smaller than all safeties         
853      //  -> so we do not have to move the safe    
854                                                   
855      fPreStepCenterRenewed = false;               
856                                                   
857      for( num=0; num< fNoActiveNavigators; ++n    
858      {                                            
859         fCurrentStepSize[num] = kInfinity;        
860         safety = std::max( 0.0,  fPreSafetyVal    
861         minSafety= std::min( safety, minSafety    
862         fCurrentPreStepSafety[num] = safety;      
863      }                                            
864      minStep = kInfinity;                         
865                                                   
866 #ifdef G4DEBUG_PATHFINDER                         
867      if( fVerboseLevel > 2 )                      
868      {                                            
869        G4cout << "G4PathFinder::DoNextLinearSt    
870                << " proposedStepLength " <<  p    
871                << " < (full) safety = " << ful    
872                << " at " << initialPosition       
873                << G4endl;                         
874      }                                            
875 #endif                                            
876   }                                               
877   else                                            
878 #endif   // End of G4PATHFINDER_OPTIMISATION 1    
879   {                                               
880      // Move is larger than at least one of th    
881      //  -> so we must move the safety center!    
882                                                   
883      fPreStepCenterRenewed = true;                
884      pNavigatorIter = fpTransportManager-> Get    
885                                                   
886      minStep = kInfinity;  // Not proposedStep    
887                                                   
888      for( num=0; num< fNoActiveNavigators; ++p    
889      {                                            
890         safety = std::max( 0.0,  fPreSafetyVal    
891                                                   
892 #ifdef G4PATHFINDER_OPTIMISATION                  
893         if( proposedStepLength <= safety )  //    
894         {                                         
895            // The Step is guaranteed to be tak    
896                                                   
897            step = kInfinity;    //  ComputeSte    
898                                                   
899 #ifdef G4DEBUG_PATHFINDER                         
900            G4cout.precision(8);                   
901            G4cout << "PathFinder::ComputeStep>    
902                   << proposedStepLength           
903                   << " <=  safety = " << safet    
904                   << " Step fully taken. " <<     
905 #endif                                            
906         }                                         
907         else                                      
908 #endif   // End of G4PATHFINDER_OPTIMISATION 2    
909         {                                         
910 #ifdef G4DEBUG_PATHFINDER                         
911            G4double previousSafety = safety;      
912 #endif                                            
913            step = (*pNavigatorIter)->ComputeSt    
914                                                   
915                                                   
916                                                   
917            minStep = std::min(step, minStep);     
918                                                   
919                                                   
920 #ifdef G4DEBUG_PATHFINDER                         
921            if( fVerboseLevel > 0)                 
922            {                                      
923              G4cout.precision(8);                 
924              G4cout << "PathFinder::ComputeSte    
925                     << proposedStepLength         
926                     << "  >  safety = " << pre    
927                     << " for nav " << num         
928                     << " .  New safety = " <<     
929                     << G4endl;                    
930            }                                      
931 #endif                                            
932         }                                         
933         fCurrentStepSize[num] = step;   // Raw    
934                                                   
935            //  TODO: consider whether/how to r    
936            //        to the latest minStep val    
937            //        ( If so, much change 1st     
938                                                   
939         // Save safety value, must be done for    
940         // (even if not recomputed using call     
941         // since they share the fPreSafetyLoca    
942                                                   
943         fPreSafetyValues[num] = safety;           
944         fCurrentPreStepSafety[num] = safety;      
945                                                   
946         minSafety = std::min( safety, minSafet    
947                                                   
948 #ifdef G4DEBUG_PATHFINDER                         
949         if( fVerboseLevel > 2 )                   
950         {                                         
951           G4cout << "G4PathFinder::DoNextLinea    
952                  << num << "] -- step size " <    
953         }                                         
954 #endif                                            
955      }                                            
956                                                   
957      // Only change these when safety is recal    
958      // it is good/relevant only for safety ca    
959                                                   
960      fPreSafetyLocation =  initialPosition;       
961      fPreSafetyMinValue =  minSafety;             
962   } // end of else for  if( proposedStepLength    
963                                                   
964   // For use in Relocation, need PreStep point    
965   //                                              
966   fPreStepLocation = initialPosition;             
967   fMinSafety_PreStepPt = minSafety;               
968                                                   
969   fMinStep = minStep;                             
970                                                   
971   if( fMinStep == kInfinity )                     
972   {                                               
973      minStep = proposedStepLength;   //  Use t    
974   }                                               
975   fTrueMinStep = minStep;                         
976                                                   
977   // Set the EndState                             
978                                                   
979   G4ThreeVector endPosition;                      
980                                                   
981   fEndState = initialState;                       
982   endPosition = initialPosition + minStep * in    
983                                                   
984 #ifdef G4DEBUG_PATHFINDER                         
985   if( fVerboseLevel > 1 )                         
986   {                                               
987     G4int oldPrec= G4cout.precision(14);          
988     G4cout << "G4PathFinder::DoNextLinearStep     
989            << " initialPosition = " << initial    
990            << " and endPosition = " << endPosi    
991     G4cout.precision(oldPrec);                    
992   }                                               
993 #endif                                            
994                                                   
995   fEndState.SetPosition( endPosition );           
996   fEndState.SetProperTimeOfFlight( -1.000 );      
997                                                   
998   if( fNoActiveNavigators == 1 )                  
999   {                                               
1000      G4bool transportLimited = (fMinStep!= kI    
1001      fLimitTruth[IdTransport] = transportLimi    
1002      fLimitedStep[IdTransport] = transportLim    
1003                                                  
1004      // Set fNoGeometriesLimiting - as WhichL    
1005      fNoGeometriesLimiting = transportLimited    
1006   }                                              
1007   else                                           
1008   {                                              
1009      WhichLimited();                             
1010   }                                              
1011                                                  
1012 #ifdef G4DEBUG_PATHFINDER                        
1013   if( fVerboseLevel > 2 )                        
1014   {                                              
1015     G4cout << " G4PathFinder::DoNextLinearSte    
1016            << minStep << G4endl;                 
1017     G4cout << " - Endpoint values = " << fEnd    
1018     G4cout << G4endl;                            
1019   }                                              
1020 #endif                                           
1021                                                  
1022   return minStep;                                
1023 }                                                
1024                                                  
1025 void G4PathFinder::WhichLimited()                
1026 {                                                
1027   // Flag which processes limited the step       
1028                                                  
1029   G4int num = -1, last = -1;                     
1030   G4int noLimited = 0;                           
1031   ELimited shared = kSharedOther;                
1032                                                  
1033   const G4int IdTransport = 0;  // Id of Mass    
1034                                                  
1035   // Assume that [IdTransport] is Mass / Tran    
1036   //                                             
1037   G4bool transportLimited = (fCurrentStepSize    
1038                          && (fMinStep != kInf    
1039                                                  
1040   if( transportLimited )                         
1041   {                                              
1042      shared= kSharedTransport;                   
1043   }                                              
1044                                                  
1045   for ( num = 0; num < fNoActiveNavigators; +    
1046   {                                              
1047     G4bool limitedStep;                          
1048                                                  
1049     G4double step = fCurrentStepSize[num];       
1050                                                  
1051     limitedStep = ( std::fabs(step - fMinStep    
1052                && ( step != kInfinity);          
1053                                                  
1054     fLimitTruth[ num ] = limitedStep;            
1055     if( limitedStep )                            
1056     {                                            
1057       ++noLimited;                               
1058       fLimitedStep[num] = shared;                
1059       last= num;                                 
1060     }                                            
1061     else                                         
1062     {                                            
1063       fLimitedStep[num] = kDoNot;                
1064     }                                            
1065   }                                              
1066   fNoGeometriesLimiting= noLimited;  // Save     
1067                                                  
1068   if( (last > -1) && (noLimited == 1 ) )         
1069   {                                              
1070     fLimitedStep[ last ] = kUnique;              
1071   }                                              
1072                                                  
1073 #ifdef G4DEBUG_PATHFINDER                        
1074   if( fVerboseLevel > 1 )                        
1075   {                                              
1076     PrintLimited();   // --> for tracing         
1077     if( fVerboseLevel > 4 )                      
1078     {                                            
1079       G4cout << " G4PathFinder::WhichLimited     
1080     }                                            
1081   }                                              
1082 #endif                                           
1083 }                                                
1084                                                  
1085 void G4PathFinder::PrintLimited()                
1086 {                                                
1087   // Report results -- for checking              
1088                                                  
1089   G4cout << "G4PathFinder::PrintLimited repor    
1090   G4cout << "  Minimum step (true)= " << fTru    
1091          << "  reported min = " << fMinStep      
1092          << G4endl;                              
1093   if(  (fCurrentStepNo <= 2) || (fVerboseLeve    
1094   {                                              
1095     G4cout << std::setw(5) << " Step#"  << "     
1096            << std::setw(5) << " NavId"  << "     
1097            << std::setw(12) << " step-size "     
1098            << std::setw(12) << " raw-size "      
1099            << std::setw(12) << " pre-safety "    
1100            << std::setw(15) << " Limited / fl    
1101            << std::setw(15) << "  World "  <<    
1102            << G4endl;                            
1103   }                                              
1104   for ( auto num = 0; num < fNoActiveNavigato    
1105   {                                              
1106     G4double rawStep = fCurrentStepSize[num];    
1107     G4double stepLen = fCurrentStepSize[num];    
1108     if( stepLen > fTrueMinStep )                 
1109     {                                            
1110       stepLen = fTrueMinStep;     // did not     
1111     }                                            
1112     G4long oldPrec = G4cout.precision(9);        
1113                                                  
1114     G4cout << std::setw(5) << fCurrentStepNo     
1115            << std::setw(5) << num  << " "        
1116            << std::setw(12) << stepLen << " "    
1117            << std::setw(12) << rawStep << " "    
1118            << std::setw(12) << fCurrentPreSte    
1119            << std::setw(5) << (fLimitTruth[nu    
1120     G4String limitedStr= LimitedString(fLimit    
1121     G4cout << " " << std::setw(15) << limited    
1122     G4cout.precision(oldPrec);                   
1123                                                  
1124     G4Navigator* pNav = GetNavigator( num );     
1125     G4String  WorldName( "Not-Set" );            
1126     if (pNav != nullptr)                         
1127     {                                            
1128        G4VPhysicalVolume *pWorld = pNav->GetW    
1129        if( pWorld != nullptr )                   
1130        {                                         
1131           WorldName = pWorld->GetName();         
1132        }                                         
1133     }                                            
1134     G4cout << " " << WorldName ;                 
1135     G4cout << G4endl;                            
1136   }                                              
1137                                                  
1138   if( fVerboseLevel > 4 )                        
1139   {                                              
1140     G4cout << " G4PathFinder::PrintLimited -     
1141   }                                              
1142 }                                                
1143                                                  
1144 G4double                                         
1145 G4PathFinder::DoNextCurvedStep( const G4Field    
1146                                       G4doubl    
1147                                 G4VPhysicalVo    
1148 {                                                
1149   const G4double toleratedRelativeError = 1.0    
1150   G4double minStep= kInfinity, newSafety = 0.    
1151   G4int numNav;                                  
1152   G4FieldTrack fieldTrack = initialState;        
1153   G4ThreeVector startPoint = initialState.Get    
1154                                                  
1155                                                  
1156   G4EquationOfMotion* equationOfMotion =         
1157      fpFieldPropagator->GetCurrentEquationOfM    
1158                                                  
1159   equationOfMotion->SetChargeMomentumMass( *(    
1160                                            in    
1161                                            in    
1162                                                  
1163 #ifdef G4DEBUG_PATHFINDER                        
1164   G4int prc = G4cout.precision(9);               
1165   if( fVerboseLevel > 2 )                        
1166   {                                              
1167     G4cout << " G4PathFinder::DoNextCurvedSte    
1168     G4cout << " Initial value of field track     
1169            << " and proposed step= " << propo    
1170   }                                              
1171 #endif                                           
1172                                                  
1173   fPreStepCenterRenewed = true; // Always upd    
1174                                                  
1175   if( fNoActiveNavigators > 1 )                  
1176   {                                              
1177      // Calculate the safety values before ma    
1178                                                  
1179      G4double minSafety= kInfinity, safety;      
1180      for( numNav=0; numNav < fNoActiveNavigat    
1181      {                                           
1182         safety= fpNavigator[numNav]->ComputeS    
1183         fPreSafetyValues[numNav] = safety;       
1184         fCurrentPreStepSafety[numNav] = safet    
1185         minSafety = std::min( safety, minSafe    
1186      }                                           
1187                                                  
1188      // Save safety value, related position      
1189                                                  
1190      fPreSafetyLocation = startPoint;            
1191      fPreSafetyMinValue = minSafety;             
1192      fPreStepLocation = startPoint;              
1193      fMinSafety_PreStepPt = minSafety;           
1194   }                                              
1195                                                  
1196   // Allow Propagator In Field to do the hard    
1197   //                                             
1198   minStep = fpFieldPropagator->ComputeStep( f    
1199                                             p    
1200                                             n    
1201                                             p    
1202                                             f    
1203                                                  
1204   // fieldTrack now contains the endpoint inf    
1205   //                                             
1206   fEndState = fieldTrack;                        
1207   fMinStep = minStep;                            
1208   fTrueMinStep = std::min( minStep, proposedS    
1209                                                  
1210   if( fNoActiveNavigators == 1 )                 
1211   {                                              
1212      // Update the 'PreSafety' sphere - as an    
1213      // (must be done anyway in field)           
1214                                                  
1215      fPreSafetyValues[0] = newSafety;            
1216      fPreSafetyLocation = startPoint;            
1217      fPreSafetyMinValue = newSafety;             
1218                                                  
1219      // Update the current 'PreStep' point's     
1220      //                                          
1221      fCurrentPreStepSafety[0] = newSafety;       
1222      fPreStepLocation = startPoint;              
1223      fMinSafety_PreStepPt= newSafety;            
1224   }                                              
1225                                                  
1226 #ifdef G4DEBUG_PATHFINDER                        
1227   if( fVerboseLevel > 2 )                        
1228   {                                              
1229     G4cout << "G4PathFinder::DoNextCurvedStep    
1230            << " initialState = " << initialSt    
1231            << " and endState = " << fEndState    
1232     G4cout << "G4PathFinder::DoNextCurvedStep    
1233            << " minStep = " << minStep           
1234            << " proposedStepLength " << propo    
1235            << " safety = " << newSafety << G4    
1236   }                                              
1237 #endif                                           
1238   G4double currentStepSize;   // = 0.0;          
1239   if( minStep < proposedStepLength ) // if ==    
1240   {                                              
1241     // Recover the remaining information from    
1242     // especially regarding which Navigator l    
1243                                                  
1244     G4int noLimited = 0;  //   No geometries     
1245     for( numNav=0; numNav < fNoActiveNavigato    
1246     {                                            
1247       G4double finalStep, lastPreSafety = 0.0    
1248       ELimited didLimit;                         
1249       G4bool limited;                            
1250                                                  
1251       finalStep=  fpMultiNavigator->ObtainFin    
1252                                                  
1253                                                  
1254       // Calculate the step for this geometry    
1255       // final step (the only one which can d    
1256                                                  
1257       currentStepSize = fTrueMinStep;            
1258       G4double diffStep = 0.0;                   
1259       if( (minStepLast != kInfinity) )           
1260       {                                          
1261         diffStep = (finalStep-minStepLast);      
1262         if ( std::abs(diffStep) <= toleratedR    
1263         {                                        
1264           diffStep = 0.0;                        
1265         }                                        
1266         currentStepSize += diffStep;             
1267       }                                          
1268       fCurrentStepSize[numNav] = currentStepS    
1269                                                  
1270       // TODO: could refine the way to obtain    
1271       //     - for pre step safety               
1272       //        notify MultiNavigator about n    
1273       //        allow it to return this value    
1274       //        instead of lastPreSafety (or     
1275       //     - for final step start (availabl    
1276       //        get final Step start from Mul    
1277       //        and corresponding safety valu    
1278       // and/or ALSO calculate ComputeSafety     
1279       //     endSafety= fpNavigator[numNav]->    
1280                                                  
1281       fLimitedStep[numNav] = didLimit;           
1282       fLimitTruth[numNav] = limited = (didLim    
1283       if( limited ) { ++noLimited; }             
1284                                                  
1285 #ifdef G4DEBUG_PATHFINDER                        
1286       G4bool StepError = (currentStepSize < 0    
1287                       || ( (minStepLast != kI    
1288       if( StepError || (fVerboseLevel > 2) )     
1289       {                                          
1290         G4String  limitedString =  LimitedStr    
1291                                                  
1292         G4cout << " G4PathFinder::ComputeStep    
1293                << "  step= " << fCurrentStepS    
1294                << " from final-step= " << fin    
1295                << " fTrueMinStep= " << fTrueM    
1296                << " minStepLast= "  << minSte    
1297                << "  limited = " << (fLimitTr    
1298                << " ";                           
1299         G4cout << "  status = " << limitedStr    
1300                << G4endl;                        
1301                                                  
1302         if( StepError )                          
1303         {                                        
1304           std::ostringstream message;            
1305           message << "Incorrect calculation o    
1306                   << G4endl                      
1307                   << "        currentStepSize    
1308                   << ", diffStep= " << diffSt    
1309                   << "ERROR in computing step    
1310           G4Exception("G4PathFinder::DoNextCu    
1311                       "GeomNav0003", FatalExc    
1312         }                                        
1313       }                                          
1314 #endif                                           
1315     } // for num Navigators                      
1316                                                  
1317     fNoGeometriesLimiting = noLimited;  // Sa    
1318   }                                              
1319   else if ( (minStep == proposedStepLength)      
1320             || (minStep == kInfinity)            
1321             || ( std::abs(minStep-proposedSte    
1322                < toleratedRelativeError * pro    
1323   {                                              
1324     // In case the step was not limited, use     
1325     //  --> all Navigators                       
1326     // Also avoid problems in case of PathFin    
1327     //  - it is possible that the Navigators     
1328     //    if the safety was already satisfact    
1329     //    (In that case calling ObtainFinalSt    
1330                                                  
1331     currentStepSize = minStep;                   
1332     for( numNav=0; numNav < fNoActiveNavigato    
1333     {                                            
1334       fCurrentStepSize[numNav] = minStep;        
1335       // Safety for endpoint ??  // Can event    
1336       fLimitedStep[numNav] = kDoNot;             
1337       fLimitTruth[numNav] = false;               
1338     }                                            
1339     fNoGeometriesLimiting = 0;  // Save # pro    
1340   }                                              
1341   else    //  (minStep > proposedStepLength)     
1342   {                                              
1343     std::ostringstream message;                  
1344     message << "Incorrect calculation of step    
1345             << "        currentStepSize = " <    
1346             << " proposed StepSize = " << pro    
1347     G4Exception("G4PathFinder::DoNextCurvedSt    
1348                 "GeomNav0003", FatalException    
1349   }                                              
1350                                                  
1351 #ifdef G4DEBUG_PATHFINDER                        
1352   if( fVerboseLevel > 2 )                        
1353   {                                              
1354     G4cout << " Exiting G4PathFinder::DoNextC    
1355     PrintLimited();                              
1356   }                                              
1357   G4cout.precision(prc);                         
1358 #endif                                           
1359                                                  
1360   return minStep;                                
1361 }                                                
1362                                                  
1363 G4String& G4PathFinder::LimitedString( ELimit    
1364 {                                                
1365   static G4String StrDoNot("DoNot"),             
1366                   StrUnique("Unique"),           
1367                   StrUndefined("Undefined"),     
1368                   StrSharedTransport("SharedT    
1369                   StrSharedOther("SharedOther    
1370                                                  
1371   G4String* limitedStr;                          
1372   switch ( lim )                                 
1373   {                                              
1374      case kDoNot:  limitedStr = &StrDoNot; br    
1375      case kUnique: limitedStr = &StrUnique; b    
1376      case kSharedTransport:  limitedStr = &St    
1377      case kSharedOther: limitedStr = &StrShar    
1378      default: limitedStr = &StrUndefined; bre    
1379   }                                              
1380   return *limitedStr;                            
1381 }                                                
1382                                                  
1383 void G4PathFinder::PushPostSafetyToPreSafety(    
1384 {                                                
1385   fPreSafetyLocation = fSafetyLocation;          
1386   fPreSafetyMinValue = fMinSafety_atSafLocati    
1387   for( auto nav=0; nav < fNoActiveNavigators;    
1388   {                                              
1389      fPreSafetyValues[nav] = fNewSafetyComput    
1390   }                                              
1391 }                                                
1392