69static G4bool gVerboseCtor =
false;
74 : fDefaultDeltaChord(0.25 * mm), fIntgrDriver(pIntegrationDriver)
78 G4cout <<
"G4ChordFinder: Simple constructor -- it uses pre-existing driver." <<
G4endl;
80 fDeltaChord = fDefaultDeltaChord;
89 G4int stepperDriverId )
90 : fDefaultDeltaChord(0.25 * mm)
94 constexpr G4int nVar6 = 6;
96 fDeltaChord = fDefaultDeltaChord;
100 G4bool useFSALstepper= (stepperDriverId == 1);
101 G4bool useTemplatedStepper= (stepperDriverId == 2);
102 G4bool useRegularStepper = (stepperDriverId == 3);
110 using TemplatedStepperType =
112 const char* TemplatedStepperName =
113 "G4TDormandPrince745 (templated Dormand-Prince45, aka DoPri5): 5th/4th Order 7-stage embedded";
115 using RegularStepperType =
122 const char* RegularStepperName =
123 "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded";
129 const char* NewFSALStepperName =
130 "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
133 static G4bool verboseDebug =
true;
136 G4cout <<
"G4ChordFinder 2nd Constructor called. " <<
G4endl;
138 <<
" - min step = " << stepMinimum <<
G4endl
139 <<
" - stepper ptr provided : "
140 << ( pItsStepper==
nullptr ?
" no " :
" yes " ) <<
G4endl;
141 if( pItsStepper==
nullptr )
142 G4cout <<
" - stepper/driver Id = " << stepperDriverId <<
" i.e. "
143 <<
" useFSAL = " << useFSALstepper
144 <<
" , useTemplated = " << useTemplatedStepper
145 <<
" , useRegular = " << useRegularStepper
146 <<
" , useFSAL = " << useFSALstepper
154 fEquation = pEquation;
160 G4bool errorInStepperCreation =
false;
162 std::ostringstream message;
164 if( pItsStepper !=
nullptr )
167 G4cout <<
" G4ChordFinder: Creating G4IntegrationDriver<G4MagIntegratorStepper> with "
168 <<
" stepMinimum = " << stepMinimum
180 else if ( useTemplatedStepper )
183 G4cout <<
" G4ChordFinder: Creating Templated Stepper of type> "
184 << TemplatedStepperName <<
G4endl;
186 auto templatedStepper =
new TemplatedStepperType(pEquation);
191 fRegularStepperOwned = templatedStepper;
192 if( templatedStepper ==
nullptr )
194 message <<
"Templated Stepper instantiation FAILED." <<
G4endl;
195 message <<
"G4ChordFinder: Attempted to instantiate "
196 << TemplatedStepperName <<
" type stepper " <<
G4endl;
197 errorInStepperCreation =
true;
202 stepMinimum, templatedStepper, nVar6 );
204 G4cout <<
" G4ChordFinder: Using G4IntegrationDriver. " <<
G4endl;
208 else if ( useRegularStepper )
210 auto regularStepper =
new RegularStepperType(pEquation);
212 fRegularStepperOwned = regularStepper;
215 G4cout <<
" G4ChordFinder: Creating Driver for regular stepper.";
217 if( regularStepper ==
nullptr )
219 message <<
"Regular Stepper instantiation FAILED." <<
G4endl;
220 message <<
"G4ChordFinder: Attempted to instantiate "
221 << RegularStepperName <<
" type stepper " <<
G4endl;
222 errorInStepperCreation =
true;
229 stepMinimum, dp5, nVar6 );
231 G4cout <<
" Using InterpolationDriver<DoPri5> " <<
G4endl;
234 stepMinimum, regularStepper, nVar6 );
236 G4cout <<
" Using IntegrationDriver<DoPri5> " <<
G4endl;
240 else if ( !useFSALstepper )
245 fRegularStepperOwned = regularStepper;
251 fLongStepper = std::unique_ptr<G4HelixHeum>(
new G4HelixHeum(pEquation));
254 std::unique_ptr<SmallStepDriver>(
new SmallStepDriver(stepMinimum,
255 regularStepper, regularStepper->GetNumberOfVariables())),
256 std::unique_ptr<LargeStepDriver>(
new LargeStepDriver(stepMinimum,
257 fLongStepper.get(), regularStepper->GetNumberOfVariables())) );
259 if( fIntgrDriver ==
nullptr)
261 message <<
"Using G4BFieldIntegrationDriver with "
262 << RegularStepperName <<
" type stepper " <<
G4endl;
263 message <<
"Driver instantiation FAILED." <<
G4endl;
271 auto fsalStepper=
new NewFsalStepperType(pEquation);
273 fNewFSALStepperOwned = fsalStepper;
275 if( fsalStepper ==
nullptr )
277 message <<
"Stepper instantiation FAILED." <<
G4endl;
278 message <<
"Attempted to instantiate "
279 << NewFSALStepperName <<
" type stepper " <<
G4endl;
282 errorInStepperCreation =
true;
288 fsalStepper->GetNumberOfVariables() );
291 if( fIntgrDriver ==
nullptr )
293 message <<
"Using G4FSALIntegrationDriver with stepper type: "
294 << NewFSALStepperName <<
G4endl;
295 message <<
"Integration Driver instantiation FAILED." <<
G4endl;
312 if( errorInStepperCreation || (fIntgrDriver ==
nullptr ))
314 std::ostringstream errmsg;
316 if( errorInStepperCreation )
318 errmsg <<
"ERROR> Failure to create Stepper object." <<
G4endl
319 <<
" --------------------------------" <<
G4endl;
321 if (fIntgrDriver ==
nullptr )
323 errmsg <<
"ERROR> Failure to create Integration-Driver object."
325 <<
" -------------------------------------------"
328 const std::string BoolName[2]= {
"False",
"True" };
329 errmsg <<
" Configuration: (constructor arguments) " <<
G4endl
330 <<
" provided Stepper = " << pItsStepper <<
G4endl
331 <<
" stepper/driver Id = " << stepperDriverId <<
" i.e. "
332 <<
" useTemplated = " << BoolName[useTemplatedStepper]
333 <<
" useRegular = " << BoolName[useRegularStepper]
334 <<
" useFSAL = " << BoolName[useFSALstepper]
335 <<
" using combo BField Driver = " <<
336 BoolName[ ! (useFSALstepper||useTemplatedStepper
337 || useRegularStepper ) ]
339 errmsg << message.str();
340 errmsg <<
"Aborting.";
341 G4Exception(
"G4ChordFinder::G4ChordFinder() - constructor 2",
345 assert( ( pItsStepper !=
nullptr )
346 || ( fRegularStepperOwned !=
nullptr )
347 || ( fNewFSALStepperOwned !=
nullptr )
349 assert( fIntgrDriver !=
nullptr );
358 delete fRegularStepperOwned;
359 delete fNewFSALStepperOwned;
385 if(!first) { EndPoint = ApproxCurveV; }
398 ya=(PointG-Point_A).mag();
399 xb=(Point_A-CurrentF_Point).mag();
400 yb=-(PointG-CurrentF_Point).mag();
401 xc=(Point_A-Point_B).mag();
402 yc=-(CurrentE_Point-Point_B).mag();
407 ya=(Point_A-CurrentE_Point).mag();
408 xb=(Point_A-CurrentF_Point).mag();
409 yb=(PointG-CurrentF_Point).mag();
410 xc=(Point_A-Point_B).mag();
411 yc=-(Point_B-PointG).mag();
415 CurrentE_Point, eps_step);
421 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
437 test_step = test_step - xb;
440 xb = (CurrentF_Point-Point_B).mag();
443 if(test_step<=0) { test_step=0.1*xb; }
444 if(test_step>=xb) { test_step=0.5*xb; }
445 if(test_step>=curve){ test_step=0.5*curve; }
447 if(curve*(1.+eps_step)<xb)
457 G4cout <<
"G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
458 << test_step <<
" EndPoint = " << EndPoint <<
G4endl;
464 CurveB_PointVelocity,
465 CurrentE_Point, eps_step );
467 G4cout <<
"G4ChordFinder::BrentApprox = " << EndPoint <<
G4endl;
468 G4cout <<
"G4ChordFinder::LinearApprox= " << TestTrack <<
G4endl;
486 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
501 G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
502 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
505 G4cerr <<
" Warning in G4ChordFinder::ApproxCurvePoint: "
507 <<
" The two points are further apart than the curve length "
509 <<
" Dist = " << ABdist
510 <<
" curve length = " << curve_length
511 <<
" relativeDiff = " << (curve_length-ABdist)/ABdist
513 if( curve_length < ABdist * (1. - 10*eps_step) )
515 std::ostringstream message;
516 message <<
"Unphysical curve length." <<
G4endl
517 <<
"The size of the above difference exceeds allowed limits."
520 G4Exception(
"G4ChordFinder::ApproxCurvePointV()",
"GeomField0003",
533 AE_fraction = ChordAE_Vector.
mag() / ABdist;
539 G4cout <<
"Warning in G4ChordFinder::ApproxCurvePointV():"
540 <<
" A and B are the same point!" <<
G4endl
541 <<
" Chord AB length = " << ChordAE_Vector.
mag() <<
G4endl
546 if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) )
549 G4cerr <<
" G4ChordFinder::ApproxCurvePointV() - Warning:"
550 <<
" Anomalous condition:AE > AB or AE/AB <= 0 " <<
G4endl
551 <<
" AE_fraction = " << AE_fraction <<
G4endl
552 <<
" Chord AE length = " << ChordAE_Vector.
mag() <<
G4endl
554 G4cerr <<
" OK if this condition occurs after a recalculation of 'B'"
565 new_st_length = AE_fraction * curve_length;
567 if ( AE_fraction > 0.0 )
570 new_st_length, eps_step );
580 return Current_PointVelocity;
588 os <<
"State of G4ChordFinder : " << std::endl;
589 os <<
" delta_chord = " << cf.fDeltaChord;
590 os <<
" Default d_c = " << cf.fDefaultDeltaChord;
592 os <<
" stats-verbose = " << cf.fStatsVerbose;
std::ostream & operator<<(std::ostream &os, const G4ChordFinder &cf)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
G4double InvParabolic(const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector ¤tEPoint, G4double epsStep)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector ¤tEPoint, const G4ThreeVector ¤tFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
G4ChordFinder(G4VIntegrationDriver *pIntegrationDriver)
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
G4int GetNumberOfVariables() const
virtual G4bool AccurateAdvance(G4FieldTrack &track, G4double hstep, G4double eps, G4double hinitial=0)=0