Geant4  10.02.p03
G4ChordFinder Class Reference

#include <G4ChordFinder.hh>

Inheritance diagram for G4ChordFinder:
Collaboration diagram for G4ChordFinder:

Public Member Functions

 G4ChordFinder (G4MagInt_Driver *pIntegrationDriver)
 
 G4ChordFinder (G4MagneticField *itsMagField, G4double stepMinimum=1.0e-2, G4MagIntegratorStepper *pItsStepper=0)
 
virtual ~G4ChordFinder ()
 
G4double AdvanceChordLimited (G4FieldTrack &yCurrent, G4double stepInitial, G4double epsStep_Relative, const G4ThreeVector latestSafetyOrigin, G4double lasestSafetyRadius)
 
G4FieldTrack ApproxCurvePointS (const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector &currentEPoint, const G4ThreeVector &currentFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
 
G4FieldTrack ApproxCurvePointV (const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector &currentEPoint, G4double epsStep)
 
G4double InvParabolic (const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
 
G4double GetDeltaChord () const
 
void SetDeltaChord (G4double newval)
 
void SetIntegrationDriver (G4MagInt_Driver *IntegrationDriver)
 
G4MagInt_DriverGetIntegrationDriver ()
 
void ResetStepEstimate ()
 
G4int GetNoCalls ()
 
G4int GetNoTrials ()
 
G4int GetNoMaxTrials ()
 
virtual void PrintStatistics ()
 
G4int SetVerbose (G4int newvalue=1)
 
void SetFractions_Last_Next (G4double fractLast=0.90, G4double fractNext=0.95)
 
void SetFirstFraction (G4double fractFirst)
 
void TestChordPrint (G4int noTrials, G4int lastStepTrial, G4double dChordStep, G4double nextStepTrial)
 
G4double GetFirstFraction ()
 
G4double GetFractionLast ()
 
G4double GetFractionNextEstimate ()
 
G4double GetMultipleRadius ()
 

Protected Member Functions

void AccumulateStatistics (G4int noTrials)
 
G4bool AcceptableMissDist (G4double dChordStep) const
 
G4double NewStep (G4double stepTrialOld, G4double dChordStep, G4double &stepEstimate_Unconstrained)
 
virtual G4double FindNextChord (const G4FieldTrack &yStart, G4double stepMax, G4FieldTrack &yEnd, G4double &dyErr, G4double epsStep, G4double *pNextStepForAccuracy, const G4ThreeVector latestSafetyOrigin, G4double latestSafetyRadius)
 
void PrintDchordTrial (G4int noTrials, G4double stepTrial, G4double oldStepTrial, G4double dChordStep)
 
G4double GetLastStepEstimateUnc ()
 
void SetLastStepEstimateUnc (G4double stepEst)
 

Private Member Functions

 G4ChordFinder (const G4ChordFinder &)
 
G4ChordFinderoperator= (const G4ChordFinder &)
 

Private Attributes

const G4double fDefaultDeltaChord
 
G4double fDeltaChord
 
G4double fFirstFraction
 
G4double fFractionLast
 
G4double fFractionNextEstimate
 
G4double fMultipleRadius
 
G4int fStatsVerbose
 
G4MagInt_DriverfIntgrDriver
 
G4MagIntegratorStepperfDriversStepper
 
G4bool fAllocatedStepper
 
G4EquationOfMotionfEquation
 
G4double fLastStepEstimate_Unconstrained
 
G4int fTotalNoTrials_FNC
 
G4int fNoCalls_FNC
 
G4int fmaxTrials_FNC
 

Detailed Description

Definition at line 50 of file G4ChordFinder.hh.

Constructor & Destructor Documentation

◆ G4ChordFinder() [1/3]

G4ChordFinder::G4ChordFinder ( G4MagInt_Driver pIntegrationDriver)

Definition at line 44 of file G4ChordFinder.cc.

45  : fDefaultDeltaChord( 0.25 * mm ), // Parameters
46  fDeltaChord( fDefaultDeltaChord ), // Internal parameters
48  fMultipleRadius(15.0),
49  fStatsVerbose(0),
50  fDriversStepper(0), // Dependent objects
51  fAllocatedStepper(false),
52  fEquation(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 }
G4MagIntegratorStepper * fDriversStepper
G4double fMultipleRadius
G4int fTotalNoTrials_FNC
G4double fDeltaChord
const G4double fDefaultDeltaChord
G4double fFractionLast
G4double fLastStepEstimate_Unconstrained
G4bool fAllocatedStepper
G4double fFirstFraction
G4double fFractionNextEstimate
void SetFractions_Last_Next(G4double fractLast=0.90, G4double fractNext=0.95)
G4EquationOfMotion * fEquation
G4MagInt_Driver * fIntgrDriver
#define DBL_MAX
Definition: templates.hh:83
static const double mm
Definition: G4SIunits.hh:114
Here is the call graph for this function:

◆ G4ChordFinder() [2/3]

G4ChordFinder::G4ChordFinder ( G4MagneticField itsMagField,
G4double  stepMinimum = 1.0e-2,
G4MagIntegratorStepper pItsStepper = 0 
)

Definition at line 68 of file G4ChordFinder.cc.

71  : fDefaultDeltaChord( 0.25 * mm ), // Constants
72  fDeltaChord( fDefaultDeltaChord ), // Parameters
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 }
G4MagIntegratorStepper * fDriversStepper
G4double fMultipleRadius
G4int fTotalNoTrials_FNC
G4double fDeltaChord
const G4double fDefaultDeltaChord
G4double fFractionLast
G4double fLastStepEstimate_Unconstrained
G4bool fAllocatedStepper
G4int GetNumberOfVariables() const
G4double fFirstFraction
G4double fFractionNextEstimate
void SetFractions_Last_Next(G4double fractLast=0.90, G4double fractNext=0.95)
G4EquationOfMotion * fEquation
G4MagInt_Driver * fIntgrDriver
#define DBL_MAX
Definition: templates.hh:83
static const double mm
Definition: G4SIunits.hh:114
Here is the call graph for this function:

◆ ~G4ChordFinder()

G4ChordFinder::~G4ChordFinder ( )
virtual

Definition at line 111 of file G4ChordFinder.cc.

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 }
G4MagIntegratorStepper * fDriversStepper
virtual void PrintStatistics()
G4bool fAllocatedStepper
G4EquationOfMotion * fEquation
G4MagInt_Driver * fIntgrDriver
Here is the call graph for this function:

◆ G4ChordFinder() [3/3]

G4ChordFinder::G4ChordFinder ( const G4ChordFinder )
private

Member Function Documentation

◆ AcceptableMissDist()

G4bool G4ChordFinder::AcceptableMissDist ( G4double  dChordStep) const
inlineprotected
Here is the caller graph for this function:

◆ AccumulateStatistics()

void G4ChordFinder::AccumulateStatistics ( G4int  noTrials)
inlineprotected
Here is the caller graph for this function:

◆ AdvanceChordLimited()

G4double G4ChordFinder::AdvanceChordLimited ( G4FieldTrack yCurrent,
G4double  stepInitial,
G4double  epsStep_Relative,
const G4ThreeVector  latestSafetyOrigin,
G4double  lasestSafetyRadius 
)

Definition at line 172 of file G4ChordFinder.cc.

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 }
virtual G4double FindNextChord(const G4FieldTrack &yStart, G4double stepMax, G4FieldTrack &yEnd, G4double &dyErr, G4double epsStep, G4double *pNextStepForAccuracy, const G4ThreeVector latestSafetyOrigin, G4double latestSafetyRadius)
bool G4bool
Definition: G4Types.hh:79
G4MagInt_Driver * fIntgrDriver
double G4double
Definition: G4Types.hh:76
G4bool AccurateAdvance(G4FieldTrack &y_current, G4double hstep, G4double eps, G4double hinitial=0.0)
G4double GetCurveLength() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ApproxCurvePointS()

G4FieldTrack G4ChordFinder::ApproxCurvePointS ( const G4FieldTrack curveAPointVelocity,
const G4FieldTrack curveBPointVelocity,
const G4FieldTrack ApproxCurveV,
const G4ThreeVector currentEPoint,
const G4ThreeVector currentFPoint,
const G4ThreeVector PointG,
G4bool  first,
G4double  epsStep 
)

Definition at line 429 of file G4ChordFinder.cc.

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 }
G4double InvParabolic(const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector &currentEPoint, G4double epsStep)
static const G4double tolerance
G4GLOB_DLL std::ostream G4cout
G4MagInt_Driver * fIntgrDriver
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4bool AccurateAdvance(G4FieldTrack &y_current, G4double hstep, G4double eps, G4double hinitial=0.0)
G4double GetCurveLength() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ApproxCurvePointV()

