92 G4int stepperDriverId )
93 : fDefaultDeltaChord(0.25 * mm)
97 constexpr G4int nVar6 = 6;
99 fDeltaChord = fDefaultDeltaChord;
101 G4cout <<
" G4ChordFinder: stepperDriverId: " << stepperDriverId <<
G4endl;
112 G4cout <<
" G4ChordFinder: QSS 3 is currently replaced by QSS 2 driver." <<
G4endl;
117 using TemplatedStepperType =
119 const char* TemplatedStepperName =
120 "G4TDormandPrince745 (templated Dormand-Prince45, aka DoPri5): 5th/4th Order 7-stage embedded";
122 using RegularStepperType =
129 const char* RegularStepperName =
130 "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded";
136 const char* NewFSALStepperName =
137 "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
140 static G4bool verboseDebug =
true;
143 G4cout <<
"G4ChordFinder 2nd Constructor called. " <<
G4endl;
145 <<
" - min step = " << stepMinimum <<
G4endl
146 <<
" - stepper ptr provided : "
147 << ( pItsStepper==
nullptr ?
" no " :
" yes " ) <<
G4endl;
148 if( pItsStepper==
nullptr )
149 G4cout <<
" - stepper/driver Id = " << stepperDriverId <<
" i.e. "
150 <<
" useFSAL = " << useFSALstepper
151 <<
" , useTemplated = " << useTemplatedStepper
152 <<
" , useRegular = " << useRegularStepper
153 <<
" , useFSAL = " << useFSALstepper
161 fEquation = pEquation;
167 G4bool errorInStepperCreation =
false;
169 std::ostringstream message;
171 if( pItsStepper !=
nullptr )
175 G4cout <<
" G4ChordFinder: Creating G4IntegrationDriver<G4MagIntegratorStepper> with "
176 <<
" stepMinimum = " << stepMinimum
181 if(pItsStepper->
isQSS())
186 "Cannot provide QSS stepper in constructor. User c-tor with Driver instead.");
202 else if ( useTemplatedStepper )
206 G4cout <<
" G4ChordFinder: Creating Templated Stepper of type> "
207 << TemplatedStepperName <<
G4endl;
210 auto templatedStepper =
new TemplatedStepperType(pEquation);
215 fRegularStepperOwned = templatedStepper;
216 if( templatedStepper ==
nullptr )
218 message <<
"Templated Stepper instantiation FAILED." <<
G4endl;
219 message <<
"G4ChordFinder: Attempted to instantiate "
220 << TemplatedStepperName <<
" type stepper " <<
G4endl;
221 errorInStepperCreation =
true;
226 stepMinimum, templatedStepper, nVar6 );
229 G4cout <<
" G4ChordFinder: Using G4IntegrationDriver. " <<
G4endl;
234 else if ( useRegularStepper )
236 auto regularStepper =
new RegularStepperType(pEquation);
238 fRegularStepperOwned = regularStepper;
242 G4cout <<
" G4ChordFinder: Creating Driver for regular stepper.";
245 if( regularStepper ==
nullptr )
247 message <<
"Regular Stepper instantiation FAILED." <<
G4endl;
248 message <<
"G4ChordFinder: Attempted to instantiate "
249 << RegularStepperName <<
" type stepper " <<
G4endl;
250 errorInStepperCreation =
true;
258 stepMinimum, dp5, nVar6 );
261 G4cout <<
" Using InterpolationDriver<DoPri5> " <<
G4endl;
267 stepMinimum, regularStepper, nVar6 );
270 G4cout <<
" Using IntegrationDriver<DoPri5> " <<
G4endl;
275 else if ( useBfieldDriver )
280 fRegularStepperOwned = regularStepper;
286 fLongStepper = std::make_unique<G4HelixHeum>(pEquation);
289 std::make_unique<SmallStepDriver>(stepMinimum,
290 regularStepper, regularStepper->GetNumberOfVariables()),
291 std::make_unique<LargeStepDriver>(stepMinimum,
292 fLongStepper.get(), regularStepper->GetNumberOfVariables()) );
294 if( fIntgrDriver ==
nullptr)
296 message <<
"Using G4BFieldIntegrationDriver with "
297 << RegularStepperName <<
" type stepper " <<
G4endl;
298 message <<
"Driver instantiation FAILED." <<
G4endl;
304 else if( useG4QSSDriver )
326 G4cout <<
"-- G4ChordFinder: Using QSS Driver." <<
G4endl;
331 auto fsalStepper=
new NewFsalStepperType(pEquation);
333 fNewFSALStepperOwned = fsalStepper;
335 if( fsalStepper ==
nullptr )
337 message <<
"Stepper instantiation FAILED." <<
G4endl;
338 message <<
"Attempted to instantiate "
339 << NewFSALStepperName <<
" type stepper " <<
G4endl;
342 errorInStepperCreation =
true;
348 fsalStepper->GetNumberOfVariables() );
351 if( fIntgrDriver ==
nullptr )
353 message <<
"Using G4FSALIntegrationDriver with stepper type: "
354 << NewFSALStepperName <<
G4endl;
355 message <<
"Integration Driver instantiation FAILED." <<
G4endl;
372 if( errorInStepperCreation || (fIntgrDriver ==
nullptr ))
374 std::ostringstream errmsg;
376 if( errorInStepperCreation )
378 errmsg <<
"ERROR> Failure to create Stepper object." <<
G4endl
379 <<
" --------------------------------" <<
G4endl;
381 if (fIntgrDriver ==
nullptr )
383 errmsg <<
"ERROR> Failure to create Integration-Driver object."
385 <<
" -------------------------------------------"
388 const std::string BoolName[2]= {
"False",
"True" };
389 errmsg <<
" Configuration: (constructor arguments) " <<
G4endl
390 <<
" provided Stepper = " << pItsStepper <<
G4endl
391 <<
" stepper/driver Id = " << stepperDriverId <<
" i.e. "
392 <<
" useTemplated = " << BoolName[useTemplatedStepper]
393 <<
" useRegular = " << BoolName[useRegularStepper]
394 <<
" useFSAL = " << BoolName[useFSALstepper]
395 <<
" using combo BField Driver = " <<
396 BoolName[ ! (useFSALstepper||useTemplatedStepper
397 || useRegularStepper ) ]
399 errmsg << message.str();
400 errmsg <<
"Aborting.";
401 G4Exception(
"G4ChordFinder::G4ChordFinder() - constructor 2",
405 assert( ( pItsStepper !=
nullptr )
406 || ( fRegularStepperOwned !=
nullptr )
407 || ( fNewFSALStepperOwned !=
nullptr )
410 assert( fIntgrDriver !=
nullptr );
445 if(!first) { EndPoint = ApproxCurveV; }
458 ya=(PointG-Point_A).mag();
459 xb=(Point_A-CurrentF_Point).mag();
460 yb=-(PointG-CurrentF_Point).mag();
461 xc=(Point_A-Point_B).mag();
462 yc=-(CurrentE_Point-Point_B).mag();
467 ya=(Point_A-CurrentE_Point).mag();
468 xb=(Point_A-CurrentF_Point).mag();
469 yb=(PointG-CurrentF_Point).mag();
470 xc=(Point_A-Point_B).mag();
471 yc=-(Point_B-PointG).mag();
475 CurrentE_Point, eps_step);
481 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
497 test_step = test_step - xb;
500 xb = (CurrentF_Point-Point_B).mag();
503 if(test_step<=0) { test_step=0.1*xb; }
504 if(test_step>=xb) { test_step=0.5*xb; }
505 if(test_step>=curve){ test_step=0.5*curve; }
507 if(curve*(1.+eps_step)<xb)
517 G4cout <<
"G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
518 << test_step <<
" EndPoint = " << EndPoint <<
G4endl;
524 CurveB_PointVelocity,
525 CurrentE_Point, eps_step );
527 G4cout <<
"G4ChordFinder::BrentApprox = " << EndPoint <<
G4endl;
528 G4cout <<
"G4ChordFinder::LinearApprox= " << TestTrack <<
G4endl;
546 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
561 G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
562 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
565 G4cerr <<
" Warning in G4ChordFinder::ApproxCurvePoint: "
567 <<
" The two points are further apart than the curve length "
569 <<
" Dist = " << ABdist
570 <<
" curve length = " << curve_length
571 <<
" relativeDiff = " << (curve_length-ABdist)/ABdist
573 if( curve_length < ABdist * (1. - 10*eps_step) )
575 std::ostringstream message;
576 message <<
"Unphysical curve length." <<
G4endl
577 <<
"The size of the above difference exceeds allowed limits."
580 G4Exception(
"G4ChordFinder::ApproxCurvePointV()",
"GeomField0003",
593 AE_fraction = ChordAE_Vector.
mag() / ABdist;
599 G4cout <<
"Warning in G4ChordFinder::ApproxCurvePointV():"
600 <<
" A and B are the same point!" <<
G4endl
601 <<
" Chord AB length = " << ChordAE_Vector.
mag() <<
G4endl
606 if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) )
609 G4cerr <<
" G4ChordFinder::ApproxCurvePointV() - Warning:"
610 <<
" Anomalous condition:AE > AB or AE/AB <= 0 " <<
G4endl
611 <<
" AE_fraction = " << AE_fraction <<
G4endl
612 <<
" Chord AE length = " << ChordAE_Vector.
mag() <<
G4endl
614 G4cerr <<
" OK if this condition occurs after a recalculation of 'B'"
625 new_st_length = AE_fraction * curve_length;
627 if ( AE_fraction > 0.0 )
630 new_st_length, eps_step );
640 return Current_PointVelocity;
G4double InvParabolic(const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector ¤tEPoint, const G4ThreeVector ¤tFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)