Geant4  10.02
G4ChordFinder.cc
Go to the documentation of this file.
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 93806 2015-11-02 11:21:01Z gcosmo $
28 //
29 //
30 // 25.02.97 - John Apostolakis - Design and implementation
31 // -------------------------------------------------------------------
32 
33 #include <iomanip>
34 
35 #include "G4ChordFinder.hh"
36 #include "G4SystemOfUnits.hh"
37 #include "G4MagneticField.hh"
38 #include "G4Mag_UsualEqRhs.hh"
39 #include "G4ClassicalRK4.hh"
40 
41 
42 // ..........................................................................
43 
45  : fDefaultDeltaChord( 0.25 * mm ), // Parameters
46  fDeltaChord( fDefaultDeltaChord ), // Internal parameters
47  fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
48  fMultipleRadius(15.0),
49  fStatsVerbose(0),
50  fDriversStepper(0), // Dependent objects
51  fAllocatedStepper(false),
52  fEquation(0),
53  fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0)
54 {
55  // Simple constructor -- it does not create equation
56  fIntgrDriver= pIntegrationDriver;
57  fAllocatedStepper= false;
58 
59  fLastStepEstimate_Unconstrained = DBL_MAX; // Should move q, p to
60 
62  // check the values and set the other parameters
63 }
64 
65 
66 // ..........................................................................
67 
69  G4double stepMinimum,
70  G4MagIntegratorStepper* pItsStepper )
71  : fDefaultDeltaChord( 0.25 * mm ), // Constants
72  fDeltaChord( fDefaultDeltaChord ), // Parameters
73  fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
74  fMultipleRadius(15.0),
75  fStatsVerbose(0),
76  fDriversStepper(0), // Dependent objects
77  fAllocatedStepper(false),
78  fEquation(0),
79  fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0) // State - stats
80 {
81  // Construct the Chord Finder
82  // by creating in inverse order the Driver, the Stepper and EqRhs ...
83 
84  G4Mag_EqRhs *pEquation = new G4Mag_UsualEqRhs(theMagField);
85  fEquation = pEquation;
86  fLastStepEstimate_Unconstrained = DBL_MAX; // Should move q, p to
87  // G4FieldTrack ??
88 
90  // check the values and set the other parameters
91 
92  // --->> Charge Q = 0
93  // --->> Momentum P = 1 NOMINAL VALUES !!!!!!!!!!!!!!!!!!
94 
95  if( pItsStepper == 0 )
96  {
97  pItsStepper = fDriversStepper = new G4ClassicalRK4(pEquation);
98  fAllocatedStepper= true;
99  }
100  else
101  {
102  fAllocatedStepper= false;
103  }
104  fIntgrDriver = new G4MagInt_Driver(stepMinimum, pItsStepper,
105  pItsStepper->GetNumberOfVariables() );
106 }
107 
108 
109 // ......................................................................
110 
112 {
113  delete fEquation; // fIntgrDriver->pIntStepper->theEquation_Rhs;
114  if( fAllocatedStepper)
115  {
116  delete fDriversStepper;
117  }
118  delete fIntgrDriver;
119 
120  if( fStatsVerbose ) { PrintStatistics(); }
121 }
122 
123 
124 // ......................................................................
125 
126 void
128 {
129  // Use -1.0 as request for Default.
130  if( fractLast == -1.0 ) fractLast = 1.0; // 0.9;
131  if( fractNext == -1.0 ) fractNext = 0.98; // 0.9;
132 
133  // fFirstFraction = 0.999; // Orig 0.999 A safe value, range: ~ 0.95 - 0.999
134  // fMultipleRadius = 15.0; // For later use, range: ~ 2 - 20
135 
136  if( fStatsVerbose )
137  {
138  G4cout << " ChordFnd> Trying to set fractions: "
139  << " first " << fFirstFraction
140  << " last " << fractLast
141  << " next " << fractNext
142  << " and multiple " << fMultipleRadius
143  << G4endl;
144  }
145 
146  if( (fractLast > 0.0) && (fractLast <=1.0) )
147  {
148  fFractionLast= fractLast;
149  }
150  else
151  {
152  G4cerr << "G4ChordFinder::SetFractions_Last_Next: Invalid "
153  << " fraction Last = " << fractLast
154  << " must be 0 < fractionLast <= 1 " << G4endl;
155  }
156  if( (fractNext > 0.0) && (fractNext <1.0) )
157  {
158  fFractionNextEstimate = fractNext;
159  }
160  else
161  {
162  G4cerr << "G4ChordFinder:: SetFractions_Last_Next: Invalid "
163  << " fraction Next = " << fractNext
164  << " must be 0 < fractionNext < 1 " << G4endl;
165  }
166 }
167 
168 
169 // ......................................................................
170 
171 G4double
173  G4double stepMax,
174  G4double epsStep,
175  const G4ThreeVector latestSafetyOrigin,
176  G4double latestSafetyRadius )
177 {
178  G4double stepPossible;
179  G4double dyErr;
180  G4FieldTrack yEnd( yCurrent);
181  G4double startCurveLen= yCurrent.GetCurveLength();
182  G4double nextStep;
183  // *************
184  stepPossible= FindNextChord(yCurrent, stepMax, yEnd, dyErr, epsStep,
185  &nextStep, latestSafetyOrigin, latestSafetyRadius
186  );
187  // *************
188 
189  G4bool good_advance;
190 
191  if ( dyErr < epsStep * stepPossible )
192  {
193  // Accept this accuracy.
194 
195  yCurrent = yEnd;
196  good_advance = true;
197  }
198  else
199  {
200  // Advance more accurately to "end of chord"
201  // ***************
202  good_advance = fIntgrDriver->AccurateAdvance(yCurrent, stepPossible,
203  epsStep, nextStep);
204  if ( ! good_advance )
205  {
206  // In this case the driver could not do the full distance
207  stepPossible= yCurrent.GetCurveLength()-startCurveLen;
208  }
209  }
210  return stepPossible;
211 }
212 
213 
214 // ............................................................................
215 
216 G4double
218  G4double stepMax,
219  G4FieldTrack& yEnd, // Endpoint
220  G4double& dyErrPos, // Error of endpoint
221  G4double epsStep,
222  G4double* pStepForAccuracy,
223  const G4ThreeVector, // latestSafetyOrigin,
224  G4double // latestSafetyRadius
225  )
226 {
227  // Returns Length of Step taken
228 
229  G4FieldTrack yCurrent= yStart;
230  G4double stepTrial, stepForAccuracy;
232 
233  // 1.) Try to "leap" to end of interval
234  // 2.) Evaluate if resulting chord gives d_chord that is good enough.
235  // 2a.) If d_chord is not good enough, find one that is.
236 
237  G4bool validEndPoint= false;
238  G4double dChordStep, lastStepLength; // stepOfLastGoodChord;
239 
240  fIntgrDriver-> GetDerivatives( yCurrent, dydx );
241 
242  unsigned int noTrials=0;
243  const unsigned int maxTrials= 300; // Avoid endless loop for bad convergence
244 
245  const G4double safetyFactor= fFirstFraction; // 0.975 or 0.99 ? was 0.999
246 
247  stepTrial = std::min( stepMax, safetyFactor*fLastStepEstimate_Unconstrained );
248 
249  G4double newStepEst_Uncons= 0.0;
250  G4double stepForChord;
251  do
252  {
253  yCurrent = yStart; // Always start from initial point
254 
255  // ************
256  fIntgrDriver->QuickAdvance( yCurrent, dydx, stepTrial,
257  dChordStep, dyErrPos);
258  // ************
259 
260  // We check whether the criterion is met here.
261  validEndPoint = AcceptableMissDist(dChordStep);
262 
263  lastStepLength = stepTrial;
264 
265  // This method estimates to step size for a good chord.
266  stepForChord = NewStep(stepTrial, dChordStep, newStepEst_Uncons );
267 
268  if( ! validEndPoint )
269  {
270  if( stepTrial<=0.0 )
271  {
272  stepTrial = stepForChord;
273  }
274  else if (stepForChord <= stepTrial)
275  {
276  // Reduce by a fraction, possibly up to 20%
277  stepTrial = std::min( stepForChord, fFractionLast * stepTrial);
278  }
279  else
280  {
281  stepTrial *= 0.1;
282  }
283  }
284  noTrials++;
285  }
286  while( (! validEndPoint) && (noTrials < maxTrials) ); // End of do-while RKD
287 
288  if( noTrials >= maxTrials )
289  {
290  std::ostringstream message;
291  message << "Exceeded maximum number of trials= " << maxTrials << G4endl
292  << "Current sagita dist= " << dChordStep << G4endl
293  << "Step sizes (actual and proposed): " << G4endl
294  << "Last trial = " << lastStepLength << G4endl
295  << "Next trial = " << stepTrial << G4endl
296  << "Proposed for chord = " << stepForChord << G4endl
297  ;
298  G4Exception("G4ChordFinder::FindNextChord()", "GeomField0003",
299  JustWarning, message);
300  }
301 
302  if( newStepEst_Uncons > 0.0 )
303  {
304  fLastStepEstimate_Unconstrained= newStepEst_Uncons;
305  }
306 
307  AccumulateStatistics( noTrials );
308 
309  if( pStepForAccuracy )
310  {
311  // Calculate the step size required for accuracy, if it is needed
312  //
313  G4double dyErr_relative = dyErrPos/(epsStep*lastStepLength);
314  if( dyErr_relative > 1.0 )
315  {
316  stepForAccuracy = fIntgrDriver->ComputeNewStepSize( dyErr_relative,
317  lastStepLength );
318  }
319  else
320  {
321  stepForAccuracy = 0.0; // Convention to show step was ok
322  }
323  *pStepForAccuracy = stepForAccuracy;
324  }
325 
326 #ifdef TEST_CHORD_PRINT
327  static int dbg=0;
328  if( dbg )
329  {
330  G4cout << "ChordF/FindNextChord: NoTrials= " << noTrials
331  << " StepForGoodChord=" << std::setw(10) << stepTrial << G4endl;
332  }
333 #endif
334  yEnd= yCurrent;
335  return stepTrial;
336 }
337 
338 
339 // ...........................................................................
340 
342  G4double dChordStep, // Curr. dchord achieved
343  G4double& stepEstimate_Unconstrained )
344 {
345  // Is called to estimate the next step size, even for successful steps,
346  // in order to predict an accurate 'chord-sensitive' first step
347  // which is likely to assist in more performant 'stepping'.
348 
349  G4double stepTrial;
350 
351 #if 1
352 
353  if (dChordStep > 0.0)
354  {
355  stepEstimate_Unconstrained =
356  stepTrialOld*std::sqrt( fDeltaChord / dChordStep );
357  stepTrial = fFractionNextEstimate * stepEstimate_Unconstrained;
358  }
359  else
360  {
361  // Should not update the Unconstrained Step estimate: incorrect!
362  stepTrial = stepTrialOld * 2.;
363  }
364 
365  if( stepTrial <= 0.001 * stepTrialOld)
366  {
367  if ( dChordStep > 1000.0 * fDeltaChord )
368  {
369  stepTrial= stepTrialOld * 0.03;
370  }
371  else
372  {
373  if ( dChordStep > 100. * fDeltaChord )
374  {
375  stepTrial= stepTrialOld * 0.1;
376  }
377  else // Try halving the length until dChordStep OK
378  {
379  stepTrial= stepTrialOld * 0.5;
380  }
381  }
382  }
383  else if (stepTrial > 1000.0 * stepTrialOld)
384  {
385  stepTrial= 1000.0 * stepTrialOld;
386  }
387 
388  if( stepTrial == 0.0 )
389  {
390  stepTrial= 0.000001;
391  }
392 
393 #else
394 
395  if ( dChordStep > 1000. * fDeltaChord )
396  {
397  stepTrial= stepTrialOld * 0.03;
398  }
399  else
400  {
401  if ( dChordStep > 100. * fDeltaChord )
402  {
403  stepTrial= stepTrialOld * 0.1;
404  }
405  else // Keep halving the length until dChordStep OK
406  {
407  stepTrial= stepTrialOld * 0.5;
408  }
409  }
410 
411 #endif
412 
413  // A more sophisticated chord-finder could figure out a better
414  // stepTrial, from dChordStep and the required d_geometry
415  // e.g.
416  // Calculate R, r_helix (eg at orig point)
417  // if( stepTrial < 2 pi R )
418  // stepTrial = R arc_cos( 1 - fDeltaChord / r_helix )
419  // else
420  // ??
421 
422  return stepTrial;
423 }
424 
425 
426 // ...........................................................................
427 
429 G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
430  const G4FieldTrack& CurveB_PointVelocity,
431  const G4FieldTrack& ApproxCurveV,
432  const G4ThreeVector& CurrentE_Point,
433  const G4ThreeVector& CurrentF_Point,
434  const G4ThreeVector& PointG,
435  G4bool first, G4double eps_step)
436 {
437  // ApproxCurvePointS is 2nd implementation of ApproxCurvePoint.
438  // Use Brent Algorithm (or InvParabolic) when possible.
439  // Given a starting curve point A (CurveA_PointVelocity), curve point B
440  // (CurveB_PointVelocity), a point E which is (generally) not on the curve
441  // and a point F which is on the curve (first approximation), find new
442  // point S on the curve closer to point E.
443  // While advancing towards S utilise 'eps_step' as a measure of the
444  // relative accuracy of each Step.
445 
446  G4FieldTrack EndPoint(CurveA_PointVelocity);
447  if(!first){EndPoint= ApproxCurveV;}
448 
449  G4ThreeVector Point_A,Point_B;
450  Point_A=CurveA_PointVelocity.GetPosition();
451  Point_B=CurveB_PointVelocity.GetPosition();
452 
453  G4double xa,xb,xc,ya,yb,yc;
454 
455  // InverseParabolic. AF Intersects (First Part of Curve)
456 
457  if(first)
458  {
459  xa=0.;
460  ya=(PointG-Point_A).mag();
461  xb=(Point_A-CurrentF_Point).mag();
462  yb=-(PointG-CurrentF_Point).mag();
463  xc=(Point_A-Point_B).mag();
464  yc=-(CurrentE_Point-Point_B).mag();
465  }
466  else
467  {
468  xa=0.;
469  ya=(Point_A-CurrentE_Point).mag();
470  xb=(Point_A-CurrentF_Point).mag();
471  yb=(PointG-CurrentF_Point).mag();
472  xc=(Point_A-Point_B).mag();
473  yc=-(Point_B-PointG).mag();
474  if(xb==0.)
475  {
476  EndPoint=
477  ApproxCurvePointV(CurveA_PointVelocity, CurveB_PointVelocity,
478  CurrentE_Point, eps_step);
479  return EndPoint;
480  }
481  }
482 
483  const G4double tolerance= 1.e-12;
484  if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
485  {
486  ; // What to do for the moment: return the same point as at start
487  // then PropagatorInField will take care
488  }
489  else
490  {
491  G4double test_step = InvParabolic(xa,ya,xb,yb,xc,yc);
492  G4double curve;
493  if(first)
494  {
495  curve=std::abs(EndPoint.GetCurveLength()
496  -ApproxCurveV.GetCurveLength());
497  }
498  else
499  {
500  test_step=(test_step-xb);
501  curve=std::abs(EndPoint.GetCurveLength()
502  -CurveB_PointVelocity.GetCurveLength());
503  xb=(CurrentF_Point-Point_B).mag();
504  }
505 
506  if(test_step<=0) { test_step=0.1*xb; }
507  if(test_step>=xb) { test_step=0.5*xb; }
508  if(test_step>=curve){ test_step=0.5*curve; }
509 
510  if(curve*(1.+eps_step)<xb) // Similar to ReEstimate Step from
511  { // G4VIntersectionLocator
512  test_step=0.5*curve;
513  }
514 
515  fIntgrDriver->AccurateAdvance(EndPoint,test_step, eps_step);
516 
517 #ifdef G4DEBUG_FIELD
518  // Printing Brent and Linear Approximation
519  //
520  G4cout << "G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
521  << test_step << " EndPoint = " << EndPoint << G4endl;
522 
523  // Test Track
524  //
525  G4FieldTrack TestTrack( CurveA_PointVelocity);
526  TestTrack = ApproxCurvePointV( CurveA_PointVelocity,
527  CurveB_PointVelocity,
528  CurrentE_Point, eps_step );
529  G4cout.precision(14);
530  G4cout << "G4ChordFinder::BrentApprox = " << EndPoint << G4endl;
531  G4cout << "G4ChordFinder::LinearApprox= " << TestTrack << G4endl;
532 #endif
533  }
534  return EndPoint;
535 }
536 
537 
538 // ...........................................................................
539 
541 ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
542  const G4FieldTrack& CurveB_PointVelocity,
543  const G4ThreeVector& CurrentE_Point,
544  G4double eps_step)
545 {
546  // If r=|AE|/|AB|, and s=true path lenght (AB)
547  // return the point that is r*s along the curve!
548 
549  G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
550 
551  G4ThreeVector CurveA_Point= CurveA_PointVelocity.GetPosition();
552  G4ThreeVector CurveB_Point= CurveB_PointVelocity.GetPosition();
553 
554  G4ThreeVector ChordAB_Vector= CurveB_Point - CurveA_Point;
555  G4ThreeVector ChordAE_Vector= CurrentE_Point - CurveA_Point;
556 
557  G4double ABdist= ChordAB_Vector.mag();
558  G4double curve_length; // A curve length of AB
559  G4double AE_fraction;
560 
561  curve_length= CurveB_PointVelocity.GetCurveLength()
562  - CurveA_PointVelocity.GetCurveLength();
563 
564  G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
565  if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
566  {
567 #ifdef G4DEBUG_FIELD
568  G4cerr << " Warning in G4ChordFinder::ApproxCurvePoint: "
569  << G4endl
570  << " The two points are further apart than the curve length "
571  << G4endl
572  << " Dist = " << ABdist
573  << " curve length = " << curve_length
574  << " relativeDiff = " << (curve_length-ABdist)/ABdist
575  << G4endl;
576  if( curve_length < ABdist * (1. - 10*eps_step) )
577  {
578  std::ostringstream message;
579  message << "Unphysical curve length." << G4endl
580  << "The size of the above difference exceeds allowed limits."
581  << G4endl
582  << "Aborting.";
583  G4Exception("G4ChordFinder::ApproxCurvePointV()", "GeomField0003",
584  FatalException, message);
585  }
586 #endif
587  // Take default corrective action: adjust the maximum curve length.
588  // NOTE: this case only happens for relatively straight paths.
589  // curve_length = ABdist;
590  }
591 
592  G4double new_st_length;
593 
594  if ( ABdist > 0.0 )
595  {
596  AE_fraction = ChordAE_Vector.mag() / ABdist;
597  }
598  else
599  {
600  AE_fraction = 0.5; // Guess .. ?;
601 #ifdef G4DEBUG_FIELD
602  G4cout << "Warning in G4ChordFinder::ApproxCurvePointV():"
603  << " A and B are the same point!" << G4endl
604  << " Chord AB length = " << ChordAE_Vector.mag() << G4endl
605  << G4endl;
606 #endif
607  }
608 
609  if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) )
610  {
611 #ifdef G4DEBUG_FIELD
612  G4cerr << " G4ChordFinder::ApproxCurvePointV() - Warning:"
613  << " Anomalous condition:AE > AB or AE/AB <= 0 " << G4endl
614  << " AE_fraction = " << AE_fraction << G4endl
615  << " Chord AE length = " << ChordAE_Vector.mag() << G4endl
616  << " Chord AB length = " << ABdist << G4endl << G4endl;
617  G4cerr << " OK if this condition occurs after a recalculation of 'B'"
618  << G4endl << " Otherwise it is an error. " << G4endl ;
619 #endif
620  // This course can now result if B has been re-evaluated,
621  // without E being recomputed (1 July 99).
622  // In this case this is not a "real error" - but it is undesired
623  // and we cope with it by a default corrective action ...
624  //
625  AE_fraction = 0.5; // Default value
626  }
627 
628  new_st_length= AE_fraction * curve_length;
629 
630  if ( AE_fraction > 0.0 )
631  {
632  fIntgrDriver->AccurateAdvance(Current_PointVelocity,
633  new_st_length, eps_step );
634  //
635  // In this case it does not matter if it cannot advance the full distance
636  }
637 
638  // If there was a memory of the step_length actually required at the start
639  // of the integration Step, this could be re-used ...
640 
641  G4cout.precision(14);
642 
643  return Current_PointVelocity;
644 }
645 
646 
647 // ......................................................................
648 
649 void
651 {
652  // Print Statistics
653 
654  G4cout << "G4ChordFinder statistics report: " << G4endl;
655  G4cout
656  << " No trials: " << fTotalNoTrials_FNC
657  << " No Calls: " << fNoCalls_FNC
658  << " Max-trial: " << fmaxTrials_FNC
659  << G4endl;
660  G4cout
661  << " Parameters: "
662  << " fFirstFraction " << fFirstFraction
663  << " fFractionLast " << fFractionLast
664  << " fFractionNextEstimate " << fFractionNextEstimate
665  << G4endl;
666 }
667 
668 
669 // ...........................................................................
670 
672  G4int lastStepTrial,
673  G4double dChordStep,
674  G4double nextStepTrial )
675 {
676  G4int oldprec= G4cout.precision(5);
677  G4cout << " ChF/fnc: notrial " << std::setw( 3) << noTrials
678  << " this_step= " << std::setw(10) << lastStepTrial;
679  if( std::fabs( (dChordStep / fDeltaChord) - 1.0 ) < 0.001 )
680  {
681  G4cout.precision(8);
682  }
683  else
684  {
685  G4cout.precision(6);
686  }
687  G4cout << " dChordStep= " << std::setw(12) << dChordStep;
688  if( dChordStep > fDeltaChord ) { G4cout << " d+"; }
689  else { G4cout << " d-"; }
690  G4cout.precision(5);
691  G4cout << " new_step= " << std::setw(10)
693  << " new_step_constr= " << std::setw(10)
694  << lastStepTrial << G4endl;
695  G4cout << " nextStepTrial = " << std::setw(10) << nextStepTrial << G4endl;
696  G4cout.precision(oldprec);
697 }
G4double InvParabolic(const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
G4MagIntegratorStepper * fDriversStepper
G4double GetCurveLength() const
CLHEP::Hep3Vector G4ThreeVector
G4double fMultipleRadius
G4ChordFinder(G4MagInt_Driver *pIntegrationDriver)
static const G4float tolerance
G4int fTotalNoTrials_FNC
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector &currentEPoint, G4double epsStep)
G4double fDeltaChord
int G4int
Definition: G4Types.hh:78
G4double fFractionLast
virtual void PrintStatistics()
G4int GetNumberOfVariables() const
virtual G4double FindNextChord(const G4FieldTrack &yStart, G4double stepMax, G4FieldTrack &yEnd, G4double &dyErr, G4double epsStep, G4double *pNextStepForAccuracy, const G4ThreeVector latestSafetyOrigin, G4double latestSafetyRadius)
G4double fLastStepEstimate_Unconstrained
G4ThreeVector GetPosition() const
G4GLOB_DLL std::ostream G4cout
void TestChordPrint(G4int noTrials, G4int lastStepTrial, G4double dChordStep, G4double nextStepTrial)
G4bool fAllocatedStepper
bool G4bool
Definition: G4Types.hh:79
G4bool AcceptableMissDist(G4double dChordStep) const
G4double fFirstFraction
G4double fFractionNextEstimate
void AccumulateStatistics(G4int noTrials)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4double AdvanceChordLimited(G4FieldTrack &yCurrent, G4double stepInitial, G4double epsStep_Relative, const G4ThreeVector latestSafetyOrigin, G4double lasestSafetyRadius)
static const double perMillion
Definition: G4SIunits.hh:331
G4bool QuickAdvance(G4FieldTrack &y_val, const G4double dydx[], G4double hstep, G4double &dchord_step, G4double &dyerr)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
void SetFractions_Last_Next(G4double fractLast=0.90, G4double fractNext=0.95)
G4double NewStep(G4double stepTrialOld, G4double dChordStep, G4double &stepEstimate_Unconstrained)
G4EquationOfMotion * fEquation
G4MagInt_Driver * fIntgrDriver
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4double ComputeNewStepSize(G4double errMaxNorm, G4double hstepCurrent)
#define G4endl
Definition: G4ios.hh:61
virtual ~G4ChordFinder()
double G4double
Definition: G4Types.hh:76
#define DBL_MAX
Definition: templates.hh:83
static const double mm
Definition: G4SIunits.hh:114
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector &currentEPoint, const G4ThreeVector &currentFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
G4bool AccurateAdvance(G4FieldTrack &y_current, G4double hstep, G4double eps, G4double hinitial=0.0)
G4GLOB_DLL std::ostream G4cerr