Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ChordFinder Class Reference

G4ChordFinder is a class that provides Runge-Kutta integration of motion ODE and also has a method that returns an approximate point on the curve near to a (chord) point. More...

#include <G4ChordFinder.hh>

Public Types

enum  kIntegrationType {
  kDefaultDriverType =0 , kFSALStepperType =1 , kTemplatedStepperType , kRegularStepperType ,
  kBfieldDriverType , kQss2DriverType , kQss3DriverType
}

Public Member Functions

 G4ChordFinder (G4VIntegrationDriver *pIntegrationDriver)
 G4ChordFinder (G4MagneticField *itsMagField, G4double stepMinimum=G4FieldDefaults::kMinimumStep, G4MagIntegratorStepper *pItsStepper=nullptr, G4int stepperDriverChoice=kTemplatedStepperType)
 ~G4ChordFinder ()
 G4ChordFinder (const G4ChordFinder &)=delete
G4ChordFinderoperator= (const G4ChordFinder &)=delete
G4double AdvanceChordLimited (G4FieldTrack &yCurrent, G4double stepInitial, G4double epsStep_Relative, const G4ThreeVector &latestSafetyOrigin, G4double lasestSafetyRadius)
G4FieldTrack ApproxCurvePointS (const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector &currentEPoint, const G4ThreeVector &currentFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
G4FieldTrack ApproxCurvePointV (const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector &currentEPoint, G4double epsStep)
G4double InvParabolic (const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
G4double GetDeltaChord () const
void SetDeltaChord (G4double newval)
void SetIntegrationDriver (G4VIntegrationDriver *IntegrationDriver)
G4VIntegrationDriverGetIntegrationDriver ()
void ResetStepEstimate ()
G4int SetVerbose (G4int newvalue=1)
void OnComputeStep (const G4FieldTrack *track)

Static Public Member Functions

static void SetVerboseConstruction (G4bool v=true)

Friends

std::ostream & operator<< (std::ostream &os, const G4ChordFinder &cf)

Detailed Description

G4ChordFinder is a class that provides Runge-Kutta integration of motion ODE and also has a method that returns an approximate point on the curve near to a (chord) point.

Definition at line 58 of file G4ChordFinder.hh.

Member Enumeration Documentation

◆ kIntegrationType

Enumerator
kDefaultDriverType 
kFSALStepperType 
kTemplatedStepperType 
kRegularStepperType 
kBfieldDriverType 
kQss2DriverType 
kQss3DriverType 

Definition at line 62 of file G4ChordFinder.hh.

Constructor & Destructor Documentation

◆ G4ChordFinder() [1/3]

G4ChordFinder::G4ChordFinder ( G4VIntegrationDriver * pIntegrationDriver)
explicit

The most flexible constructor, which allows the user to specify any type of field, equation, stepper and integration driver.

Parameters
[in]pIntegrationDriverPointer to the integrator driver to use.

Definition at line 78 of file G4ChordFinder.cc.

79 : fIntgrDriver(pIntegrationDriver)
80{
81 // Simple constructor -- it does not create equation
82
83 if( gVerboseCtor )
84 {
85 G4cout << "G4ChordFinder: Simple constructor -- it uses pre-existing driver." << G4endl;
86 }
87
88 fDeltaChord = fDefaultDeltaChord; // Parameters
89}
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout

Referenced by G4ChordFinder(), OnComputeStep(), operator<<, and operator=().

◆ G4ChordFinder() [2/3]

G4ChordFinder::G4ChordFinder ( G4MagneticField * itsMagField,
G4double stepMinimum = G4FieldDefaults::kMinimumStep,
G4MagIntegratorStepper * pItsStepper = nullptr,
G4int stepperDriverChoice = kTemplatedStepperType )

Constructor that creates defaults for all "children" classes. The type of equation of motion is fixed. A default type of stepper (Dormand Prince since release 10.4) is used, and the corresponding integration driver.

Parameters
[in]itsMagFieldPointer to the magnetic field.
[in]stepMinimumPointer to the magnetic field.
[in]pItsStepperOptional pointer to the stepper algorithm.
[in]stepperDriverChoiceType of stepper driver.

Definition at line 93 of file G4ChordFinder.cc.

97{
98 // Construct the Chord Finder
99 // by creating in inverse order the Driver, the Stepper and EqRhs ...
100 constexpr G4int nVar6 = 6; // Components integrated in Usual Equation of motion
101
102 fDeltaChord = fDefaultDeltaChord; // Parameters
103
104 G4cout << " G4ChordFinder: stepperDriverId: " << stepperDriverId << G4endl;
105
106 G4bool useFSALstepper = (stepperDriverId == kFSALStepperType); // Was 1
107 G4bool useTemplatedStepper= (stepperDriverId == kTemplatedStepperType); // Was 2
108 G4bool useRegularStepper = (stepperDriverId == kRegularStepperType); // Was 3
109 G4bool useBfieldDriver = (stepperDriverId == kBfieldDriverType); // Was 4
110 G4bool useG4QSSDriver = (stepperDriverId == kQss2DriverType)
111 || (stepperDriverId == kQss3DriverType);
112
113 if( stepperDriverId == kQss3DriverType )
114 {
116 }
117
118 using EquationType = G4Mag_UsualEqRhs;
119
120 using TemplatedStepperType =
121 G4TDormandPrince45<EquationType,nVar6>; // 5th order embedded method. High efficiency.
122 const char* TemplatedStepperName =
123 "G4TDormandPrince745 (templated Dormand-Prince45, aka DoPri5): 5th/4th Order 7-stage embedded";
124
125 using RegularStepperType =
126 G4DormandPrince745; // 5th order embedded method. High efficiency.
127 // G4ClassicalRK4; // The old default
128 // G4CashKarpRKF45; // First embedded method in G4
129 // G4BogackiShampine45; // High efficiency 5th order embedded method
130 // G4NystromRK4; // Nystrom stepper 4th order
131 // G4RK547FEq1; // or 2 or 3
132 const char* RegularStepperName =
133 "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded";
134 // "BogackiShampine 45 (Embedded 5th/4th Order, 7-stage)";
135 // "Nystrom stepper 4th order";
136
137 using NewFsalStepperType = G4DormandPrince745; // Now works -- 2020.10.08
138 // Was G4RK547FEq1; // or 2 or 3
139 const char* NewFSALStepperName =
140 "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
141
142#ifdef G4DEBUG_FIELD
143 static G4bool verboseDebug = true;
144 if( verboseDebug )
145 {
146 G4cout << "G4ChordFinder 2nd Constructor called. " << G4endl;
147 G4cout << " Arguments: " << G4endl
148 << " - min step = " << stepMinimum << G4endl
149 << " - stepper ptr provided : "
150 << ( pItsStepper==nullptr ? " no " : " yes " ) << G4endl;
151 if( pItsStepper==nullptr )
152 {
153 G4cout << " - stepper/driver Id = " << stepperDriverId << " i.e. "
154 << " useFSAL = " << useFSALstepper
155 << " , useTemplated = " << useTemplatedStepper
156 << " , useRegular = " << useRegularStepper
157 << " , useFSAL = " << useFSALstepper
158 << G4endl;
159 }
160 }
161#endif
162
163 // useHigherStepper = forceHigherEffiencyStepper || useHigherStepper;
164
165 auto pEquation = new G4Mag_UsualEqRhs(theMagField);
166 fEquation = pEquation;
167
168 // G4MagIntegratorStepper* regularStepper = nullptr;
169 // G4VFSALIntegrationStepper* fsalStepper = nullptr; // for FSAL steppers only
170 // G4MagIntegratorStepper* oldFSALStepper = nullptr;
171
172 G4bool errorInStepperCreation = false;
173
174 std::ostringstream message; // In case of failure, load with description !
175
176 if( pItsStepper != nullptr )
177 {
178 if( gVerboseCtor )
179 {
180 G4cout << " G4ChordFinder: Creating G4IntegrationDriver<G4MagIntegratorStepper> with "
181 << " stepMinimum = " << stepMinimum
182 << " numVar= " << pItsStepper->GetNumberOfVariables() << G4endl;
183 }
184
185 // Stepper type is not known - so must use base class G4MagIntegratorStepper
186 if(pItsStepper->isQSS())
187 {
188 // fIntgrDriver = pItsStepper->build_driver(stepMinimum, true);
189 G4Exception("G4ChordFinder::G4ChordFinder()",
190 "GeomField1001", FatalException,
191 "Cannot provide QSS stepper in constructor. User c-tor with Driver instead.");
192 }
193 else
194 {
195 fIntgrDriver = new G4IntegrationDriver<G4MagIntegratorStepper>( stepMinimum,
196 pItsStepper, pItsStepper->GetNumberOfVariables() );
197 // Stepper type is not known - so must use base class G4MagIntegratorStepper
198 // Non-interpolating driver used by default.
199 // WAS: fIntgrDriver = pItsStepper->build_driver(stepMinimum); // QSS introduction -- axed
200 }
201 // -- Older:
202 // G4cout << " G4ChordFinder: Creating G4MagInt_Driver with " ...
203 // Type is not known - so must use old class
204 // fIntgrDriver = new G4MagInt_Driver( stepMinimum, pItsStepper,
205 // pItsStepper->GetNumberOfVariables());
206 }
207 else if ( useTemplatedStepper )
208 {
209 if( gVerboseCtor )
210 {
211 G4cout << " G4ChordFinder: Creating Templated Stepper of type> "
212 << TemplatedStepperName << G4endl;
213 }
214 // RegularStepperType* regularStepper = nullptr; // To check the exception
215 auto templatedStepper = new TemplatedStepperType(pEquation);
216 // *** ******************
217 //
218 // Alternative - for G4NystromRK4:
219 // = new G4NystromRK4(pEquation, 0.1*mm );
220 fRegularStepperOwned = templatedStepper;
221 if( templatedStepper == nullptr )
222 {
223 message << "Templated Stepper instantiation FAILED." << G4endl;
224 message << "G4ChordFinder: Attempted to instantiate "
225 << TemplatedStepperName << " type stepper " << G4endl;
226 errorInStepperCreation = true;
227 }
228 else
229 {
230 fIntgrDriver = new G4IntegrationDriver<TemplatedStepperType>(
231 stepMinimum, templatedStepper, nVar6 );
232 if( gVerboseCtor )
233 {
234 G4cout << " G4ChordFinder: Using G4IntegrationDriver. " << G4endl;
235 }
236 }
237
238 }
239 else if ( useRegularStepper ) // Plain stepper -- not double ...
240 {
241 auto regularStepper = new RegularStepperType(pEquation);
242 // *** ******************
243 fRegularStepperOwned = regularStepper;
244
245 if( gVerboseCtor )
246 {
247 G4cout << " G4ChordFinder: Creating Driver for regular stepper.";
248 }
249
250 if( regularStepper == nullptr )
251 {
252 message << "Regular Stepper instantiation FAILED." << G4endl;
253 message << "G4ChordFinder: Attempted to instantiate "
254 << RegularStepperName << " type stepper " << G4endl;
255 errorInStepperCreation = true;
256 }
257 else
258 {
259 auto dp5= dynamic_cast<G4DormandPrince745*>(regularStepper);
260 if( dp5 != nullptr )
261 {
262 fIntgrDriver = new G4InterpolationDriver<G4DormandPrince745>(
263 stepMinimum, dp5, nVar6 );
264 if( gVerboseCtor )
265 {
266 G4cout << " Using InterpolationDriver<DoPri5> " << G4endl;
267 }
268 }
269 else
270 {
271 fIntgrDriver = new G4IntegrationDriver<RegularStepperType>(
272 stepMinimum, regularStepper, nVar6 );
273 if( gVerboseCtor )
274 {
275 G4cout << " Using IntegrationDriver<DoPri5> " << G4endl;
276 }
277 }
278 }
279 }
280 else if ( useBfieldDriver )
281 {
282 auto regularStepper = new G4DormandPrince745(pEquation);
283 // *** ******************
284 //
285 fRegularStepperOwned = regularStepper;
286
287 {
288 using SmallStepDriver = G4InterpolationDriver<G4DormandPrince745>;
289 using LargeStepDriver = G4IntegrationDriver<G4HelixHeum>;
290
291 fLongStepper = std::make_unique<G4HelixHeum>(pEquation);
292
293 fIntgrDriver = new G4BFieldIntegrationDriver(
294 std::make_unique<SmallStepDriver>(stepMinimum,
295 regularStepper, regularStepper->GetNumberOfVariables()),
296 std::make_unique<LargeStepDriver>(stepMinimum,
297 fLongStepper.get(), regularStepper->GetNumberOfVariables()) );
298
299 if( fIntgrDriver == nullptr)
300 {
301 message << "Using G4BFieldIntegrationDriver with "
302 << RegularStepperName << " type stepper " << G4endl;
303 message << "Driver instantiation FAILED." << G4endl;
304 G4Exception("G4ChordFinder::G4ChordFinder()",
305 "GeomField1001", JustWarning, message);
306 }
307 }
308 }
309 else if( useG4QSSDriver )
310 {
311 G4int qssOrder= -1;
312 if ((stepperDriverId == kQss2DriverType) || (stepperDriverId == kQss3DriverType))
313 {
314 qssOrder= (stepperDriverId == kQss2DriverType) ? 2 : 3;
316 }
317 // Else we will use the default value, which can be steered interactively
318
319 fQssStepperOwned= new G4QSStepper(pEquation, 6);
320 auto qss_driver = new G4QSSDriver<G4QSStepper>(fQssStepperOwned);
321 fIntgrDriver = qss_driver;
322
323 if( gVerboseCtor )
324 {
325 G4cout << "-- Created QSS-" << G4QSSMessenger::instance()->GetQssOrder() << " stepper" << G4endl;
326 G4cout << "-- G4ChordFinder: Using QSS Driver." << G4endl;
327 }
328 }
329 else
330 {
331 auto fsalStepper= new NewFsalStepperType(pEquation);
332 // *** ******************
333 fNewFSALStepperOwned = fsalStepper;
334
335 if( fsalStepper == nullptr )
336 {
337 message << "Stepper instantiation FAILED." << G4endl;
338 message << "Attempted to instantiate "
339 << NewFSALStepperName << " type stepper " << G4endl;
340 G4Exception("G4ChordFinder::G4ChordFinder()",
341 "GeomField1001", JustWarning, message);
342 errorInStepperCreation = true;
343 }
344 else
345 {
346 fIntgrDriver = new
347 G4FSALIntegrationDriver<NewFsalStepperType>(stepMinimum, fsalStepper,
348 fsalStepper->GetNumberOfVariables() );
349 // ==== Create the driver which knows the class type
350
351 if( fIntgrDriver == nullptr )
352 {
353 message << "Using G4FSALIntegrationDriver with stepper type: "
354 << NewFSALStepperName << G4endl;
355 message << "Integration Driver instantiation FAILED." << G4endl;
356 G4Exception("G4ChordFinder::G4ChordFinder()",
357 "GeomField1001", JustWarning, message);
358 }
359 }
360 }
361
362 // -- Main work is now done
363
364 // Now check that no error occured, and report it if one did.
365
366 // To test failure to create driver
367 // delete fIntgrDriver;
368 // fIntgrDriver = nullptr;
369
370 // Detect and report Error conditions
371 //
372 if( errorInStepperCreation || (fIntgrDriver == nullptr ))
373 {
374 std::ostringstream errmsg;
375
376 if( errorInStepperCreation )
377 {
378 errmsg << "ERROR> Failure to create Stepper object." << G4endl
379 << " --------------------------------" << G4endl;
380 }
381 if (fIntgrDriver == nullptr )
382 {
383 errmsg << "ERROR> Failure to create Integration-Driver object."
384 << G4endl
385 << " -------------------------------------------"
386 << G4endl;
387 }
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 ) ]
398 << G4endl;
399 errmsg << message.str();
400 errmsg << "Aborting.";
401 G4Exception("G4ChordFinder::G4ChordFinder() - constructor 2",
402 "GeomField0003", FatalException, errmsg);
403 }
404
405 assert( ( pItsStepper != nullptr )
406 || ( fRegularStepperOwned != nullptr )
407 || ( fNewFSALStepperOwned != nullptr )
408 || useG4QSSDriver
409 );
410 assert( fIntgrDriver != nullptr );
411}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4bool SetQssOrder(G4int order)
static G4QSSMessenger * instance()