G4FieldTrack G4ChordFinder::ApproxCurvePointV ( const G4FieldTrack curveAPointVelocity,
const G4FieldTrack curveBPointVelocity,
const G4ThreeVector currentEPoint,
G4double  epsStep 
)

Definition at line 541 of file G4ChordFinder.cc.

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 }
G4GLOB_DLL std::ostream G4cout
double mag() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
static const double perMillion
Definition: G4SIunits.hh:331
G4MagInt_Driver * fIntgrDriver
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4bool AccurateAdvance(G4FieldTrack &y_current, G4double hstep, G4double eps, G4double hinitial=0.0)
G4GLOB_DLL std::ostream G4cerr
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindNextChord()

G4double G4ChordFinder::FindNextChord ( const G4FieldTrack yStart,
G4double  stepMax,
G4FieldTrack yEnd,
G4double dyErr,
G4double  epsStep,
G4double pNextStepForAccuracy,
const G4ThreeVector  latestSafetyOrigin,
G4double  latestSafetyRadius 
)
protectedvirtual

Reimplemented in G4ChordFinderSaf.

Definition at line 217 of file G4ChordFinder.cc.

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 }
G4double fFractionLast
G4double fLastStepEstimate_Unconstrained
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
G4double fFirstFraction
void AccumulateStatistics(G4int noTrials)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool QuickAdvance(G4FieldTrack &y_val, const G4double dydx[], G4double hstep, G4double &dchord_step, G4double &dyerr)
G4bool AcceptableMissDist(G4double dChordStep) const
G4double NewStep(G4double stepTrialOld, G4double dChordStep, G4double &stepEstimate_Unconstrained)
G4MagInt_Driver * fIntgrDriver
G4double ComputeNewStepSize(G4double errMaxNorm, G4double hstepCurrent)
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDeltaChord()

G4double G4ChordFinder::GetDeltaChord ( ) const
inline
Here is the caller graph for this function:

◆ GetFirstFraction()

G4double G4ChordFinder::GetFirstFraction ( )
inline
Here is the caller graph for this function:

◆ GetFractionLast()

G4double G4ChordFinder::GetFractionLast ( )
inline
Here is the caller graph for this function:

◆ GetFractionNextEstimate()

G4double G4ChordFinder::GetFractionNextEstimate ( )
inline

◆ GetIntegrationDriver()

G4MagInt_Driver* G4ChordFinder::GetIntegrationDriver ( )
inline
Here is the caller graph for this function:

◆ GetLastStepEstimateUnc()

G4double G4ChordFinder::GetLastStepEstimateUnc ( )
inlineprotected
Here is the caller graph for this function:

◆ GetMultipleRadius()

G4double G4ChordFinder::GetMultipleRadius ( )
inline

◆ GetNoCalls()

G4int G4ChordFinder::GetNoCalls ( )
inline

◆ GetNoMaxTrials()

G4int G4ChordFinder::GetNoMaxTrials ( )
inline

◆ GetNoTrials()

G4int G4ChordFinder::GetNoTrials ( )
inline

◆ InvParabolic()

G4double G4ChordFinder::InvParabolic ( const G4double  xa,
const G4double  ya,
const G4double  xb,
const G4double  yb,
const G4double  xc,
const G4double  yc 
)
inline
Here is the caller graph for this function:

◆ NewStep()

G4double G4ChordFinder::NewStep ( G4double  stepTrialOld,
G4double  dChordStep,
G4double stepEstimate_Unconstrained 
)
protected

Definition at line 341 of file G4ChordFinder.cc.

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 }
G4double fDeltaChord
G4double fFractionNextEstimate
double G4double
Definition: G4Types.hh:76
Here is the caller graph for this function:

◆ operator=()

G4ChordFinder& G4ChordFinder::operator= ( const G4ChordFinder )
private

◆ PrintDchordTrial()

void G4ChordFinder::PrintDchordTrial ( G4int  noTrials,
G4double  stepTrial,
G4double  oldStepTrial,
G4double  dChordStep 
)
protected

◆ PrintStatistics()

void G4ChordFinder::PrintStatistics ( )
virtual

Reimplemented in G4ChordFinderSaf.

