Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/magneticfield/src/G4ChordFinder.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/magneticfield/src/G4ChordFinder.cc (Version 11.3.0) and /geometry/magneticfield/src/G4ChordFinder.cc (Version ReleaseNotes)


** Warning: Cannot open xref database.

  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 // G4ChordFinder implementation                   
 27 //                                                
 28 // Author: J.Apostolakis - Design and implemen    
 29 // -------------------------------------------    
 30                                                   
 31 #include <iomanip>                                
 32                                                   
 33 #include "G4ChordFinder.hh"                       
 34 #include "G4SystemOfUnits.hh"                     
 35 #include "G4MagneticField.hh"                     
 36 #include "G4Mag_UsualEqRhs.hh"                    
 37 #include "G4MagIntegratorDriver.hh"               
 38 // #include "G4ClassicalRK4.hh"                   
 39 // #include "G4CashKarpRKF45.hh"                  
 40 // #include "G4NystromRK4.hh"                     
 41 // #include "G4BogackiShampine23.hh"              
 42 // #include "G4BogackiShampine45.hh"              
 43                                                   
 44 #include "G4DormandPrince745.hh"                  
 45                                                   
 46 // New templated stepper(s) -- avoid virtual c    
 47 #include "G4TDormandPrince45.hh"                  
 48                                                   
 49 // FSAL type driver / steppers -----              
 50 #include "G4FSALIntegrationDriver.hh"             
 51 #include "G4VFSALIntegrationStepper.hh"           
 52 #include "G4RK547FEq1.hh"                         
 53 // #include "G4RK547FEq2.hh"                      
 54 // #include "G4RK547FEq3.hh"                      
 55 // #include "G4FSALBogackiShampine45.hh"          
 56 // #include "G4FSALDormandPrince745.hh"           
 57                                                   
 58 // Templated type drivers -----                   
 59 #include "G4IntegrationDriver.hh"                 
 60 #include "G4InterpolationDriver.hh"               
 61                                                   
 62 #include "G4HelixHeum.hh"                         
 63 #include "G4BFieldIntegrationDriver.hh"           
 64                                                   
 65 #include "G4QSSDriverCreator.hh"                  
 66                                                   
 67 #include "G4CachedMagneticField.hh"               
 68                                                   
 69 #include <cassert>                                
 70 #include <memory>                                 
 71                                                   
 72 G4bool G4ChordFinder::gVerboseCtor = false;       
 73 // ...........................................    
 74                                                   
 75 G4ChordFinder::G4ChordFinder(G4VIntegrationDri    
 76   : fDefaultDeltaChord(0.25 * mm), fIntgrDrive    
 77 {                                                 
 78   // Simple constructor -- it does not create     
 79   if( gVerboseCtor )                              
 80   {                                               
 81     G4cout << "G4ChordFinder: Simple construct    
 82   }                                               
 83                                                   
 84   fDeltaChord = fDefaultDeltaChord;       // P    
 85 }                                                 
 86                                                   
 87 // ...........................................    
 88                                                   
 89 G4ChordFinder::G4ChordFinder( G4MagneticField*    
 90                               G4double            
 91                               G4MagIntegratorS    
 92                               G4int               
 93   : fDefaultDeltaChord(0.25 * mm)                 
 94 {                                                 
 95   // Construct the Chord Finder                   
 96   // by creating in inverse order the Driver,     
 97   constexpr G4int nVar6 = 6;   // Components i    
 98                                                   
 99   fDeltaChord = fDefaultDeltaChord;       // P    
100                                                   
101   G4cout << " G4ChordFinder: stepperDriverId:     
102                                                   
103   G4bool useFSALstepper     = (stepperDriverId    
104   G4bool useTemplatedStepper= (stepperDriverId    
105   G4bool useRegularStepper  = (stepperDriverId    
106   G4bool useBfieldDriver    = (stepperDriverId    
107   G4bool useG4QSSDriver     = (stepperDriverId    
108                                                   
109   if( stepperDriverId == kQss3DriverType)         
110   {                                               
111     stepperDriverId = kQss2DriverType;            
112     G4cout << " G4ChordFinder: QSS 3 is curren    
113   }                                               
114                                                   
115   using EquationType = G4Mag_UsualEqRhs;          
116                                                   
117   using TemplatedStepperType =                    
118          G4TDormandPrince45<EquationType,nVar6    
119   const char* TemplatedStepperName =              
120       "G4TDormandPrince745 (templated Dormand-    
121                                                   
122   using RegularStepperType =                      
123          G4DormandPrince745; // 5th order embe    
124          // G4ClassicalRK4;        // The old     
125          // G4CashKarpRKF45;       // First em    
126          // G4BogackiShampine45;   // High eff    
127          // G4NystromRK4;          // Nystrom     
128          // G4RK547FEq1;  // or 2 or 3            
129   const char* RegularStepperName =                
130       "G4DormandPrince745 (aka DOPRI5): 5th/4t    
131       // "BogackiShampine 45 (Embedded 5th/4th    
132       // "Nystrom stepper 4th order";             
133                                                   
134   using NewFsalStepperType = G4DormandPrince74    
135                                                   
136   const char* NewFSALStepperName =                
137       "G4RK574FEq1> FSAL 4th/5th order 7-stage    
138                                                   
139 #ifdef G4DEBUG_FIELD                              
140   static G4bool verboseDebug = true;              
141   if( verboseDebug )                              
142   {                                               
143      G4cout << "G4ChordFinder 2nd Constructor     
144      G4cout << " Arguments: " << G4endl           
145             << " - min step = " << stepMinimum    
146             << " - stepper ptr provided : "       
147             << ( pItsStepper==nullptr ? " no      
148      if( pItsStepper==nullptr )                   
149         G4cout << " - stepper/driver Id = " <<    
150                << "  useFSAL = " << useFSALste    
151                << "  , useTemplated = " << use    
152                << "  , useRegular = " << useRe    
153                << "  , useFSAL = " << useFSALs    
154                << G4endl;                         
155   }                                               
156 #endif                                            
157                                                   
158   // useHigherStepper = forceHigherEffiencySte    
159                                                   
160   auto  pEquation = new G4Mag_UsualEqRhs(theMa    
161   fEquation = pEquation;                          
162                                                   
163   // G4MagIntegratorStepper* regularStepper =     
164   // G4VFSALIntegrationStepper* fsalStepper =     
165   // G4MagIntegratorStepper* oldFSALStepper =     
166                                                   
167   G4bool errorInStepperCreation = false;          
168                                                   
169   std::ostringstream message;  // In case of f    
170                                                   
171   if( pItsStepper != nullptr )                    
172   {                                               
173      if( gVerboseCtor )                           
174      {                                            
175        G4cout << " G4ChordFinder: Creating G4I    
176               << " stepMinimum = " << stepMini    
177               << " numVar= " << pItsStepper->G    
178      }                                            
179                                                   
180      // Stepper type is not known - so must us    
181       if(pItsStepper->isQSS())                    
182       {                                           
183          // fIntgrDriver = pItsStepper->build_    
184          G4Exception("G4ChordFinder::G4ChordFi    
185                       "GeomField1001", FatalEx    
186                       "Cannot provide  QSS ste    
187       }                                           
188       else                                        
189       {                                           
190          fIntgrDriver = new G4IntegrationDrive    
191                                   pItsStepper,    
192          // Stepper type is not known - so mus    
193          // Non-interpolating driver used by d    
194          // WAS:  fIntgrDriver = pItsStepper->    
195       }                                           
196      // -- Older:                                 
197      // G4cout << " G4ChordFinder: Creating G4    
198      // Type is not known - so must use old cl    
199      // fIntgrDriver = new G4MagInt_Driver( st    
200      //                                 pItsSt    
201   }                                               
202   else if ( useTemplatedStepper )                 
203   {                                               
204      if( gVerboseCtor )                           
205      {                                            
206         G4cout << " G4ChordFinder: Creating Te    
207                << TemplatedStepperName << G4en    
208      }                                            
209      // RegularStepperType* regularStepper = n    
210      auto templatedStepper = new TemplatedStep    
211      //                    *** ***************    
212      //                                           
213      // Alternative - for G4NystromRK4:           
214      // = new G4NystromRK4(pEquation, 0.1*mm )    
215      fRegularStepperOwned = templatedStepper;     
216      if( templatedStepper == nullptr )            
217      {                                            
218         message << "Templated Stepper instanti    
219         message << "G4ChordFinder: Attempted t    
220                 << TemplatedStepperName << " t    
221         errorInStepperCreation = true;            
222      }                                            
223      else                                         
224      {                                            
225         fIntgrDriver = new G4IntegrationDriver    
226            stepMinimum, templatedStepper, nVar    
227         if( gVerboseCtor )                        
228         {                                         
229            G4cout << " G4ChordFinder: Using G4    
230         }                                         
231      }                                            
232                                                   
233   }                                               
234   else if ( useRegularStepper   )  // Plain st    
235   {                                               
236      auto regularStepper = new RegularStepperT    
237      //                    *** ***************    
238      fRegularStepperOwned = regularStepper;       
239                                                   
240      if( gVerboseCtor )                           
241      {                                            
242         G4cout << " G4ChordFinder: Creating Dr    
243      }                                            
244                                                   
245      if( regularStepper == nullptr )              
246      {                                            
247         message << "Regular Stepper instantiat    
248         message << "G4ChordFinder: Attempted t    
249                 << RegularStepperName << " typ    
250         errorInStepperCreation = true;            
251      }                                            
252      else                                         
253      {                                            
254         auto dp5= dynamic_cast<G4DormandPrince    
255         if( dp5 != nullptr )                      
256         {                                         
257            fIntgrDriver = new G4InterpolationD    
258                                   stepMinimum,    
259            if( gVerboseCtor )                     
260            {                                      
261               G4cout << " Using InterpolationD    
262            }                                      
263         }                                         
264         else                                      
265         {                                         
266            fIntgrDriver = new G4IntegrationDri    
267                                   stepMinimum,    
268            if( gVerboseCtor )                     
269            {                                      
270               G4cout << " Using IntegrationDri    
271            }                                      
272         }                                         
273      }                                            
274   }                                               
275   else if ( useBfieldDriver )                     
276   {                                               
277      auto regularStepper = new G4DormandPrince    
278      //                    *** ***************    
279      //                                           
280      fRegularStepperOwned = regularStepper;       
281                                                   
282      {                                            
283         using SmallStepDriver = G4Interpolatio    
284         using LargeStepDriver = G4IntegrationD    
285                                                   
286         fLongStepper = std::make_unique<G4Heli    
287                                                   
288         fIntgrDriver = new G4BFieldIntegration    
289           std::make_unique<SmallStepDriver>(st    
290               regularStepper, regularStepper->    
291           std::make_unique<LargeStepDriver>(st    
292               fLongStepper.get(), regularStepp    
293                                                   
294         if( fIntgrDriver == nullptr)              
295         {                                         
296            message << "Using G4BFieldIntegrati    
297                    << RegularStepperName << "     
298            message << "Driver instantiation FA    
299            G4Exception("G4ChordFinder::G4Chord    
300                        "GeomField1001", JustWa    
301         }                                         
302      }                                            
303   }                                               
304   else if( useG4QSSDriver )                       
305   {                                               
306      if( stepperDriverId == kQss2DriverType )     
307      {                                            
308        auto qssStepper2 = G4QSSDriverCreator::    
309        if( gVerboseCtor )                         
310        {                                          
311          G4cout << "-- Created QSS-2 stepper"     
312        }                                          
313        fIntgrDriver = G4QSSDriverCreator::Crea    
314      }                                            
315      else                                         
316      {                                            
317        auto qssStepper3 = G4QSSDriverCreator::    
318        if( gVerboseCtor )                         
319        {                                          
320          G4cout << "-- Created QSS-3 stepper"     
321        }                                          
322        fIntgrDriver = G4QSSDriverCreator::Crea    
323      }                                            
324      if( gVerboseCtor )                           
325      {                                            
326        G4cout << "-- G4ChordFinder: Using QSS     
327      }                                            
328   }                                               
329   else                                            
330   {                                               
331      auto fsalStepper=  new NewFsalStepperType    
332      //                 *** ******************    
333      fNewFSALStepperOwned = fsalStepper;          
334                                                   
335      if( fsalStepper == nullptr )                 
336      {                                            
337         message << "Stepper instantiation FAIL    
338         message << "Attempted to instantiate "    
339                 << NewFSALStepperName << " typ    
340         G4Exception("G4ChordFinder::G4ChordFin    
341                     "GeomField1001", JustWarni    
342         errorInStepperCreation = true;            
343      }                                            
344      else                                         
345      {                                            
346         fIntgrDriver = new                        
347            G4FSALIntegrationDriver<NewFsalStep    
348                                           fsal    
349            //  ====  Create the driver which k    
350                                                   
351         if( fIntgrDriver == nullptr )             
352         {                                         
353            message << "Using G4FSALIntegration    
354                    << NewFSALStepperName << G4    
355            message << "Integration Driver inst    
356            G4Exception("G4ChordFinder::G4Chord    
357                        "GeomField1001", JustWa    
358         }                                         
359      }                                            
360   }                                               
361                                                   
362   // -- Main work is now done                     
363                                                   
364   //    Now check that no error occured, and r    
365                                                   
366   // To test failure to create driver             
367   // delete fIntgrDriver;                         
368   // fIntgrDriver = nullptr;                      
369                                                   
370   // Detect and report Error conditions           
371   //                                              
372   if( errorInStepperCreation || (fIntgrDriver     
373   {                                               
374      std::ostringstream errmsg;                   
375                                                   
376      if( errorInStepperCreation )                 
377      {                                            
378         errmsg  << "ERROR> Failure to create S    
379                 << "       -------------------    
380      }                                            
381      if (fIntgrDriver == nullptr )                
382      {                                            
383         errmsg  << "ERROR> Failure to create I    
384                 << G4endl                         
385                 << "       -------------------    
386                 << G4endl;                        
387      }                                            
388      const std::string BoolName[2]= { "False",    
389      errmsg << "  Configuration:  (constructor    
390             << "    provided Stepper = " << pI    
391             << " stepper/driver Id = " << step    
392             << "   useTemplated = " << BoolNam    
393             << "   useRegular = " << BoolName[    
394             << "   useFSAL = " << BoolName[use    
395             << "   using combo BField Driver =    
396                    BoolName[ ! (useFSALstepper    
397                                || useRegularSt    
398             << G4endl;                            
399      errmsg << message.str();                     
400      errmsg << "Aborting.";                       
401      G4Exception("G4ChordFinder::G4ChordFinder    
402                  "GeomField0003", FatalExcepti    
403   }                                               
404                                                   
405   assert(    ( pItsStepper != nullptr )           
406           || ( fRegularStepperOwned != nullptr    
407           || ( fNewFSALStepperOwned != nullptr    
408           || useG4QSSDriver                       
409      );                                           
410   assert( fIntgrDriver != nullptr );              
411 }                                                 
412                                                   
413 // ...........................................    
414                                                   
415 G4ChordFinder::~G4ChordFinder()                   
416 {                                                 
417   delete fEquation;                               
418   delete fRegularStepperOwned;                    
419   delete fNewFSALStepperOwned;                    
420   delete fCachedField;                            
421   delete fIntgrDriver;                            
422 }                                                 
423                                                   
424 // ...........................................    
425                                                   
426 G4FieldTrack                                      
427 G4ChordFinder::ApproxCurvePointS( const G4Fiel    
428                                   const G4Fiel    
429                                   const G4Fiel    
430                                   const G4Thre    
431                                   const G4Thre    
432                                   const G4Thre    
433                                         G4bool    
434 {                                                 
435   // ApproxCurvePointS is 2nd implementation o    
436   // Use Brent Algorithm (or InvParabolic) whe    
437   // Given a starting curve point A (CurveA_Po    
438   // (CurveB_PointVelocity), a point E which i    
439   // and  a point F which is on the curve (fir    
440   // point S on the curve closer to point E.      
441   // While advancing towards S utilise 'eps_st    
442   // relative accuracy of each Step.              
443                                                   
444   G4FieldTrack EndPoint(CurveA_PointVelocity);    
445   if(!first) { EndPoint = ApproxCurveV; }         
446                                                   
447   G4ThreeVector Point_A,Point_B;                  
448   Point_A=CurveA_PointVelocity.GetPosition();     
449   Point_B=CurveB_PointVelocity.GetPosition();     
450                                                   
451   G4double xa,xb,xc,ya,yb,yc;                     
452                                                   
453   // InverseParabolic. AF Intersects (First Pa    
454                                                   
455   if(first)                                       
456   {                                               
457     xa=0.;                                        
458     ya=(PointG-Point_A).mag();                    
459     xb=(Point_A-CurrentF_Point).mag();            
460     yb=-(PointG-CurrentF_Point).mag();            
461     xc=(Point_A-Point_B).mag();                   
462     yc=-(CurrentE_Point-Point_B).mag();           
463   }                                               
464   else                                            
465   {                                               
466     xa=0.;                                        
467     ya=(Point_A-CurrentE_Point).mag();            
468     xb=(Point_A-CurrentF_Point).mag();            
469     yb=(PointG-CurrentF_Point).mag();             
470     xc=(Point_A-Point_B).mag();                   
471     yc=-(Point_B-PointG).mag();                   
472     if(xb==0.)                                    
473     {                                             
474       EndPoint = ApproxCurvePointV(CurveA_Poin    
475                                    CurrentE_Po    
476       return EndPoint;                            
477     }                                             
478   }                                               
479                                                   
480   const G4double tolerance = 1.e-12;              
481   if(std::abs(ya)<=tolerance||std::abs(yc)<=to    
482   {                                               
483     ; // What to do for the moment: return the    
484       // then PropagatorInField will take care    
485   }                                               
486   else                                            
487   {                                               
488     G4double test_step = InvParabolic(xa,ya,xb    
489     G4double curve;                               
490     if(first)                                     
491     {                                             
492       curve=std::abs(EndPoint.GetCurveLength()    
493                     -ApproxCurveV.GetCurveLeng    
494     }                                             
495     else                                          
496     {                                             
497       test_step = test_step - xb;                 
498       curve=std::abs(EndPoint.GetCurveLength()    
499                     -CurveB_PointVelocity.GetC    
500       xb = (CurrentF_Point-Point_B).mag();        
501     }                                             
502                                                   
503     if(test_step<=0)    { test_step=0.1*xb; }     
504     if(test_step>=xb)   { test_step=0.5*xb; }     
505     if(test_step>=curve){ test_step=0.5*curve;    
506                                                   
507     if(curve*(1.+eps_step)<xb) // Similar to R    
508     {                          // G4VIntersect    
509       test_step=0.5*curve;                        
510     }                                             
511                                                   
512     fIntgrDriver->AccurateAdvance(EndPoint,tes    
513                                                   
514 #ifdef G4DEBUG_FIELD                              
515     // Printing Brent and Linear Approximation    
516     //                                            
517     G4cout << "G4ChordFinder::ApproxCurvePoint    
518            << test_step << "  EndPoint = " <<     
519                                                   
520     //  Test Track                                
521     //                                            
522     G4FieldTrack TestTrack( CurveA_PointVeloci    
523     TestTrack = ApproxCurvePointV( CurveA_Poin    
524                                    CurveB_Poin    
525                                    CurrentE_Po    
526     G4cout.precision(14);                         
527     G4cout << "G4ChordFinder::BrentApprox = "     
528     G4cout << "G4ChordFinder::LinearApprox= "     
529 #endif                                            
530   }                                               
531   return EndPoint;                                
532 }                                                 
533                                                   
534                                                   
535 // ...........................................    
536                                                   
537 G4FieldTrack G4ChordFinder::                      
538 ApproxCurvePointV( const G4FieldTrack& CurveA_    
539                    const G4FieldTrack& CurveB_    
540                    const G4ThreeVector& Curren    
541                          G4double eps_step)       
542 {                                                 
543   // If r=|AE|/|AB|, and s=true path lenght (A    
544   // return the point that is r*s along the cu    
545                                                   
546   G4FieldTrack   Current_PointVelocity = Curve    
547                                                   
548   G4ThreeVector  CurveA_Point= CurveA_PointVel    
549   G4ThreeVector  CurveB_Point= CurveB_PointVel    
550                                                   
551   G4ThreeVector  ChordAB_Vector= CurveB_Point     
552   G4ThreeVector  ChordAE_Vector= CurrentE_Poin    
553                                                   
554   G4double       ABdist= ChordAB_Vector.mag();    
555   G4double  curve_length;  //  A curve length     
556   G4double  AE_fraction;                          
557                                                   
558   curve_length= CurveB_PointVelocity.GetCurveL    
559               - CurveA_PointVelocity.GetCurveL    
560                                                   
561   G4double integrationInaccuracyLimit= std::ma    
562   if( curve_length < ABdist * (1. - integratio    
563   {                                               
564 #ifdef G4DEBUG_FIELD                              
565     G4cerr << " Warning in G4ChordFinder::Appr    
566            << G4endl                              
567            << " The two points are further apa    
568            << G4endl                              
569            << " Dist = "         << ABdist        
570            << " curve length = " << curve_leng    
571            << " relativeDiff = " << (curve_len    
572            << G4endl;                             
573     if( curve_length < ABdist * (1. - 10*eps_s    
574     {                                             
575       std::ostringstream message;                 
576       message << "Unphysical curve length." <<    
577               << "The size of the above differ    
578               << G4endl                           
579               << "Aborting.";                     
580       G4Exception("G4ChordFinder::ApproxCurveP    
581                   FatalException, message);       
582     }                                             
583 #endif                                            
584     // Take default corrective action: adjust     
585     // NOTE: this case only happens for relati    
586     // curve_length = ABdist;                     
587   }                                               
588                                                   
589   G4double new_st_length;                         
590                                                   
591   if ( ABdist > 0.0 )                             
592   {                                               
593      AE_fraction = ChordAE_Vector.mag() / ABdi    
594   }                                               
595   else                                            
596   {                                               
597      AE_fraction = 0.5;                           
598 #ifdef G4DEBUG_FIELD                              
599      G4cout << "Warning in G4ChordFinder::Appr    
600             << " A and B are the same point!"     
601             << " Chord AB length = " << ChordA    
602             << G4endl;                            
603 #endif                                            
604   }                                               
605                                                   
606   if( (AE_fraction> 1.0 + perMillion) || (AE_f    
607   {                                               
608 #ifdef G4DEBUG_FIELD                              
609     G4cerr << " G4ChordFinder::ApproxCurvePoin    
610            << " Anomalous condition:AE > AB or    
611            << "   AE_fraction = " <<  AE_fract    
612            << "   Chord AE length = " << Chord    
613            << "   Chord AB length = " << ABdis    
614     G4cerr << " OK if this condition occurs af    
615            << G4endl << " Otherwise it is an e    
616 #endif                                            
617      // This course can now result if B has be    
618      // without E being recomputed (1 July 99)    
619      // In this case this is not a "real error    
620      // and we cope with it by a default corre    
621      //                                           
622      AE_fraction = 0.5;                           
623   }                                               
624                                                   
625   new_st_length = AE_fraction * curve_length;     
626                                                   
627   if ( AE_fraction > 0.0 )                        
628   {                                               
629      fIntgrDriver->AccurateAdvance(Current_Poi    
630                                    new_st_leng    
631      //                                           
632      // In this case it does not matter if it     
633   }                                               
634                                                   
635   // If there was a memory of the step_length     
636   // of the integration Step, this could be re    
637                                                   
638   G4cout.precision(14);                           
639                                                   
640   return Current_PointVelocity;                   
641 }                                                 
642                                                   
643 // ...........................................    
644                                                   
645 std::ostream& operator<<( std::ostream& os, co    
646 {                                                 
647    // Dumping the state of G4ChordFinder          
648    os << "State of G4ChordFinder : " << std::e    
649    os << "   delta_chord   = " <<  cf.fDeltaCh    
650    os << "   Default d_c   = " <<  cf.fDefault    
651                                                   
652    os << "   stats-verbose = " <<  cf.fStatsVe    
653                                                   
654    return os;                                     
655 }                                                 
656