◆ ~G4ChordFinder()

G4ChordFinder::~G4ChordFinder ( )

Destructor.

Definition at line 415 of file G4ChordFinder.cc.

416{
417 delete fEquation;
418 delete fRegularStepperOwned;
419 delete fNewFSALStepperOwned;
420 delete fQssStepperOwned;
421 delete fCachedField;
422 delete fIntgrDriver;
423}

◆ G4ChordFinder() [3/3]

G4ChordFinder::G4ChordFinder ( const G4ChordFinder & )
delete

Copy constructor and assignment operator not allowed.

Member Function Documentation

◆ AdvanceChordLimited()

G4double G4ChordFinder::AdvanceChordLimited ( G4FieldTrack & yCurrent,
G4double stepInitial,
G4double epsStep_Relative,
const G4ThreeVector & latestSafetyOrigin,
G4double lasestSafetyRadius )
inline

Computes the step to take, based on chord limits. Uses ODE solver's driver to find the endpoint that satisfies the chord criterion that: d_chord < delta_chord.

Parameters
[in,out]yCurrentThe current track in field.
[in]stepInitialProposed initial step length.
[in]epsStep_RelativeRequested accuracy.
[in]latestSafetyOriginLast safety origin point. Unused.
[in]lasestSafetyRadiusLast safety distance. Unused.
Returns
The length of step taken.

