Geant4 Cross Reference

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


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // class G4BrentLocator implementation            
 27 //                                                
 28 // 27.10.08 - Tatiana Nikitina.                   
 29 // 04.10.11 - John Apostolakis, revised conver    
 30 // -------------------------------------------    
 31                                                   
 32 #include <iomanip>                                
 33                                                   
 34 #include "G4BrentLocator.hh"                      
 35 #include "G4ios.hh"                               
 36                                                   
 37 G4BrentLocator::G4BrentLocator(G4Navigator *th    
 38   : G4VIntersectionLocator(theNavigator)          
 39 {                                                 
 40   // In case of too slow progress in finding I    
 41   // intermediates Points on the Track must be    
 42   // Initialise the array of Pointers [max_dep    
 43                                                   
 44   G4ThreeVector zeroV(0.0,0.0,0.0);               
 45   for (auto & idepth : ptrInterMedFT)             
 46   {                                               
 47     idepth = new G4FieldTrack( zeroV, zeroV, 0    
 48   }                                               
 49 }                                                 
 50                                                   
 51 G4BrentLocator::~G4BrentLocator()                 
 52 {                                                 
 53   for (auto & idepth : ptrInterMedFT)             
 54   {                                               
 55     delete idepth;                                
 56   }                                               
 57 }                                                 
 58                                                   
 59 // -------------------------------------------    
 60 // G4bool G4PropagatorInField::LocateIntersect    
 61 //        const G4FieldTrack&       CurveStart    
 62 //        const G4FieldTrack&       CurveEndPo    
 63 //        const G4ThreeVector&      TrialPoint    
 64 //              G4FieldTrack&       Intersecte    
 65 //              G4bool&             recalculat    
 66 // -------------------------------------------    
 67 //                                                
 68 // Function that returns the intersection of t    
 69 // of the current volume (either the external     
 70 // of the daughters:                              
 71 //                                                
 72 //     A = Initial point                          
 73 //     B = another point                          
 74 //                                                
 75 // Both A and B are assumed to be on the true     
 76 //                                                
 77 //     E is the first point of intersection of    
 78 //     a volume other than A  (on the surface     
 79 //                                                
 80 // Convention of Use :                            
 81 //     i) If it returns "true", then Intersect    
 82 //        to the approximate intersection poin    
 83 //    ii) If it returns "false", no intersecti    
 84 //        The validity of IntersectedOrRecalcu    
 85 //        a) if latter is false, then Intersec    
 86 //        b) if latter is true,  then Intersec    
 87 //           the new endpoint, due to a re-int    
 88 // -------------------------------------------    
 89 // NOTE: implementation taken from G4Propagato    
 90 //       New second order locator is added        
 91 //                                                
 92 G4bool G4BrentLocator::EstimateIntersectionPoi    
 93          const  G4FieldTrack&       CurveStart    
 94          const  G4FieldTrack&       CurveEndPo    
 95          const  G4ThreeVector&      TrialPoint    
 96                 G4FieldTrack&       Intersecte    
 97                 G4bool&             recalculat    
 98                 G4double&           fPreviousS    
 99                 G4ThreeVector&      fPreviousS    
100                                                   
101 {                                                 
102   // Find Intersection Point ( A, B, E )  of t    
103                                                   
104   G4bool found_approximate_intersection = fals    
105   G4bool there_is_no_intersection       = fals    
106                                                   
107   G4FieldTrack  CurrentA_PointVelocity = Curve    
108   G4FieldTrack  CurrentB_PointVelocity = Curve    
109   G4ThreeVector CurrentE_Point = TrialPoint;      
110   G4bool        validNormalAtE = false;           
111   G4ThreeVector NormalAtEntry;                    
112                                                   
113   G4FieldTrack  ApproxIntersecPointV(CurveEndP    
114   G4double      NewSafety = 0.0;                  
115   G4bool        last_AF_intersection = false;     
116                                                   
117   // G4bool final_section= true;  // Shows whe    
118                                   // (i.e. B=f    
119   G4bool first_section = true;                    
120   recalculatedEndPoint = false;                   
121                                                   
122   G4bool restoredFullEndpoint = false;            
123                                                   
124   G4long oldprc;  // cout, cerr precision         
125   G4int substep_no = 0;                           
126                                                   
127   // Limits for substep number                    
128   //                                              
129   const G4int max_substeps=   10000;  // Test     
130   const G4int warn_substeps=   1000;  //          
131                                                   
132   // Statistics for substeps                      
133   //                                              
134   static G4ThreadLocal G4int max_no_seen= -1;     
135                                                   
136   // Counter for restarting Bintermed             
137   //                                              
138   G4int restartB = 0;                             
139                                                   
140   //------------------------------------------    
141   //  Algorithm for the case if progress in fo    
142   //  Process is defined too slow if after N=p    
143   //  path, it will be only 'fraction_done' of    
144   //  In this case the remaining length is div    
145   //  the loop is restarted for each half.        
146   //  If progress is still too slow, the divis    
147   //  until 'max_depth'.                          
148   //------------------------------------------    
149                                                   
150   const G4int param_substeps = 50; // Test val    
151                                    // of subst    
152   const G4double fraction_done = 0.3;             
153                                                   
154   G4bool Second_half = false;     // First hal    
155                                                   
156   NormalAtEntry = GetSurfaceNormal(CurrentE_Po    
157                                                   
158   // We need to know this for the 'final_secti    
159   // real 'final_section' or first half 'final    
160   // In algorithm it is considered that the 'S    
161   // and it becomes false only if we are in th    
162   // depthness or if we are in the first secti    
163                                                   
164   G4int depth = 0; // Depth counts how many su    
165                                                   
166 #ifdef G4DEBUG_FIELD                              
167   const G4double tolerance = 1.0e-8;              
168   G4ThreeVector  StartPosition = CurveStartPoi    
169   if( (TrialPoint - StartPosition).mag() < tol    
170   {                                               
171      G4Exception("G4BrentLocator::EstimateInte    
172                  "GeomNav1002", JustWarning,      
173                  "Intersection point F is exac    
174   }                                               
175 #endif                                            
176                                                   
177   // Intermediates Points on the Track = Subdi    
178   // Give the initial values to 'InterMedFt'      
179   // Important is 'ptrInterMedFT[0]', it saves    
180   //                                              
181   *ptrInterMedFT[0] = CurveEndPointVelocity;      
182   for (auto idepth=1; idepth<max_depth+1; ++id    
183   {                                               
184     *ptrInterMedFT[idepth] = CurveStartPointVe    
185   }                                               
186                                                   
187   //Final_section boolean store                   
188   G4bool fin_section_depth[max_depth];            
189   for (bool & idepth : fin_section_depth)         
190   {                                               
191     idepth = true;                                
192   }                                               
193                                                   
194   // 'SubStartPoint' is needed to calculate th    
195   //                                              
196   G4FieldTrack SubStart_PointVelocity = CurveS    
197                                                   
198   do   // Loop checking, 07.10.2016, J.Apostol    
199   {                                               
200     G4int substep_no_p = 0;                       
201     G4bool sub_final_section = false; // the s    
202                                       // but f    
203     SubStart_PointVelocity = CurrentA_PointVel    
204                                                   
205     do   // Loop checking, 07.10.2016, J.Apost    
206     { // REPEAT param                             
207       G4ThreeVector Point_A = CurrentA_PointVe    
208       G4ThreeVector Point_B = CurrentB_PointVe    
209                                                   
210       // F = a point on true AB path close to     
211       // (the closest if possible)                
212       //                                          
213       if(substep_no_p==0)                         
214       {                                           
215         ApproxIntersecPointV = GetChordFinderF    
216                                ->ApproxCurvePo    
217                                                   
218                                                   
219                                                   
220           //  The above method is the key & mo    
221       }                                           
222 #ifdef G4DEBUG_FIELD                              
223       if( ApproxIntersecPointV.GetCurveLength(    
224           CurrentB_PointVelocity.GetCurveLengt    
225       {                                           
226         G4Exception("G4BrentLocator::EstimateI    
227                     "GeomNav0003", FatalExcept    
228                     "Intermediate F point is p    
229       }                                           
230 #endif                                            
231                                                   
232       G4ThreeVector CurrentF_Point = ApproxInt    
233                                                   
234       // First check whether EF is small - the    
235       // Calculate the length and direction of    
236       //                                          
237       G4ThreeVector  ChordEF_Vector = CurrentF    
238       G4ThreeVector  NewMomentumDir = ApproxIn    
239       G4double       MomDir_dot_Norm = NewMome    
240                                                   
241 #ifdef G4DEBUG_FIELD                              
242       G4ThreeVector  ChordAB = Point_B - Point    
243                                                   
244       G4VIntersectionLocator::ReportTrialStep(    
245                ChordEF_Vector, NewMomentumDir,    
246 #endif                                            
247                                                   
248       G4bool adequate_angle;                      
249       adequate_angle =  ( MomDir_dot_Norm >= 0    
250                     || (! validNormalAtE );       
251       G4double EF_dist2 = ChordEF_Vector.mag2(    
252       if ( ( EF_dist2 <= sqr(fiDeltaIntersecti    
253         || ( EF_dist2 <= kCarTolerance*kCarTol    
254       {                                           
255         found_approximate_intersection = true;    
256                                                   
257         // Create the "point" return value        
258         //                                        
259         IntersectedOrRecalculatedFT = ApproxIn    
260         IntersectedOrRecalculatedFT.SetPositio    
261                                                   
262         if ( GetAdjustementOfFoundIntersection    
263         {                                         
264           // Try to Get Correction of Intersec    
265           //                                      
266           G4ThreeVector IP;                       
267           G4ThreeVector MomentumDir=ApproxInte    
268           G4bool goodCorrection = AdjustmentOf    
269                                     CurrentE_P    
270                                     last_AF_in    
271                                     fPreviousS    
272           if ( goodCorrection )                   
273           {                                       
274             IntersectedOrRecalculatedFT = Appr    
275             IntersectedOrRecalculatedFT.SetPos    
276           }                                       
277         }                                         
278                                                   
279         // Note: in order to return a point on    
280         //       we must return E. But it is F    
281         //       So we must "cheat": we are us    
282         //       and the velocity at point F !    
283         //                                        
284         // This must limit the length we can a    
285       }                                           
286       else  // E is NOT close enough to the cu    
287       {                                           
288         // Check whether any volumes are encou    
289         // -----------------------------------    
290         // First relocate to restore any Voxel    
291         // in the Navigator before calling Com    
292         //                                        
293         GetNavigatorFor()->LocateGlobalPointWi    
294                                                   
295         G4ThreeVector PointG;   // Candidate i    
296         G4double stepLengthAF;                    
297         G4bool usedNavigatorAF = false;           
298         G4bool Intersects_AF = IntersectChord(    
299                                                   
300                                                   
301                                                   
302                                                   
303                                                   
304         last_AF_intersection = Intersects_AF;     
305         if( Intersects_AF )                       
306         {                                         
307           // G is our new Candidate for the in    
308           // It replaces  "E" and we will repe    
309           // it is a good enough approximate p    
310           //       B    <- F                      
311           //       E    <- G                      
312           //                                      
313           G4FieldTrack EndPoint = ApproxInters    
314           ApproxIntersecPointV = GetChordFinde    
315                                  CurrentA_Poin    
316                                  EndPoint,Curr    
317                                  true, GetEpsi    
318           CurrentB_PointVelocity = EndPoint;      
319           CurrentE_Point = PointG;                
320                                                   
321           // Need to recalculate the Exit Norm    
322           // Know that a call was made to Navi    
323           // IntersectChord above.                
324           //                                      
325           G4bool validNormalLast;                 
326           NormalAtEntry  = GetSurfaceNormal( P    
327           validNormalAtE = validNormalLast;       
328                                                   
329           // By moving point B, must take care    
330           // AF has no intersection to try cur    
331           //                                      
332           fin_section_depth[depth] = false;       
333 #ifdef G4VERBOSE                                  
334           if( fVerboseLevel > 3 )                 
335           {                                       
336             G4cout << "G4PiF::LI> Investigatin    
337                    << " at s=" << ApproxInters    
338                    << " on way to full s="        
339                    << CurveEndPointVelocity.Ge    
340           }                                       
341 #endif                                            
342         }                                         
343         else  // not Intersects_AF                
344         {                                         
345           // In this case:                        
346           // There is NO intersection of AF wi    
347           // We must continue the search in th    
348           //                                      
349           GetNavigatorFor()->LocateGlobalPoint    
350                                                   
351           G4double stepLengthFB;                  
352           G4ThreeVector PointH;                   
353           G4bool usedNavigatorFB = false;         
354                                                   
355           // Check whether any volumes are enc    
356           // ---------------------------------    
357                                                   
358           G4bool Intersects_FB = IntersectChor    
359                                                   
360                                                   
361                                                   
362                                                   
363                                                   
364           if( Intersects_FB )                     
365           {                                       
366             // There is an intersection of FB     
367             // H <- First Intersection of Chor    
368                                                   
369             // H is our new Candidate for the     
370             // It replaces  "E" and we will re    
371             // it is a good enough approximate    
372                                                   
373             // Note that F must be in volume v    
374             // (otherwise AF would meet a volu    
375             //   A    <- F                        
376             //   E    <- H                        
377             //                                    
378             G4FieldTrack InterMed = ApproxInte    
379             ApproxIntersecPointV = GetChordFin    
380                           CurrentA_PointVeloci    
381                           InterMed,CurrentE_Po    
382                           false,GetEpsilonStep    
383             CurrentA_PointVelocity = InterMed;    
384             CurrentE_Point = PointH;              
385                                                   
386             // Need to recalculate the Exit No    
387             //                                    
388             G4bool validNormalLast;               
389             NormalAtEntry = GetSurfaceNormal(     
390             validNormalAtE = validNormalLast;     
391           }                                       
392           else  // not Intersects_FB              
393           {                                       
394             // There is NO intersection of FB     
395                                                   
396             if( fin_section_depth[depth]  )       
397             {                                     
398               // If B is the original endpoint    
399               // volume(s) intersected the ori    
400               // smaller chords we have used.     
401               // The value of 'IntersectedOrRe    
402               // likely not valid                 
403                                                   
404               // Check on real final_section o    
405               //                                  
406               if( ((Second_half)&&(depth==0))     
407               {                                   
408                 there_is_no_intersection = tru    
409               }                                   
410               else                                
411               {                                   
412                 // end of subsection, not real    
413                 // exit from the and go to the    
414                                                   
415                 substep_no_p = param_substeps+    
416                                                   
417                 // but 'Second_half' is still     
418                 // the 'CurrentE_point' for th    
419                 //                                
420                 Second_half = true;               
421                 sub_final_section = true;         
422               }                                   
423             }                                     
424             else                                  
425             {                                     
426               if( depth==0 )                      
427               {                                   
428                 // We must restore the origina    
429                 //                                
430                 CurrentA_PointVelocity = Curre    
431                 CurrentB_PointVelocity = Curve    
432                 SubStart_PointVelocity = Curre    
433                 ApproxIntersecPointV = GetChor    
434                                ->ApproxCurvePo    
435                                                   
436                                                   
437                                                   
438                                                   
439                 restoredFullEndpoint = true;      
440                 ++restartB; // counter            
441               }                                   
442               else                                
443               {                                   
444                 // We must restore the depth e    
445                 //                                
446                 CurrentA_PointVelocity = Curre    
447                 CurrentB_PointVelocity =  *ptr    
448                 SubStart_PointVelocity = Curre    
449                 ApproxIntersecPointV = GetChor    
450                                ->ApproxCurvePo    
451                                                   
452                                                   
453                                                   
454                 restoredFullEndpoint = true;      
455                 ++restartB; // counter            
456               }                                   
457             }                                     
458           } // Endif (Intersects_FB)              
459         } // Endif (Intersects_AF)                
460                                                   
461         // Ensure that the new endpoints are n    
462         // than on the curve due to different     
463         //                                        
464         G4double linDistSq, curveDist;            
465         linDistSq = ( CurrentB_PointVelocity.G    
466                     - CurrentA_PointVelocity.G    
467         curveDist = CurrentB_PointVelocity.Get    
468                     - CurrentA_PointVelocity.G    
469                                                   
470         // Change this condition for very stri    
471         //                                        
472         if( curveDist*curveDist*(1+2* GetEpsil    
473         {                                         
474           // Re-integrate to obtain a new B       
475           //                                      
476           G4FieldTrack newEndPointFT=             
477                   ReEstimateEndpoint( CurrentA    
478                                       CurrentB    
479                                       linDistS    
480                                       curveDis    
481           G4FieldTrack oldPointVelB = CurrentB    
482           CurrentB_PointVelocity = newEndPoint    
483                                                   
484           if ( (fin_section_depth[depth])         
485              &&( first_section  || ((Second_ha    
486           {                                       
487             recalculatedEndPoint = true;          
488             IntersectedOrRecalculatedFT = newE    
489               // So that we can return it, if     
490           }                                       
491         }                                         
492         if( curveDist < 0.0 )                     
493         {                                         
494           fVerboseLevel = 5; // Print out a ma    
495           printStatus( CurrentA_PointVelocity,    
496                        -1.0, NewSafety,  subst    
497           std::ostringstream message;             
498           message << "Error in advancing propa    
499                   << "        Error in advanci    
500                   << "        Point A (start)     
501                   << G4endl                       
502                   << "        Point B (end)       
503                   << G4endl                       
504                   << "        Curve distance i    
505                   << G4endl                       
506                   << "The final curve point is    
507                   << " than the original!" <<     
508                                                   
509           if( recalculatedEndPoint )              
510           {                                       
511             message << "Recalculation of EndPo    
512                     << GetEpsilonStepFor() <<     
513           }                                       
514           oldprc = G4cerr.precision(20);          
515           message << " Point A (Curve start)      
516                   << G4endl                       
517                   << " Point B (Curve   end)      
518                   << G4endl                       
519                   << " Point A (Current start)    
520                   << G4endl                       
521                   << " Point B (Current end)      
522                   << G4endl                       
523                   << " Point S (Sub start)        
524                   << G4endl                       
525                   << " Point E (Trial Point)      
526                   << G4endl                       
527                   << " Old Point F(Intersectio    
528                   << G4endl                       
529                   << " New Point F(Intersectio    
530                   << G4endl                       
531                   << "        LocateIntersecti    
532                   << substep_no << G4endl         
533                   << "        Substep depth no    
534                   << depth << G4endl              
535                   << "        Restarted no= "<    
536                   << GetEpsilonStepFor() <<" D    
537                   << GetDeltaIntersectionFor()    
538           G4cerr.precision( oldprc );             
539                                                   
540           G4Exception("G4BrentLocator::Estimat    
541                       "GeomNav0003", FatalExce    
542         }                                         
543                                                   
544         if( restoredFullEndpoint )                
545         {                                         
546           fin_section_depth[depth] = restoredF    
547           restoredFullEndpoint = false;           
548         }                                         
549       } // EndIf ( E is close enough to the cu    
550         // tests ChordAF_Vector.mag() <= maxim    
551                                                   
552 #ifdef G4DEBUG_LOCATE_INTERSECTION                
553       G4int trigger_substepno_print= warn_subs    
554                                                   
555       if( substep_no >= trigger_substepno_prin    
556       {                                           
557         G4cout << "Difficulty in converging in    
558                << "G4BrentLocator::EstimateInt    
559                << G4endl                          
560                << "    Substep no = " << subst    
561         if( substep_no == trigger_substepno_pr    
562         {                                         
563           printStatus( CurveStartPointVelocity    
564                        -1.0, NewSafety, 0);       
565         }                                         
566         G4cout << " State of point A: ";          
567         printStatus( CurrentA_PointVelocity, C    
568                      -1.0, NewSafety, substep_    
569         G4cout << " State of point B: ";          
570         printStatus( CurrentA_PointVelocity, C    
571                      -1.0, NewSafety, substep_    
572       }                                           
573 #endif                                            
574       ++substep_no;                               
575       ++substep_no_p;                             
576                                                   
577     } while (  ( ! found_approximate_intersect    
578             && ( ! there_is_no_intersection )     
579             && ( substep_no_p <= param_substep    
580                                                   
581     first_section = false;                        
582                                                   
583     if( (!found_approximate_intersection) && (    
584     {                                             
585       G4double did_len = std::abs( CurrentA_Po    
586                        - SubStart_PointVelocit    
587       G4double all_len = std::abs( CurrentB_Po    
588                        - SubStart_PointVelocit    
589                                                   
590       G4double stepLengthAB;                      
591       G4ThreeVector PointGe;                      
592                                                   
593       // Check if progress is too slow and if     
594       // then halve the step if so                
595       //                                          
596       if ( ( did_len < fraction_done*all_len )    
597         && (depth < max_depth) && (!sub_final_    
598       {                                           
599         Second_half=false;                        
600         ++depth;                                  
601                                                   
602         G4double Sub_len = (all_len-did_len)/(    
603         G4FieldTrack start = CurrentA_PointVel    
604         auto integrDriver =                       
605                          GetChordFinderFor()->    
606         integrDriver->AccurateAdvance(start, S    
607         *ptrInterMedFT[depth] = start;            
608         CurrentB_PointVelocity = *ptrInterMedF    
609                                                   
610         // Adjust 'SubStartPoint' to calculate    
611         //                                        
612         SubStart_PointVelocity = CurrentA_Poin    
613                                                   
614         // Find new trial intersection point n    
615         //                                        
616         G4ThreeVector Point_A = CurrentA_Point    
617         G4ThreeVector SubE_point = CurrentB_Po    
618                                                   
619         GetNavigatorFor()->LocateGlobalPointWi    
620         G4bool Intersects_AB = IntersectChord(    
621                                                   
622                                                   
623                                                   
624         if( Intersects_AB )                       
625         {                                         
626           last_AF_intersection = Intersects_AB    
627           CurrentE_Point = PointGe;               
628           fin_section_depth[depth] = true;        
629                                                   
630           // Need to recalculate the Exit Norm    
631           //                                      
632           G4bool validNormalAB;                   
633           NormalAtEntry = GetSurfaceNormal( Po    
634           validNormalAtE = validNormalAB;         
635         }                                         
636         else                                      
637         {                                         
638           // No intersection found for first p    
639           // (CurrentA,InterMedPoint[depth]).     
640           //                                      
641           Second_half = true;                     
642         }                                         
643       } // if did_len                             
644                                                   
645       if( (Second_half)&&(depth!=0) )             
646       {                                           
647         // Second part of curve (InterMed[dept    
648         // On the depth-1 level normally we ar    
649                                                   
650         Second_half = true;                       
651                                                   
652         //  Find new trial intersection point     
653         //                                        
654         SubStart_PointVelocity = *ptrInterMedF    
655         CurrentA_PointVelocity = *ptrInterMedF    
656         CurrentB_PointVelocity = *ptrInterMedF    
657          // Ensure that the new endpoints are     
658         // than on the curve due to different     
659         //                                        
660         G4double linDistSq, curveDist;            
661         linDistSq = ( CurrentB_PointVelocity.G    
662                     - CurrentA_PointVelocity.G    
663         curveDist = CurrentB_PointVelocity.Get    
664                     - CurrentA_PointVelocity.G    
665         if( curveDist*curveDist*(1+2*GetEpsilo    
666         {                                         
667           // Re-integrate to obtain a new B       
668           //                                      
669           G4FieldTrack newEndPointFT =            
670                   ReEstimateEndpoint( CurrentA    
671                                       CurrentB    
672                                       linDistS    
673                                       curveDis    
674           G4FieldTrack oldPointVelB = CurrentB    
675           CurrentB_PointVelocity = newEndPoint    
676           if ( depth==1 )                         
677           {                                       
678             recalculatedEndPoint = true;          
679             IntersectedOrRecalculatedFT = newE    
680             // So that we can return it, if it    
681           }                                       
682         }                                         
683                                                   
684                                                   
685         G4ThreeVector Point_A    = CurrentA_Po    
686         G4ThreeVector SubE_point = CurrentB_Po    
687         GetNavigatorFor()->LocateGlobalPointWi    
688         G4bool Intersects_AB = IntersectChord(    
689                                                   
690                                                   
691         if( Intersects_AB )                       
692         {                                         
693           last_AF_intersection = Intersects_AB    
694           CurrentE_Point = PointGe;               
695                                                   
696           G4bool validNormalAB;                   
697           NormalAtEntry  = GetSurfaceNormal( P    
698           validNormalAtE = validNormalAB;         
699         }                                         
700                                                   
701         depth--;                                  
702         fin_section_depth[depth]=true;            
703       }                                           
704     }  // if(!found_aproximate_intersection)      
705                                                   
706   } while ( ( ! found_approximate_intersection    
707             && ( ! there_is_no_intersection )     
708             && ( substep_no <= max_substeps) )    
709                                                   
710   if( substep_no > max_no_seen )                  
711   {                                               
712     max_no_seen = substep_no;                     
713 #ifdef G4DEBUG_LOCATE_INTERSECTION                
714     if( max_no_seen > warn_substeps )             
715     {                                             
716       trigger_substepno_print = max_no_seen-20    
717     }                                             
718 #endif                                            
719   }                                               
720                                                   
721   if(  ( substep_no >= max_substeps)              
722       && !there_is_no_intersection                
723       && !found_approximate_intersection )        
724   {                                               
725     G4cout << "ERROR - G4BrentLocator::Estimat    
726            << "        Start and end-point of     
727     printStatus( CurveStartPointVelocity, Curv    
728                  -1.0, NewSafety, 0);             
729     G4cout << "        Start and end-point of     
730     printStatus( CurrentA_PointVelocity, Curre    
731                  -1.0, NewSafety, substep_no-1    
732     printStatus( CurrentA_PointVelocity, Curre    
733                  -1.0, NewSafety, substep_no);    
734     std::ostringstream message;                   
735     message << "Too many substeps!" << G4endl     
736             << "          Convergence is requi    
737             << substep_no << G4endl               
738             << "          Abandoning effort to    
739             << "          Found intersection =    
740             << found_approximate_intersection     
741             << "          Intersection exists     
742             << !there_is_no_intersection << G4    
743     oldprc = G4cout.precision( 10 );              
744     G4double done_len = CurrentA_PointVelocity    
745     G4double full_len = CurveEndPointVelocity.    
746     message << "        Undertaken only length    
747             << " out of " << full_len << " req    
748             << "        Remaining length = " <    
749     G4cout.precision( oldprc );                   
750                                                   
751     G4Exception("G4BrentLocator::EstimateInter    
752                 "GeomNav0003", FatalException,    
753   }                                               
754   else if( substep_no >= warn_substeps )          
755   {                                               
756     oldprc = G4cout.precision( 10 );              
757     std::ostringstream message;                   
758     message << "Many substeps while trying to     
759             << G4endl                             
760             << "          Undertaken length: "    
761             << CurrentB_PointVelocity.GetCurve    
762             << " - Needed: "  << substep_no <<    
763             << "          Warning level = " <<    
764             << " and maximum substeps = " << m    
765     G4Exception("G4BrentLocator::EstimateInter    
766                 "GeomNav1002", JustWarning, me    
767     G4cout.precision( oldprc );                   
768   }                                               
769   return  !there_is_no_intersection; //  Succe    
770 }                                                 
771