96 G4int stepperDriverId )
100 constexpr G4int nVar6 = 6;
102 fDeltaChord = fDefaultDeltaChord;
104 G4cout <<
" G4ChordFinder: stepperDriverId: " << stepperDriverId <<
G4endl;
120 using TemplatedStepperType =
122 const char* TemplatedStepperName =
123 "G4TDormandPrince745 (templated Dormand-Prince45, aka DoPri5): 5th/4th Order 7-stage embedded";
125 using RegularStepperType =
132 const char* RegularStepperName =
133 "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded";
139 const char* NewFSALStepperName =
140 "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
143 static G4bool verboseDebug =
true;
146 G4cout <<
"G4ChordFinder 2nd Constructor called. " <<
G4endl;
148 <<
" - min step = " << stepMinimum <<
G4endl
149 <<
" - stepper ptr provided : "
150 << ( pItsStepper==
nullptr ?
" no " :
" yes " ) <<
G4endl;
151 if( pItsStepper==
nullptr )
153 G4cout <<
" - stepper/driver Id = " << stepperDriverId <<
" i.e. "
154 <<
" useFSAL = " << useFSALstepper
155 <<
" , useTemplated = " << useTemplatedStepper
156 <<
" , useRegular = " << useRegularStepper
157 <<
" , useFSAL = " << useFSALstepper
166 fEquation = pEquation;
172 G4bool errorInStepperCreation =
false;
174 std::ostringstream message;
176 if( pItsStepper !=
nullptr )
180 G4cout <<
" G4ChordFinder: Creating G4IntegrationDriver<G4MagIntegratorStepper> with "
181 <<
" stepMinimum = " << stepMinimum
186 if(pItsStepper->
isQSS())
191 "Cannot provide QSS stepper in constructor. User c-tor with Driver instead.");
207 else if ( useTemplatedStepper )
211 G4cout <<
" G4ChordFinder: Creating Templated Stepper of type> "
212 << TemplatedStepperName <<
G4endl;
215 auto templatedStepper =
new TemplatedStepperType(pEquation);
220 fRegularStepperOwned = templatedStepper;
221 if( templatedStepper ==
nullptr )
223 message <<
"Templated Stepper instantiation FAILED." <<
G4endl;
224 message <<
"G4ChordFinder: Attempted to instantiate "
225 << TemplatedStepperName <<
" type stepper " <<
G4endl;
226 errorInStepperCreation =
true;
231 stepMinimum, templatedStepper, nVar6 );
234 G4cout <<
" G4ChordFinder: Using G4IntegrationDriver. " <<
G4endl;
239 else if ( useRegularStepper )
241 auto regularStepper =
new RegularStepperType(pEquation);
243 fRegularStepperOwned = regularStepper;
247 G4cout <<
" G4ChordFinder: Creating Driver for regular stepper.";
250 if( regularStepper ==
nullptr )
252 message <<
"Regular Stepper instantiation FAILED." <<
G4endl;
253 message <<
"G4ChordFinder: Attempted to instantiate "
254 << RegularStepperName <<
" type stepper " <<
G4endl;
255 errorInStepperCreation =
true;
263 stepMinimum, dp5, nVar6 );
266 G4cout <<
" Using InterpolationDriver<DoPri5> " <<
G4endl;
272 stepMinimum, regularStepper, nVar6 );
275 G4cout <<
" Using IntegrationDriver<DoPri5> " <<
G4endl;
280 else if ( useBfieldDriver )
285 fRegularStepperOwned = regularStepper;
291 fLongStepper = std::make_unique<G4HelixHeum>(pEquation);
294 std::make_unique<SmallStepDriver>(stepMinimum,
295 regularStepper, regularStepper->GetNumberOfVariables()),
296 std::make_unique<LargeStepDriver>(stepMinimum,
297 fLongStepper.get(), regularStepper->GetNumberOfVariables()) );
299 if( fIntgrDriver ==
nullptr)
301 message <<
"Using G4BFieldIntegrationDriver with "
302 << RegularStepperName <<
" type stepper " <<
G4endl;
303 message <<
"Driver instantiation FAILED." <<
G4endl;
309 else if( useG4QSSDriver )
321 fIntgrDriver = qss_driver;
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 );
446 if(!first) { EndPoint = ApproxCurveV; }
459 ya=(PointG-Point_A).mag();
460 xb=(Point_A-CurrentF_Point).mag();
461 yb=-(PointG-CurrentF_Point).mag();
462 xc=(Point_A-Point_B).mag();
463 yc=-(CurrentE_Point-Point_B).mag();
468 ya=(Point_A-CurrentE_Point).mag();
469 xb=(Point_A-CurrentF_Point).mag();
470 yb=(PointG-CurrentF_Point).mag();
471 xc=(Point_A-Point_B).mag();
472 yc=-(Point_B-PointG).mag();
476 CurrentE_Point, eps_step);
482 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
498 test_step = test_step - xb;
501 xb = (CurrentF_Point-Point_B).mag();
504 if(test_step<=0) { test_step=0.1*xb; }
505 if(test_step>=xb) { test_step=0.5*xb; }
506 if(test_step>=curve){ test_step=0.5*curve; }
508 if(curve*(1.+eps_step)<xb)
513 fIntgrDriver->AccurateAdvance(EndPoint,test_step, eps_step);
518 G4cout <<
"G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
519 << test_step <<
" EndPoint = " << EndPoint <<
G4endl;
525 CurveB_PointVelocity,
526 CurrentE_Point, eps_step );
528 G4cout <<
"G4ChordFinder::BrentApprox = " << EndPoint <<
G4endl;
529 G4cout <<
"G4ChordFinder::LinearApprox= " << TestTrack <<
G4endl;
547 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
562 G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
563 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
566 G4cerr <<
" Warning in G4ChordFinder::ApproxCurvePoint: "
568 <<
" The two points are further apart than the curve length "
570 <<
" Dist = " << ABdist
571 <<
" curve length = " << curve_length
572 <<
" relativeDiff = " << (curve_length-ABdist)/ABdist
574 if( curve_length < ABdist * (1. - 10*eps_step) )
576 std::ostringstream message;
577 message <<
"Unphysical curve length." <<
G4endl
578 <<
"The size of the above difference exceeds allowed limits."
581 G4Exception(
"G4ChordFinder::ApproxCurvePointV()",
"GeomField0003",
594 AE_fraction = ChordAE_Vector.
mag() / ABdist;
600 G4cout <<
"Warning in G4ChordFinder::ApproxCurvePointV():"
601 <<
" A and B are the same point!" <<
G4endl
602 <<
" Chord AB length = " << ChordAE_Vector.
mag() <<
G4endl
607 if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) )
610 G4cerr <<
" G4ChordFinder::ApproxCurvePointV() - Warning:"
611 <<
" Anomalous condition:AE > AB or AE/AB <= 0 " <<
G4endl
612 <<
" AE_fraction = " << AE_fraction <<
G4endl
613 <<
" Chord AE length = " << ChordAE_Vector.
mag() <<
G4endl
615 G4cerr <<
" OK if this condition occurs after a recalculation of 'B'"
626 new_st_length = AE_fraction * curve_length;
628 if ( AE_fraction > 0.0 )
630 fIntgrDriver->AccurateAdvance(Current_PointVelocity,
631 new_st_length, eps_step );
641 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)