Referenced by G4PropagatorInField::ComputeStep().

◆ ApproxCurvePointS()

G4FieldTrack G4ChordFinder::ApproxCurvePointS ( const G4FieldTrack & curveAPointVelocity,
const G4FieldTrack & curveBPointVelocity,
const G4FieldTrack & ApproxCurveV,
const G4ThreeVector & currentEPoint,
const G4ThreeVector & currentFPoint,
const G4ThreeVector & PointG,
G4bool first,
G4double epsStep )

Uses the Brent algorithm when possible, to determine the closest point on the curve. Given a starting curve point A (CurveA_PointVelocity), curve point B (CurveB_PointVelocity), a point E which is (generally) not on the curve and a point F which is on the curve (first approximation), find new point S on the curve closer to point E. While advancing towards S utilise 'eps_step' as a measure of the relative accuracy of each Step.

Returns
The end point on the curve closer to the given point E.

Definition at line 428 of file G4ChordFinder.cc.

435{
436 // ApproxCurvePointS is 2nd implementation of ApproxCurvePoint.
437 // Use Brent Algorithm (or InvParabolic) when possible.
438 // Given a starting curve point A (CurveA_PointVelocity), curve point B
439 // (CurveB_PointVelocity), a point E which is (generally) not on the curve
440 // and a point F which is on the curve (first approximation), find new
441 // point S on the curve closer to point E.
442 // While advancing towards S utilise 'eps_step' as a measure of the
443 // relative accuracy of each Step.
444
445 G4FieldTrack EndPoint(CurveA_PointVelocity);
446 if(!first) { EndPoint = ApproxCurveV; }
447
448 G4ThreeVector Point_A,Point_B;
449 Point_A=CurveA_PointVelocity.GetPosition();
450 Point_B=CurveB_PointVelocity.GetPosition();
451
452 G4double xa,xb,xc,ya,yb,yc;
453
454 // InverseParabolic. AF Intersects (First Part of Curve)
455
456 if(first)
457 {
458 xa=0.;
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();
464 }
465 else
466 {
467 xa=0.;
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();
473 if(xb==0.)
474 {
475 EndPoint = ApproxCurvePointV(CurveA_PointVelocity, CurveB_PointVelocity,
476 CurrentE_Point, eps_step);
477 return EndPoint;
478 }
479 }
480
481 const G4double tolerance = 1.e-12;
482 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
483 {
484 ; // What to do for the moment: return the same point as at start
485 // then PropagatorInField will take care
486 }
487 else
488 {
489 G4double test_step = InvParabolic(xa,ya,xb,yb,xc,yc);
490 G4double curve;
491 if(first)
492 {
493 curve=std::abs(EndPoint.GetCurveLength()
494 -ApproxCurveV.GetCurveLength());
495 }
496 else
497 {
498 test_step = test_step - xb;
499 curve=std::abs(EndPoint.GetCurveLength()
500 -CurveB_PointVelocity.GetCurveLength());
501 xb = (CurrentF_Point-Point_B).mag();
502 }
503
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; }
507
508 if(curve*(1.+eps_step)<xb) // Similar to ReEstimate Step from
509 { // G4VIntersectionLocator
510 test_step=0.5*curve;
511 }
512
513 fIntgrDriver->AccurateAdvance(EndPoint,test_step, eps_step);
514
515#ifdef G4DEBUG_FIELD
516 // Printing Brent and Linear Approximation
517 //
518 G4cout << "G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
519 << test_step << " EndPoint = " << EndPoint << G4endl;
520
521 // Test Track
522 //
523 G4FieldTrack TestTrack( CurveA_PointVelocity);
524 TestTrack = ApproxCurvePointV( CurveA_PointVelocity,
525 CurveB_PointVelocity,
526 CurrentE_Point, eps_step );
527 G4cout.precision(14);
528 G4cout << "G4ChordFinder::BrentApprox = " << EndPoint << G4endl;
529 G4cout << "G4ChordFinder::LinearApprox= " << TestTrack << G4endl;
530#endif
531 }
532 return EndPoint;
533}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
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 &currentEPoint, G4double epsStep)
G4double GetCurveLength() const