Definition at line 650 of file G4ChordFinder.cc.

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 }
G4int fTotalNoTrials_FNC
G4double fFractionLast
G4GLOB_DLL std::ostream G4cout
G4double fFirstFraction
G4double fFractionNextEstimate
#define G4endl
Definition: G4ios.hh:61
Here is the caller graph for this function:

◆ ResetStepEstimate()

void G4ChordFinder::ResetStepEstimate ( )
inline
Here is the caller graph for this function:

◆ SetDeltaChord()

void G4ChordFinder::SetDeltaChord ( G4double  newval)
inline
Here is the caller graph for this function:

◆ SetFirstFraction()

void G4ChordFinder::SetFirstFraction ( G4double  fractFirst)
inline

◆ SetFractions_Last_Next()

void G4ChordFinder::SetFractions_Last_Next ( G4double  fractLast = 0.90,
G4double  fractNext = 0.95 
)

Definition at line 127 of file G4ChordFinder.cc.

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 }
G4double fMultipleRadius
G4double fFractionLast
G4GLOB_DLL std::ostream G4cout
G4double fFirstFraction
G4double fFractionNextEstimate
#define G4endl
Definition: G4ios.hh:61
G4GLOB_DLL std::ostream G4cerr
Here is the caller graph for this function:

◆ SetIntegrationDriver()

void G4ChordFinder::SetIntegrationDriver ( G4MagInt_Driver IntegrationDriver)
inline

◆ SetLastStepEstimateUnc()

void G4ChordFinder::SetLastStepEstimateUnc ( G4double  stepEst)
inlineprotected
Here is the caller graph for this function:

◆ SetVerbose()

G4int G4ChordFinder::SetVerbose ( G4int  newvalue = 1)
inline
Here is the caller graph for this function:

◆ TestChordPrint()

void G4ChordFinder::TestChordPrint ( G4int  noTrials,
G4int  lastStepTrial,
G4double  dChordStep,
G4double  nextStepTrial 
)

Definition at line 671 of file G4ChordFinder.cc.

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 fDeltaChord
int G4int
Definition: G4Types.hh:78
G4double fLastStepEstimate_Unconstrained
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61

Member Data Documentation

◆ fAllocatedStepper

G4bool G4ChordFinder::fAllocatedStepper
private

Definition at line 185 of file G4ChordFinder.hh.

◆ fDefaultDeltaChord

const G4double G4ChordFinder::fDefaultDeltaChord
private

Definition at line 171 of file G4ChordFinder.hh.

◆ fDeltaChord

G4double G4ChordFinder::fDeltaChord
private

Definition at line 175 of file G4ChordFinder.hh.

◆ fDriversStepper

G4MagIntegratorStepper* G4ChordFinder::fDriversStepper
private

Definition at line 184 of file G4ChordFinder.hh.

◆ fEquation

G4EquationOfMotion* G4ChordFinder::fEquation
private

Definition at line 186 of file G4ChordFinder.hh.

◆ fFirstFraction

G4double G4ChordFinder::fFirstFraction
private

Definition at line 177 of file G4ChordFinder.hh.

◆ fFractionLast

G4double G4ChordFinder::fFractionLast
private

Definition at line 177 of file G4ChordFinder.hh.

◆ fFractionNextEstimate

G4double G4ChordFinder::fFractionNextEstimate
private

Definition at line 177 of file G4ChordFinder.hh.

◆ fIntgrDriver

G4MagInt_Driver* G4ChordFinder::fIntgrDriver
private

Definition at line 183 of file G4ChordFinder.hh.

◆ fLastStepEstimate_Unconstrained

G4double G4ChordFinder::fLastStepEstimate_Unconstrained
private

Definition at line 190 of file G4ChordFinder.hh.

◆ fmaxTrials_FNC

G4int G4ChordFinder::fmaxTrials_FNC
private

Definition at line 195 of file G4ChordFinder.hh.

◆ fMultipleRadius

G4double G4ChordFinder::fMultipleRadius
private

Definition at line 178 of file G4ChordFinder.hh.

◆ fNoCalls_FNC

G4int G4ChordFinder::fNoCalls_FNC
private

Definition at line 195 of file G4ChordFinder.hh.

◆ fStatsVerbose

G4int G4ChordFinder::fStatsVerbose
private

Definition at line 179 of file G4ChordFinder.hh.

◆ fTotalNoTrials_FNC

G4int G4ChordFinder::fTotalNoTrials_FNC
private

Definition at line 195 of file G4ChordFinder.hh.


The documentation for this class was generated from the following files: