Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/navigation/src/G4PropagatorInField.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/G4PropagatorInField.cc (Version 11.3.0) and /geometry/navigation/src/G4PropagatorInField.cc (Version 5.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 // class G4PropagatorInField Implementation       
 27 //                                                
 28 //  This class implements an algorithm to trac    
 29 //  non-uniform magnetic field. It utilises an    
 30 //  the Runge - Kutta method) to evolve the pa    
 31 //  until the particle has traveled a set dist    
 32 //  volume.                                       
 33 //                                                
 34 // 14.10.96 John Apostolakis, design and imple    
 35 // 17.03.97 John Apostolakis, renaming new set    
 36 // -------------------------------------------    
 37                                                   
 38 #include <iomanip>                                
 39                                                   
 40 #include "G4PropagatorInField.hh"                 
 41 #include "G4ios.hh"                               
 42 #include "G4SystemOfUnits.hh"                     
 43 #include "G4ThreeVector.hh"                       
 44 #include "G4Material.hh"                          
 45 #include "G4VPhysicalVolume.hh"                   
 46 #include "G4Navigator.hh"                         
 47 #include "G4GeometryTolerance.hh"                 
 48 #include "G4VCurvedTrajectoryFilter.hh"           
 49 #include "G4ChordFinder.hh"                       
 50 #include "G4MultiLevelLocator.hh"                 
 51                                                   
 52                                                   
 53 // -------------------------------------------    
 54 // Constructors and destructor                    
 55 //                                                
 56 G4PropagatorInField::G4PropagatorInField( G4Na    
 57                                           G4Fi    
 58                                           G4VI    
 59   : fDetectorFieldMgr(detectorFieldMgr),          
 60     fNavigator(theNavigator),                     
 61     fCurrentFieldMgr(detectorFieldMgr),           
 62     End_PointAndTangent(G4ThreeVector(0.,0.,0.    
 63                         G4ThreeVector(0.,0.,0.    
 64 {                                                 
 65   fEpsilonStep = (fDetectorFieldMgr != nullptr    
 66                ? fDetectorFieldMgr->GetMaximum    
 67                                                   
 68                                                   
 69   fPreviousSftOrigin = G4ThreeVector(0.,0.,0.)    
 70   kCarTolerance = G4GeometryTolerance::GetInst    
 71   fZeroStepThreshold = std::max( 1.0e5 * kCarT    
 72                                                   
 73   fLargestAcceptableStep = 100.0 * meter;  //     
 74   fMaxStepSizeMultiplier=   0.1 ;   // 0.1 in     
 75   fMinBigDistance= 100. * CLHEP::mm;              
 76 #ifdef G4DEBUG_FIELD                              
 77   G4cout << " PiF: Zero Step Threshold set to     
 78          << fZeroStepThreshold / millimeter       
 79          << " mm." << G4endl;                     
 80   G4cout << " PiF:   Value of kCarTolerance =     
 81          << kCarTolerance / millimeter            
 82          << " mm. " << G4endl;                    
 83   fVerboseLevel = 2;                              
 84   fVerbTracePiF = true;                           
 85 #endif                                            
 86                                                   
 87   // Defining Intersection Locator and his par    
 88   if ( vLocator == nullptr )                      
 89   {                                               
 90     fIntersectionLocator = new G4MultiLevelLoc    
 91     fAllocatedLocator = true;                     
 92   }                                               
 93   else                                            
 94   {                                               
 95     fIntersectionLocator = vLocator;              
 96     fAllocatedLocator = false;                    
 97   }                                               
 98   RefreshIntersectionLocator();  //  Copy all     
 99 }                                                 
100                                                   
101 // -------------------------------------------    
102 //                                                
103 G4PropagatorInField::~G4PropagatorInField()       
104 {                                                 
105   if(fAllocatedLocator)  { delete  fIntersecti    
106 }                                                 
107                                                   
108 // -------------------------------------------    
109 // Update the IntersectionLocator with current    
110 //                                                
111 void G4PropagatorInField::RefreshIntersectionL    
112 {                                                 
113   fIntersectionLocator->SetEpsilonStepFor(fEps    
114   fIntersectionLocator->SetDeltaIntersectionFo    
115   fIntersectionLocator->SetChordFinderFor(GetC    
116   fIntersectionLocator->SetSafetyParametersFor    
117 }                                                 
118                                                   
119 // -------------------------------------------    
120 // Compute the next geometric Step                
121 //                                                
122 G4double G4PropagatorInField::ComputeStep(        
123                 G4FieldTrack&      pFieldTrack    
124                 G4double           CurrentProp    
125                 G4double&          currentSafe    
126                 G4VPhysicalVolume* pPhysVol,      
127                 G4bool             canRelaxDel    
128 {                                                 
129   GetChordFinder()->OnComputeStep(&pFieldTrack    
130   const G4double deltaChord = GetChordFinder()    
131                                                   
132   // If CurrentProposedStepLength is too small    
133   // then return with no action (for now - TOD    
134   //                                              
135   const char* methodName = "G4PropagatorInFiel    
136   if (CurrentProposedStepLength<kCarTolerance)    
137   {                                               
138     return kInfinity;                             
139   }                                               
140                                                   
141   // Introducing smooth trajectory display (ja    
142   //                                              
143   if (fpTrajectoryFilter != nullptr)              
144   {                                               
145     fpTrajectoryFilter->CreateNewTrajectorySeg    
146   }                                               
147                                                   
148   fFirstStepInVolume = fNewTrack ? true : fLas    
149   fLastStepInVolume = false;                      
150   fNewTrack = false;                              
151                                                   
152   if( fVerboseLevel > 2 )                         
153   {                                               
154     G4cout << methodName << " called" << G4end    
155     G4cout << "   Starting FT: " << pFieldTrac    
156     G4cout << "   Requested length = " << Curr    
157     G4cout << "   PhysVol = ";                    
158     if( pPhysVol != nullptr )                     
159     {                                             
160        G4cout << pPhysVol->GetName() << G4endl    
161     }                                             
162     else                                          
163     {                                             
164        G4cout << " N/A ";                         
165     }                                             
166     G4cout << G4endl;                             
167   }                                               
168                                                   
169   // Parameters for adaptive Runge-Kutta integ    
170                                                   
171   G4double h_TrialStepSize;        // 1st Step    
172   G4double TruePathLength = CurrentProposedSte    
173   G4double StepTaken = 0.0;                       
174   G4double s_length_taken, epsilon;               
175   G4bool   intersects;                            
176   G4bool   first_substep = true;                  
177                                                   
178   G4double NewSafety;                             
179   fParticleIsLooping = false;                     
180                                                   
181   // If not yet done,                             
182   //   Set the field manager to the local  one    
183   //                      or to the global one    
184   //                                              
185   if( !fSetFieldMgr )                             
186   {                                               
187     fCurrentFieldMgr = FindAndSetFieldManager(    
188   }                                               
189   fSetFieldMgr = false; // For next call, the     
190                                                   
191   G4FieldTrack CurrentState(pFieldTrack);         
192   G4FieldTrack OriginalState = CurrentState;      
193                                                   
194   // If the Step length is "infinite", then an    
195   // length (used to calculate the relative ac    
196   //                                              
197   if( CurrentProposedStepLength >= fLargestAcc    
198   {                                               
199     G4ThreeVector StartPointA, VelocityUnit;      
200     StartPointA  = pFieldTrack.GetPosition();     
201     VelocityUnit = pFieldTrack.GetMomentumDir(    
202                                                   
203     G4double trialProposedStep = fMaxStepSizeM    
204       fNavigator->GetWorldVolume()->GetLogical    
205                   GetSolid()->DistanceToOut(St    
206     CurrentProposedStepLength = std::min( tria    
207                                           fLar    
208   }                                               
209   epsilon = fCurrentFieldMgr->GetDeltaOneStep(    
210   G4double epsilonMin= fCurrentFieldMgr->GetMi    
211   G4double epsilonMax= fCurrentFieldMgr->GetMa    
212   if( epsilon < epsilonMin )  { epsilon = epsi    
213   if( epsilon > epsilonMax )  { epsilon = epsi    
214   SetEpsilonStep( epsilon );                      
215                                                   
216   // Values for Intersection Locator has to be    
217   // case that CurrentFieldManager has changed    
218   //                                              
219   RefreshIntersectionLocator();                   
220                                                   
221   // Shorten the proposed step in case of earl    
222   //                                              
223   if( fNoZeroStep > fActionThreshold_NoZeroSte    
224   {                                               
225     G4double stepTrial;                           
226                                                   
227     stepTrial = fFull_CurveLen_of_LastAttempt;    
228     if( (stepTrial <= 0.0) && (fLast_ProposedS    
229     {                                             
230       stepTrial = fLast_ProposedStepLength;       
231     }                                             
232                                                   
233     G4double decreaseFactor = 0.9; // Unused d    
234     if(   (fNoZeroStep < fSevereActionThreshol    
235        && (stepTrial > 100.0*fZeroStepThreshol    
236     {                                             
237       // Attempt quick convergence                
238       //                                          
239       decreaseFactor= 0.25;                       
240     }                                             
241     else                                          
242     {                                             
243       // We are in significant difficulties, p    
244       // is either geometrically sharp or betw    
245       // Careful decreases to cope with tolera    
246       //                                          
247       if( stepTrial > 100.0*fZeroStepThreshold    
248         decreaseFactor = 0.35;     // Try decr    
249       } else if( stepTrial > 30.0*fZeroStepThr    
250         decreaseFactor= 0.5;       // Try yet     
251       } else if( stepTrial > 10.0*fZeroStepThr    
252         decreaseFactor= 0.75;      // Try even    
253       } else {                                    
254         decreaseFactor= 0.9;       // Try very    
255       }                                           
256      }                                            
257      stepTrial *= decreaseFactor;                 
258                                                   
259 #ifdef G4DEBUG_FIELD                              
260      if( fVerboseLevel > 2                        
261       || (fNoZeroStep >= fSevereActionThreshol    
262      {                                            
263         G4cerr << " " << methodName               
264                << "  Decreasing step after " <    
265                << " - in volume " << pPhysVol;    
266         if( pPhysVol )                            
267            G4cerr << " with name " << pPhysVol    
268         else                                      
269            G4cerr << " i.e. *unknown* volume."    
270         G4cerr << G4endl;                         
271         PrintStepLengthDiagnostic(CurrentPropo    
272                                   stepTrial, p    
273      }                                            
274 #endif                                            
275      if( stepTrial == 0.0 )  //  Change to mak    
276      {                                            
277        std::ostringstream message;                
278        message << "Particle abandoned due to l    
279                << G4endl                          
280                << "  Properties : " << pFieldT    
281                << "  Attempting a zero step =     
282                << "  while attempting to progr    
283                << " trial steps. Will abandon     
284        G4Exception(methodName, "GeomNav1002",     
285        fParticleIsLooping = true;                 
286        return 0;  // = stepTrial;                 
287      }                                            
288      if( stepTrial < CurrentProposedStepLength    
289      {                                            
290        CurrentProposedStepLength = stepTrial;     
291      }                                            
292   }                                               
293   fLast_ProposedStepLength = CurrentProposedSt    
294                                                   
295   G4int do_loop_count = 0;                        
296   do  // Loop checking, 07.10.2016, JA            
297   {                                               
298     G4FieldTrack SubStepStartState = CurrentSt    
299     G4ThreeVector SubStartPoint = CurrentState    
300                                                   
301     if(!first_substep)                            
302     {                                             
303       if( fVerboseLevel > 4 )                     
304       {                                           
305         G4cout << " PiF: Calling Nav/Locate Gl    
306                << G4endl;                         
307       }                                           
308       fNavigator->LocateGlobalPointWithinVolum    
309     }                                             
310                                                   
311     // How far to attempt to move the particle    
312     //                                            
313     h_TrialStepSize = CurrentProposedStepLengt    
314                                                   
315     if (canRelaxDeltaChord &&                     
316         fIncreaseChordDistanceThreshold > 0  &    
317         do_loop_count > fIncreaseChordDistance    
318         do_loop_count % fIncreaseChordDistance    
319     {                                             
320         GetChordFinder()->SetDeltaChord(          
321           GetChordFinder()->GetDeltaChord() *     
322         );                                        
323     }                                             
324                                                   
325     // Integrate as far as "chord miss" rule a    
326     //                                            
327     s_length_taken = GetChordFinder()->Advance    
328                              CurrentState,        
329                              h_TrialStepSize,     
330                              fEpsilonStep,        
331                              fPreviousSftOrigi    
332                              fPreviousSafety )    
333       // CurrentState is now updated with the     
334                                                   
335     fFull_CurveLen_of_LastAttempt = s_length_t    
336                                                   
337     G4ThreeVector EndPointB = CurrentState.Get    
338     G4ThreeVector InterSectionPointE;             
339     G4double      LinearStepLength;               
340                                                   
341     // Intersect chord AB with geometry           
342     //                                            
343     intersects= IntersectChord( SubStartPoint,    
344                                 NewSafety, Lin    
345                                 InterSectionPo    
346       // E <- Intersection Point of chord AB a    
347       //                                  or a    
348                                                   
349     if( first_substep )                           
350     {                                             
351        currentSafety = NewSafety;                 
352     } // Updating safety in other steps is pot    
353                                                   
354     if( intersects )                              
355     {                                             
356        G4FieldTrack IntersectPointVelct_G(Curr    
357                                                   
358        // Find the intersection point of AB tr    
359        //   of vol(A), if it exists. Start wit    
360        G4bool recalculatedEndPt = false;          
361                                                   
362        G4bool found_intersection = fIntersecti    
363          EstimateIntersectionPoint( SubStepSta    
364                                     InterSecti    
365                                     recalculat    
366                                     fPreviousS    
367        intersects = found_intersection;           
368        if( found_intersection )                   
369        {                                          
370           End_PointAndTangent= IntersectPointV    
371           StepTaken = TruePathLength = Interse    
372                                      - Origina    
373        }                                          
374        else                                       
375        {                                          
376           // Either "minor" chords do not inte    
377           // or else stopped (due to too many     
378           //                                      
379           if( recalculatedEndPt )                 
380           {                                       
381              G4double endAchieved = IntersectP    
382              G4double endExpected = CurrentSta    
383                                                   
384              // Detect failure - due to too ma    
385              G4bool shortEnd = endAchieved        
386                              < (endExpected*(1    
387                                                   
388              G4double stepAchieved = endAchiev    
389                                    - SubStepSt    
390                                                   
391              // Update remaining state - must     
392              // abandonned intersection           
393              //                                   
394              CurrentState = IntersectPointVelc    
395              s_length_taken = stepAchieved;       
396              if( shortEnd )                       
397              {                                    
398                 fParticleIsLooping = true;        
399              }                                    
400           }                                       
401        }                                          
402     }                                             
403     if( !intersects )                             
404     {                                             
405       StepTaken += s_length_taken;                
406                                                   
407       if (fpTrajectoryFilter != nullptr) // Fo    
408       {                                           
409         fpTrajectoryFilter->TakeIntermediatePo    
410       }                                           
411     }                                             
412     first_substep = false;                        
413                                                   
414 #ifdef G4DEBUG_FIELD                              
415     if( fNoZeroStep > fActionThreshold_NoZeroS    
416     {                                             
417       if( fNoZeroStep > fSevereActionThreshold    
418         G4cout << " Above 'Severe Action' thre    
419       else                                        
420         G4cout << " Above 'action' threshold -    
421       G4cout << " Number of zero steps = " <<     
422       printStatus( SubStepStartState,  // or O    
423                    CurrentState, CurrentPropos    
424                    NewSafety, do_loop_count, p    
425     }                                             
426     if( (fVerboseLevel > 1) && (do_loop_count     
427     {                                             
428       if( do_loop_count == fMax_loop_count-9 )    
429       {                                           
430         G4cout << " G4PropagatorInField::Compu    
431                << "  Difficult track - taking     
432         printStatus( SubStepStartState, SubSte    
433                      NewSafety, 0, pPhysVol );    
434       }                                           
435       printStatus( SubStepStartState, CurrentS    
436                    NewSafety, do_loop_count, p    
437     }                                             
438 #endif                                            
439                                                   
440     ++do_loop_count;                              
441                                                   
442   } while( (!intersects )                         
443         && (!fParticleIsLooping)                  
444         && (StepTaken + kCarTolerance < Curren    
445         && ( do_loop_count < fMax_loop_count )    
446                                                   
447   if(  do_loop_count >= fMax_loop_count           
448     && (StepTaken + kCarTolerance < CurrentPro    
449   {                                               
450     fParticleIsLooping = true;                    
451   }                                               
452   if ( ( fParticleIsLooping ) && (fVerboseLeve    
453   {                                               
454     ReportLoopingParticle( do_loop_count, Step    
455                            CurrentProposedStep    
456                            CurrentState.GetMom    
457   }                                               
458                                                   
459   if( !intersects )                               
460   {                                               
461     // Chord AB or "minor chords" do not inter    
462     // B is the endpoint Step of the current S    
463     //                                            
464     End_PointAndTangent = CurrentState;           
465     TruePathLength = StepTaken;   //  Original    
466                                                   
467     // Tried the following to avoid potential     
468     // - but has issues... Suppressing this ch    
469     // TruePathLength = CurrentProposedStepLen    
470   }                                               
471   fLastStepInVolume = intersects;                 
472                                                   
473   // Set pFieldTrack to the return value          
474   //                                              
475   pFieldTrack = End_PointAndTangent;              
476                                                   
477 #ifdef G4VERBOSE                                  
478   // Check that "s" is correct                    
479   //                                              
480   if( std::fabs(OriginalState.GetCurveLength()    
481       - End_PointAndTangent.GetCurveLength())     
482   {                                               
483     std::ostringstream message;                   
484     message << "Curve length mis-match between    
485             << "and proposed endpoint of propa    
486             << "  The curve length of the endp    
487             << OriginalState.GetCurveLength()     
488             << "  and it is instead: "            
489             << End_PointAndTangent.GetCurveLen    
490             << "  A difference of: "              
491             << OriginalState.GetCurveLength()     
492                - End_PointAndTangent.GetCurveL    
493             << "  Original state = " << Origin    
494             << "  Proposed state = " << End_Po    
495     G4Exception(methodName, "GeomNav0003", Fat    
496   }                                               
497 #endif                                            
498                                                   
499   if( TruePathLength+kCarTolerance >= CurrentP    
500   {                                               
501      fNoZeroStep = 0;                             
502   }                                               
503   else                                            
504   {                                               
505      // In particular anomalous cases, we can     
506      // We identify these cases and take corre    
507      //                                           
508      if( TruePathLength < std::max( fZeroStepT    
509      {                                            
510         ++fNoZeroStep;                            
511      }                                            
512      else                                         
513      {                                            
514         fNoZeroStep = 0;                          
515      }                                            
516   }                                               
517   if( fNoZeroStep > fAbandonThreshold_NoZeroSt    
518   {                                               
519      fParticleIsLooping = true;                   
520      ReportStuckParticle( fNoZeroStep, Current    
521                           fFull_CurveLen_of_La    
522      fNoZeroStep = 0;                             
523   }                                               
524                                                   
525   GetChordFinder()->SetDeltaChord(deltaChord);    
526   return TruePathLength;                          
527 }                                                 
528                                                   
529 // -------------------------------------------    
530 // Dumps status of propagator                     
531 //                                                
532 void                                              
533 G4PropagatorInField::printStatus( const G4Fiel    
534                                   const G4Fiel    
535                                         G4doub    
536                                         G4doub    
537                                         G4int     
538                                         G4VPhy    
539 {                                                 
540   const G4int verboseLevel = fVerboseLevel;       
541   const G4ThreeVector StartPosition       = St    
542   const G4ThreeVector StartUnitVelocity   = St    
543   const G4ThreeVector CurrentPosition     = Cu    
544   const G4ThreeVector CurrentUnitVelocity = Cu    
545                                                   
546   G4double step_len = CurrentFT.GetCurveLength    
547                                                   
548   G4long oldprec;   // cout/cerr precision set    
549                                                   
550   if( ((stepNo == 0) && (verboseLevel <3)) ||     
551   {                                               
552     oldprec = G4cout.precision(4);                
553     G4cout << std::setw( 5) << "Step#"            
554            << std::setw(10) << "  s  " << " "     
555            << std::setw(10) << "X(mm)" << " "     
556            << std::setw(10) << "Y(mm)" << " "     
557            << std::setw(10) << "Z(mm)" << " "     
558            << std::setw( 7) << " N_x " << " "     
559            << std::setw( 7) << " N_y " << " "     
560            << std::setw( 7) << " N_z " << " "     
561     G4cout << std::setw( 7) << " Delta|N|" <<     
562            << std::setw( 9) << "StepLen" << "     
563            << std::setw(12) << "StartSafety" <    
564            << std::setw( 9) << "PhsStep" << "     
565     if( startVolume != nullptr )                  
566       { G4cout << std::setw(18) << "NextVolume    
567     G4cout.precision(oldprec);                    
568     G4cout << G4endl;                             
569   }                                               
570   if((stepNo == 0) && (verboseLevel <=3))         
571   {                                               
572     // Recurse to print the start values          
573     //                                            
574     printStatus( StartFT, StartFT, -1.0, safet    
575   }                                               
576   if( verboseLevel <= 3 )                         
577   {                                               
578     if( stepNo >= 0)                              
579       { G4cout << std::setw( 4) << stepNo << "    
580     else                                          
581       { G4cout << std::setw( 5) << "Start" ; }    
582     oldprec = G4cout.precision(8);                
583     G4cout << std::setw(10) << CurrentFT.GetCu    
584     G4cout.precision(8);                          
585     G4cout << std::setw(10) << CurrentPosition    
586            << std::setw(10) << CurrentPosition    
587            << std::setw(10) << CurrentPosition    
588     G4cout.precision(4);                          
589     G4cout << std::setw( 7) << CurrentUnitVelo    
590            << std::setw( 7) << CurrentUnitVelo    
591            << std::setw( 7) << CurrentUnitVelo    
592     G4cout.precision(3);                          
593     G4cout << std::setw( 7)                       
594            << CurrentFT.GetMomentum().mag()-St    
595     G4cout << std::setw( 9) << step_len << " "    
596     G4cout << std::setw(12) << safety << " ";     
597     if( requestStep != -1.0 )                     
598       { G4cout << std::setw( 9) << requestStep    
599     else                                          
600       { G4cout << std::setw( 9) << "Init/NotKn    
601     if( startVolume != nullptr)                   
602       { G4cout << std::setw(12) << startVolume    
603     G4cout.precision(oldprec);                    
604     G4cout << G4endl;                             
605   }                                               
606   else // if( verboseLevel > 3 )                  
607   {                                               
608     //  Multi-line output                         
609                                                   
610     G4cout << "Step taken was " << step_len       
611            << " out of PhysicalStep = " <<  re    
612     G4cout << "Final safety is: " << safety <<    
613     G4cout << "Chord length = " << (CurrentPos    
614            << G4endl;                             
615     G4cout << G4endl;                             
616   }                                               
617 }                                                 
618                                                   
619 // -------------------------------------------    
620 // Prints Step diagnostics                        
621 //                                                
622 void                                              
623 G4PropagatorInField::PrintStepLengthDiagnostic    
624                           G4double CurrentProp    
625                           G4double decreaseFac    
626                           G4double stepTrial,     
627                     const G4FieldTrack& )         
628 {                                                 
629   G4long iprec= G4cout.precision(8);              
630   G4cout << " " << std::setw(12) << " PiF: NoZ    
631          << " " << std::setw(20) << " CurrentP    
632          << " " << std::setw(18) << " Full_cur    
633          << " " << std::setw(18) << " last pro    
634          << " " << std::setw(18) << " decrease    
635          << " " << std::setw(15) << " step tri    
636          << G4endl;                               
637                                                   
638   G4cout << " " << std::setw(10) << fNoZeroSte    
639          << " " << std::setw(20) << CurrentPro    
640          << " " << std::setw(18) << fFull_Curv    
641          << " " << std::setw(18) << fLast_Prop    
642          << " " << std::setw(18) << decreaseFa    
643          << " " << std::setw(15) << stepTrial     
644          << G4endl;                               
645   G4cout.precision( iprec );                      
646 }                                                 
647                                                   
648 // Access the points which have passed through    
649 // points are stored as ThreeVectors for the i    
650 // only (jacek 30/10/2002)                        
651 // Responsibility for deleting the points lies    
652 // SmoothTrajectoryPoint, which is the points'    
653 // destination. The points pointer is set to N    
654 // the points are not re-used in subsequent st    
655 // METHOD MUST BE CALLED EXACTLY ONCE PER STEP    
656                                                   
657 std::vector<G4ThreeVector>*                       
658 G4PropagatorInField::GimmeTrajectoryVectorAndF    
659 {                                                 
660   // NB, GimmeThePointsAndForgetThem really fo    
661   // only be called (exactly) once for each st    
662                                                   
663   if (fpTrajectoryFilter != nullptr)              
664   {                                               
665     return fpTrajectoryFilter->GimmeThePointsA    
666   }                                               
667   return nullptr;                                 
668 }                                                 
669                                                   
670 // -------------------------------------------    
671 //                                                
672 void                                              
673 G4PropagatorInField::SetTrajectoryFilter(G4VCu    
674 {                                                 
675   fpTrajectoryFilter = filter;                    
676 }                                                 
677                                                   
678 // -------------------------------------------    
679 //                                                
680 void G4PropagatorInField::ClearPropagatorState    
681 {                                                 
682   // Goal: Clear all memory of previous steps,    
683                                                   
684   fParticleIsLooping = false;                     
685   fNoZeroStep = 0;                                
686                                                   
687   fSetFieldMgr = false;  // Has field-manager     
688   fEpsilonStep= 1.0e-5;  // Relative accuracy     
689                                                   
690   End_PointAndTangent= G4FieldTrack( G4ThreeVe    
691                                      G4ThreeVe    
692                                      0.0,0.0,0    
693   fFull_CurveLen_of_LastAttempt = -1;             
694   fLast_ProposedStepLength = -1;                  
695                                                   
696   fPreviousSftOrigin= G4ThreeVector(0.,0.,0.);    
697   fPreviousSafety= 0.0;                           
698                                                   
699   fNewTrack = true;                               
700 }                                                 
701                                                   
702 // -------------------------------------------    
703 //                                                
704 G4FieldManager* G4PropagatorInField::             
705 FindAndSetFieldManager( G4VPhysicalVolume* pCu    
706 {                                                 
707   G4FieldManager* currentFieldMgr;                
708                                                   
709   currentFieldMgr = fDetectorFieldMgr;            
710   if( pCurrentPhysicalVolume != nullptr )         
711   {                                               
712      G4FieldManager *pRegionFieldMgr = nullptr    
713      G4LogicalVolume* pLogicalVol = pCurrentPh    
714                                                   
715      if( pLogicalVol != nullptr )                 
716      {                                            
717         // Value for Region, if any, overrides    
718         //                                        
719         G4Region*  pRegion = pLogicalVol->GetR    
720         if( pRegion != nullptr )                  
721         {                                         
722            pRegionFieldMgr = pRegion->GetField    
723            if( pRegionFieldMgr != nullptr )       
724            {                                      
725               currentFieldMgr= pRegionFieldMgr    
726            }                                      
727         }                                         
728                                                   
729         // 'Local' Value from logical volume,     
730         //                                        
731         localFieldMgr = pLogicalVol->GetFieldM    
732         if ( localFieldMgr != nullptr )           
733         {                                         
734            currentFieldMgr = localFieldMgr;       
735         }                                         
736      }                                            
737   }                                               
738   fCurrentFieldMgr = currentFieldMgr;             
739                                                   
740   // Flag that field manager has been set         
741   //                                              
742   fSetFieldMgr = true;                            
743                                                   
744   return currentFieldMgr;                         
745 }                                                 
746                                                   
747 // -------------------------------------------    
748 //                                                
749 G4int G4PropagatorInField::SetVerboseLevel( G4    
750 {                                                 
751   G4int oldval = fVerboseLevel;                   
752   fVerboseLevel = level;                          
753                                                   
754   // Forward the verbose level 'reduced' to Ch    
755   // MagIntegratorDriver ... ?                    
756   //                                              
757   auto integrDriver = GetChordFinder()->GetInt    
758   integrDriver->SetVerboseLevel( fVerboseLevel    
759   G4cout << "Set Driver verbosity to " << fVer    
760                                                   
761   return oldval;                                  
762 }                                                 
763                                                   
764 // -------------------------------------------    
765 //                                                
766 void G4PropagatorInField::ReportLoopingParticl    
767                                                   
768                                                   
769                                                   
770                                                   
771                                                   
772 {                                                 
773    std::ostringstream message;                    
774    G4double fraction = StepTaken / StepRequest    
775    message << " Unfinished integration of trac    
776            << " of momentum " << momentumVec <    
777            << momentumVec.mag() << " ) " << G4    
778            << " after " << count << " field su    
779            << " totaling " << std::setprecisio    
780            << " out of requested step " << std    
781            << StepRequested / mm << " mm ";       
782    message << " a fraction of ";                  
783    G4int prec = 4;                                
784    if( fraction > 0.99 )                          
785    {                                              
786      prec = 7;                                    
787    }                                              
788    else                                           
789    {                                              
790      if (fraction > 0.97 )  { prec = 5; }         
791    }                                              
792    message << std::setprecision(prec)             
793            << 100. * StepTaken / StepRequested    
794    if( pPhysVol != nullptr )                      
795    {                                              
796      message << " in volume " << pPhysVol->Get    
797      auto material = pPhysVol->GetLogicalVolum    
798      if( material != nullptr )                    
799      {                                            
800        message << " with material " << materia    
801                << " ( density = "                 
802                << material->GetDensity() / ( g    
803      }                                            
804    }                                              
805    else                                           
806    {                                              
807      message << " in unknown (null) volume. "     
808    }                                              
809    G4Exception(methodName, "GeomNav1002", Just    
810 }                                                 
811                                                   
812 // -------------------------------------------    
813 //                                                
814 void G4PropagatorInField::ReportStuckParticle(    
815                                                   
816                                                   
817                                                   
818 {                                                 
819    std::ostringstream message;                    
820    message << "Particle is stuck; it will be k    
821            << "  Zero progress for " << noZero    
822            << G4endl                              
823            << "  Proposed Step is " << propose    
824            << " but Step Taken is "<< lastTrie    
825    if( physVol != nullptr )                       
826    {                                              
827       message << " in volume " << physVol->Get    
828    }                                              
829    else                                           
830    {                                              
831       message << " in unknown or null volume.     
832    }                                              
833    G4Exception("G4PropagatorInField::ComputeSt    
834                "GeomNav1002", JustWarning, mes    
835 }                                                 
836                                                   
837 // -------------------------------------------    
838                                                   
839 // -------------------------------------------    
840 // Methods to alter Parameters                    
841 // -------------------------------------------    
842                                                   
843 // Was a data member (of an object) -- now mov    
844 G4double  G4PropagatorInField::GetLargestAccep    
845 {                                                 
846   return fLargestAcceptableStep;                  
847 }                                                 
848                                                   
849 // -------------------------------------------    
850 //                                                
851 void G4PropagatorInField::SetLargestAcceptable    
852 {                                                 
853   if( fLargestAcceptableStep>0.0 )                
854   {                                               
855     fLargestAcceptableStep = newBigDist;          
856   }                                               
857 }                                                 
858                                                   
859 // -------------------------------------------    
860                                                   
861 G4double G4PropagatorInField::GetMaxStepSizeMu    
862 {                                                 
863   return fMaxStepSizeMultiplier;                  
864 }                                                 
865                                                   
866 // -------------------------------------------    
867                                                   
868 void     G4PropagatorInField::SetMaxStepSizeMu    
869 {                                                 
870   fMaxStepSizeMultiplier=vm;                      
871 }                                                 
872                                                   
873 // -------------------------------------------    
874                                                   
875 G4double G4PropagatorInField::GetMinBigDistanc    
876 {                                                 
877   return fMinBigDistance;                         
878 }                                                 
879                                                   
880 // -------------------------------------------    
881                                                   
882 void     G4PropagatorInField::SetMinBigDistanc    
883 {                                                 
884   fMinBigDistance= val;                           
885 }                                                 
886