45 : fDefaultDeltaChord( 0.25 *
mm ),
46 fDeltaChord( fDefaultDeltaChord ),
47 fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
48 fMultipleRadius(15.0),
51 fAllocatedStepper(false),
53 fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0)
71 : fDefaultDeltaChord( 0.25 *
mm ),
72 fDeltaChord( fDefaultDeltaChord ),
73 fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
74 fMultipleRadius(15.0),
77 fAllocatedStepper(false),
79 fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0)
95 if( pItsStepper == 0 )
130 if( fractLast == -1.0 ) fractLast = 1.0;
131 if( fractNext == -1.0 ) fractNext = 0.98;
138 G4cout <<
" ChordFnd> Trying to set fractions: "
140 <<
" last " << fractLast
141 <<
" next " << fractNext
146 if( (fractLast > 0.0) && (fractLast <=1.0) )
152 G4cerr <<
"G4ChordFinder::SetFractions_Last_Next: Invalid "
153 <<
" fraction Last = " << fractLast
154 <<
" must be 0 < fractionLast <= 1 " <<
G4endl;
156 if( (fractNext > 0.0) && (fractNext <1.0) )
162 G4cerr <<
"G4ChordFinder:: SetFractions_Last_Next: Invalid "
163 <<
" fraction Next = " << fractNext
164 <<
" must be 0 < fractionNext < 1 " <<
G4endl;
184 stepPossible=
FindNextChord(yCurrent, stepMax, yEnd, dyErr, epsStep,
185 &nextStep, latestSafetyOrigin, latestSafetyRadius
191 if ( dyErr < epsStep * stepPossible )
204 if ( ! good_advance )
230 G4double stepTrial, stepForAccuracy;
237 G4bool validEndPoint=
false;
238 G4double dChordStep, lastStepLength;
242 unsigned int noTrials=0;
243 const unsigned int maxTrials= 300;
257 dChordStep, dyErrPos);
263 lastStepLength = stepTrial;
266 stepForChord =
NewStep(stepTrial, dChordStep, newStepEst_Uncons );
268 if( ! validEndPoint )
272 stepTrial = stepForChord;
274 else if (stepForChord <= stepTrial)
286 while( (! validEndPoint) && (noTrials < maxTrials) );
288 if( noTrials >= maxTrials )
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
298 G4Exception(
"G4ChordFinder::FindNextChord()",
"GeomField0003",
302 if( newStepEst_Uncons > 0.0 )
304 fLastStepEstimate_Unconstrained= newStepEst_Uncons;
309 if( pStepForAccuracy )
313 G4double dyErr_relative = dyErrPos/(epsStep*lastStepLength);
314 if( dyErr_relative > 1.0 )
321 stepForAccuracy = 0.0;
323 *pStepForAccuracy = stepForAccuracy;
326 #ifdef TEST_CHORD_PRINT
330 G4cout <<
"ChordF/FindNextChord: NoTrials= " << noTrials
331 <<
" StepForGoodChord=" << std::setw(10) << stepTrial <<
G4endl;
343 G4double& stepEstimate_Unconstrained )
353 if (dChordStep > 0.0)
355 stepEstimate_Unconstrained =
356 stepTrialOld*std::sqrt(
fDeltaChord / dChordStep );
362 stepTrial = stepTrialOld * 2.;
365 if( stepTrial <= 0.001 * stepTrialOld)
369 stepTrial= stepTrialOld * 0.03;
375 stepTrial= stepTrialOld * 0.1;
379 stepTrial= stepTrialOld * 0.5;
383 else if (stepTrial > 1000.0 * stepTrialOld)
385 stepTrial= 1000.0 * stepTrialOld;
388 if( stepTrial == 0.0 )
397 stepTrial= stepTrialOld * 0.03;
403 stepTrial= stepTrialOld * 0.1;
407 stepTrial= stepTrialOld * 0.5;
447 if(!first){EndPoint= ApproxCurveV;}
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();
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();
478 CurrentE_Point, eps_step);
484 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
500 test_step=(test_step-xb);
503 xb=(CurrentF_Point-Point_B).mag();
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; }
510 if(curve*(1.+eps_step)<xb)
520 G4cout <<
"G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
521 << test_step <<
" EndPoint = " << EndPoint <<
G4endl;
527 CurveB_PointVelocity,
528 CurrentE_Point, eps_step );
530 G4cout <<
"G4ChordFinder::BrentApprox = " << EndPoint <<
G4endl;
531 G4cout <<
"G4ChordFinder::LinearApprox= " << TestTrack <<
G4endl;
549 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
557 G4double ABdist= ChordAB_Vector.mag();
565 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
568 G4cerr <<
" Warning in G4ChordFinder::ApproxCurvePoint: "
570 <<
" The two points are further apart than the curve length "
572 <<
" Dist = " << ABdist
573 <<
" curve length = " << curve_length
574 <<
" relativeDiff = " << (curve_length-ABdist)/ABdist
576 if( curve_length < ABdist * (1. - 10*eps_step) )
578 std::ostringstream message;
579 message <<
"Unphysical curve length." <<
G4endl
580 <<
"The size of the above difference exceeds allowed limits."
583 G4Exception(
"G4ChordFinder::ApproxCurvePointV()",
"GeomField0003",
596 AE_fraction = ChordAE_Vector.mag() / ABdist;
602 G4cout <<
"Warning in G4ChordFinder::ApproxCurvePointV():"
603 <<
" A and B are the same point!" <<
G4endl
604 <<
" Chord AB length = " << ChordAE_Vector.mag() <<
G4endl
609 if( (AE_fraction> 1.0 +
perMillion) || (AE_fraction< 0.) )
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
617 G4cerr <<
" OK if this condition occurs after a recalculation of 'B'"
618 << G4endl <<
" Otherwise it is an error. " <<
G4endl ;
628 new_st_length= AE_fraction * curve_length;
630 if ( AE_fraction > 0.0 )
633 new_st_length, eps_step );
643 return Current_PointVelocity;
654 G4cout <<
"G4ChordFinder statistics report: " <<
G4endl;
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 )
687 G4cout <<
" dChordStep= " << std::setw(12) << dChordStep;
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);
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
G4ChordFinder(G4MagInt_Driver *pIntegrationDriver)
static const G4float tolerance
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)
static const double perMillion
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