Geant4 11.2.2
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: J.Apostolakis - Design and implementation - 25.02.1997
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 "G4QSSDriverCreator.hh"
66
68
69#include <cassert>
70#include <memory>
71
73// ..........................................................................
74
76 : fDefaultDeltaChord(0.25 * mm), fIntgrDriver(pIntegrationDriver)
77{
78 // Simple constructor -- it does not create equation
79 if( gVerboseCtor )
80 {
81 G4cout << "G4ChordFinder: Simple constructor -- it uses pre-existing driver." << G4endl;
82 }
83
84 fDeltaChord = fDefaultDeltaChord; // Parameters
85}
86
87// ..........................................................................
88
90 G4double stepMinimum,
91 G4MagIntegratorStepper* pItsStepper,
92 G4int stepperDriverId )
93 : fDefaultDeltaChord(0.25 * mm)
94{
95 // Construct the Chord Finder
96 // by creating in inverse order the Driver, the Stepper and EqRhs ...
97 constexpr G4int nVar6 = 6; // Components integrated in Usual Equation of motion
98
99 fDeltaChord = fDefaultDeltaChord; // Parameters
100
101 G4cout << " G4ChordFinder: stepperDriverId: " << stepperDriverId << G4endl;
102
103 G4bool useFSALstepper = (stepperDriverId == kFSALStepperType); // Was 1
104 G4bool useTemplatedStepper= (stepperDriverId == kTemplatedStepperType); // Was 2
105 G4bool useRegularStepper = (stepperDriverId == kRegularStepperType); // Was 3
106 G4bool useBfieldDriver = (stepperDriverId == kBfieldDriverType); // Was 4
107 G4bool useG4QSSDriver = (stepperDriverId == kQss2DriverType) || (stepperDriverId == kQss3DriverType);
108
109 if( stepperDriverId == kQss3DriverType)
110 {
111 stepperDriverId = kQss2DriverType;
112 G4cout << " G4ChordFinder: QSS 3 is currently replaced by QSS 2 driver." << G4endl;
113 }
114
115 using EquationType = G4Mag_UsualEqRhs;
116
117 using TemplatedStepperType =
118 G4TDormandPrince45<EquationType,nVar6>; // 5th order embedded method. High efficiency.
119 const char* TemplatedStepperName =
120 "G4TDormandPrince745 (templated Dormand-Prince45, aka DoPri5): 5th/4th Order 7-stage embedded";
121
122 using RegularStepperType =
123 G4DormandPrince745; // 5th order embedded method. High efficiency.
124 // G4ClassicalRK4; // The old default
125 // G4CashKarpRKF45; // First embedded method in G4
126 // G4BogackiShampine45; // High efficiency 5th order embedded method
127 // G4NystromRK4; // Nystrom stepper 4th order
128 // G4RK547FEq1; // or 2 or 3
129 const char* RegularStepperName =
130 "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded";
131 // "BogackiShampine 45 (Embedded 5th/4th Order, 7-stage)";
132 // "Nystrom stepper 4th order";
133
134 using NewFsalStepperType = G4DormandPrince745; // Now works -- 2020.10.08
135 // Was G4RK547FEq1; // or 2 or 3
136 const char* NewFSALStepperName =
137 "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
138
139#ifdef G4DEBUG_FIELD
140 static G4bool verboseDebug = true;
141 if( verboseDebug )
142 {
143 G4cout << "G4ChordFinder 2nd Constructor called. " << G4endl;
144 G4cout << " Arguments: " << G4endl
145 << " - min step = " << stepMinimum << G4endl
146 << " - stepper ptr provided : "
147 << ( pItsStepper==nullptr ? " no " : " yes " ) << G4endl;
148 if( pItsStepper==nullptr )
149 G4cout << " - stepper/driver Id = " << stepperDriverId << " i.e. "
150 << " useFSAL = " << useFSALstepper
151 << " , useTemplated = " << useTemplatedStepper
152 << " , useRegular = " << useRegularStepper
153 << " , useFSAL = " << useFSALstepper
154 << G4endl;
155 }
156#endif
157
158 // useHigherStepper = forceHigherEffiencyStepper || useHigherStepper;
159
160 auto pEquation = new G4Mag_UsualEqRhs(theMagField);
161 fEquation = pEquation;
162
163 // G4MagIntegratorStepper* regularStepper = nullptr;
164 // G4VFSALIntegrationStepper* fsalStepper = nullptr; // for FSAL steppers only
165 // G4MagIntegratorStepper* oldFSALStepper = nullptr;
166
167 G4bool errorInStepperCreation = false;
168
169 std::ostringstream message; // In case of failure, load with description !
170
171 if( pItsStepper != nullptr )
172 {
173 if( gVerboseCtor )
174 {
175 G4cout << " G4ChordFinder: Creating G4IntegrationDriver<G4MagIntegratorStepper> with "
176 << " stepMinimum = " << stepMinimum
177 << " numVar= " << pItsStepper->GetNumberOfVariables() << G4endl;
178 }
179
180 // Stepper type is not known - so must use base class G4MagIntegratorStepper
181 if(pItsStepper->isQSS())
182 {
183 // fIntgrDriver = pItsStepper->build_driver(stepMinimum, true);
184 G4Exception("G4ChordFinder::G4ChordFinder()",
185 "GeomField1001", FatalException,
186 "Cannot provide QSS stepper in constructor. User c-tor with Driver instead.");
187 }
188 else
189 {
190 fIntgrDriver = new G4IntegrationDriver<G4MagIntegratorStepper>( stepMinimum,
191 pItsStepper, pItsStepper->GetNumberOfVariables() );
192 // Stepper type is not known - so must use base class G4MagIntegratorStepper
193 // Non-interpolating driver used by default.
194 // WAS: fIntgrDriver = pItsStepper->build_driver(stepMinimum); // QSS introduction -- axed
195 }
196 // -- Older:
197 // G4cout << " G4ChordFinder: Creating G4MagInt_Driver with " ...
198 // Type is not known - so must use old class
199 // fIntgrDriver = new G4MagInt_Driver( stepMinimum, pItsStepper,
200 // pItsStepper->GetNumberOfVariables());
201 }
202 else if ( useTemplatedStepper )
203 {
204 if( gVerboseCtor )
205 {
206 G4cout << " G4ChordFinder: Creating Templated Stepper of type> "
207 << TemplatedStepperName << G4endl;
208 }
209 // RegularStepperType* regularStepper = nullptr; // To check the exception
210 auto templatedStepper = new TemplatedStepperType(pEquation);
211 // *** ******************
212 //
213 // Alternative - for G4NystromRK4:
214 // = new G4NystromRK4(pEquation, 0.1*mm );
215 fRegularStepperOwned = templatedStepper;
216 if( templatedStepper == nullptr )
217 {
218 message << "Templated Stepper instantiation FAILED." << G4endl;
219 message << "G4ChordFinder: Attempted to instantiate "
220 << TemplatedStepperName << " type stepper " << G4endl;
221 errorInStepperCreation = true;
222 }
223 else
224 {
226 stepMinimum, templatedStepper, nVar6 );
227 if( gVerboseCtor )
228 {
229 G4cout << " G4ChordFinder: Using G4IntegrationDriver. " << G4endl;
230 }
231 }
232
233 }
234 else if ( useRegularStepper ) // Plain stepper -- not double ...
235 {
236 auto regularStepper = new RegularStepperType(pEquation);
237 // *** ******************
238 fRegularStepperOwned = regularStepper;
239
240 if( gVerboseCtor )
241 {
242 G4cout << " G4ChordFinder: Creating Driver for regular stepper.";
243 }
244
245 if( regularStepper == nullptr )
246 {
247 message << "Regular Stepper instantiation FAILED." << G4endl;
248 message << "G4ChordFinder: Attempted to instantiate "
249 << RegularStepperName << " type stepper " << G4endl;
250 errorInStepperCreation = true;
251 }
252 else
253 {
254 auto dp5= dynamic_cast<G4DormandPrince745*>(regularStepper);
255 if( dp5 != nullptr )
256 {
258 stepMinimum, dp5, nVar6 );
259 if( gVerboseCtor )
260 {
261 G4cout << " Using InterpolationDriver<DoPri5> " << G4endl;
262 }
263 }
264 else
265 {
267 stepMinimum, regularStepper, nVar6 );
268 if( gVerboseCtor )
269 {
270 G4cout << " Using IntegrationDriver<DoPri5> " << G4endl;
271 }
272 }
273 }
274 }
275 else if ( useBfieldDriver )
276 {
277 auto regularStepper = new G4DormandPrince745(pEquation);
278 // *** ******************
279 //
280 fRegularStepperOwned = regularStepper;
281
282 {
283 using SmallStepDriver = G4InterpolationDriver<G4DormandPrince745>;
284 using LargeStepDriver = G4IntegrationDriver<G4HelixHeum>;
285
286 fLongStepper = std::make_unique<G4HelixHeum>(pEquation);
287
288 fIntgrDriver = new G4BFieldIntegrationDriver(
289 std::make_unique<SmallStepDriver>(stepMinimum,
290 regularStepper, regularStepper->GetNumberOfVariables()),
291 std::make_unique<LargeStepDriver>(stepMinimum,
292 fLongStepper.get(), regularStepper->GetNumberOfVariables()) );
293
294 if( fIntgrDriver == nullptr)
295 {
296 message << "Using G4BFieldIntegrationDriver with "
297 << RegularStepperName << " type stepper " << G4endl;
298 message << "Driver instantiation FAILED." << G4endl;
299 G4Exception("G4ChordFinder::G4ChordFinder()",
300 "GeomField1001", JustWarning, message);
301 }
302 }
303 }
304 else if( useG4QSSDriver )
305 {
306 if( stepperDriverId == kQss2DriverType )
307 {
308 auto qssStepper2 = G4QSSDriverCreator::CreateQss2Stepper(pEquation);
309 if( gVerboseCtor )
310 {
311 G4cout << "-- Created QSS-2 stepper" << G4endl;
312 }
313 fIntgrDriver = G4QSSDriverCreator::CreateDriver(qssStepper2);
314 }
315 else
316 {
317 auto qssStepper3 = G4QSSDriverCreator::CreateQss3Stepper(pEquation);
318 if( gVerboseCtor )
319 {
320 G4cout << "-- Created QSS-3 stepper" << G4endl;
321 }
322 fIntgrDriver = G4QSSDriverCreator::CreateDriver(qssStepper3);
323 }
324 if( gVerboseCtor )
325 {
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 fCachedField;
421 delete fIntgrDriver;
422}
423
424// ...........................................................................
425
427G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
428 const G4FieldTrack& CurveB_PointVelocity,
429 const G4FieldTrack& ApproxCurveV,
430 const G4ThreeVector& CurrentE_Point,
431 const G4ThreeVector& CurrentF_Point,
432 const G4ThreeVector& PointG,
433 G4bool first, G4double eps_step)
434{
435 // ApproxCurvePointS is 2nd implementation of ApproxCurvePoint.
436 // Use Brent Algorithm (or InvParabolic) when possible.
437 // Given a starting curve point A (CurveA_PointVelocity), curve point B
438 // (CurveB_PointVelocity), a point E which is (generally) not on the curve
439 // and a point F which is on the curve (first approximation), find new
440 // point S on the curve closer to point E.
441 // While advancing towards S utilise 'eps_step' as a measure of the
442 // relative accuracy of each Step.
443
444 G4FieldTrack EndPoint(CurveA_PointVelocity);
445 if(!first) { EndPoint = ApproxCurveV; }
446
447 G4ThreeVector Point_A,Point_B;
448 Point_A=CurveA_PointVelocity.GetPosition();
449 Point_B=CurveB_PointVelocity.GetPosition();
450
451 G4double xa,xb,xc,ya,yb,yc;
452
453 // InverseParabolic. AF Intersects (First Part of Curve)
454
455 if(first)
456 {
457 xa=0.;
458 ya=(PointG-Point_A).mag();
459 xb=(Point_A-CurrentF_Point).mag();
460 yb=-(PointG-CurrentF_Point).mag();
461 xc=(Point_A-Point_B).mag();
462 yc=-(CurrentE_Point-Point_B).mag();
463 }
464 else
465 {
466 xa=0.;
467 ya=(Point_A-CurrentE_Point).mag();
468 xb=(Point_A-CurrentF_Point).mag();
469 yb=(PointG-CurrentF_Point).mag();
470 xc=(Point_A-Point_B).mag();
471 yc=-(Point_B-PointG).mag();
472 if(xb==0.)
473 {
474 EndPoint = ApproxCurvePointV(CurveA_PointVelocity, CurveB_PointVelocity,
475 CurrentE_Point, eps_step);
476 return EndPoint;
477 }
478 }
479
480 const G4double tolerance = 1.e-12;
481 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
482 {
483 ; // What to do for the moment: return the same point as at start
484 // then PropagatorInField will take care
485 }
486 else
487 {
488 G4double test_step = InvParabolic(xa,ya,xb,yb,xc,yc);
489 G4double curve;
490 if(first)
491 {
492 curve=std::abs(EndPoint.GetCurveLength()
493 -ApproxCurveV.GetCurveLength());
494 }
495 else
496 {
497 test_step = test_step - xb;
498 curve=std::abs(EndPoint.GetCurveLength()
499 -CurveB_PointVelocity.GetCurveLength());
500 xb = (CurrentF_Point-Point_B).mag();
501 }
502
503 if(test_step<=0) { test_step=0.1*xb; }
504 if(test_step>=xb) { test_step=0.5*xb; }
505 if(test_step>=curve){ test_step=0.5*curve; }
506
507 if(curve*(1.+eps_step)<xb) // Similar to ReEstimate Step from
508 { // G4VIntersectionLocator
509 test_step=0.5*curve;
510 }
511
512 fIntgrDriver->AccurateAdvance(EndPoint,test_step, eps_step);
513
514#ifdef G4DEBUG_FIELD
515 // Printing Brent and Linear Approximation
516 //
517 G4cout << "G4ChordFinder::ApproxCurvePointS() - test-step ShF = "
518 << test_step << " EndPoint = " << EndPoint << G4endl;
519
520 // Test Track
521 //
522 G4FieldTrack TestTrack( CurveA_PointVelocity);
523 TestTrack = ApproxCurvePointV( CurveA_PointVelocity,
524 CurveB_PointVelocity,
525 CurrentE_Point, eps_step );
526 G4cout.precision(14);
527 G4cout << "G4ChordFinder::BrentApprox = " << EndPoint << G4endl;
528 G4cout << "G4ChordFinder::LinearApprox= " << TestTrack << G4endl;
529#endif
530 }
531 return EndPoint;
532}
533
534
535// ...........................................................................
536
538ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
539 const G4FieldTrack& CurveB_PointVelocity,
540 const G4ThreeVector& CurrentE_Point,
541 G4double eps_step)
542{
543 // If r=|AE|/|AB|, and s=true path lenght (AB)
544 // return the point that is r*s along the curve!
545
546 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity;
547
548 G4ThreeVector CurveA_Point= CurveA_PointVelocity.GetPosition();
549 G4ThreeVector CurveB_Point= CurveB_PointVelocity.GetPosition();
550
551 G4ThreeVector ChordAB_Vector= CurveB_Point - CurveA_Point;
552 G4ThreeVector ChordAE_Vector= CurrentE_Point - CurveA_Point;
553
554 G4double ABdist= ChordAB_Vector.mag();
555 G4double curve_length; // A curve length of AB
556 G4double AE_fraction;
557
558 curve_length= CurveB_PointVelocity.GetCurveLength()
559 - CurveA_PointVelocity.GetCurveLength();
560
561 G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
562 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
563 {
564#ifdef G4DEBUG_FIELD
565 G4cerr << " Warning in G4ChordFinder::ApproxCurvePoint: "
566 << G4endl
567 << " The two points are further apart than the curve length "
568 << G4endl
569 << " Dist = " << ABdist
570 << " curve length = " << curve_length
571 << " relativeDiff = " << (curve_length-ABdist)/ABdist
572 << G4endl;
573 if( curve_length < ABdist * (1. - 10*eps_step) )
574 {
575 std::ostringstream message;
576 message << "Unphysical curve length." << G4endl
577 << "The size of the above difference exceeds allowed limits."
578 << G4endl
579 << "Aborting.";
580 G4Exception("G4ChordFinder::ApproxCurvePointV()", "GeomField0003",
581 FatalException, message);
582 }
583#endif
584 // Take default corrective action: adjust the maximum curve length.
585 // NOTE: this case only happens for relatively straight paths.
586 // curve_length = ABdist;
587 }
588
589 G4double new_st_length;
590
591 if ( ABdist > 0.0 )
592 {
593 AE_fraction = ChordAE_Vector.mag() / ABdist;
594 }
595 else
596 {
597 AE_fraction = 0.5; // Guess .. ?;
598#ifdef G4DEBUG_FIELD
599 G4cout << "Warning in G4ChordFinder::ApproxCurvePointV():"
600 << " A and B are the same point!" << G4endl
601 << " Chord AB length = " << ChordAE_Vector.mag() << G4endl
602 << G4endl;
603#endif
604 }
605
606 if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) )
607 {
608#ifdef G4DEBUG_FIELD
609 G4cerr << " G4ChordFinder::ApproxCurvePointV() - Warning:"
610 << " Anomalous condition:AE > AB or AE/AB <= 0 " << G4endl
611 << " AE_fraction = " << AE_fraction << G4endl
612 << " Chord AE length = " << ChordAE_Vector.mag() << G4endl
613 << " Chord AB length = " << ABdist << G4endl << G4endl;
614 G4cerr << " OK if this condition occurs after a recalculation of 'B'"
615 << G4endl << " Otherwise it is an error. " << G4endl ;
616#endif
617 // This course can now result if B has been re-evaluated,
618 // without E being recomputed (1 July 99).
619 // In this case this is not a "real error" - but it is undesired
620 // and we cope with it by a default corrective action ...
621 //
622 AE_fraction = 0.5; // Default value
623 }
624
625 new_st_length = AE_fraction * curve_length;
626
627 if ( AE_fraction > 0.0 )
628 {
629 fIntgrDriver->AccurateAdvance(Current_PointVelocity,
630 new_st_length, eps_step );
631 //
632 // In this case it does not matter if it cannot advance the full distance
633 }
634
635 // If there was a memory of the step_length actually required at the start
636 // of the integration Step, this could be re-used ...
637
638 G4cout.precision(14);
639
640 return Current_PointVelocity;
641}
642
643// ...........................................................................
644
645std::ostream& operator<<( std::ostream& os, const G4ChordFinder& cf)
646{
647 // Dumping the state of G4ChordFinder
648 os << "State of G4ChordFinder : " << std::endl;
649 os << " delta_chord = " << cf.fDeltaChord;
650 os << " Default d_c = " << cf.fDefaultDeltaChord;
651
652 os << " stats-verbose = " << cf.fStatsVerbose;
653
654 return os;
655}
std::ostream & operator<<(std::ostream &os, const G4ChordFinder &cf)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
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
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)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector &currentEPoint, const G4ThreeVector &currentFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
virtual ~G4ChordFinder()
static G4bool gVerboseCtor
G4ChordFinder(G4VIntegrationDriver *pIntegrationDriver)
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
G4int GetNumberOfVariables() const
static G4QSStepper< G4QSS3 > * CreateQss3Stepper(G4Mag_EqRhs *Equation)
static G4VIntegrationDriver * CreateDriver(G4MagIntegratorStepper *pStepper, G4double)
static G4QSStepper< G4QSS2 > * CreateQss2Stepper(G4Mag_EqRhs *Equation)
virtual G4bool AccurateAdvance(G4FieldTrack &track, G4double hstep, G4double eps, G4double hinitial=0)=0