source: trunk/source/geometry/magneticfield/src/G4ChordFinder.cc @ 862

Last change on this file since 862 was 850, checked in by garnier, 16 years ago

geant4.8.2 beta

File size: 22.8 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4ChordFinder.cc,v 1.49 2008/07/15 14:02:06 japost Exp $
28// GEANT4 tag $Name: HEAD $
29//
30//
31// 25.02.97 John Apostolakis,  design and implimentation
32// 05.03.97 V. Grichine , style modification
33// -------------------------------------------------------------------
34
35#include "G4ChordFinder.hh"
36#include "G4MagneticField.hh"
37#include "G4Mag_UsualEqRhs.hh"
38#include "G4ClassicalRK4.hh"
39
40#include <iomanip>
41
42// ..........................................................................
43
44G4ChordFinder::G4ChordFinder(G4MagInt_Driver* pIntegrationDriver)
45  : fDefaultDeltaChord( 0.25 * mm ), 
46    fDeltaChord( fDefaultDeltaChord ),
47    fAllocatedStepper(false),
48    fEquation(0), 
49    fDriversStepper(0), 
50    fFirstFraction(0.999), fFractionLast(1.00),  fFractionNextEstimate(0.98), 
51    fMultipleRadius(15.0), 
52    fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0),
53    fStatsVerbose(0)
54{
55  // Simple constructor which does not create equation, ..
56      // fDeltaChord= fDefaultDeltaChord;
57  fIntgrDriver= pIntegrationDriver;
58  fAllocatedStepper= false;
59  fLastStepEstimate_Unconstrained = DBL_MAX;          // Should move q, p to
60
61  SetFractions_Last_Next( fFractionLast, fFractionNextEstimate); 
62    // check the values and set the other parameters
63}
64
65// ..........................................................................
66
67G4ChordFinder::G4ChordFinder( G4MagneticField*        theMagField,
68                              G4double                stepMinimum, 
69                              G4MagIntegratorStepper* pItsStepper )
70  : fDefaultDeltaChord( 0.25 * mm ), 
71    fDeltaChord( fDefaultDeltaChord ),
72    fAllocatedStepper(false),
73    fEquation(0), 
74    fDriversStepper(0), 
75    fFirstFraction(0.999), fFractionLast(1.00),  fFractionNextEstimate(0.98), 
76    fMultipleRadius(15.0), 
77    fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0),
78    fStatsVerbose(0)
79{
80  //  Construct the Chord Finder
81  //  by creating in inverse order the  Driver, the Stepper and EqRhs ...
82  G4Mag_EqRhs *pEquation = new G4Mag_UsualEqRhs(theMagField);
83  fEquation = pEquation;                           
84  fLastStepEstimate_Unconstrained = DBL_MAX;          // Should move q, p to
85                                                     //    G4FieldTrack ??
86
87  SetFractions_Last_Next( fFractionLast, fFractionNextEstimate); 
88    // check the values and set the other parameters
89
90  // --->>  Charge    Q = 0
91  // --->>  Momentum  P = 1       NOMINAL VALUES !!!!!!!!!!!!!!!!!!
92
93  if( pItsStepper == 0 )
94  { 
95     pItsStepper = fDriversStepper = new G4ClassicalRK4(pEquation);
96     fAllocatedStepper= true;
97  }
98  else
99  {
100     fAllocatedStepper= false; 
101  }
102  fIntgrDriver = new G4MagInt_Driver(stepMinimum, pItsStepper, 
103                                     pItsStepper->GetNumberOfVariables() );
104}
105
106// ......................................................................
107
108void   
109G4ChordFinder::SetFractions_Last_Next( G4double fractLast, G4double fractNext )
110{ 
111  // Use -1.0 as request for Default.
112  if( fractLast == -1.0 )   fractLast = 1.0;   // 0.9;
113  if( fractNext == -1.0 )   fractNext = 0.98;  // 0.9;
114
115  // fFirstFraction  = 0.999;  // Orig 0.999 A safe value,  range: ~ 0.95 - 0.999
116  // fMultipleRadius = 15.0;   // For later use, range: ~  2 - 20
117
118  if( fStatsVerbose ) { 
119    G4cout << " ChordFnd> Trying to set fractions: "
120           << " first " << fFirstFraction
121           << " last " <<  fractLast
122           << " next " <<  fractNext
123           << " and multiple " << fMultipleRadius
124           << G4endl;
125  } 
126
127  if( (fractLast > 0.0) && (fractLast <=1.0) ) 
128    { fFractionLast= fractLast; }
129  else
130    G4cerr << "G4ChordFinder:: SetFractions_Last_Next: Invalid "
131           << " fraction Last = " << fractLast
132           << " must be  0 <  fractionLast <= 1 " << G4endl;
133  if( (fractNext > 0.0) && (fractNext <1.0) )
134    { fFractionNextEstimate = fractNext; }
135  else
136    G4cerr << "G4ChordFinder:: SetFractions_Last_Next: Invalid "
137           << " fraction Next = " << fractNext
138           << " must be  0 <  fractionNext < 1 " << G4endl;
139}
140
141// ......................................................................
142
143G4ChordFinder::~G4ChordFinder()
144{
145  delete   fEquation; // fIntgrDriver->pIntStepper->theEquation_Rhs;
146  if( fAllocatedStepper)
147  { 
148     delete fDriversStepper; 
149  }                                //  fIntgrDriver->pIntStepper;}
150  delete   fIntgrDriver; 
151
152  if( fStatsVerbose ) { PrintStatistics();  }
153}
154
155void
156G4ChordFinder::PrintStatistics()
157{
158  // Print Statistics
159  G4cout << "G4ChordFinder statistics report: " << G4endl;
160  G4cout
161    << "  No trials: " << fTotalNoTrials_FNC
162    << "  No Calls: "  << fNoCalls_FNC
163    << "  Max-trial: " <<  fmaxTrials_FNC
164    << G4endl; 
165  G4cout
166    << "  Parameters: " 
167    << "  fFirstFraction "  << fFirstFraction
168    << "  fFractionLast "   << fFractionLast
169    << "  fFractionNextEstimate " << fFractionNextEstimate
170    << G4endl; 
171}
172
173// ......................................................................
174
175G4double
176G4ChordFinder::AdvanceChordLimited( G4FieldTrack& yCurrent,
177                                    G4double      stepMax,
178                                    G4double      epsStep,
179                                    const G4ThreeVector latestSafetyOrigin,
180                                    G4double       latestSafetyRadius
181                                    )
182{
183  G4double stepPossible;
184  G4double dyErr;
185  G4FieldTrack yEnd( yCurrent);
186  G4double  startCurveLen= yCurrent.GetCurveLength();
187  G4double nextStep;
188  //            *************
189  stepPossible= FindNextChord(yCurrent, stepMax, yEnd, dyErr, epsStep, &nextStep
190                              , latestSafetyOrigin, latestSafetyRadius
191                             );
192  //            *************
193  //  G4cout<<"Exit Find Next Chord Err= "<<dyErr<<" eps=  "<<epsStep<<"stepPos=  "<<stepPossible<<G4endl;
194  G4bool good_advance;
195
196  if ( dyErr < epsStep * stepPossible )
197 
198      {   //G4cout<<"err comparison = "<<dyErr<<" eps=  "<<epsStep<<G4endl;
199     // Accept this accuracy.
200     yCurrent = yEnd;
201     good_advance = true; 
202  }
203  else
204  { 
205    // G4cout<<"Entering Accurate Advance"<<G4endl;
206     // Advance more accurately to "end of chord"
207     //                           ***************
208     good_advance = fIntgrDriver->AccurateAdvance(yCurrent, stepPossible, epsStep, nextStep);
209     //                           ***************
210     if ( ! good_advance ){ 
211       // In this case the driver could not do the full distance
212       stepPossible= yCurrent.GetCurveLength()-startCurveLen;
213     }
214  }
215
216#ifdef G4DEBUG_FIELD
217  //G4cout << "Exiting FindNextChord Limited with:" << G4endl
218  //       << "   yCurrent: " << yCurrent<< G4endl;
219#endif
220
221  return stepPossible;
222}
223
224// #define  TEST_CHORD_PRINT  1
225
226// ............................................................................
227
228G4double
229G4ChordFinder::FindNextChord( const  G4FieldTrack& yStart,
230                                     G4double     stepMax,
231                                     G4FieldTrack&   yEnd, // Endpoint
232                                     G4double&   dyErrPos, // Error of endpoint
233                                     G4double    epsStep,
234                                     G4double*  pStepForAccuracy, 
235                              const  G4ThreeVector, //  latestSafetyOrigin,
236                                     G4double       //  latestSafetyRadius
237                                        )
238  // Returns Length of Step taken
239{
240  //G4cout<<"Inter Find Next Chord with step="<<stepMax<<G4endl; 
241  // G4int       stepRKnumber=0;
242  G4FieldTrack yCurrent=  yStart; 
243  G4double    stepTrial, stepForAccuracy;
244  G4double    dydx[G4FieldTrack::ncompSVEC]; 
245
246  //  1.)  Try to "leap" to end of interval
247  //  2.)  Evaluate if resulting chord gives d_chord that is good enough.
248  //     2a.)  If d_chord is not good enough, find one that is.
249 
250  G4bool    validEndPoint= false;
251  G4double  dChordStep, lastStepLength; //  stepOfLastGoodChord;
252
253  fIntgrDriver-> GetDerivatives( yCurrent, dydx )  ;
254  //for (G4int i=0;i<G4FieldTrack::ncompSVEC;i++){
255  //  dydx[i]=0.;
256  //}
257  G4int     noTrials=0;
258  const G4double safetyFactor= fFirstFraction; //  0.975 or 0.99 ? was 0.999
259
260  stepTrial = std::min( stepMax, 
261                          safetyFactor * fLastStepEstimate_Unconstrained );
262
263  G4double newStepEst_Uncons= 0.0; 
264  do
265  { 
266     G4double stepForChord; 
267     yCurrent = yStart;    // Always start from initial point
268   
269     //            ************
270     fIntgrDriver->QuickAdvance( yCurrent, dydx, stepTrial, 
271                                 dChordStep, dyErrPos);
272     //            ************
273
274     // G4cout<<"AfterQuickAdv step="<<stepTrial<<"  dC="<<dChordStep<<" yErr="<<dyErrPos<<G4endl;
275     
276      //  We check whether the criterion is met here.
277     validEndPoint = AcceptableMissDist(dChordStep);
278     // if(validEndPoint){G4cout<<"validEndPoint"<<fDeltaChord<<G4endl;}
279     // else{G4cout<<"No__validEndPoint"<<G4endl;}
280
281
282     //&& (dyErrPos < eps) ;
283     //   validEndPoint = AcceptableMissDist(dChordStep) && (dyErrPos < epsStep) ;
284
285     lastStepLength = stepTrial; 
286
287     // This method estimates to step size for a good chord.
288     stepForChord = NewStep(stepTrial, dChordStep, newStepEst_Uncons );
289
290     if( ! validEndPoint ) {
291        if( stepTrial<=0.0 )
292          stepTrial = stepForChord; 
293        else if (stepForChord <= stepTrial) 
294          // Reduce by a fraction, possibly up to 20%
295          stepTrial = std::min( stepForChord, 
296                                fFractionLast * stepTrial); 
297        else
298          stepTrial *= 0.1;
299
300        // if(dbg) G4cerr<<"Dchord too big. Try new hstep="<<stepTrial<<G4endl;
301     }
302     // #ifdef  TEST_CHORD_PRINT
303     // TestChordPrint( noTrials, lastStepLength, dChordStep, stepTrial );
304     // #endif
305
306     noTrials++; 
307  }
308  while( ! validEndPoint );   // End of do-while  RKD
309
310  if( newStepEst_Uncons > 0.0  ){ 
311    fLastStepEstimate_Unconstrained= newStepEst_Uncons;
312  }
313
314  AccumulateStatistics( noTrials );
315
316  // stepOfLastGoodChord = stepTrial;
317
318  if( pStepForAccuracy ){ 
319     // Calculate the step size required for accuracy, if it is needed
320     G4double dyErr_relative = dyErrPos/(epsStep*lastStepLength);
321     if( dyErr_relative > 1.0 ) {
322        stepForAccuracy =
323           fIntgrDriver->ComputeNewStepSize( dyErr_relative,
324                                             lastStepLength );
325     }else{
326        stepForAccuracy = 0.0;   // Convention to show step was ok
327     }
328     *pStepForAccuracy = stepForAccuracy;
329  }
330
331#ifdef  TEST_CHORD_PRINT
332  static int dbg=0;
333  if( dbg ) 
334    G4cout << "ChordF/FindNextChord:  NoTrials= " << noTrials
335           << " StepForGoodChord=" << std::setw(10) << stepTrial << G4endl;
336#endif
337  //G4cout << "ChordF/FindNextChord:  NoTrials= " << noTrials
338  //         << " StepForGoodChord=" << std::setw(10) << stepTrial << G4endl;
339  yEnd=  yCurrent; 
340  return stepTrial; 
341}
342
343// ----------------------------------------------------------------------------
344#if 0         
345//   #ifdef G4VERBOSE
346if( dbg ) {
347   G4cerr << "Returned from QuickAdvance with: yCur=" << yCurrent <<G4endl;
348   G4cerr << " dChordStep= "<< dChordStep <<" dyErr=" << dyErr << G4endl;
349}
350#endif
351// ----------------------------------------------------------------------------
352
353// ...........................................................................
354
355G4double G4ChordFinder::NewStep(G4double  stepTrialOld, 
356                                G4double  dChordStep, // Curr. dchord achieved
357                                G4double& stepEstimate_Unconstrained ) 
358//
359// Is called to estimate the next step size, even for successful steps,
360// in order to predict an accurate 'chord-sensitive' first step
361// which is likely to assist in more performant 'stepping'.
362//
363       
364{
365  G4double stepTrial;
366  static G4double lastStepTrial = 1.,  lastDchordStep= 1.;
367
368#if 1
369  // const G4double  threshold = 1.21, multiplier = 0.9;
370  //  0.9 < 1 / std::sqrt(1.21)
371
372  if (dChordStep > 0.0)
373  {
374    stepEstimate_Unconstrained = stepTrialOld*std::sqrt( fDeltaChord / dChordStep );
375    // stepTrial =  0.98 * stepEstimate_Unconstrained;
376    stepTrial =  fFractionNextEstimate * stepEstimate_Unconstrained;
377  }
378  else
379  {
380    // Should not update the Unconstrained Step estimate: incorrect!
381    stepTrial =  stepTrialOld * 2.; 
382  }
383
384  // if ( dChordStep < threshold * fDeltaChord ){
385  //    stepTrial= stepTrialOld *  multiplier;   
386  // }
387  if( stepTrial <= 0.001 * stepTrialOld)
388  {
389     if ( dChordStep > 1000.0 * fDeltaChord ){
390        stepTrial= stepTrialOld * 0.03;   
391     }else{
392        if ( dChordStep > 100. * fDeltaChord ){
393          stepTrial= stepTrialOld * 0.1;   
394        }else{
395    // Try halving the length until dChordStep OK
396          stepTrial= stepTrialOld * 0.5;   
397        }
398     }
399  }else if (stepTrial > 1000.0 * stepTrialOld)
400  {
401     stepTrial= 1000.0 * stepTrialOld;
402  }
403
404  if( stepTrial == 0.0 ){
405     stepTrial= 0.000001;
406  }
407
408  lastStepTrial = stepTrialOld; 
409  lastDchordStep= dChordStep;
410#else
411  if ( dChordStep > 1000. * fDeltaChord ){
412        stepTrial= stepTrialOld * 0.03;   
413  }else{
414     if ( dChordStep > 100. * fDeltaChord ){
415        stepTrial= stepTrialOld * 0.1;   
416     }else{
417        // Keep halving the length until dChordStep OK
418        stepTrial= stepTrialOld * 0.5;   
419     }
420  }
421#endif
422
423  // A more sophisticated chord-finder could figure out a better
424  //   stepTrial, from dChordStep and the required d_geometry
425  //   eg
426  //      Calculate R, r_helix (eg at orig point)
427  //      if( stepTrial < 2 pi  R )
428  //          stepTrial = R arc_cos( 1 - fDeltaChord / r_helix )
429  //      else   
430  //          ??
431
432  return stepTrial;
433}
434
435//  ApproxCurvePointS is 2nd implementation of ApproxCurvePoint.
436//  Use Brent Algorithm(or InvParabolic) when it possible.
437//  Given a starting curve point A (CurveA_PointVelocity), 
438//  curve point B (CurveB_PointVelocity), a point E which is (generally)
439//  not on the curve  and  a point F which is on the curve(first approximation)
440//  From this information find new point S on the curve closer to point E.
441//  While advancing towards S utilise eps_step
442//  as a measure of the relative accuracy of each Step.
443G4FieldTrack
444G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity, 
445                                  const G4FieldTrack& CurveB_PointVelocity, 
446                                  const G4ThreeVector& CurrentE_Point,
447                                  const G4ThreeVector& CurrentF_Point,
448                                  const G4ThreeVector& PointG,
449                                       G4bool first, G4double eps_step)
450{
451
452 
453  G4FieldTrack EndPoint( CurveA_PointVelocity);
454  G4ThreeVector Point_A=CurveA_PointVelocity.GetPosition();
455  G4ThreeVector Point_B=CurveB_PointVelocity.GetPosition();
456  G4double xa,xb,xc,ya,yb,yc;
457 
458//InverseParabolic
459//AF Intersects (First Part of Curve)
460  if(first){
461      xa=0.;
462      ya=(PointG-Point_A).mag();
463      xb=(Point_A-CurrentF_Point).mag();
464      yb=-(PointG-CurrentF_Point).mag();
465      xc=(Point_A-Point_B).mag();
466      yc=-(CurrentE_Point-Point_B).mag();
467  }   
468  else{
469     xa=0.;
470     ya=(Point_A-PointG).mag();
471     xb=(Point_B-Point_A).mag();
472     yb=-(PointG-Point_B).mag();
473     xc=-(Point_A-CurrentF_Point).mag();
474     yc=-(Point_A-CurrentE_Point).mag();
475   
476  }
477  const G4double tolerance= 1.e-12;
478  if(ya<=tolerance||std::abs(yc)<=tolerance){
479    ; //What to do for the moment return the same point as in begin
480     //Then PropagatorInField will take care
481   }
482   else{
483         
484      G4double test_step  =InvParabolic(xa,ya,xb,yb,xc,yc);
485      G4double curve=std::abs(EndPoint.GetCurveLength()-CurveB_PointVelocity.GetCurveLength());
486      G4double dist= (EndPoint.GetPosition()-Point_B).mag();
487      if(test_step<=0) { test_step=0.1*xb;}
488      if(test_step>=xb){ test_step=0.5*xb;}
489       
490
491      if(curve*(1.+eps_step)<dist){
492        test_step=0.5*dist;
493       }
494
495       G4bool goodAdvance;
496       goodAdvance= 
497             fIntgrDriver->AccurateAdvance(EndPoint,test_step, eps_step);
498            //            ***************
499     
500       #ifdef G4DEBUG_FIELD
501        G4cout<<"G4ChordFinder:: test-step ShF="<<test_step<<"  EndPoint="<<EndPoint<<G4endl;
502      //    Test Track
503       G4FieldTrack TestTrack( CurveA_PointVelocity);
504       TestTrack = ApproxCurvePointV( CurveA_PointVelocity, 
505                                                  CurveB_PointVelocity, 
506                                                  CurrentE_Point,
507                                                  eps_step );
508       G4cout.precision(14);
509       G4cout<<"G4ChordFinder:: BrentApprox="<<EndPoint<<G4endl;
510       G4cout<<"G4ChordFinder::LinearApprox="<<TestTrack<<G4endl; 
511       #endif
512  }
513return EndPoint;
514} 
515
516G4FieldTrack
517G4ChordFinder::ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity, 
518                                  const G4FieldTrack& CurveB_PointVelocity, 
519                                  const G4ThreeVector& CurrentE_Point,
520                                        G4double eps_step)
521{
522  // 1st implementation:
523  //    if r=|AE|/|AB|, and s=true path lenght (AB)
524  //    return the point that is r*s along the curve!
525  /////////////////////////////
526  //
527  //2st implementation : Inverse Parabolic Extrapolation by D.C.Williams
528  //
529  //    Uses InvParabolic (xa,ya,xb,yb,xc,yc)
530
531  G4FieldTrack    Current_PointVelocity = CurveA_PointVelocity; 
532
533  G4ThreeVector  CurveA_Point= CurveA_PointVelocity.GetPosition();
534  G4ThreeVector  CurveB_Point= CurveB_PointVelocity.GetPosition();
535
536  G4ThreeVector  ChordAB_Vector= CurveB_Point   - CurveA_Point;
537  G4ThreeVector  ChordAE_Vector= CurrentE_Point - CurveA_Point;
538
539  G4double       ABdist= ChordAB_Vector.mag();
540  G4double  curve_length;  //  A curve length  of AB
541  G4double  AE_fraction; 
542 
543  curve_length= CurveB_PointVelocity.GetCurveLength()
544              - CurveA_PointVelocity.GetCurveLength(); 
545
546  // const
547  G4double  integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step ); 
548  if( curve_length < ABdist * (1. - integrationInaccuracyLimit) ){ 
549#ifdef G4DEBUG_FIELD
550    G4cerr << " Warning in G4ChordFinder::ApproxCurvePoint: "
551           << G4endl
552           << " The two points are further apart than the curve length "
553           << G4endl
554           << " Dist = "         << ABdist
555           << " curve length = " << curve_length
556           << " relativeDiff = " << (curve_length-ABdist)/ABdist
557           << G4endl;
558    if( curve_length < ABdist * (1. - 10*eps_step) ) {
559      G4cerr << " ERROR: the size of the above difference"
560             << " exceeds allowed limits.  Aborting." << G4endl;
561      G4Exception("G4ChordFinder::ApproxCurvePointV()", "PrecisionError",
562                  FatalException, "Unphysical curve length.");
563    }
564#endif
565    // Take default corrective action:
566    //    -->  adjust the maximum curve length.
567    //  NOTE: this case only happens for relatively straight paths.
568    curve_length = ABdist; 
569  }
570
571  G4double  new_st_length; 
572
573  if ( ABdist > 0.0 ){
574     AE_fraction = ChordAE_Vector.mag() / ABdist;
575  }else{
576     AE_fraction = 0.5;                         // Guess .. ?;
577#ifdef G4DEBUG_FIELD
578     G4cout << "Warning in G4ChordFinder::ApproxCurvePoint:"
579            << " A and B are the same point!" << G4endl
580            << " Chord AB length = " << ChordAE_Vector.mag() << G4endl
581            << G4endl;
582#endif
583  }
584 
585  if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) ){
586#ifdef G4DEBUG_FIELD
587    G4cerr << " G4ChordFinder::ApproxCurvePointV - Warning:"
588           << " Anomalous condition:AE > AB or AE/AB <= 0 " << G4endl
589           << "   AE_fraction = " <<  AE_fraction << G4endl
590           << "   Chord AE length = " << ChordAE_Vector.mag() << G4endl
591           << "   Chord AB length = " << ABdist << G4endl << G4endl;
592    G4cerr << " OK if this condition occurs after a recalculation of 'B'"
593           << G4endl << " Otherwise it is an error. " << G4endl ; 
594#endif
595     // This course can now result if B has been re-evaluated,
596     //   without E being recomputed   (1 July 99)
597     //  In this case this is not a "real error" - but it undesired
598     //   and we cope with it by a default corrective action ...
599     AE_fraction = 0.5;                         // Default value
600  }
601
602  new_st_length= AE_fraction * curve_length; 
603
604  G4bool good_advance;
605  if ( AE_fraction > 0.0 ) { 
606     good_advance = 
607      fIntgrDriver->AccurateAdvance(Current_PointVelocity, 
608                                    new_st_length,
609                                    eps_step ); // Relative accuracy
610     // In this case it does not matter if it cannot advance the full distance
611  }
612
613  // If there was a memory of the step_length actually require at the start
614  // of the integration Step, this could be re-used ...
615   G4cout.precision(14);
616     
617   //     G4cout<<"G4ChordFinder::LinearApprox="<<Current_PointVelocity<<G4endl;
618  return Current_PointVelocity;
619}
620
621void
622G4ChordFinder::TestChordPrint( G4int    noTrials, 
623                               G4int    lastStepTrial, 
624                               G4double dChordStep, 
625                               G4double nextStepTrial )
626{
627     G4int oldprec= G4cout.precision(5);
628     G4cout << " ChF/fnc: notrial " << std::setw( 3) << noTrials
629            << " this_step= "       << std::setw(10) << lastStepTrial;
630     if( std::fabs( (dChordStep / fDeltaChord) - 1.0 ) < 0.001 ){
631             G4cout.precision(8);
632     }else{  G4cout.precision(6); }
633     G4cout << " dChordStep=  "     << std::setw(12) << dChordStep;
634     if( dChordStep > fDeltaChord ) { G4cout << " d+"; }
635     else                           { G4cout << " d-"; }
636     G4cout.precision(5);
637     G4cout <<  " new_step= "       << std::setw(10)
638            << fLastStepEstimate_Unconstrained
639            << " new_step_constr= " << std::setw(10)
640            << lastStepTrial << G4endl;
641     G4cout << " nextStepTrial = " << std::setw(10) << nextStepTrial << G4endl;
642     G4cout.precision(oldprec);
643}
Note: See TracBrowser for help on using the repository browser.