Referenced by G4BrentLocator::EstimateIntersectionPoint().

◆ ApproxCurvePointV()

G4FieldTrack G4ChordFinder::ApproxCurvePointV ( const G4FieldTrack & curveAPointVelocity,
const G4FieldTrack & curveBPointVelocity,
const G4ThreeVector & currentEPoint,
G4double epsStep )

If r=|AE|/|AB|, and s=true path lenght (AB) returns the point that is r*s along the curve.

Definition at line 538 of file G4ChordFinder.cc.

543{
544 // If r=|AE|/|AB|, and s=true path lenght (AB)
545 // return the point that is r*s along the curve!
546
547 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
548
549 G4ThreeVector CurveA_Point= CurveA_PointVelocity.GetPosition();
550 G4ThreeVector CurveB_Point= CurveB_PointVelocity.GetPosition();
551
552 G4ThreeVector ChordAB_Vector= CurveB_Point - CurveA_Point;
553 G4ThreeVector ChordAE_Vector= CurrentE_Point - CurveA_Point;
554
555 G4double ABdist= ChordAB_Vector.mag();
556 G4double curve_length; // A curve length of AB
557 G4double AE_fraction;
558
559 curve_length= CurveB_PointVelocity.GetCurveLength()
560 - CurveA_PointVelocity.GetCurveLength();
561
562 G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
563 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
564 {
565#ifdef G4DEBUG_FIELD
566 G4cerr << " Warning in G4ChordFinder::ApproxCurvePoint: "
567 << G4endl
568 << " The two points are further apart than the curve length "
569 << G4endl
570 << " Dist = " << ABdist
571 << " curve length = " << curve_length
572 << " relativeDiff = " << (curve_length-ABdist)/ABdist
573 << G4endl;
574 if( curve_length < ABdist * (1. - 10*eps_step) )
575 {
576 std::ostringstream message;
577 message << "Unphysical curve length." << G4endl
578 << "The size of the above difference exceeds allowed limits."
579 << G4endl
580 << "Aborting.";
581 G4Exception("G4ChordFinder::ApproxCurvePointV()", "GeomField0003",
582 FatalException, message);
583 }
584#endif
585 // Take default corrective action: adjust the maximum curve length.
586 // NOTE: this case only happens for relatively straight paths.
587 // curve_length = ABdist;
588 }
589
590 G4double new_st_length;
591
592 if ( ABdist > 0.0 )
593 {
594 AE_fraction = ChordAE_Vector.mag() / ABdist;
595 }
596 else
597 {
598 AE_fraction = 0.5; // Guess .. ?;
599#ifdef G4DEBUG_FIELD
600 G4cout << "Warning in G4ChordFinder::ApproxCurvePointV():"
601 << " A and B are the same point!" << G4endl
602 << " Chord AB length = " << ChordAE_Vector.mag() << G4endl
603 << G4endl;
604#endif
605 }
606
607 if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) )
608 {
609#ifdef G4DEBUG_FIELD
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
614 << " Chord AB length = " << ABdist << G4endl << G4endl;
615 G4cerr << " OK if this condition occurs after a recalculation of 'B'"
616 << G4endl << " Otherwise it is an error. " << G4endl ;
617#endif
618 // This course can now result if B has been re-evaluated,
619 // without E being recomputed (1 July 99).
620 // In this case this is not a "real error" - but it is undesired
621 // and we cope with it by a default corrective action ...
622 //
623 AE_fraction = 0.5; // Default value
624 }
625
626 new_st_length = AE_fraction * curve_length;
627
628 if ( AE_fraction > 0.0 )
629 {
630 fIntgrDriver->AccurateAdvance(Current_PointVelocity,
631 new_st_length, eps_step );
632 //
633 // In this case it does not matter if it cannot advance the full distance
634 }
635
636 // If there was a memory of the step_length actually required at the start
637 // of the integration Step, this could be re-used ...
638
639 G4cout.precision(14);
640
641 return Current_PointVelocity;
642}
G4GLOB_DLL std::ostream G4cerr
double mag() const

