48 : fDefaultDeltaChord( 0.25 *
mm ),
49 fDeltaChord( fDefaultDeltaChord ),
50 fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
51 fMultipleRadius(15.0),
54 fAllocatedStepper(false),
56 fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0)
74 : fDefaultDeltaChord( 0.25 *
mm ),
75 fDeltaChord( fDefaultDeltaChord ),
76 fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
77 fMultipleRadius(15.0),
80 fAllocatedStepper(false),
82 fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0)
98 if( pItsStepper == 0 )
138 if( fractLast == -1.0 ) fractLast = 1.0;
139 if( fractNext == -1.0 ) fractNext = 0.98;
146 G4cout <<
" ChordFnd> Trying to set fractions: "
148 <<
" last " << fractLast
149 <<
" next " << fractNext
154 if( (fractLast > 0.0) && (fractLast <=1.0) )
160 G4cerr <<
"G4ChordFinder::SetFractions_Last_Next: Invalid "
161 <<
" fraction Last = " << fractLast
162 <<
" must be 0 < fractionLast <= 1 " <<
G4endl;
164 if( (fractNext > 0.0) && (fractNext <1.0) )
170 G4cerr <<
"G4ChordFinder:: SetFractions_Last_Next: Invalid "
171 <<
" fraction Next = " << fractNext
172 <<
" must be 0 < fractionNext < 1 " <<
G4endl;
192 stepPossible=
FindNextChord(yCurrent, stepMax, yEnd, dyErr, epsStep,
193 &nextStep, latestSafetyOrigin, latestSafetyRadius
199 if ( dyErr < epsStep * stepPossible )
212 if ( ! good_advance )
238 G4double stepTrial, stepForAccuracy;
245 G4bool validEndPoint=
false;
246 G4double dChordStep, lastStepLength;
250 unsigned int noTrials=0;
251 const unsigned int maxTrials= 75;
264 dChordStep, dyErrPos);
270 lastStepLength = stepTrial;
273 stepForChord =
NewStep(stepTrial, dChordStep, newStepEst_Uncons );
275 if( ! validEndPoint )
279 stepTrial = stepForChord;
281 else if (stepForChord <= stepTrial)
293 while( (! validEndPoint) && (noTrials < maxTrials) );
296 if( noTrials >= maxTrials )
298 std::ostringstream message;
299 message <<
"Exceeded maximum number of trials= " << maxTrials <<
G4endl
300 <<
"Current sagita dist= " << dChordStep <<
G4endl
301 <<
"Step sizes (actual and proposed): " <<
G4endl
302 <<
"Last trial = " << lastStepLength <<
G4endl
303 <<
"Next trial = " << stepTrial <<
G4endl
304 <<
"Proposed for chord = " << stepForChord <<
G4endl
306 G4Exception(
"G4ChordFinder::FindNextChord()",
"GeomField0003",
310 if( newStepEst_Uncons > 0.0 )
312 fLastStepEstimate_Unconstrained= newStepEst_Uncons;
317 if( pStepForAccuracy )
321 G4double dyErr_relative = dyErrPos/(epsStep*lastStepLength);
322 if( dyErr_relative > 1.0 )
329 stepForAccuracy = 0.0;
331 *pStepForAccuracy = stepForAccuracy;
334 #ifdef TEST_CHORD_PRINT
338 G4cout <<
"ChordF/FindNextChord: NoTrials= " << noTrials
339 <<
" StepForGoodChord=" << std::setw(10) << stepTrial <<
G4endl;
351 G4double& stepEstimate_Unconstrained )
361 if (dChordStep > 0.0)
363 stepEstimate_Unconstrained =
364 stepTrialOld*std::sqrt(
fDeltaChord / dChordStep );
370 stepTrial = stepTrialOld * 2.;
373 if( stepTrial <= 0.001 * stepTrialOld)
377 stepTrial= stepTrialOld * 0.03;
383 stepTrial= stepTrialOld * 0.1;
387 stepTrial= stepTrialOld * 0.5;
391 else if (stepTrial > 1000.0 * stepTrialOld)
393 stepTrial= 1000.0 * stepTrialOld;
396 if( stepTrial == 0.0 )
405 stepTrial= stepTrialOld * 0.03;
411 stepTrial= stepTrialOld * 0.1;
415 stepTrial= stepTrialOld * 0.5;
455 if(!first){EndPoint= ApproxCurveV;}
468 ya=(PointG-Point_A).mag();
469 xb=(Point_A-CurrentF_Point).mag();
470 yb=-(PointG-CurrentF_Point).mag();
471 xc=(Point_A-Point_B).mag();
472 yc=-(CurrentE_Point-Point_B).mag();
477 ya=(Point_A-CurrentE_Point).mag();
478 xb=(Point_A-CurrentF_Point).mag();
479 yb=(PointG-CurrentF_Point).mag();
480 xc=(Point_A-Point_B).mag();
481 yc=-(Point_B-PointG).mag();
486 CurrentE_Point, eps_step);
492 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
508 test_step=(test_step-xb);
511 xb=(CurrentF_Point-Point_B).mag();
514 if(test_step<=0) { test_step=0.1*xb; }
515 if(test_step>=xb) { test_step=0.5*xb; }
516 if(test_step>=curve){ test_step=0.5*curve; }
518 if(curve*(1.+eps_step)<xb)
528 G4cout <<
"G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
529 << test_step <<
" EndPoint = " << EndPoint <<
G4endl;
535 CurveB_PointVelocity,
536 CurrentE_Point, eps_step );
538 G4cout <<
"G4ChordFinder::BrentApprox = " << EndPoint <<
G4endl;
539 G4cout <<
"G4ChordFinder::LinearApprox= " << TestTrack <<
G4endl;
557 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
565 G4double ABdist= ChordAB_Vector.mag();
573 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
576 G4cerr <<
" Warning in G4ChordFinder::ApproxCurvePoint: "
578 <<
" The two points are further apart than the curve length "
580 <<
" Dist = " << ABdist
581 <<
" curve length = " << curve_length
582 <<
" relativeDiff = " << (curve_length-ABdist)/ABdist
584 if( curve_length < ABdist * (1. - 10*eps_step) )
586 std::ostringstream message;
587 message <<
"Unphysical curve length." <<
G4endl
588 <<
"The size of the above difference exceeds allowed limits."
591 G4Exception(
"G4ChordFinder::ApproxCurvePointV()",
"GeomField0003",
604 AE_fraction = ChordAE_Vector.mag() / ABdist;
610 G4cout <<
"Warning in G4ChordFinder::ApproxCurvePointV():"
611 <<
" A and B are the same point!" <<
G4endl
612 <<
" Chord AB length = " << ChordAE_Vector.mag() <<
G4endl
617 if( (AE_fraction> 1.0 +
perMillion) || (AE_fraction< 0.) )
620 G4cerr <<
" G4ChordFinder::ApproxCurvePointV() - Warning:"
621 <<
" Anomalous condition:AE > AB or AE/AB <= 0 " <<
G4endl
622 <<
" AE_fraction = " << AE_fraction <<
G4endl
623 <<
" Chord AE length = " << ChordAE_Vector.mag() <<
G4endl
625 G4cerr <<
" OK if this condition occurs after a recalculation of 'B'"
626 << G4endl <<
" Otherwise it is an error. " <<
G4endl ;
636 new_st_length= AE_fraction * curve_length;
638 if ( AE_fraction > 0.0 )
641 new_st_length, eps_step );
651 return Current_PointVelocity;
662 G4cout <<
"G4ChordFinder statistics report: " <<
G4endl;
685 G4cout <<
" ChF/fnc: notrial " << std::setw( 3) << noTrials
686 <<
" this_step= " << std::setw(10) << lastStepTrial;
687 if( std::fabs( (dChordStep /
fDeltaChord) - 1.0 ) < 0.001 )
695 G4cout <<
" dChordStep= " << std::setw(12) << dChordStep;
699 G4cout <<
" new_step= " << std::setw(10)
701 <<
" new_step_constr= " << std::setw(10)
702 << lastStepTrial <<
G4endl;
703 G4cout <<
" nextStepTrial = " << std::setw(10) << nextStepTrial <<
G4endl;
704 G4cout.precision(oldprec);
static constexpr double perMillion
G4double InvParabolic(const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
static constexpr double mm
G4MagIntegratorStepper * fDriversStepper
G4double GetCurveLength() const
CLHEP::Hep3Vector G4ThreeVector
G4ChordFinder(G4MagInt_Driver *pIntegrationDriver)
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector ¤tEPoint, G4double epsStep)
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 AcceptableMissDist(G4double dChordStep) const
G4double fFractionNextEstimate
void AccumulateStatistics(G4int noTrials)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4double AdvanceChordLimited(G4FieldTrack &yCurrent, G4double stepInitial, G4double epsStep_Relative, const G4ThreeVector latestSafetyOrigin, G4double lasestSafetyRadius)
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)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector ¤tEPoint, const G4ThreeVector ¤tFPoint, 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