65 : fDefaultDeltaChord(0.25 *
mm), fIntgrDriver(pIntegrationDriver)
79 : fDefaultDeltaChord(0.25 *
mm)
87 const char* NewFSALStepperName =
88 "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
89 using RegularStepperType =
96 const char* RegularStepperName =
97 "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded stepper";
102 G4bool forceFSALstepper =
false;
103 G4bool recallFSALflag = useFSALstepper;
104 useFSALstepper = forceFSALstepper || useFSALstepper;
107 G4cout <<
"G4ChordFinder 2nd Constructor called. " <<
G4endl;
109 G4cout <<
" useFSAL stepper= " << useFSALstepper
110 <<
" (request = " << recallFSALflag
111 <<
" force FSAL = " << forceFSALstepper <<
" )" <<
G4endl;
123 G4bool errorInStepperCreation =
false;
127 if( pItsStepper !=
nullptr )
131 stepMinimum, pItsStepper, pItsStepper->GetNumberOfVariables());
133 else if ( !useFSALstepper )
136 auto regularStepper =
new RegularStepperType(pEquation);
143 if( regularStepper ==
nullptr )
145 message <<
"Stepper instantiation FAILED." <<
G4endl;
146 message <<
"G4ChordFinder: Attempted to instantiate "
147 << RegularStepperName <<
" type stepper " <<
G4endl;
150 errorInStepperCreation =
true;
160 std::unique_ptr<SmallStepDriver>(
new SmallStepDriver(stepMinimum,
161 regularStepper, regularStepper->GetNumberOfVariables())),
162 std::unique_ptr<LargeStepDriver>(
new LargeStepDriver(stepMinimum,
163 fLongStepper.get(), regularStepper->GetNumberOfVariables())) );
165 if( fIntgrDriver ==
nullptr)
167 message <<
"Using G4BFieldIntegrationDriver with "
168 << RegularStepperName <<
" type stepper " <<
G4endl;
169 message <<
"Driver instantiation FAILED." <<
G4endl;
177 auto fsalStepper=
new NewFsalStepperType(pEquation);
181 if( fsalStepper ==
nullptr )
183 message <<
"Stepper instantiation FAILED." <<
G4endl;
184 message <<
"Attempted to instantiate "
185 << NewFSALStepperName <<
" type stepper " <<
G4endl;
188 errorInStepperCreation =
true;
194 fsalStepper->GetNumberOfVariables() );
199 message <<
"Using G4FSALIntegrationDriver with stepper type: "
200 << NewFSALStepperName <<
G4endl;
201 message <<
"Integration Driver instantiation FAILED." <<
G4endl;
218 if( errorInStepperCreation || (
fIntgrDriver ==
nullptr ))
220 std::ostringstream errmsg;
222 if( errorInStepperCreation )
224 errmsg <<
"ERROR> Failure to create Stepper object." << G4endl
225 <<
" --------------------------------" <<
G4endl;
229 errmsg <<
"ERROR> Failure to create Integration-Driver object."
231 <<
" -------------------------------------------"
234 const std::string BoolName[2]= {
"False",
"True" };
235 errmsg <<
" Configuration: (constructor arguments) " << G4endl
236 <<
" provided Stepper = " << pItsStepper << G4endl
237 <<
" use FSAL stepper = " << BoolName[useFSALstepper]
238 <<
" (request = " << BoolName[recallFSALflag]
239 <<
" force FSAL = " << BoolName[forceFSALstepper] <<
" )"
241 errmsg << message.str();
242 errmsg <<
"Aborting.";
243 G4Exception(
"G4ChordFinder::G4ChordFinder() - constructor 2",
247 assert( ( pItsStepper !=
nullptr )
287 if(!first) { EndPoint = ApproxCurveV; }
300 ya=(PointG-Point_A).mag();
301 xb=(Point_A-CurrentF_Point).mag();
302 yb=-(PointG-CurrentF_Point).mag();
303 xc=(Point_A-Point_B).mag();
304 yc=-(CurrentE_Point-Point_B).mag();
309 ya=(Point_A-CurrentE_Point).mag();
310 xb=(Point_A-CurrentF_Point).mag();
311 yb=(PointG-CurrentF_Point).mag();
312 xc=(Point_A-Point_B).mag();
313 yc=-(Point_B-PointG).mag();
317 CurrentE_Point, eps_step);
339 test_step = test_step - xb;
342 xb = (CurrentF_Point-Point_B).mag();
345 if(test_step<=0) { test_step=0.1*xb; }
346 if(test_step>=xb) { test_step=0.5*xb; }
347 if(test_step>=curve){ test_step=0.5*curve; }
349 if(curve*(1.+eps_step)<xb)
359 G4cout <<
"G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
360 << test_step <<
" EndPoint = " << EndPoint <<
G4endl;
366 CurveB_PointVelocity,
367 CurrentE_Point, eps_step );
369 G4cout <<
"G4ChordFinder::BrentApprox = " << EndPoint <<
G4endl;
370 G4cout <<
"G4ChordFinder::LinearApprox= " << TestTrack <<
G4endl;
388 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
404 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
407 G4cerr <<
" Warning in G4ChordFinder::ApproxCurvePoint: "
409 <<
" The two points are further apart than the curve length "
411 <<
" Dist = " << ABdist
412 <<
" curve length = " << curve_length
413 <<
" relativeDiff = " << (curve_length-ABdist)/ABdist
415 if( curve_length < ABdist * (1. - 10*eps_step) )
418 message <<
"Unphysical curve length." <<
G4endl
419 <<
"The size of the above difference exceeds allowed limits."
422 G4Exception(
"G4ChordFinder::ApproxCurvePointV()",
"GeomField0003",
435 AE_fraction = ChordAE_Vector.
mag() / ABdist;
441 G4cout <<
"Warning in G4ChordFinder::ApproxCurvePointV():"
442 <<
" A and B are the same point!" <<
G4endl
443 <<
" Chord AB length = " << ChordAE_Vector.
mag() <<
G4endl
448 if( (AE_fraction> 1.0 +
perMillion) || (AE_fraction< 0.) )
451 G4cerr <<
" G4ChordFinder::ApproxCurvePointV() - Warning:"
452 <<
" Anomalous condition:AE > AB or AE/AB <= 0 " <<
G4endl
453 <<
" AE_fraction = " << AE_fraction <<
G4endl
454 <<
" Chord AE length = " << ChordAE_Vector.
mag() <<
G4endl
456 G4cerr <<
" OK if this condition occurs after a recalculation of 'B'"
457 << G4endl <<
" Otherwise it is an error. " <<
G4endl ;
467 new_st_length = AE_fraction * curve_length;
469 if ( AE_fraction > 0.0 )
472 new_st_length, eps_step );
482 return Current_PointVelocity;