Referenced by ApproxCurvePointS(), G4BrentLocator::EstimateIntersectionPoint(), G4MultiLevelLocator::EstimateIntersectionPoint(), and G4SimpleLocator::EstimateIntersectionPoint().

◆ GetDeltaChord()

G4double G4ChordFinder::GetDeltaChord ( ) const
inline

Accessors and modifiers.

Referenced by G4PropagatorInField::ComputeStep().

◆ GetIntegrationDriver()

◆ InvParabolic()

G4double G4ChordFinder::InvParabolic ( const G4double xa,
const G4double ya,
const G4double xb,
const G4double yb,
const G4double xc,
const G4double yc )
inline

Calculates the inverse parabolic through the three points (x,y) and returns the value x that, for the inverse parabolic, corresponds to y=0.

Referenced by ApproxCurvePointS().

◆ OnComputeStep()

void G4ChordFinder::OnComputeStep ( const G4FieldTrack * track)
inline

Dispatch interface method for computing step.

Referenced by G4PropagatorInField::ComputeStep().

◆ operator=()

G4ChordFinder & G4ChordFinder::operator= ( const G4ChordFinder & )
delete

◆ ResetStepEstimate()

void G4ChordFinder::ResetStepEstimate ( )
inline

Clears the internal state (last step estimate).

