Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ChordFinder.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4ChordFinder implementation
27//
28// Author: John Apostolakis (CERN), 25.02.1997 - Design and implementation
29// -------------------------------------------------------------------
30
31#include <iomanip>
32
33#include "G4ChordFinder.hh"
34#include "G4SystemOfUnits.hh"
35#include "G4MagneticField.hh"
36#include "G4Mag_UsualEqRhs.hh"
38// #include "G4ClassicalRK4.hh"
39// #include "G4CashKarpRKF45.hh"
40// #include "G4NystromRK4.hh"
41// #include "G4BogackiShampine23.hh"
42// #include "G4BogackiShampine45.hh"
43
44#include "G4DormandPrince745.hh"
45
46// New templated stepper(s) -- avoid virtual calls to equation rhs
47#include "G4TDormandPrince45.hh"
48
49// FSAL type driver / steppers -----
52#include "G4RK547FEq1.hh"
53// #include "G4RK547FEq2.hh"
54// #include "G4RK547FEq3.hh"
55// #include "G4FSALBogackiShampine45.hh"
56// #include "G4FSALDormandPrince745.hh"
57
58// Templated type drivers -----
61
62#include "G4HelixHeum.hh"
64
65#include "G4QSStepper.hh"
66#include "G4QSSDriver.hh"
67#include "G4AutoDelete.hh"
68
70
71#include <cassert>
72#include <memory>
73
74G4bool G4ChordFinder::gVerboseCtor = false;
75
76// ..........................................................................
77
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}
90
91// ..........................................................................
92
94 G4double stepMinimum,
95 G4MagIntegratorStepper* pItsStepper,
96 G4int stepperDriverId )
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 {
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 {
263 stepMinimum, dp5, nVar6 );
264 if( gVerboseCtor )
265 {
266 G4cout << " Using InterpolationDriver<DoPri5> " << G4endl;
267 }
268 }
269 else
270 {
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}
412
413// ......................................................................
414
416{
417 delete fEquation;
418 delete fRegularStepperOwned;
419 delete fNewFSALStepperOwned;
420 delete fQssStepperOwned;
421 delete fCachedField;
422 delete fIntgrDriver;
423}
424
425// ...........................................................................
426
428G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
429 const G4FieldTrack& CurveB_PointVelocity,
430 const G4FieldTrack& ApproxCurveV,
431 const G4ThreeVector& CurrentE_Point,
432 const G4ThreeVector& CurrentF_Point,
433 const G4ThreeVector& PointG,
434 G4bool first, G4double eps_step)
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}
534
535
536// ...........................................................................
537
539ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
540 const G4FieldTrack& CurveB_PointVelocity,
541 const G4ThreeVector& CurrentE_Point,
542 G4double eps_step)
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}
643
644// ...........................................................................
645
647{
648 gVerboseCtor = v;
649}
650
651// ...........................................................................
652
653std::ostream& operator<<( std::ostream& os, const G4ChordFinder& cf)
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}
std::ostream & operator<<(std::ostream &os, const G4ChordFinder &cf)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double mag() const
G4BFieldIntegrationDriver is specialised integration driver for pure magnetic field.
G4double InvParabolic(const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc)
static void SetVerboseConstruction(G4bool v=true)
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector &currentEPoint, G4double epsStep)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector &currentEPoint, const G4ThreeVector &currentFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
G4ChordFinder(G4VIntegrationDriver *pIntegrationDriver)
G4DormandPrince745 implements the 5th order embedded Runge-Kutta method, non-FSAL definition of the s...
G4FSALIntegrationDriver is a templated driver class which controls the integration error of a Runge-K...
G4FieldTrack defines a data structure bringing together a magnetic track's state (position,...
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
G4IntegrationDriver is a templated driver class which controls the integration error of a Runge-Kutta...
G4InterpolationDriver is a templated driver class which uses Runge-Kutta stepper with interpolation p...
G4MagIntegratorStepper is an abstract base class for integrator of particle's equation of motion,...
G4int GetNumberOfVariables() const
G4bool isQSS() const
G4Mag_UsualEqRhs defines the standard right-hand side for equation of motion.
G4QSSDriver is a templated driver class defining the QSS (Quantum State Simulation) Interpolator Driv...
G4bool SetQssOrder(G4int order)
static G4QSSMessenger * instance()
G4QSStepper is an integrator of particle's equation of motion based on the QSS implementation.
G4TDormandPrince45 is a templated version of G4DormandPrince745 5th order Runge-Kutta stepper.