Import Geant4 10.4.0 source tree
This commit is contained in:
@@ -68,12 +68,11 @@ class G4BogackiShampine23 : public G4MagIntegratorStepper{
|
||||
|
||||
G4double DistChord() const;
|
||||
G4int IntegratorOrder() const { return 2; }
|
||||
G4bool isFSAL() const{ return true; }
|
||||
G4double *getLastDydx();
|
||||
|
||||
G4BogackiShampine23(const G4BogackiShampine23&);
|
||||
G4BogackiShampine23& operator=(const G4BogackiShampine23&);
|
||||
G4double *getLastDydx();
|
||||
|
||||
private:
|
||||
G4BogackiShampine23(const G4BogackiShampine23&) = delete;
|
||||
G4BogackiShampine23& operator=(const G4BogackiShampine23&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ChordFinder.hh 69699 2013-05-13 08:50:30Z gcosmo $
|
||||
// $Id: G4ChordFinder.hh 107470 2017-11-15 07:14:28Z gcosmo $
|
||||
//
|
||||
//
|
||||
// Class G4ChordFinder
|
||||
@@ -42,8 +42,10 @@
|
||||
#ifndef G4CHORDFINDER_HH
|
||||
#define G4CHORDFINDER_HH
|
||||
|
||||
#include "G4MagIntegratorDriver.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
class G4VFSALIntegrationStepper;
|
||||
// #include "G4VFSALIntegratorSteper.hh"
|
||||
|
||||
class G4MagneticField;
|
||||
|
||||
@@ -51,11 +53,13 @@ class G4ChordFinder
|
||||
{
|
||||
public: // with description
|
||||
|
||||
G4ChordFinder( G4MagInt_Driver* pIntegrationDriver );
|
||||
explicit G4ChordFinder( G4VIntegrationDriver* pIntegrationDriver );
|
||||
|
||||
G4ChordFinder( G4MagneticField* itsMagField,
|
||||
G4double stepMinimum = 1.0e-2, // * mm
|
||||
G4MagIntegratorStepper* pItsStepper = 0 );
|
||||
G4MagIntegratorStepper* pItsStepper = nullptr,
|
||||
// G4bool useHigherEfficiencyStepper = true,
|
||||
G4bool useFSALstepper = false );
|
||||
// A constructor that creates defaults for all "children" classes.
|
||||
|
||||
virtual ~G4ChordFinder();
|
||||
@@ -63,7 +67,7 @@ class G4ChordFinder
|
||||
G4double AdvanceChordLimited( G4FieldTrack& yCurrent,
|
||||
G4double stepInitial,
|
||||
G4double epsStep_Relative,
|
||||
const G4ThreeVector latestSafetyOrigin,
|
||||
const G4ThreeVector& latestSafetyOrigin,
|
||||
G4double lasestSafetyRadius);
|
||||
// Uses ODE solver's driver to find the endpoint that satisfies
|
||||
// the chord criterion: that d_chord < delta_chord
|
||||
@@ -89,8 +93,8 @@ class G4ChordFinder
|
||||
inline G4double GetDeltaChord() const;
|
||||
inline void SetDeltaChord(G4double newval);
|
||||
|
||||
inline void SetIntegrationDriver(G4MagInt_Driver* IntegrationDriver);
|
||||
inline G4MagInt_Driver* GetIntegrationDriver();
|
||||
inline void SetIntegrationDriver(G4VIntegrationDriver* IntegrationDriver);
|
||||
inline G4VIntegrationDriver* GetIntegrationDriver();
|
||||
// Access and set Driver.
|
||||
|
||||
inline void ResetStepEstimate();
|
||||
@@ -180,10 +184,11 @@ class G4ChordFinder
|
||||
|
||||
// DEPENDENT Objects
|
||||
// ---------------------
|
||||
G4MagInt_Driver* fIntgrDriver;
|
||||
G4MagIntegratorStepper* fDriversStepper;
|
||||
G4bool fAllocatedStepper; // Bookkeeping of dependent object
|
||||
G4EquationOfMotion* fEquation;
|
||||
G4VIntegrationDriver* fIntgrDriver;
|
||||
G4MagIntegratorStepper* fRegularStepperOwned= nullptr;
|
||||
G4MagIntegratorStepper* fNewFSALStepperOwned= nullptr;
|
||||
// G4VFSALIntegrationStepper* fOldFSALStepperOwned= nullptr;
|
||||
G4EquationOfMotion* fEquation;
|
||||
|
||||
// STATE information
|
||||
// --------------------
|
||||
|
||||
@@ -24,20 +24,20 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ChordFinder.icc 69699 2013-05-13 08:50:30Z gcosmo $
|
||||
// $Id: G4ChordFinder.icc 107059 2017-11-01 14:58:16Z gcosmo $
|
||||
//
|
||||
// G4ChordFinder inline implementations
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
void G4ChordFinder::SetIntegrationDriver(G4MagInt_Driver* IntegrationDriver)
|
||||
void G4ChordFinder::SetIntegrationDriver(G4VIntegrationDriver* IntegrationDriver)
|
||||
{
|
||||
fIntgrDriver=IntegrationDriver;
|
||||
}
|
||||
|
||||
inline
|
||||
G4MagInt_Driver* G4ChordFinder::GetIntegrationDriver()
|
||||
G4VIntegrationDriver* G4ChordFinder::GetIntegrationDriver()
|
||||
{
|
||||
return fIntgrDriver;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4ChordFinderSaf.hh 66356 2012-12-18 09:02:32Z gcosmo $
|
||||
// $Id: G4ChordFinderSaf.hh 107059 2017-11-01 14:58:16Z gcosmo $
|
||||
//
|
||||
//
|
||||
// class G4ChordFinderRad
|
||||
@@ -43,7 +43,7 @@ class G4ChordFinderSaf : public G4ChordFinder
|
||||
{
|
||||
|
||||
public:
|
||||
G4ChordFinderSaf(G4MagInt_Driver* pIntegrationDriver);
|
||||
G4ChordFinderSaf(G4VIntegrationDriver* pIntegrationDriver);
|
||||
|
||||
G4ChordFinderSaf( G4MagneticField* theMagField,
|
||||
G4double stepMinimum,
|
||||
|
||||
@@ -29,18 +29,6 @@
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
//
|
||||
// First version: 26 June 2015
|
||||
//
|
||||
// This code is made available subject to the Geant4 license, a copy of
|
||||
// which is available at
|
||||
// http://geant4.org/license
|
||||
// G4DormandPrince745.cc
|
||||
// Geant4
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath on 26 June 2015
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DORMAND_PRINCE_RK56_H
|
||||
@@ -48,8 +36,8 @@
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
class G4DormandPrinceRK56 : public G4MagIntegratorStepper{
|
||||
|
||||
class G4DormandPrinceRK56 : public G4MagIntegratorStepper
|
||||
{
|
||||
|
||||
public:
|
||||
//constructor
|
||||
|
||||
@@ -23,7 +23,24 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DormandPrinceRK78.hh
|
||||
// Description of G4DormandPrinceRK78 class
|
||||
//
|
||||
// Implementation of Dormand-Prince 8(7)13M non-FSAL RK method
|
||||
// Author: Somnath Banerjee
|
||||
// Supported by Google as part of Google Summer of Code 2015.
|
||||
// Supervision / code review: John Apostolakis
|
||||
//
|
||||
// Implements a 13 stage embedded explicit Runge-Kutta method,
|
||||
// using a pair of 7th and 8th order formulae
|
||||
//
|
||||
// Paper proposing this RK scheme:
|
||||
// Title: "High order embedded Runge-Kutta formulae",
|
||||
// Authors: P.J. Prince, J.R. Dormand
|
||||
// Journal of Computational and Applied Mathematics, Volume 7, Issue 1, 1981,
|
||||
// Pages 67-75, ISSN 0377-0427,
|
||||
// Reference: DOI: 10.1016/0771-050X(81)90010-3
|
||||
// http://dx.doi.org/10.1016/0771-050X(81)90010-3.
|
||||
// (http://www.sciencedirect.com/science/article/pii/0771050X81900103)
|
||||
//
|
||||
// Created by Somnath on 30/06/15.
|
||||
|
||||
|
||||
@@ -28,14 +28,13 @@
|
||||
//
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
//
|
||||
// First version: 26 May 2015
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath on 26 May 2015
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Created by Somnath Banerjee on 26 May 2015
|
||||
// Fixes:
|
||||
// J. Apostolakis - June 2017: Coverity issues
|
||||
// J. Apostolakis - July 2017: Initialise bi coefficients only once.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4FSAL_Bogacki_Shampine_45_hh
|
||||
#define G4FSAL_Bogacki_Shampine_45_hh
|
||||
@@ -67,22 +66,29 @@ public:
|
||||
G4double DistChord() const;
|
||||
G4int IntegratorOrder() const { return 4; }
|
||||
|
||||
private :
|
||||
|
||||
G4FSALBogackiShampine45(const G4FSALBogackiShampine45&);
|
||||
G4FSALBogackiShampine45& operator=(const G4FSALBogackiShampine45&);
|
||||
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7, *ak8,
|
||||
*ak9, *ak10, *ak11,
|
||||
*yTemp, *yIn;
|
||||
private :
|
||||
|
||||
G4FSALBogackiShampine45(const G4FSALBogackiShampine45&) = delete;
|
||||
G4FSALBogackiShampine45& operator=(const G4FSALBogackiShampine45&) = delete;
|
||||
void PrepareConstants();
|
||||
|
||||
// Working arrays -- used during stepping
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7, *ak8, *ak9, *ak10, *ak11,
|
||||
*DyDx, *yTemp, *yIn;
|
||||
G4double *pseudoDydx_for_DistChord;
|
||||
|
||||
G4double fLastStepLength;
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
// for DistChord calculations
|
||||
|
||||
|
||||
G4double b[12]; // Working array for interpolation
|
||||
|
||||
G4FSALBogackiShampine45* fAuxStepper;
|
||||
|
||||
static bool fPreparedConstants;
|
||||
// Class constants
|
||||
static G4double bi[12][7];
|
||||
};
|
||||
|
||||
#endif /* defined( G4FSAL_Bogacki_Shampine_45_hh ) */
|
||||
|
||||
@@ -88,15 +88,15 @@ private :
|
||||
G4FSALDormandPrince745& operator=(const G4FSALDormandPrince745&);
|
||||
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7,
|
||||
*ak8, *ak9, //For additional stages in the interpolant
|
||||
*yTemp, *yIn;
|
||||
*ak8, *ak9, //For additional stages in the interpolant
|
||||
*yTemp, *yIn;
|
||||
|
||||
//Only for use with DistChord :-
|
||||
G4double *pseudoDydx_for_DistChord;
|
||||
|
||||
G4double fLastStepLength;
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
*fInitialDyDx, *fLastDyDx, *fMidVector, *fMidError;
|
||||
// for DistChord calculations
|
||||
|
||||
G4FSALDormandPrince745* fAuxStepper;
|
||||
|
||||
@@ -24,245 +24,168 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4FSALIntegrationDriver.hh 97387 2016-06-02 10:03:42Z gcosmo $
|
||||
// $Id: G4FSALIntegrationDriver.hh 107164 2017-11-03 12:11:45Z gcosmo $
|
||||
//
|
||||
//
|
||||
// class G4FSALIntegrationDriver
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Provides a driver that talks to the Integrator Stepper, and insures that
|
||||
// the error is within acceptable bounds.
|
||||
// Driver class which controls the integration error of a
|
||||
// Runge-Kutta stepper with a FSAL property
|
||||
|
||||
// History:
|
||||
// - Created. J.Apostolakis.
|
||||
// - Created. D.Sorokin
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#ifndef G4FSALIntegrationDriver_Def
|
||||
#define G4FSALIntegrationDriver_Def
|
||||
#ifndef G4FSALIntegrationDriver_HH
|
||||
#define G4FSALIntegrationDriver_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4VFSALIntegrationStepper.hh"
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
|
||||
class G4FSALIntegrationDriver
|
||||
{
|
||||
public: // with description
|
||||
template <class T>
|
||||
class G4FSALIntegrationDriver : public G4VIntegrationDriver {
|
||||
public:
|
||||
G4FSALIntegrationDriver(
|
||||
G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 1);
|
||||
|
||||
G4bool AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial=0.0); // Suggested 1st interval
|
||||
// Above drivers for integrator (Runge-Kutta) with stepsize control.
|
||||
// Integrates ODE starting values y_current
|
||||
// from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output ystart is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
virtual ~G4FSALIntegrationDriver() override;
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_val, // INOUT
|
||||
G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr ) ;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
G4FSALIntegrationDriver(const G4FSALIntegrationDriver &) = delete;
|
||||
const G4FSALIntegrationDriver& operator =(const G4FSALIntegrationDriver &) = delete;
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_posvel, // INOUT
|
||||
G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq ) ;
|
||||
// New QuickAdvance that also just tries one Step
|
||||
// (so also does not ensure accuracy)
|
||||
// but does return the errors in position and
|
||||
// momentum (normalised: Delta_Integration(p^2)/(p^2) )
|
||||
// Integrates ODE from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output track is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
virtual G4bool AccurateAdvance(
|
||||
G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0) override; // Suggested 1st interval
|
||||
|
||||
G4FSALIntegrationDriver( G4double hminimum,
|
||||
G4VFSALIntegrationStepper *pItsStepper,
|
||||
G4int numberOfComponents=6,
|
||||
G4int statisticsVerbosity=1);
|
||||
~G4FSALIntegrationDriver();
|
||||
// Constructor, destructor.
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
virtual G4bool QuickAdvance(
|
||||
G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
|
||||
inline G4double GetHmin() const;
|
||||
inline G4double Hmin() const; // Obsolete
|
||||
inline G4double GetSafety() const;
|
||||
inline G4double GetPshrnk() const;
|
||||
inline G4double GetPgrow() const;
|
||||
inline G4double GetErrcon() const;
|
||||
inline G4int GetNoTotalSteps() const; //Only for debug purposes
|
||||
inline void GetDerivatives( const G4FieldTrack &y_curr, // const, INput
|
||||
G4double dydx[] ); // OUTput
|
||||
// Accessors.
|
||||
virtual void GetDerivatives(
|
||||
const G4FieldTrack &track,
|
||||
G4double dydx[]) const override;
|
||||
|
||||
inline void RenewStepperAndAdjust(G4VFSALIntegrationStepper *pItsStepper);
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
virtual G4double ComputeNewStepSize(
|
||||
G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent) override; // current step size
|
||||
|
||||
inline void ReSetParameters(G4double new_safety= 0.9 );
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
// ii) calculates "errcon" according to the above values.
|
||||
virtual void SetVerboseLevel(G4int newLevel) override;
|
||||
virtual G4int GetVerboseLevel() const override;
|
||||
|
||||
inline void SetSafety(G4double valS);
|
||||
inline void SetPshrnk(G4double valPs);
|
||||
inline void SetPgrow (G4double valPg);
|
||||
inline void SetErrcon(G4double valEc);
|
||||
// When setting safety or pgrow, errcon will be set to a
|
||||
// compatible value.
|
||||
virtual G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
inline G4double ComputeAndSetErrcon();
|
||||
virtual const G4MagIntegratorStepper* GetStepper() const override;
|
||||
virtual G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
const T* GetStepperOfPreciseType() const; // Get ptr of precise type
|
||||
T* GetStepperOfPreciseType();
|
||||
|
||||
// Accessors.
|
||||
G4double GetMinimumStep() const;
|
||||
G4double GetSafety() const;
|
||||
G4double GetPshrnk() const;
|
||||
G4double GetPgrow() const;
|
||||
|
||||
inline const G4VFSALIntegrationStepper* GetStepper() const;
|
||||
inline G4VFSALIntegrationStepper* GetStepper();
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
void RenewStepperAndAdjust(T *pItsStepper);
|
||||
|
||||
void OneGoodStep( G4double ystart[], // Like old RKF45step()
|
||||
G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps, // memb variables ?
|
||||
G4double& hdid,
|
||||
G4double& hnext ) ;
|
||||
// This takes one Step that is as large as possible while
|
||||
// satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
void ReSetParameters(G4double safety = 0.9);
|
||||
|
||||
G4double ComputeNewStepSize( G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent); // current step size
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
|
||||
G4double ComputeNewStepSize_WithinLimits(
|
||||
G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent); // current step size
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Limit the next step's size within a range around the current one.
|
||||
void SetMinimumStep(G4double newval);
|
||||
void SetSafety(G4double valS);
|
||||
|
||||
inline G4int GetMaxNoSteps() const;
|
||||
inline void SetMaxNoSteps( G4int val);
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (ie a single call to AccurateAdvance).
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//The following has been introduced by [hackabot] for testing purposes only
|
||||
inline G4int GetTotalNoStepperCalls() const;
|
||||
//---------------------------------------------------------------------
|
||||
// This takes one Step that is as large as possible while
|
||||
// satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
void OneGoodStep(
|
||||
G4double ystart[],
|
||||
G4double dydx[],
|
||||
G4double& curveLength,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
|
||||
public: // without description
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (ie a single call to AccurateAdvance).
|
||||
G4int GetMaxNoSteps() const;
|
||||
void SetMaxNoSteps( G4int val);
|
||||
|
||||
inline void SetHmin(G4double newval);
|
||||
inline void SetVerboseLevel(G4int newLevel);
|
||||
inline G4double GetVerboseLevel() const;
|
||||
G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction(G4double val);
|
||||
|
||||
inline G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction( G4double val );
|
||||
|
||||
|
||||
|
||||
private:
|
||||
G4double ShrinkStepSize(G4double h, G4double error) const;
|
||||
G4double GrowStepSize(G4double h, G4double error) const;
|
||||
void UpdateErrorConstraints();
|
||||
|
||||
protected: // without description
|
||||
void WarnSmallStepSize( G4double hnext, G4double hstep,
|
||||
G4double h, G4double xDone,
|
||||
G4int noSteps);
|
||||
void WarnTooManyStep( G4double x1start, G4double x2end, G4double xCurrent);
|
||||
void WarnEndPointTooFar (G4double endPointDist,
|
||||
G4double hStepSize ,
|
||||
G4double epsilonRelative,
|
||||
G4int debugFlag);
|
||||
// Issue warnings for undesirable situations
|
||||
|
||||
void PrintStatus( const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
G4int subStepNo );
|
||||
void PrintStatus( const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
G4int subStepNo );
|
||||
void PrintStat_Aux( const G4FieldTrack& aFieldTrack,
|
||||
G4double requestStep,
|
||||
G4double actualStep,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVelocities );
|
||||
// Verbose output for debugging
|
||||
|
||||
void PrintStatisticsReport() ;
|
||||
// Report on the number of steps, maximum errors etc.
|
||||
|
||||
#ifdef QUICK_ADV_TWO
|
||||
G4bool QuickAdvance( G4double yarrin[], // In
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yarrout[], // Out
|
||||
G4double& dchord_step, // Out
|
||||
G4double& dyerr ); // in length
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
G4FSALIntegrationDriver(const G4FSALIntegrationDriver&);
|
||||
G4FSALIntegrationDriver& operator=(const G4FSALIntegrationDriver&);
|
||||
// Private copy constructor and assignment operator.
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// INVARIANTS
|
||||
void CheckStep(
|
||||
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid);
|
||||
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
G4double fMinimumStep;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
G4double fSmallestFraction; // Expected range 1e-12 to 5e-15;
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
|
||||
const G4int fNoIntegrationVariables; // Number of Variables in integration
|
||||
const G4int fMinNoVars; // Minimum number for FieldTrack
|
||||
const G4int fNoVars; // Full number of variable
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
// Expected range 1e-12 to 5e-15;
|
||||
G4double fSmallestFraction;
|
||||
|
||||
G4int fMaxNoSteps;
|
||||
static const G4int fMaxStepBase;
|
||||
|
||||
// The (default) maximum number of steps is Base
|
||||
// divided by the order of Stepper
|
||||
static constexpr G4int fMaxStepBase = 250;
|
||||
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
G4double safety;
|
||||
G4double pshrnk; // exponent for shrinking
|
||||
G4double pgrow; // exponent for growth
|
||||
G4double errcon;
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
|
||||
static const G4double max_stepping_increase;
|
||||
static const G4double max_stepping_decrease;
|
||||
// Maximum stepsize increase/decrease factors.
|
||||
// muximum error values for shrinking / growing (optimisation).
|
||||
G4double errorConstraintShrink;
|
||||
G4double errorConstraintGrow;
|
||||
|
||||
G4int fStatisticsVerboseLevel;
|
||||
// Maximum stepsize increase/decrease factors.
|
||||
static constexpr G4double max_stepping_increase = 5;
|
||||
static constexpr G4double max_stepping_decrease = 0.1;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// DEPENDENT Objects
|
||||
G4VFSALIntegrationStepper *pIntStepper;
|
||||
T* pIntStepper;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// STATE
|
||||
|
||||
G4int fNoTotalSteps, fNoBadSteps, fNoSmallSteps, fNoInitialSmallSteps;
|
||||
G4double fDyerr_max, fDyerr_mx2;
|
||||
G4double fDyerrPos_smTot, fDyerrPos_lgTot, fDyerrVel_lgTot;
|
||||
G4double fSumH_sm, fSumH_lg;
|
||||
// Step Statistics
|
||||
// Step Statistics
|
||||
unsigned long fNoTotalSteps, fNoBadSteps, fNoGoodSteps;
|
||||
|
||||
G4int fVerboseLevel; // Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
//For Test Purposes :-
|
||||
G4int TotalNoStepperCalls;
|
||||
|
||||
G4int fNoQuickAvanceCalls;
|
||||
};
|
||||
|
||||
#include "G4FSALIntegrationDriver.icc"
|
||||
|
||||
#endif /* G4FSALIntegrationDriver_Def */
|
||||
#endif
|
||||
|
||||
@@ -24,155 +24,437 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4FSALIntegrationDriver.icc 97387 2016-06-02 10:03:42Z gcosmo $
|
||||
// $Id: G4FSALIntegrationDriver.icc 107495 2017-11-16 13:51:06Z gcosmo $
|
||||
//
|
||||
//
|
||||
// class G4FSALIntegrationDriver
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Driver class which controls the integration error of a
|
||||
// Runge-Kutta stepper with a FSAL property
|
||||
|
||||
// History:
|
||||
// - Created. D.Sorokin
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetHmin() const
|
||||
#include "globals.hh"
|
||||
#include "G4GeometryTolerance.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4FieldUtils.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
template <class T>
|
||||
G4FSALIntegrationDriver<T>::G4FSALIntegrationDriver (
|
||||
G4double hminimum,
|
||||
T* pStepper,
|
||||
G4int numComponents,
|
||||
G4int statisticsVerbose)
|
||||
: fSmallestFraction(1e-12),
|
||||
fNoTotalSteps(0),
|
||||
fNoBadSteps(0),
|
||||
fNoGoodSteps(0),
|
||||
fVerboseLevel(statisticsVerbose),
|
||||
fNoQuickAvanceCalls(0)
|
||||
{
|
||||
return fMinimumStep;
|
||||
if (numComponents != pStepper->GetNumberOfVariables()) {
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components " << numComponents
|
||||
<< " != Stepper's number of components " << pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4FSALIntegrationDriver","001", FatalException, message);
|
||||
}
|
||||
RenewStepperAndAdjust(pStepper);
|
||||
fMinimumStep = hminimum;
|
||||
fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4FSALIntegrationDriver<T>::~G4FSALIntegrationDriver()
|
||||
{
|
||||
if( fVerboseLevel > 0 )
|
||||
G4cout << "G4FSALIntegration Driver Stats: "
|
||||
<< "#QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " #AccurateAdvance " << fNoTotalSteps << G4endl;
|
||||
}
|
||||
|
||||
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
|
||||
// values at y_current over hstep x2 with accuracy eps.
|
||||
// On output ystart is replaced by values at the end of the integration
|
||||
// interval. RightHandSide is the right-hand side of ODE system.
|
||||
// The source is similar to odeint routine from NRC p.721-722 .
|
||||
template <class T>
|
||||
G4bool G4FSALIntegrationDriver<T>::AccurateAdvance(
|
||||
G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial)
|
||||
{
|
||||
if (hstep < GetMinimumStep()) {
|
||||
G4double dchord_step = 0, dyerr = 0;
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
GetDerivatives(track, dydx);
|
||||
return QuickAdvance(track, dydx, hstep, dchord_step, dyerr);
|
||||
}
|
||||
|
||||
G4bool succeeded = false;
|
||||
|
||||
G4double hnext, hdid;
|
||||
|
||||
|
||||
G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
|
||||
|
||||
track.DumpToArray(y);
|
||||
|
||||
// hstep somtimes is too small. No need to add large curveLength.
|
||||
G4double curveLength = 0;
|
||||
G4double endCurveLength = hstep;
|
||||
|
||||
|
||||
G4double h = hstep;
|
||||
if (hinitial > perMillion * hstep && hinitial < hstep) {
|
||||
h = hinitial;
|
||||
}
|
||||
|
||||
pIntStepper->RightHandSide(y, dydx);
|
||||
|
||||
for (G4int iter = 0; iter < fMaxNoSteps; ++iter) {
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
G4double restCurveLength = endCurveLength - curveLength;
|
||||
if (restCurveLength < GetSmallestFraction() * hstep) {
|
||||
succeeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
h = std::min(hnext, restCurveLength);
|
||||
}
|
||||
|
||||
|
||||
if (succeeded) {
|
||||
track.LoadFromArray(y, pIntStepper->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + curveLength);
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// Step failed; compute the size of retrial Step.
|
||||
template <class T>
|
||||
G4double G4FSALIntegrationDriver<T>::ShrinkStepSize(G4double h, G4double error) const
|
||||
{
|
||||
if (error > errorConstraintShrink) {
|
||||
return max_stepping_decrease * h;
|
||||
}
|
||||
return GetSafety() * h * std::pow(error, GetPshrnk());
|
||||
}
|
||||
|
||||
// Compute size of next Step
|
||||
template<class T>
|
||||
G4double G4FSALIntegrationDriver<T>::GrowStepSize(G4double h, G4double error) const
|
||||
{
|
||||
if (error < errorConstraintGrow) {
|
||||
return max_stepping_increase * h;
|
||||
}
|
||||
return GetSafety() * h * std::pow(error, GetPgrow());
|
||||
}
|
||||
|
||||
// Driver for one Runge-Kutta Step with monitoring of local truncation error
|
||||
// to ensure accuracy and adjust stepsize. Input are dependent variable
|
||||
// array y[0,...,5] and its derivative dydx[0,...,5] at the
|
||||
// starting value of the independent variable x . Also input are stepsize
|
||||
// to be attempted htry, and the required accuracy eps. On output y and x
|
||||
// are replaced by their new values, hdid is the stepsize that was actually
|
||||
// accomplished, and hnext is the estimated next stepsize.
|
||||
// This is similar to the function rkqs from the book:
|
||||
// Numerical Recipes in C: The Art of Scientific Computing (NRC), Second
|
||||
// Edition, by William H. Press, Saul A. Teukolsky, William T.
|
||||
// Vetterling, and Brian P. Flannery (Cambridge University Press 1992),
|
||||
// 16.2 Adaptive StepSize Control for Runge-Kutta, p. 719
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::OneGoodStep(
|
||||
G4double y[],
|
||||
G4double dydx[],
|
||||
G4double& curveLength, // InOut
|
||||
G4double htry,
|
||||
G4double eps_rel_max,
|
||||
G4double& hdid, // Out
|
||||
G4double& hnext) // Out
|
||||
{
|
||||
G4double error = DBL_MAX;
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
dydxOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
// Set stepsize to the initial trial value
|
||||
G4double hstep = htry;
|
||||
|
||||
static G4ThreadLocal G4int tot_no_trials = 0;
|
||||
const G4int max_trials = 100;
|
||||
|
||||
for (G4int iter = 0; iter < max_trials; ++iter) {
|
||||
++tot_no_trials;
|
||||
|
||||
pIntStepper->Stepper(y, dydx, hstep, yOut, yError, dydxOut);
|
||||
error = field_utils::relativeError(y, yError, hstep, eps_rel_max);
|
||||
|
||||
// Step succeeded.
|
||||
if (error <= 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
hstep = ShrinkStepSize(hstep, error);
|
||||
}
|
||||
|
||||
hnext = GrowStepSize(hstep, error);
|
||||
curveLength += (hdid = hstep);
|
||||
|
||||
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k) {
|
||||
y[k] = yOut[k];
|
||||
dydx[k] = dydxOut[k];
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4bool G4FSALIntegrationDriver<T>::QuickAdvance(
|
||||
G4FieldTrack& fieldTrack,
|
||||
const G4double dydxIn[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr)
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
|
||||
if (hstep == 0) {
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
if (hstep < 0) {
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = " << hstep << "." << G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
dydxOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
fieldTrack.DumpToArray(yIn);
|
||||
|
||||
pIntStepper->Stepper(yIn, dydxIn, hstep, yOut, yError, dydxOut);
|
||||
dchord_step = pIntStepper->DistChord();
|
||||
|
||||
fieldTrack.LoadFromArray(yOut, pIntStepper->GetNumberOfVariables());
|
||||
fieldTrack.SetCurveLength(fieldTrack.GetCurveLength() + hstep);
|
||||
|
||||
dyerr = field_utils::relativeError(yOut, yError, hstep) * hstep;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4FSALIntegrationDriver<T>::ComputeNewStepSize(
|
||||
G4double errMaxNorm, // max error (normalised)
|
||||
G4double hstepCurrent) // current step size
|
||||
{
|
||||
if (errMaxNorm > 1) {
|
||||
return ShrinkStepSize(hstepCurrent, errMaxNorm);
|
||||
} else if(errMaxNorm >= 0) {
|
||||
return GrowStepSize(hstepCurrent, errMaxNorm);
|
||||
}
|
||||
|
||||
G4Exception("G4FSALIntegrationDriver::ConputeNewStepSize", "Field002",
|
||||
FatalException, "error is negative");
|
||||
|
||||
return max_stepping_increase * hstepCurrent;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
|
||||
{
|
||||
if( newFraction > 1.e-16 && newFraction < 1e-8 ) {
|
||||
fSmallestFraction = newFraction;
|
||||
} else {
|
||||
G4cerr << "Warning: SmallestFraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::GetDerivatives(
|
||||
const G4FieldTrack& track, G4double dydx[]) const
|
||||
{
|
||||
G4double y[G4FieldTrack::ncompSVEC];
|
||||
track.DumpToArray(y);
|
||||
pIntStepper->RightHandSide(y, dydx);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::CheckStep(
|
||||
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid)
|
||||
{
|
||||
++fNoTotalSteps;
|
||||
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + perMillion)) {
|
||||
++fNoBadSteps;
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand)){
|
||||
G4cout << "WARNING: endPointDist >= hdid!" << G4endl;
|
||||
}
|
||||
} else {
|
||||
++fNoGoodSteps;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::UpdateErrorConstraints()
|
||||
{
|
||||
errorConstraintShrink = std::pow(
|
||||
max_stepping_decrease / GetSafety(), 1. / GetPshrnk());
|
||||
|
||||
errorConstraintGrow = std::pow(
|
||||
max_stepping_increase / GetSafety(), 1. / GetPgrow());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4FSALIntegrationDriver<T>::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::Hmin() const
|
||||
template <class T>
|
||||
inline G4double G4FSALIntegrationDriver<T>::GetSafety() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
return safety;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetSafety() const
|
||||
template <class T>
|
||||
inline G4double G4FSALIntegrationDriver<T>::GetPshrnk() const
|
||||
{
|
||||
return safety;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetPshrnk() const
|
||||
{
|
||||
return pshrnk;
|
||||
return pshrnk;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetPgrow() const
|
||||
template <class T>
|
||||
G4double G4FSALIntegrationDriver<T>::GetPgrow() const
|
||||
{
|
||||
return pgrow;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetErrcon() const
|
||||
{
|
||||
return errcon;
|
||||
return pgrow;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::SetHmin(G4double newval)
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetMinimumStep(G4double minimumStepLength)
|
||||
{
|
||||
fMinimumStep = newval;
|
||||
fMinimumStep = minimumStepLength;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::ComputeAndSetErrcon()
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::ReSetParameters(G4double new_safety)
|
||||
{
|
||||
errcon = std::pow(max_stepping_increase/GetSafety(),1.0/GetPgrow());
|
||||
return errcon;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::ReSetParameters(G4double new_safety)
|
||||
{
|
||||
safety = new_safety;
|
||||
pshrnk = -1.0 / pIntStepper->IntegratorOrder();
|
||||
pgrow = -1.0 / (1.0 + pIntStepper->IntegratorOrder());
|
||||
ComputeAndSetErrcon();
|
||||
safety = new_safety;
|
||||
pshrnk = -1.0 / pIntStepper->IntegratorOrder();
|
||||
pgrow = -1.0 / (1.0 + pIntStepper->IntegratorOrder());
|
||||
UpdateErrorConstraints();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::SetSafety(G4double val)
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetSafety(G4double val)
|
||||
{
|
||||
safety=val;
|
||||
ComputeAndSetErrcon();
|
||||
safety = val;
|
||||
UpdateErrorConstraints();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::SetPgrow(G4double val)
|
||||
{
|
||||
pgrow=val;
|
||||
ComputeAndSetErrcon();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::SetErrcon(G4double val)
|
||||
{
|
||||
errcon=val;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::RenewStepperAndAdjust(G4VFSALIntegrationStepper *pItsStepper)
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::RenewStepperAndAdjust(T* stepper)
|
||||
{
|
||||
pIntStepper = pItsStepper;
|
||||
pIntStepper = stepper;
|
||||
ReSetParameters();
|
||||
}
|
||||
|
||||
inline
|
||||
const G4VFSALIntegrationStepper* G4FSALIntegrationDriver::GetStepper() const
|
||||
template <class T>
|
||||
const T* G4FSALIntegrationDriver<T>::GetStepperOfPreciseType() const
|
||||
{
|
||||
return pIntStepper;
|
||||
return pIntStepper;
|
||||
}
|
||||
|
||||
inline
|
||||
G4VFSALIntegrationStepper* G4FSALIntegrationDriver::GetStepper()
|
||||
template <class T>
|
||||
T* G4FSALIntegrationDriver<T>::GetStepperOfPreciseType()
|
||||
{
|
||||
return pIntStepper;
|
||||
return pIntStepper;
|
||||
}
|
||||
|
||||
inline
|
||||
G4int G4FSALIntegrationDriver::GetMaxNoSteps() const
|
||||
template <class T>
|
||||
const G4MagIntegratorStepper* G4FSALIntegrationDriver<T>::GetStepper() const
|
||||
{
|
||||
return fMaxNoSteps;
|
||||
return nullptr; // pIntStepper;
|
||||
// It can only return 'pIntStepper' if it is a compatible type
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::SetMaxNoSteps(G4int val)
|
||||
template <class T>
|
||||
G4MagIntegratorStepper* G4FSALIntegrationDriver<T>::GetStepper()
|
||||
{
|
||||
fMaxNoSteps= val;
|
||||
return nullptr;
|
||||
// It can only return 'pIntStepper' if it is a compatible type
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::GetDerivatives(const G4FieldTrack &y_curr, // const, INput
|
||||
G4double dydx[]) // OUTput
|
||||
{
|
||||
G4double tmpValArr[G4FieldTrack::ncompSVEC];
|
||||
y_curr.DumpToArray( tmpValArr );
|
||||
pIntStepper -> RightHandSide( tmpValArr , dydx );
|
||||
|
||||
template <class T>
|
||||
G4int G4FSALIntegrationDriver<T>::GetMaxNoSteps() const
|
||||
{
|
||||
return fMaxNoSteps;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetVerboseLevel() const
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetMaxNoSteps(G4int val)
|
||||
{
|
||||
return fVerboseLevel;
|
||||
fMaxNoSteps = val;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4int G4FSALIntegrationDriver<T>::GetVerboseLevel() const
|
||||
{
|
||||
return fVerboseLevel;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4FSALIntegrationDriver::SetVerboseLevel(G4int newLevel)
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetVerboseLevel(G4int newLevel)
|
||||
{
|
||||
fVerboseLevel= newLevel;
|
||||
fVerboseLevel = newLevel;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4FSALIntegrationDriver::GetSmallestFraction() const
|
||||
template <class T>
|
||||
G4double G4FSALIntegrationDriver<T>::GetSmallestFraction() const
|
||||
{
|
||||
return fSmallestFraction;
|
||||
return fSmallestFraction;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4EquationOfMotion* G4FSALIntegrationDriver<T>::GetEquationOfMotion()
|
||||
{
|
||||
return pIntStepper->GetEquationOfMotion();
|
||||
}
|
||||
|
||||
inline
|
||||
G4int G4FSALIntegrationDriver::GetNoTotalSteps() const
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetEquationOfMotion(G4EquationOfMotion* equation)
|
||||
{
|
||||
return fNoTotalSteps;
|
||||
pIntStepper->SetEquationOfMotion(equation);
|
||||
}
|
||||
|
||||
inline
|
||||
G4int G4FSALIntegrationDriver::GetTotalNoStepperCalls() const
|
||||
{
|
||||
return TotalNoStepperCalls;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: $
|
||||
//
|
||||
// Helper namespace 'field_utils'
|
||||
//
|
||||
// Description:
|
||||
// Simple methods to extract vectors from arrays in conventions of
|
||||
// the magnetic field integration
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
#ifndef G4FIELD_UTILS_HH
|
||||
#define G4FIELD_UTILS_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
namespace field_utils {
|
||||
|
||||
enum class Value3D {
|
||||
Position = 0,
|
||||
Momentum = 3,
|
||||
Spin = 9
|
||||
};
|
||||
|
||||
enum class Value1D {
|
||||
KineticEnergy = 6,
|
||||
LabTime = 7,
|
||||
ProperTime = 8
|
||||
};
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue(const ArrayType& array, Value1D value);
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue2(const ArrayType& array, Value1D value);
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue(const ArrayType& array, Value3D value);
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue2(const ArrayType& array, Value3D value);
|
||||
|
||||
template <typename ArrayType>
|
||||
G4ThreeVector makeVector(const ArrayType& array, Value3D value);
|
||||
|
||||
G4double relativeError(
|
||||
const G4double y[],
|
||||
const G4double yerr[],
|
||||
const G4double hstep,
|
||||
const G4double errorTolerance = 1);
|
||||
|
||||
} // field_utils
|
||||
|
||||
#include "G4FieldUtils.icc"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: $
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
namespace field_utils {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<class T>
|
||||
size_t getFirstIndex(const T& value) {
|
||||
return static_cast<size_t>(value);
|
||||
}
|
||||
|
||||
} // internal
|
||||
|
||||
template <typename ArrayType>
|
||||
inline G4double getValue(const ArrayType& array, Value1D value)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return array[begin];
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue2(const ArrayType& array, Value1D value)
|
||||
{
|
||||
return sqr(getValue(array, value));
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue(const ArrayType& array, Value3D value)
|
||||
{
|
||||
return std::sqrt(getValue2(array, value));
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue2(const ArrayType& array, const Value3D value)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return sqr(array[begin]) + sqr(array[begin+1]) + sqr(array[begin+2]);
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4ThreeVector makeVector(const ArrayType& array, Value3D value)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return G4ThreeVector(array[begin], array[begin + 1], array[begin + 2]);
|
||||
}
|
||||
|
||||
} // field_utils
|
||||
@@ -0,0 +1,185 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4IntegrationDriver.hh 106739 2017-10-20 14:45:37Z dmsoroki $
|
||||
//
|
||||
//
|
||||
// class G4IntegrationDriver
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Driver class which controls the integration error of a
|
||||
// Runge-Kutta stepper
|
||||
|
||||
// History:
|
||||
// - Created. D.Sorokin
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#ifndef G4IntegrationDriver_HH
|
||||
#define G4IntegrationDriver_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
|
||||
template <class T>
|
||||
class G4IntegrationDriver : public G4VIntegrationDriver {
|
||||
public:
|
||||
G4IntegrationDriver( G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 1);
|
||||
|
||||
virtual ~G4IntegrationDriver() override;
|
||||
|
||||
G4IntegrationDriver(const G4IntegrationDriver &) = delete;
|
||||
const G4IntegrationDriver& operator =(const G4IntegrationDriver &) = delete;
|
||||
|
||||
// Integrates ODE from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output track is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
virtual G4bool AccurateAdvance(
|
||||
G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0) override; // Suggested 1st interval
|
||||
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
virtual G4bool QuickAdvance(
|
||||
G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
|
||||
virtual void GetDerivatives(
|
||||
const G4FieldTrack &track,
|
||||
G4double dydx[]) const override;
|
||||
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
virtual G4double ComputeNewStepSize(
|
||||
G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent) override; // current step size
|
||||
|
||||
virtual void SetVerboseLevel(G4int newLevel) override;
|
||||
virtual G4int GetVerboseLevel() const override;
|
||||
|
||||
virtual G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
virtual const T* GetStepper() const override;
|
||||
virtual T* GetStepper() override;
|
||||
|
||||
// Accessors.
|
||||
G4double GetMinimumStep() const;
|
||||
G4double GetSafety() const;
|
||||
G4double GetPshrnk() const;
|
||||
G4double GetPgrow() const;
|
||||
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
void RenewStepperAndAdjust(T *pItsStepper);
|
||||
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
void ReSetParameters(G4double safety = 0.9);
|
||||
|
||||
void SetMinimumStep(G4double newval);
|
||||
void SetSafety(G4double valS);
|
||||
|
||||
// This takes one Step that is of size htry, or as large
|
||||
// as possible while satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
void OneGoodStep( G4double yVar[], // InOut
|
||||
const G4double dydx[],
|
||||
G4double& curveLength,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (ie a single call to AccurateAdvance).
|
||||
G4int GetMaxNoSteps() const;
|
||||
void SetMaxNoSteps( G4int val);
|
||||
|
||||
G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction(G4double val);
|
||||
|
||||
private:
|
||||
G4double ShrinkStepSize(G4double h, G4double error) const;
|
||||
G4double GrowStepSize(G4double h, G4double error) const;
|
||||
void UpdateErrorConstraints();
|
||||
|
||||
void CheckStep(
|
||||
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid);
|
||||
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
G4double fMinimumStep;
|
||||
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
G4double fSmallestFraction;
|
||||
// Expected range: smaller than 0.1 * epsilon and bigger than 5e-13
|
||||
// ( Note: this range is not enforced. )
|
||||
G4int fMaxNoSteps;
|
||||
|
||||
// The (default) maximum number of steps is Base
|
||||
// divided by the order of Stepper
|
||||
static constexpr G4int fMaxStepBase = 250;
|
||||
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
G4double safety;
|
||||
G4double pshrnk; // exponent for shrinking
|
||||
G4double pgrow; // exponent for growth
|
||||
|
||||
// muximum error values for shrinking / growing (optimisation).
|
||||
G4double errorConstraintShrink;
|
||||
G4double errorConstraintGrow;
|
||||
|
||||
// Maximum stepsize increase/decrease factors.
|
||||
static constexpr G4double max_stepping_increase = 5;
|
||||
static constexpr G4double max_stepping_decrease = 0.1;
|
||||
|
||||
T* pIntStepper;
|
||||
|
||||
// Step Statistics
|
||||
unsigned long fNoTotalSteps, fNoBadSteps, fNoGoodSteps;
|
||||
|
||||
G4int fVerboseLevel; // Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
G4int fNoQuickAvanceCalls;
|
||||
};
|
||||
|
||||
#include "G4IntegrationDriver.icc"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,436 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4IntegrationDriver.icc 106739 2017-10-20 14:45:37Z dmsoroki $
|
||||
//
|
||||
//
|
||||
// class G4IntegrationDriver
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Driver class which controls the integration error of a
|
||||
// Runge-Kutta stepper
|
||||
|
||||
// History:
|
||||
// - Created. D.Sorokin
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4GeometryTolerance.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4FieldUtils.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
template <class T>
|
||||
G4IntegrationDriver<T>::G4IntegrationDriver (
|
||||
G4double hminimum,
|
||||
T* pStepper,
|
||||
G4int numComponents,
|
||||
G4int statisticsVerbose)
|
||||
: fSmallestFraction(1e-12),
|
||||
fNoTotalSteps(0),
|
||||
fNoBadSteps(0),
|
||||
fNoGoodSteps(0),
|
||||
fVerboseLevel(statisticsVerbose),
|
||||
fNoQuickAvanceCalls(0)
|
||||
{
|
||||
if (numComponents != pStepper->GetNumberOfVariables()) {
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components " << numComponents
|
||||
<< " != Stepper's number of components " << pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4IntegrationDriver","001", FatalException, message);
|
||||
}
|
||||
RenewStepperAndAdjust(pStepper);
|
||||
fMinimumStep = hminimum;
|
||||
fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4IntegrationDriver<T>::~G4IntegrationDriver()
|
||||
{
|
||||
if( fVerboseLevel > 0 )
|
||||
G4cout << "G4Integration Driver Stats: #QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " #AccurateAdvance " << fNoTotalSteps << G4endl;
|
||||
}
|
||||
|
||||
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
|
||||
// values at y_current over hstep x2 with accuracy eps.
|
||||
// On output ystart is replaced by values at the end of the integration
|
||||
// interval. RightHandSide is the right-hand side of ODE system.
|
||||
// The source is similar to odeint routine from NRC p.721-722 .
|
||||
template <class T>
|
||||
G4bool G4IntegrationDriver<T>::AccurateAdvance(
|
||||
G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial)
|
||||
{
|
||||
if (hstep < GetMinimumStep()) {
|
||||
G4double dchord_step = 0, dyerr = 0;
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
GetDerivatives(track, dydx);
|
||||
return QuickAdvance(track, dydx, hstep, dchord_step, dyerr);
|
||||
}
|
||||
|
||||
G4bool succeeded = false;
|
||||
G4double hnext, hdid;
|
||||
|
||||
G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
|
||||
track.DumpToArray(y);
|
||||
|
||||
// hstep somtimes is too small. No need to add large curveLength.
|
||||
G4double curveLength = 0;
|
||||
G4double endCurveLength = hstep;
|
||||
|
||||
G4double h = hstep;
|
||||
if (hinitial > perMillion * hstep && hinitial < hstep) {
|
||||
h = hinitial;
|
||||
}
|
||||
|
||||
for (G4int iter = 0; iter < fMaxNoSteps; ++iter) {
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
pIntStepper->/*Compute*/RightHandSide(y, dydx);
|
||||
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
G4double restCurveLength = endCurveLength - curveLength;
|
||||
if (restCurveLength < GetSmallestFraction() * hstep) {
|
||||
succeeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
h = std::min(hnext, restCurveLength);
|
||||
}
|
||||
|
||||
if (succeeded) {
|
||||
track.LoadFromArray(y, pIntStepper->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + curveLength);
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// Step failed; compute the size of retrial Step.
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::ShrinkStepSize(G4double h, G4double error) const
|
||||
{
|
||||
if (error > errorConstraintShrink) {
|
||||
return max_stepping_decrease * h;
|
||||
}
|
||||
return GetSafety() * h * std::pow(error, GetPshrnk());
|
||||
}
|
||||
|
||||
// Compute size of next Step
|
||||
template<class T>
|
||||
G4double G4IntegrationDriver<T>::GrowStepSize(G4double h, G4double error) const
|
||||
{
|
||||
if (error < errorConstraintGrow) {
|
||||
return max_stepping_increase * h;
|
||||
}
|
||||
return GetSafety() * h * std::pow(error, GetPgrow());
|
||||
}
|
||||
|
||||
// Driver for one Runge-Kutta Step with monitoring of local truncation error
|
||||
// to ensure accuracy and adjust stepsize. Input are dependent variable
|
||||
// array y[0,...,5] and its derivative dydx[0,...,5] at the
|
||||
// starting value of the independent variable x . Also input are stepsize
|
||||
// to be attempted htry, and the required accuracy eps. On output y and x
|
||||
// are replaced by their new values, hdid is the stepsize that was actually
|
||||
// accomplished, and hnext is the estimated next stepsize.
|
||||
// This is similar to the function rkqs from the book:
|
||||
// Numerical Recipes in C: The Art of Scientific Computing (NRC), Second
|
||||
// Edition, by William H. Press, Saul A. Teukolsky, William T.
|
||||
// Vetterling, and Brian P. Flannery (Cambridge University Press 1992),
|
||||
// 16.2 Adaptive StepSize Control for Runge-Kutta, p. 719
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::OneGoodStep(
|
||||
G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double& curveLength, // InOut
|
||||
G4double htry,
|
||||
G4double eps_rel_max,
|
||||
G4double& hdid, // Out
|
||||
G4double& hnext) // Out
|
||||
{
|
||||
G4double error = DBL_MAX;
|
||||
|
||||
G4double yerror[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
|
||||
|
||||
// Set stepsize to the initial trial value
|
||||
G4double hstep = htry;
|
||||
|
||||
static G4ThreadLocal G4int tot_no_trials = 0;
|
||||
const G4int max_trials = 100;
|
||||
|
||||
for (G4int iter = 0; iter < max_trials; ++iter) {
|
||||
++tot_no_trials;
|
||||
|
||||
pIntStepper->Stepper(y, dydx, hstep, ytemp, yerror);
|
||||
error = field_utils::relativeError(y, yerror, hstep, eps_rel_max);
|
||||
|
||||
// Step succeeded.
|
||||
if (error <= 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
hstep = ShrinkStepSize(hstep, error);
|
||||
}
|
||||
|
||||
hnext = GrowStepSize(hstep, error);
|
||||
curveLength += (hdid = hstep);
|
||||
|
||||
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k) {
|
||||
y[k] = ytemp[k];
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4bool G4IntegrationDriver<T>::QuickAdvance(
|
||||
G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr)
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
|
||||
if (hstep == 0) {
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4IntegrationDriver ::QuickAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
if (hstep < 0) {
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = " << hstep << "." << G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4IntegrationDriver ::QuickAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
fieldTrack.DumpToArray(yIn);
|
||||
|
||||
pIntStepper->Stepper(yIn, dydx, hstep, yOut, yError);
|
||||
dchord_step = pIntStepper->DistChord();
|
||||
|
||||
fieldTrack.LoadFromArray(yOut, pIntStepper->GetNumberOfVariables());
|
||||
fieldTrack.SetCurveLength(fieldTrack.GetCurveLength() + hstep);
|
||||
|
||||
dyerr = field_utils::relativeError(yOut, yError, hstep) * hstep;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::ComputeNewStepSize(
|
||||
G4double errMaxNorm, // max error (normalised)
|
||||
G4double hstepCurrent) // current step size
|
||||
{
|
||||
if (errMaxNorm > 1) {
|
||||
return ShrinkStepSize(hstepCurrent, errMaxNorm);
|
||||
} else if (errMaxNorm >= 0) {
|
||||
return GrowStepSize(hstepCurrent, errMaxNorm);
|
||||
}
|
||||
|
||||
G4Exception("G4IntegrationDriver::ConputeNewStepSize", "Field002",
|
||||
FatalException, "error is negative");
|
||||
|
||||
return max_stepping_increase * hstepCurrent;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
|
||||
{
|
||||
if( newFraction > 1.e-16 && newFraction < 1e-8 ) {
|
||||
fSmallestFraction = newFraction;
|
||||
} else {
|
||||
G4cerr << "Warning: SmallestFraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::GetDerivatives(
|
||||
const G4FieldTrack& track, G4double dydx[]) const
|
||||
{
|
||||
G4double y[G4FieldTrack::ncompSVEC];
|
||||
track.DumpToArray(y);
|
||||
pIntStepper->RightHandSide(y, dydx);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::CheckStep(
|
||||
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid)
|
||||
{
|
||||
++fNoTotalSteps;
|
||||
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + perMillion)) {
|
||||
++fNoBadSteps;
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand)){
|
||||
G4cout << "WARNING: endPointDist >= hdid!" << G4endl;
|
||||
}
|
||||
} else {
|
||||
++fNoGoodSteps;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::UpdateErrorConstraints()
|
||||
{
|
||||
errorConstraintShrink = std::pow(
|
||||
max_stepping_decrease / GetSafety(), 1. / GetPshrnk());
|
||||
|
||||
errorConstraintGrow = std::pow(
|
||||
max_stepping_increase / GetSafety(), 1. / GetPgrow());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4IntegrationDriver<T>::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4IntegrationDriver<T>::GetSafety() const
|
||||
{
|
||||
return safety;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4IntegrationDriver<T>::GetPshrnk() const
|
||||
{
|
||||
return pshrnk;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::GetPgrow() const
|
||||
{
|
||||
return pgrow;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetMinimumStep(G4double minimumStepLength)
|
||||
{
|
||||
fMinimumStep = minimumStepLength;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::ReSetParameters(G4double new_safety)
|
||||
{
|
||||
safety = new_safety;
|
||||
pshrnk = -1.0 / pIntStepper->IntegratorOrder();
|
||||
pgrow = -1.0 / (1.0 + pIntStepper->IntegratorOrder());
|
||||
UpdateErrorConstraints();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetSafety(G4double val)
|
||||
{
|
||||
safety = val;
|
||||
UpdateErrorConstraints();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::RenewStepperAndAdjust(T* stepper)
|
||||
{
|
||||
pIntStepper = stepper;
|
||||
ReSetParameters();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T* G4IntegrationDriver<T>::GetStepper() const
|
||||
{
|
||||
return pIntStepper;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* G4IntegrationDriver<T>::GetStepper()
|
||||
{
|
||||
return pIntStepper;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4int G4IntegrationDriver<T>::GetMaxNoSteps() const
|
||||
{
|
||||
return fMaxNoSteps;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetMaxNoSteps(G4int val)
|
||||
{
|
||||
fMaxNoSteps = val;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4int G4IntegrationDriver<T>::GetVerboseLevel() const
|
||||
{
|
||||
return fVerboseLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetVerboseLevel(G4int newLevel)
|
||||
{
|
||||
fVerboseLevel = newLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::GetSmallestFraction() const
|
||||
{
|
||||
return fSmallestFraction;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4EquationOfMotion* G4IntegrationDriver<T>::GetEquationOfMotion()
|
||||
{
|
||||
return pIntStepper->GetEquationOfMotion();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetEquationOfMotion(G4EquationOfMotion* equation)
|
||||
{
|
||||
pIntStepper->SetEquationOfMotion(equation);
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4MagIntegratorDriver.hh 104525 2017-06-02 07:22:58Z gcosmo $
|
||||
// $Id: G4MagIntegratorDriver.hh 107059 2017-11-01 14:58:16Z gcosmo $
|
||||
//
|
||||
//
|
||||
// class G4MagInt_Driver
|
||||
@@ -41,155 +41,161 @@
|
||||
#ifndef G4MagInt_Driver_Def
|
||||
#define G4MagInt_Driver_Def
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
class G4MagInt_Driver
|
||||
class G4MagInt_Driver : public G4VIntegrationDriver
|
||||
{
|
||||
public: // with description
|
||||
public: // with description
|
||||
|
||||
G4bool AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial=0.0); // Suggested 1st interval
|
||||
// Above drivers for integrator (Runge-Kutta) with stepsize control.
|
||||
// Integrates ODE starting values y_current
|
||||
// from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output ystart is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
G4MagInt_Driver(G4double hminimum,
|
||||
G4MagIntegratorStepper* pItsStepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 1);
|
||||
virtual ~G4MagInt_Driver() override;
|
||||
// Constructor, destructor.
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_val, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr ) ;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
G4MagInt_Driver(const G4MagInt_Driver&) = delete;
|
||||
G4MagInt_Driver& operator=(const G4MagInt_Driver&) = delete;
|
||||
// deleted Private copy constructor and assignment operator.
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_posvel, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq ) ;
|
||||
// New QuickAdvance that also just tries one Step
|
||||
// (so also does not ensure accuracy)
|
||||
// but does return the errors in position and
|
||||
// momentum (normalised: Delta_Integration(p^2)/(p^2) )
|
||||
virtual G4bool AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0.0) override; // Suggested 1st interval
|
||||
// Above drivers for integrator (Runge-Kutta) with stepsize control.
|
||||
// Integrates ODE starting values y_current
|
||||
// from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output ystart is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
|
||||
G4MagInt_Driver( G4double hminimum,
|
||||
G4MagIntegratorStepper *pItsStepper,
|
||||
G4int numberOfComponents=6,
|
||||
G4int statisticsVerbosity=1);
|
||||
~G4MagInt_Driver();
|
||||
// Constructor, destructor.
|
||||
virtual G4bool QuickAdvance(G4FieldTrack& y_val, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
|
||||
inline G4double GetHmin() const;
|
||||
inline G4double Hmin() const; // Obsolete
|
||||
inline G4double GetSafety() const;
|
||||
inline G4double GetPshrnk() const;
|
||||
inline G4double GetPgrow() const;
|
||||
inline G4double GetErrcon() const;
|
||||
inline void GetDerivatives( const G4FieldTrack &y_curr, // const, INput
|
||||
G4double dydx[] ); // OUTput
|
||||
// Accessors.
|
||||
G4bool QuickAdvance(G4FieldTrack& y_posvel, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq ) ;
|
||||
// New QuickAdvance that also just tries one Step
|
||||
// (so also does not ensure accuracy)
|
||||
// but does return the errors in position and
|
||||
// momentum (normalised: Delta_Integration(p^2)/(p^2) )
|
||||
|
||||
inline void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper);
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
inline G4double GetHmin() const;
|
||||
inline G4double Hmin() const; // Obsolete
|
||||
inline G4double GetSafety() const;
|
||||
inline G4double GetPshrnk() const;
|
||||
inline G4double GetPgrow() const;
|
||||
inline G4double GetErrcon() const;
|
||||
virtual void GetDerivatives(const G4FieldTrack &y_curr, // const, INput
|
||||
G4double dydx[]) const override; // OUTput
|
||||
// Accessors.
|
||||
|
||||
inline void ReSetParameters(G4double new_safety= 0.9 );
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
// ii) calculates "errcon" according to the above values.
|
||||
virtual G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
inline void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper);
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
|
||||
inline void SetSafety(G4double valS);
|
||||
inline void SetPshrnk(G4double valPs);
|
||||
inline void SetPgrow (G4double valPg);
|
||||
inline void SetErrcon(G4double valEc);
|
||||
// When setting safety or pgrow, errcon will be set to a
|
||||
// compatible value.
|
||||
inline void ReSetParameters(G4double new_safety= 0.9 );
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
// ii) calculates "errcon" according to the above values.
|
||||
|
||||
inline G4double ComputeAndSetErrcon();
|
||||
inline void SetSafety(G4double valS);
|
||||
inline void SetPshrnk(G4double valPs);
|
||||
inline void SetPgrow (G4double valPg);
|
||||
inline void SetErrcon(G4double valEc);
|
||||
// When setting safety or pgrow, errcon will be set to a
|
||||
// compatible value.
|
||||
|
||||
inline const G4MagIntegratorStepper* GetStepper() const;
|
||||
inline G4MagIntegratorStepper* GetStepper();
|
||||
inline G4double ComputeAndSetErrcon();
|
||||
|
||||
void OneGoodStep( G4double ystart[], // Like old RKF45step()
|
||||
const G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps, // memb variables ?
|
||||
G4double& hdid,
|
||||
G4double& hnext ) ;
|
||||
// This takes one Step that is as large as possible while
|
||||
// satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
virtual const G4MagIntegratorStepper* GetStepper() const override;
|
||||
virtual G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
G4double ComputeNewStepSize( G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent); // current step size
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
void OneGoodStep(G4double ystart[], // Like old RKF45step()
|
||||
const G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps, // memb variables ?
|
||||
G4double& hdid,
|
||||
G4double& hnext ) ;
|
||||
// This takes one Step that is as large as possible while
|
||||
// satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
|
||||
G4double ComputeNewStepSize_WithinLimits(
|
||||
G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent); // current step size
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Limit the next step's size within a range around the current one.
|
||||
virtual G4double ComputeNewStepSize(G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent) override; // current step size
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
|
||||
inline G4int GetMaxNoSteps() const;
|
||||
inline void SetMaxNoSteps( G4int val);
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (ie a single call to AccurateAdvance).
|
||||
G4double ComputeNewStepSize_WithinLimits(G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent); // current step size
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Limit the next step's size within a range around the current one.
|
||||
|
||||
public: // without description
|
||||
inline G4int GetMaxNoSteps() const;
|
||||
inline void SetMaxNoSteps( G4int val);
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (ie a single call to AccurateAdvance).
|
||||
|
||||
inline void SetHmin(G4double newval);
|
||||
inline void SetVerboseLevel(G4int newLevel);
|
||||
inline G4double GetVerboseLevel() const;
|
||||
public: // without description
|
||||
|
||||
inline G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction( G4double val );
|
||||
inline void SetHmin(G4double newval);
|
||||
virtual void SetVerboseLevel(G4int newLevel) override;
|
||||
virtual G4int GetVerboseLevel() const override;
|
||||
|
||||
protected: // without description
|
||||
void WarnSmallStepSize( G4double hnext, G4double hstep,
|
||||
G4double h, G4double xDone,
|
||||
G4int noSteps);
|
||||
void WarnTooManyStep( G4double x1start, G4double x2end, G4double xCurrent);
|
||||
void WarnEndPointTooFar (G4double endPointDist,
|
||||
G4double hStepSize ,
|
||||
G4double epsilonRelative,
|
||||
G4int debugFlag);
|
||||
// Issue warnings for undesirable situations
|
||||
inline G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction( G4double val );
|
||||
|
||||
void PrintStatus( const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
G4int subStepNo );
|
||||
void PrintStatus( const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
G4int subStepNo );
|
||||
void PrintStat_Aux( const G4FieldTrack& aFieldTrack,
|
||||
G4double requestStep,
|
||||
G4double actualStep,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVelocities );
|
||||
// Verbose output for debugging
|
||||
protected: // without description
|
||||
void WarnSmallStepSize(G4double hnext, G4double hstep,
|
||||
G4double h, G4double xDone,
|
||||
G4int noSteps);
|
||||
|
||||
void PrintStatisticsReport() ;
|
||||
// Report on the number of steps, maximum errors etc.
|
||||
void WarnTooManyStep(G4double x1start, G4double x2end, G4double xCurrent);
|
||||
void WarnEndPointTooFar(G4double endPointDist,
|
||||
G4double hStepSize ,
|
||||
G4double epsilonRelative,
|
||||
G4int debugFlag);
|
||||
// Issue warnings for undesirable situations
|
||||
|
||||
void PrintStatus(const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
G4int subStepNo);
|
||||
void PrintStatus(const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
G4int subStepNo);
|
||||
void PrintStat_Aux(const G4FieldTrack& aFieldTrack,
|
||||
G4double requestStep,
|
||||
G4double actualStep,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVelocities);
|
||||
// Verbose output for debugging
|
||||
|
||||
void PrintStatisticsReport();
|
||||
// Report on the number of steps, maximum errors etc.
|
||||
|
||||
#ifdef QUICK_ADV_TWO
|
||||
G4bool QuickAdvance( G4double yarrin[], // In
|
||||
G4bool QuickAdvance( G4double yarrin[], // In
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yarrout[], // Out
|
||||
@@ -197,58 +203,51 @@ class G4MagInt_Driver
|
||||
G4double& dyerr ); // in length
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
G4MagInt_Driver(const G4MagInt_Driver&);
|
||||
G4MagInt_Driver& operator=(const G4MagInt_Driver&);
|
||||
// Private copy constructor and assignment operator.
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
// ---------------------------------------------------------------
|
||||
// INVARIANTS
|
||||
|
||||
G4double fMinimumStep;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
G4double fSmallestFraction; // Expected range 1e-12 to 5e-15;
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
G4double fMinimumStep;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
G4double fSmallestFraction; // Expected range 1e-12 to 5e-15;
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
|
||||
const G4int fNoIntegrationVariables; // Number of Variables in integration
|
||||
const G4int fMinNoVars; // Minimum number for FieldTrack
|
||||
const G4int fNoVars; // Full number of variable
|
||||
const G4int fNoIntegrationVariables; // Number of Variables in integration
|
||||
const G4int fMinNoVars; // Minimum number for FieldTrack
|
||||
const G4int fNoVars; // Full number of variable
|
||||
|
||||
G4int fMaxNoSteps;
|
||||
static const G4int fMaxStepBase;
|
||||
G4int fMaxNoSteps;
|
||||
static const G4int fMaxStepBase;
|
||||
|
||||
G4double safety;
|
||||
G4double pshrnk; // exponent for shrinking
|
||||
G4double pgrow; // exponent for growth
|
||||
G4double errcon;
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
G4double safety;
|
||||
G4double pshrnk; // exponent for shrinking
|
||||
G4double pgrow; // exponent for growth
|
||||
G4double errcon;
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
|
||||
static const G4double max_stepping_increase;
|
||||
static const G4double max_stepping_decrease;
|
||||
// Maximum stepsize increase/decrease factors.
|
||||
static const G4double max_stepping_increase;
|
||||
static const G4double max_stepping_decrease;
|
||||
// Maximum stepsize increase/decrease factors.
|
||||
|
||||
G4int fStatisticsVerboseLevel;
|
||||
G4int fStatisticsVerboseLevel;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// DEPENDENT Objects
|
||||
G4MagIntegratorStepper *pIntStepper;
|
||||
// ---------------------------------------------------------------
|
||||
// DEPENDENT Objects
|
||||
G4MagIntegratorStepper *pIntStepper;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// STATE
|
||||
// ---------------------------------------------------------------
|
||||
// STATE
|
||||
|
||||
unsigned long fNoTotalSteps, fNoBadSteps, fNoSmallSteps, fNoInitialSmallSteps;
|
||||
unsigned long fNoCalls;
|
||||
G4double fDyerr_max, fDyerr_mx2;
|
||||
G4double fDyerrPos_smTot, fDyerrPos_lgTot, fDyerrVel_lgTot;
|
||||
G4double fSumH_sm, fSumH_lg;
|
||||
// Step Statistics
|
||||
unsigned long fNoTotalSteps, fNoBadSteps, fNoSmallSteps, fNoInitialSmallSteps;
|
||||
unsigned long fNoCalls;
|
||||
G4double fDyerr_max, fDyerr_mx2;
|
||||
G4double fDyerrPos_smTot, fDyerrPos_lgTot, fDyerrVel_lgTot;
|
||||
G4double fSumH_sm, fSumH_lg;
|
||||
// Step Statistics
|
||||
|
||||
G4int fVerboseLevel; // Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
G4int fVerboseLevel; // Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4MagIntegratorDriver.icc 69699 2013-05-13 08:50:30Z gcosmo $
|
||||
// $Id: G4MagIntegratorDriver.icc 107059 2017-11-01 14:58:16Z gcosmo $
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -113,18 +113,6 @@ void G4MagInt_Driver::RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper)
|
||||
ReSetParameters();
|
||||
}
|
||||
|
||||
inline
|
||||
const G4MagIntegratorStepper* G4MagInt_Driver::GetStepper() const
|
||||
{
|
||||
return pIntStepper;
|
||||
}
|
||||
|
||||
inline
|
||||
G4MagIntegratorStepper* G4MagInt_Driver::GetStepper()
|
||||
{
|
||||
return pIntStepper;
|
||||
}
|
||||
|
||||
inline
|
||||
G4int G4MagInt_Driver::GetMaxNoSteps() const
|
||||
{
|
||||
@@ -138,16 +126,7 @@ void G4MagInt_Driver::SetMaxNoSteps(G4int val)
|
||||
}
|
||||
|
||||
inline
|
||||
void G4MagInt_Driver::GetDerivatives(const G4FieldTrack &y_curr, // const, INput
|
||||
G4double dydx[]) // OUTput
|
||||
{
|
||||
G4double tmpValArr[G4FieldTrack::ncompSVEC];
|
||||
y_curr.DumpToArray( tmpValArr );
|
||||
pIntStepper -> RightHandSide( tmpValArr , dydx );
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4MagInt_Driver::GetVerboseLevel() const
|
||||
G4int G4MagInt_Driver::GetVerboseLevel() const
|
||||
{
|
||||
return fVerboseLevel;
|
||||
}
|
||||
@@ -162,4 +141,5 @@ inline
|
||||
G4double G4MagInt_Driver::GetSmallestFraction() const
|
||||
{
|
||||
return fSmallestFraction;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4MagIntegratorStepper.hh 97387 2016-06-02 10:03:42Z gcosmo $
|
||||
// $Id: G4MagIntegratorStepper.hh 107059 2017-11-01 14:58:16Z gcosmo $
|
||||
//
|
||||
//
|
||||
// class G4MagIntegratorStepper
|
||||
@@ -86,7 +86,7 @@ class G4MagIntegratorStepper
|
||||
inline void NormalisePolarizationVector( G4double vec[12] );
|
||||
// Simple utility function to (re)normalise 'unit spin' vector.
|
||||
|
||||
inline void RightHandSide( const double y[], double dydx[] );
|
||||
inline void RightHandSide( const double y[], double dydx[] ) const;
|
||||
// Utility method to supply the standard Evaluation of the
|
||||
// Right Hand side of the associated equation.
|
||||
|
||||
@@ -113,7 +113,7 @@ class G4MagIntegratorStepper
|
||||
inline void ResetfNORHSCalls(){ fNoRHSCalls = 0; }
|
||||
// Count number of calls to RHS method(s)
|
||||
|
||||
bool IsFSAL() { return fIsFSAL; }
|
||||
bool IsFSAL() const { return fIsFSAL; }
|
||||
|
||||
protected:
|
||||
void SetIntegrationOrder(int order) { fIntegrationOrder= order; }
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4MagIntegratorStepper.icc 97387 2016-06-02 10:03:42Z gcosmo $
|
||||
// $Id: G4MagIntegratorStepper.icc 107059 2017-11-01 14:58:16Z gcosmo $
|
||||
//
|
||||
|
||||
inline
|
||||
@@ -55,7 +55,7 @@ G4int G4MagIntegratorStepper::GetNumberOfStateVariables() const
|
||||
}
|
||||
|
||||
inline
|
||||
void G4MagIntegratorStepper::RightHandSide( const double y[], double dydx[] )
|
||||
void G4MagIntegratorStepper::RightHandSide( const double y[], double dydx[] ) const
|
||||
{
|
||||
fEquation_Rhs-> RightHandSide(y, dydx);
|
||||
fNoRHSCalls++; // IncrementRHSCalls();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4NystromRK4.hh 66356 2012-12-18 09:02:32Z gcosmo $
|
||||
// $Id: G4NystromRK4.hh 106564 2017-10-13 09:06:13Z gcosmo $
|
||||
//
|
||||
// class G4NystromRK4
|
||||
//
|
||||
@@ -64,7 +64,7 @@ class G4NystromRK4 : public G4MagIntegratorStepper
|
||||
// Single call for integration result and error
|
||||
// - Provides Error via analytical method
|
||||
|
||||
virtual void ComputeRightHandSide(const double P[],double dPdS[]);
|
||||
virtual void ComputeRightHandSide(const G4double P[],G4double dPdS[]);
|
||||
// Must compute RHS - and does caches result
|
||||
|
||||
void SetDistanceForConstantField( G4double length );
|
||||
@@ -77,6 +77,10 @@ class G4NystromRK4 : public G4MagIntegratorStepper
|
||||
|
||||
inline void getField (const G4double P[4]);
|
||||
|
||||
G4bool CheckCachedMomemtum( const G4double PosMom[6], G4double savedMom );
|
||||
G4bool CheckFieldPosition( const G4double Position[3],
|
||||
const G4double lastPosition[3] );
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Private data
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: $
|
||||
//
|
||||
// Helper namespace 'magneticfield'
|
||||
//
|
||||
// Description:
|
||||
// An implementation of the 7 stage embedded Runge-Kutta 4,5 pair (RK547FEq1)
|
||||
// from the paper D. J. Higham and G. Hall,
|
||||
// “Embedded Runge-Kutta formulae with stable equilibrium states”,
|
||||
// J. Comput. Appl. Math., vol. 29, no. 1, pp. 25–33, Jan. 1990.
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
#ifndef G4RK547FEq1_HH
|
||||
#define G4RK547FEq1_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
class G4RK547FEq1 : public G4MagIntegratorStepper {
|
||||
public:
|
||||
G4RK547FEq1(G4EquationOfMotion* EqRhs, G4int integrationVariables = 6);
|
||||
|
||||
virtual void Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[]) override;
|
||||
|
||||
void Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[]);
|
||||
|
||||
G4RK547FEq1(const G4RK547FEq1&) = delete;
|
||||
G4RK547FEq1& operator = (const G4RK547FEq1&) = delete;
|
||||
|
||||
virtual G4double DistChord() const override;
|
||||
virtual G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
private:
|
||||
void makeStep(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double* dydxOutput = nullptr,
|
||||
G4double* yError = nullptr) const;
|
||||
|
||||
G4double fyIn[G4FieldTrack::ncompSVEC],
|
||||
fdydx[G4FieldTrack::ncompSVEC],
|
||||
fyOut[G4FieldTrack::ncompSVEC],
|
||||
fdydxOut[G4FieldTrack::ncompSVEC];
|
||||
G4double fhstep = -1.0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: $
|
||||
//
|
||||
// Helper namespace 'magneticfield'
|
||||
//
|
||||
// Description:
|
||||
// An implementation of the 7 stage embedded Runge-Kutta 4,5 pair (RK547FEq2)
|
||||
// from the paper D. J. Higham and G. Hall,
|
||||
// “Embedded Runge-Kutta formulae with stable equilibrium states”,
|
||||
// J. Comput. Appl. Math., vol. 29, no. 1, pp. 25–33, Jan. 1990.
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
#ifndef G4RK547FEq2_HH
|
||||
#define G4RK547FEq2_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
class G4RK547FEq2 : public G4MagIntegratorStepper {
|
||||
public:
|
||||
G4RK547FEq2(G4EquationOfMotion* EqRhs, G4int integrationVariables = 6);
|
||||
|
||||
virtual void Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[]) override;
|
||||
|
||||
void Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[]);
|
||||
|
||||
G4RK547FEq2 (const G4RK547FEq2&) = delete;
|
||||
G4RK547FEq2& operator = (const G4RK547FEq2&) = delete;
|
||||
|
||||
virtual G4double DistChord() const override;
|
||||
virtual G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
private:
|
||||
void makeStep(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double* dydxOutput = nullptr,
|
||||
G4double* yError = nullptr) const;
|
||||
|
||||
G4double fyIn[G4FieldTrack::ncompSVEC],
|
||||
fdydx[G4FieldTrack::ncompSVEC],
|
||||
fyOut[G4FieldTrack::ncompSVEC],
|
||||
fdydxOut[G4FieldTrack::ncompSVEC];
|
||||
G4double fhstep= -1.0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: $
|
||||
//
|
||||
// Helper namespace 'magneticfield'
|
||||
//
|
||||
// Description:
|
||||
// An implementation of the 7 stage embedded Runge-Kutta 4,5 pair (RK547FEq3)
|
||||
// from the paper D. J. Higham and G. Hall,
|
||||
// “Embedded Runge-Kutta formulae with stable equilibrium states”,
|
||||
// J. Comput. Appl. Math., vol. 29, no. 1, pp. 25–33, Jan. 1990.
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
#ifndef G4RK547FEq3_HH
|
||||
#define G4RK547FEq3_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
class G4RK547FEq3 : public G4MagIntegratorStepper {
|
||||
public:
|
||||
G4RK547FEq3(G4EquationOfMotion* EqRhs, G4int integrationVariables = 6);
|
||||
|
||||
virtual void Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[]) override;
|
||||
|
||||
void Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[]);
|
||||
|
||||
G4RK547FEq3(const G4RK547FEq3&) = delete;
|
||||
G4RK547FEq3& operator = (const G4RK547FEq3&) = delete;
|
||||
|
||||
virtual G4double DistChord() const override;
|
||||
virtual G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
private:
|
||||
void makeStep(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double* dydxOutput = nullptr,
|
||||
G4double* yError = nullptr) const;
|
||||
|
||||
G4double fyIn[G4FieldTrack::ncompSVEC],
|
||||
fdydx[G4FieldTrack::ncompSVEC],
|
||||
fyOut[G4FieldTrack::ncompSVEC],
|
||||
fdydxOut[G4FieldTrack::ncompSVEC];
|
||||
G4double fhstep= -1.0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: $
|
||||
//
|
||||
// class G4VIntegrationDriver
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Abstract base class for 'driver' classes which are responsible for
|
||||
// undertaking integration of an state given an equation of motion and
|
||||
// within acceptable error bound(s).
|
||||
//
|
||||
// Different integration methods are meant to be provided via this
|
||||
// common interface, and can span the original type (explicit Runge Kutta
|
||||
// methods), enhanced RK methods and alternatives such as the
|
||||
// Bulirsch-Stoer and multi-step methods.
|
||||
//
|
||||
// The drivers' key mission is to insure that the error is below set values.
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
#ifndef G4VINTEGRATION_DRIVER_HH
|
||||
#define G4VINTEGRATION_DRIVER_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
class G4VIntegrationDriver {
|
||||
public:
|
||||
G4VIntegrationDriver() = default;
|
||||
virtual ~G4VIntegrationDriver() = default;
|
||||
|
||||
G4VIntegrationDriver(const G4VIntegrationDriver&) = delete;
|
||||
const G4VIntegrationDriver& operator = (const G4VIntegrationDriver&) = delete;
|
||||
|
||||
virtual G4bool QuickAdvance(G4FieldTrack& track, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) = 0;
|
||||
|
||||
virtual G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0) = 0; // Suggested 1st interval
|
||||
|
||||
virtual void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[]) const = 0;
|
||||
|
||||
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) = 0;
|
||||
virtual G4EquationOfMotion* GetEquationOfMotion() = 0;
|
||||
|
||||
//[[deprecated("use GetEquationOfMotion() instead of GetStepper()->GetEquationOfMotion()")]]
|
||||
virtual const G4MagIntegratorStepper* GetStepper() const = 0;
|
||||
virtual G4MagIntegratorStepper* GetStepper() = 0;
|
||||
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
virtual G4double ComputeNewStepSize(G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent) = 0; // current step size
|
||||
|
||||
virtual void SetVerboseLevel(G4int level) = 0;
|
||||
virtual G4int GetVerboseLevel() const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user