Referenced by G4FieldManagerStore::ClearAllChordFindersState().

◆ SetDeltaChord()

void G4ChordFinder::SetDeltaChord ( G4double newval)
inline

◆ SetIntegrationDriver()

void G4ChordFinder::SetIntegrationDriver ( G4VIntegrationDriver * IntegrationDriver)
inline

◆ SetVerbose()

G4int G4ChordFinder::SetVerbose ( G4int newvalue = 1)
inline

Sets the verbosity.

Returns
The old verbosity value.

◆ SetVerboseConstruction()

void G4ChordFinder::SetVerboseConstruction ( G4bool v = true)
static

Sets verbosity for constructor.

Definition at line 646 of file G4ChordFinder.cc.

647{
648 gVerboseCtor = v;
649}

◆ operator<<

std::ostream & operator<< ( std::ostream & os,
const G4ChordFinder & cf )
friend

Writes out to stream the parameters/state of the driver.

Definition at line 653 of file G4ChordFinder.cc.

654{
655 // Dumping the state of G4ChordFinder
656 os << "State of G4ChordFinder : " << std::endl;
657 os << " delta_chord = " << cf.fDeltaChord;
658 os << " Default d_c = " << cf.fDefaultDeltaChord;
659
660 os << " stats-verbose = " << cf.fStatsVerbose;
661
662 return os;
663}

The documentation for this class was generated from the following files: