Import Geant4 10.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2017-12-08 12:52:30 +01:00
parent 98e455a940
commit fc6af9e721
2166 changed files with 276760 additions and 100873 deletions
@@ -55,17 +55,20 @@ The Bogacki shampine method has the following Butcher's tableau
#include "G4BogackiShampine23.hh"
#include "G4LineSection.hh"
using namespace std;
// using namespace std;
//Constructor
G4BogackiShampine23::G4BogackiShampine23(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
fLastStepLength(0.), fAuxStepper(0)
fLastStepLength(0.), fAuxStepper(nullptr)
{
const G4int numberOfVariables = noIntegrationVariables;
SetIntegrationOrder(2); // Apparently 3-rd order extension not used
SetFSAL(true);
ak2 = new G4double[numberOfVariables] ;
ak3 = new G4double[numberOfVariables] ;
ak4 = new G4double[numberOfVariables] ;
@@ -97,6 +100,7 @@ G4BogackiShampine23::~G4BogackiShampine23()
delete[] ak2;
delete[] ak3;
delete[] ak4;
delete[] pseudoDydx_for_DistChord;
delete[] yTemp;
delete[] yIn;
@@ -131,19 +135,15 @@ G4BogackiShampine23::Stepper( const G4double yInput[],
G4double yOut[],
G4double yErr[])
{
G4int i;
const G4double b21 = 0.5 ,
b31 = 0. , b32 = 3.0/4.0 ,
b41 = 2.0/9.0, b42 = 1.0/3.0 , b43 = 4.0/9.0;
const G4double dc1 = b41 - 7.0/24.0 , dc2 = b42 - 1.0/4.0 ,
dc3 = b43 - 1.0/3.0 , dc4 = - 0.125 ;
// Initialise time to t0, needed when it is not updated by the integration.
// [ Note: Only for time dependent fields (usually electric)
// is it neccessary to integrate the time.]
@@ -157,7 +157,7 @@ G4BogackiShampine23::Stepper( const G4double yInput[],
{
yIn[i]=yInput[i];
}
// RightHandSide(yIn, dydx) ; // 1st Step --Not doing, getting passed
// RightHandSide(yIn, dydx) ; // 1st Step --Not doing, getting passed
for(i=0;i<numberOfVariables;i++)
{
@@ -170,20 +170,20 @@ G4BogackiShampine23::Stepper( const G4double yInput[],
yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ;
}
RightHandSide(yTemp, ak3) ; // 3rd Step
for(i=0;i<numberOfVariables;i++)
{
yOut[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ;
// yOut[i] = yIn[i] + Step*(c1*DyDx[i]+ c2*ak2[i] + c3*ak3[i] + c4*ak4[i]);
}
// Extra step used only in calculation of error
RightHandSide(yOut, ak4) ; // 4th Step
// Derivative and end-point already calculated in 'ak4' ! => Can be used in FSAL version
for(i=0;i<numberOfVariables;i++)
{
// yOut[i] = yIn[i] + Step*(c1*DyDx[i]+ c2*ak2[i] + c3*ak3[i] + c4*ak4[i]);
yErr[i] = Step*(dc1*DyDx[i] + dc2*ak2[i] + dc3*ak3[i] +
dc4*ak4[i] ) ;
// Store Input and Final values, for possible use in calculating chord
fLastInitialVector[i] = yIn[i] ;
@@ -77,7 +77,8 @@ G4BogackiShampine45::G4BogackiShampine45(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
fAuxStepper(0),
fLastStepLength(-1.0),
fAuxStepper(nullptr),
fPreparedInterpolation(false)
{
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ChordFinder.cc 101384 2016-11-16 11:03:44Z gcosmo $
// $Id: G4ChordFinder.cc 107508 2017-11-20 08:23:14Z gcosmo $
//
//
// 25.02.97 - John Apostolakis - Design and implementation
@@ -36,33 +36,48 @@
#include "G4SystemOfUnits.hh"
#include "G4MagneticField.hh"
#include "G4Mag_UsualEqRhs.hh"
#include "G4ClassicalRK4.hh"
#include "G4CashKarpRKF45.hh"
#include "G4MagIntegratorDriver.hh"
// #include "G4ClassicalRK4.hh"
// #include "G4CashKarpRKF45.hh"
// #include "G4BogackiShampine23.hh"
#include "G4BogackiShampine45.hh"
// #include "G4BogackiShampine45.hh"
#include "G4DormandPrince745.hh"
// New FSAL type driver / steppers -----
#include "G4FSALIntegrationDriver.hh"
#include "G4VFSALIntegrationStepper.hh"
#include "G4RK547FEq1.hh"
// #include "G4RK547FEq2.hh"
// #include "G4RK547FEq3.hh"
// #include "G4NystromRK4.hh"
// New FSAL type driver / steppers -----
#include "G4IntegrationDriver.hh"
#include "G4FSALBogackiShampine45.hh"
// #include "G4FSALDormandPrince745.hh"
// ..........................................................................
G4ChordFinder::G4ChordFinder(G4MagInt_Driver* pIntegrationDriver)
G4ChordFinder::G4ChordFinder(G4VIntegrationDriver* pIntegrationDriver)
: fDefaultDeltaChord( 0.25 * mm ), // Parameters
fDeltaChord( fDefaultDeltaChord ), // Internal parameters
fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
fMultipleRadius(15.0),
fStatsVerbose(0),
fDriversStepper(0), // Dependent objects
fAllocatedStepper(false),
fRegularStepperOwned(nullptr), // Dependent objects
fEquation(0),
fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0)
{
// Simple constructor -- it does not create equation
fIntgrDriver= pIntegrationDriver;
fAllocatedStepper= false;
fLastStepEstimate_Unconstrained = DBL_MAX; // Should move q, p to
SetFractions_Last_Next( fFractionLast, fFractionNextEstimate);
// check the values and set the other parameters
// G4cout << "G4ChordFinder 1st Constructor called - (driver given). " << G4endl;
}
@@ -70,47 +85,197 @@ G4ChordFinder::G4ChordFinder(G4MagInt_Driver* pIntegrationDriver)
G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
G4double stepMinimum,
G4MagIntegratorStepper* pItsStepper )
G4MagIntegratorStepper* pItsStepper, // nullptr is default
// G4bool useHigherEfficiencyStepper, // false by default
G4bool useFSALstepper ) // false by default
: fDefaultDeltaChord( 0.25 * mm ), // Constants
fDeltaChord( fDefaultDeltaChord ), // Parameters
fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98),
fMultipleRadius(15.0),
fStatsVerbose(0),
fDriversStepper(0), // Dependent objects
fAllocatedStepper(false),
// fRegularStepperOwned(nullptr), // Dependent objects
fEquation(0),
fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0) // State - stats
{
// Construct the Chord Finder
// by creating in inverse order the Driver, the Stepper and EqRhs ...
using NewFsalStepperType = G4RK547FEq1; // or 2 or 3
const char* NewFSALStepperName = "G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
// using OldFsalStepperType = G4FSALBogackiShampine45;
// const char* OldFSALStepperName = "FSAL BogackiShampine 45 (Embedded 5th/4th Order, 7-stage)";
// = G4FSALDormandPrince745; // = "FSAL Dormand Prince 745 stepper";
using RegularStepperType =
G4DormandPrince745; // Famous DOPRI5 (MatLab) 5th order embedded method. High efficiency.
// G4ClassicalRK4; // The old default
// G4CashKarpRKF45; // First embedded method in G4
// G4BogackiShampine45; // High efficiency 5th order embedded method
// G4NystromRK4(pEquation, 0.1*millimeter ); // *clhep::millimeter );
// G4RK547FEq1; // or 2 or 3
const char* RegularStepperName = "G4DormandPrince745 (aka DOPRI5): 5th/4th Order 7-stage embedded stepper";
// "BogackiShampine 45 (Embedded 5th/4th Order, 7-stage)";
// Configurable
G4bool forceFSALstepper= false; // Choice - true to enable !!
// G4bool useNewFSALtype= true;
// G4bool forceHigherEffiencyStepper = false;
G4bool report = false; // Report type of stepper used
bool recallFSALflag = useFSALstepper;
useFSALstepper = forceFSALstepper || useFSALstepper;
if( report ) {
G4cout << "G4ChordFinder 2nd Constructor called. " << G4endl;
G4cout << " Parameters: " << G4endl;
G4cout << " useFSAL stepper= " << useFSALstepper
<< " (request = " << recallFSALflag
<< " force FSAL = " << forceFSALstepper << " )" << G4endl;
}
// useHigherStepper = forceHigherEffiencyStepper || useHigherStepper;
G4Mag_EqRhs *pEquation = new G4Mag_UsualEqRhs(theMagField);
fEquation = pEquation;
fLastStepEstimate_Unconstrained = DBL_MAX; // Should move q, p to
// G4FieldTrack ??
SetFractions_Last_Next( fFractionLast, fFractionNextEstimate);
// check the values and set the other parameters
// --->> Charge Q = 0
// --->> Momentum P = 1 NOMINAL VALUES !!!!!!!!!!!!!!!!!!
// G4MagIntegratorStepper* regularStepper = nullptr;
// G4VFSALIntegrationStepper* fsalSepper = nullptr; // for new-type FSAL steppers only
// NewFsalStepperType* fsalStepper =nullptr;
// G4MagIntegratorStepper* oldFSALStepper =nullptr;
if( pItsStepper == 0 )
{
pItsStepper = fDriversStepper =
new G4ClassicalRK4(pEquation); // The old default
// new G4CashKarpRKF45(pEquation);
// new G4DormandPrince745(pEquation);
// new G4BogackiShampine45(pEquation);
G4bool errorInStepperCreation = false;
fAllocatedStepper= true;
std::ostringstream message; // In case of failure, load with description !
message << "G4ChordFinder 2nd Constructor called. " << G4endl;
if( pItsStepper != nullptr )
{
// Type is not known - so must use old class
fIntgrDriver = new G4MagInt_Driver(stepMinimum, pItsStepper,
pItsStepper->GetNumberOfVariables() );
}
else if ( !useFSALstepper )
{
// RegularStepperType* regularStepper =nullptr; // To check the exception
auto regularStepper =new RegularStepperType(pEquation);
// *** ******************
//
// Alternative - for G4NystromRK4:
// = new G4NystromRK4(pEquation, 0.1*millimeter ); // *clhep::millimeter );
fRegularStepperOwned = regularStepper;
if( regularStepper == nullptr )
{
message << " ERROR> 'Regular' RK Stepper instantiation FAILED." << G4endl;
message << "G4ChordFinder: Attempted to instantiate "
<< RegularStepperName << " type stepper " << G4endl;
errorInStepperCreation = true;
}
else
{
fIntgrDriver =
new G4MagInt_Driver(stepMinimum,
regularStepper,
regularStepper->GetNumberOfVariables() );
// ==== Create the old type of driver
// Alternative:
// new G4IntegrationDriver<RegularStepperType>(stepMinimum,
// ==== Create the driver which knows the class type
if( (fIntgrDriver==nullptr) || report ) {
message << "G4ChordFinder: Using G4IntegrationDriver with "
<< RegularStepperName << " type stepper " << G4endl;
}
if(fIntgrDriver==nullptr) {
message << " ERROR> 'Regular' RK Driver instantiation FAILED." << G4endl;
}
}
}
else
{
fAllocatedStepper= false;
auto fsalStepper= new NewFsalStepperType(pEquation);
// ******************
fNewFSALStepperOwned = fsalStepper;
// delete fsalStepper;
// /*NewFsalStepperType* */ fsalStepper =nullptr; // To check the exception
if( fsalStepper == nullptr )
{
message << " ERROR> 'FSAL' RK Stepper instantiation FAILED." << G4endl;
message << "G4ChordFinder: Attempted to instantiate "
<< NewFSALStepperName << " type stepper " << G4endl;
errorInStepperCreation = true;
}
else
{
fIntgrDriver = new
G4FSALIntegrationDriver<NewFsalStepperType>(stepMinimum,
fsalStepper,
fsalStepper->GetNumberOfVariables() );
// ==== Create the driver which knows the class type
if( (fIntgrDriver==nullptr) || report ) {
message << "G4ChordFinder: Using G4FSALIntegrationDriver with stepper type: " << G4endl
<< NewFSALStepperName << " (new-FSAL type stepper.) " << G4endl;
}
if(fIntgrDriver==nullptr) {
message << " ERROR> FSAL Integration Driver instantiation FAILED." << G4endl;
}
}
}
fIntgrDriver = new G4MagInt_Driver(stepMinimum, pItsStepper,
pItsStepper->GetNumberOfVariables() );
// -- Main work is now done
// Now check that no error occured, and report it if one did.
// To test failure to create driver
// delete fIntgrDriver;
// fIntgrDriver= nullptr;
// Detect and report Error conditions
if( errorInStepperCreation || (fIntgrDriver == nullptr ))
{
std::ostringstream errmsg;
if( errorInStepperCreation )
{
errmsg << "ERROR> Failure to create Stepper object." << G4endl
<< " --------------------------------" << G4endl;
}
if (fIntgrDriver == nullptr )
{
errmsg << "ERROR> Failure to create Integration-Driver object." << G4endl
<< " -------------------------------------------" << G4endl;
}
const std::string BoolName[2]= { "False", "True" };
errmsg << " Configuration: (constructor arguments) " << G4endl
<< " provided Stepper = " << pItsStepper << G4endl
<< " use FSAL stepper = " << BoolName[useFSALstepper]
// ( useFSALstepper ? "True" : "False" )
<< " (request = " << BoolName[recallFSALflag]
<< " force FSAL = " << BoolName[forceFSALstepper] << " )" << G4endl;
// << " use new FSAL stp = " << ( useNewFSALstepper ? "True" : "False" ) << G4endl;
errmsg << message.str();
errmsg << "Aborting.";
G4Exception("G4ChordFinder::G4ChordFinder() - constructor 2", "GeomField0003",
FatalException, errmsg);
}
else if ( report )
{
G4cout << message.str();
}
assert( ( pItsStepper != nullptr )
|| ( fRegularStepperOwned != nullptr )
|| ( fNewFSALStepperOwned != nullptr )
// || ( fOldFSALStepperOwned != nullptr )
);
assert( fIntgrDriver != nullptr );
}
@@ -119,10 +284,9 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
G4ChordFinder::~G4ChordFinder()
{
delete fEquation; // fIntgrDriver->pIntStepper->theEquation_Rhs;
if( fAllocatedStepper)
{
delete fDriversStepper;
}
delete fRegularStepperOwned;
delete fNewFSALStepperOwned;
// delete fOldFSALStepperOwned;
delete fIntgrDriver;
if( fStatsVerbose ) { PrintStatistics(); }
@@ -180,7 +344,7 @@ G4double
G4ChordFinder::AdvanceChordLimited( G4FieldTrack& yCurrent,
G4double stepMax,
G4double epsStep,
const G4ThreeVector latestSafetyOrigin,
const G4ThreeVector& latestSafetyOrigin,
G4double latestSafetyRadius )
{
G4double stepPossible;
@@ -234,6 +398,8 @@ G4ChordFinder::FindNextChord( const G4FieldTrack& yStart,
{
// Returns Length of Step taken
// G4cout << ">G4ChordFinder::FindNextChord called." << G4endl;
G4FieldTrack yCurrent= yStart;
G4double stepTrial, stepForAccuracy;
G4double dydx[G4FieldTrack::ncompSVEC];
@@ -29,7 +29,7 @@
// ..........................................................................
G4ChordFinderSaf::G4ChordFinderSaf(G4MagInt_Driver* pIntegrationDriver)
G4ChordFinderSaf::G4ChordFinderSaf(G4VIntegrationDriver* pIntegrationDriver)
: G4ChordFinder(pIntegrationDriver)
{
// check the values and set the other parameters
@@ -156,7 +156,7 @@ G4ChordFinderSaf::FindNextChord( const G4FieldTrack& yStart,
stepTrial = std::min( stepMax, likelyGood );
G4MagInt_Driver *pIntgrDriver= G4ChordFinder::GetIntegrationDriver();
auto pIntgrDriver= G4ChordFinder::GetIntegrationDriver();
G4double newStepEst_Uncons= 0.0;
G4double stepForChord= -1.0;
do
@@ -54,7 +54,7 @@ G4DoLoMcPriRK34::G4DoLoMcPriRK34(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
fAuxStepper(0)
fLastStepLength( -1.0 ), fAuxStepper( nullptr )
{
const G4int numberOfVariables = noIntegrationVariables;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4DormandPrince745.cc 101384 2016-11-16 11:03:44Z gcosmo $
// $Id: G4DormandPrince745.cc 107470 2017-11-15 07:14:28Z gcosmo $
//
// Class description:
//
@@ -117,11 +117,13 @@ G4DormandPrince745::G4DormandPrince745(G4EquationOfMotion *EqRhs,
fMidVector = new G4double[numberOfVariables];
fMidError = new G4double[numberOfVariables];
fAuxStepper = nullptr;
if( primary )
{
fAuxStepper = new G4DormandPrince745(EqRhs, numberOfVariables,
!primary);
}
fLastStepLength = -1.0;
}
//Destructor
@@ -48,9 +48,8 @@ G4DormandPrinceRK56::G4DormandPrinceRK56(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
fAuxStepper(0)
fLastStepLength(-1.0), fAuxStepper(nullptr)
{
const G4int numberOfVariables = noIntegrationVariables;
//New Chunk of memory being created for use by the stepper
@@ -64,7 +63,13 @@ G4DormandPrinceRK56::G4DormandPrinceRK56(G4EquationOfMotion *EqRhs,
ak7 = new G4double[numberOfVariables];
ak8 = new G4double[numberOfVariables];
ak9 = new G4double[numberOfVariables];
// Memory for Additional stages
ak10 = new G4double[numberOfVariables];
ak11 = new G4double[numberOfVariables];
ak12 = new G4double[numberOfVariables];
ak10_low = new G4double[numberOfVariables];
const G4int numStateVars = std::max(noIntegrationVariables, 8);
yTemp = new G4double[numStateVars];
yIn = new G4double[numStateVars] ;
@@ -96,7 +101,12 @@ G4DormandPrinceRK56::~G4DormandPrinceRK56(){
delete[] ak7;
delete[] ak8;
delete[] ak9;
delete[] ak10;
delete[] ak10_low;
delete[] ak11;
delete[] ak12;
delete[] yTemp;
delete[] yIn;
@@ -430,8 +440,6 @@ void G4DormandPrinceRK56::SetupInterpolate_low( const G4double yInput[],
b_108 = 2479.0/23040.0 ,
b_109 = 1.0/64.0 ;
ak10_low = new G4double[numberOfVariables];
for(int i=0;i<numberOfVariables;i++)
{
yIn[i]=yInput[i];
@@ -445,7 +453,6 @@ void G4DormandPrinceRK56::SetupInterpolate_low( const G4double yInput[],
b_107*ak7[i] + b_108*ak8[i] + b_109*ak9[i]);
}
RightHandSide(yTemp, ak10_low); //10th Stage
}
void G4DormandPrinceRK56::Interpolate_low( const G4double yInput[],
@@ -558,15 +565,7 @@ void G4DormandPrinceRK56::SetupInterpolate_high( const G4double yInput[],
yTemp[7] = yIn[7];
// New memory for Additional stages
if(ak10 == NULL)
ak10 = new G4double[numberOfVariables];
if(ak11 == NULL)
ak11 = new G4double[numberOfVariables];
if(ak12 == NULL)
ak12 = new G4double[numberOfVariables];
//Evaluate the extra stages :
@@ -24,23 +24,24 @@
// ********************************************************************
//
// Dormand-Prince 8(7)13M non-FSAL implementation by Somnath Banerjee
// Supported by Google as part of Google Summer of Code 2015.
// Supervision / code review: John Apostolakis
//
// Sponsored by Google in Google Summer of Code 2015.
//
// First version: 28 June 2015
//
// DormandPrinceRK78.cc
// Geant4
//
//
// Paper proposing this RK scheme:
// Title: "High order embedded Runge-Kutta formulae"
// Authors: P.J. Prince, J.R. Dormand,
// 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
// History
// http://dx.doi.org/10.1016/0771-050X(81)90010-3.
// (http://www.sciencedirect.com/science/article/pii/0771050X81900103)
//
// History (condensed)
// -----------------------------
// Created by Somnath on 28 June 2015
// 28 June 2015: First version created - S. Banerjee
// 4 July 2017: Small fixes (Coverity issues) - J. Apostolakis
#include "G4DormandPrinceRK78.hh"
#include "G4LineSection.hh"
@@ -49,7 +50,8 @@
G4DormandPrinceRK78::G4DormandPrinceRK78(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
fLastStepLength(-1.0), fAuxStepper(nullptr)
{
const G4int numberOfVariables = noIntegrationVariables;
@@ -64,13 +64,16 @@
#include "G4FSALBogackiShampine45.hh"
#include "G4LineSection.hh"
G4bool G4FSALBogackiShampine45::fPreparedConstants= false;
G4double G4FSALBogackiShampine45::bi[12][7];
//Constructor
G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables)
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables),
fLastStepLength( -1.0 ), fAuxStepper( nullptr )
{
const G4int numberOfVariables = noIntegrationVariables;
//New Chunk of memory being created for use by the stepper
@@ -87,7 +90,8 @@ G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion *EqRhs,
ak9 = new G4double[numberOfVariables];
ak10 = new G4double[numberOfVariables];
ak11 = new G4double[numberOfVariables];
DyDx = new G4double[numberOfVariables];
assert ( GetNumberOfStateVariables() >= 8 );
const G4int numStateVars = std::max(noIntegrationVariables,
GetNumberOfStateVariables() );
@@ -112,6 +116,8 @@ G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion *EqRhs,
fAuxStepper = new G4FSALBogackiShampine45(EqRhs, numberOfVariables,
!primary);
}
if( ! fPreparedConstants )
PrepareConstants();
}
@@ -125,11 +131,10 @@ G4FSALBogackiShampine45::~G4FSALBogackiShampine45(){
delete[] ak6;
delete[] ak7;
delete[] ak8;
delete[] ak9;
delete[] ak10;
delete[] ak11;
delete[] DyDx;
delete[] yTemp;
delete[] yIn;
@@ -211,8 +216,6 @@ void G4FSALBogackiShampine45::Stepper(const G4double yInput[],
const G4int numberOfVariables= this->GetNumberOfVariables();
G4double *DyDx = new G4double[numberOfVariables];
// The number of variables to be integrated over
yOut[7] = yTemp[7] = yIn[7];
// Saving yInput because yInput and yOut can be aliases for same array
@@ -339,93 +342,21 @@ G4double G4FSALBogackiShampine45::DistChord() const
return distChord;
}
// ---------------------------------------------------------------------------------------
void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
const G4double dydx[],
G4double yOut[],
G4double Step,
G4double tau
){
// G4double *ak9, *ak10, *ak11;
G4double
a91 = 455.0/6144.0 ,
a92 = 0.0 ,
a93 = 10256301.0/35409920.0 ,
a94 = 2307361.0/17971200.0 ,
a95 = -387.0/102400.0 ,
a96 = 73.0/5130.0 ,
a97 = -7267.0/215040.0 ,
a98 = 1.0/32.0 ,
a101 = -837888343715.0/13176988637184.0 ,
a102 = 30409415.0/52955362.0 ,
a103 = -48321525963.0/759168069632.0 ,
a104 = 8530738453321.0/197654829557760.0 ,
a105 = 1361640523001.0/1626788720640.0 ,
a106 = -13143060689.0/38604458898.0 ,
a107 = 18700221969.0/379584034816.0 ,
a108 = -5831595.0/847285792.0 ,
a109 = -5183640.0/26477681.0 ,
a111 = 98719073263.0/1551965184000.0 ,
a112 = 1307.0/123552.0 ,
a113 = 4632066559387.0/70181753241600.0 ,
a114 = 7828594302389.0/382182512025600.0 ,
a115 = 40763687.0/11070259200.0 ,
a116 = 34872732407.0/224610586200.0 ,
a117 = -2561897.0/30105600.0 ,
a118 = 1.0/10.0 ,
a119 = -1.0/10.0 ,
a1110 = -1403317093.0/11371610250.0 ;
// a91 = 455.e0/6144.e0 ,
// a101 = -837888343715.e0/13176988637184.e0 ,
// a111 = 98719073263.e0/1551965184000.e0 ,
// a92 = 0.e0 ,
// a102 = 30409415.e0/52955362.e0 ,
// a112 = 1307.e0/123552.e0 ,
// a93 = 10256301.e0/35409920.e0 ,
// a103 = -48321525963.e0/759168069632.e0 ,
// a113 = 4632066559387.e0/70181753241600.e0 ,
// a94 = 2307361.e0/17971200.e0 ,
// a104 = 8530738453321.e0/197654829557760.e0 ,
// a114 = 7828594302389.e0/382182512025600.e0 ,
// a95 = -387.e0/102400.e0 ,
// a105 = 1361640523001.e0/1626788720640.e0 ,
// a115 = 40763687.e0/11070259200.e0 ,
// a96 = 73.e0/5130.e0 ,
// a106 = -13143060689.e0/38604458898.e0 ,
// a116 = 34872732407.e0/224610586200.e0 ,
// a97 = -7267.e0/215040.e0 ,
// a107 = 18700221969.e0/379584034816.e0 ,
// a117 = -2561897.e0/30105600.e0 ,
// a98 = 1.e0/32.e0 ,
// a108 = -5831595.e0/847285792.e0 ,
// a118 = 1.e0/10.e0 ,
// a109 = -5183640.e0/26477681.e0 ,
// a119 = -1.e0/10.e0 ,
// a1110 = -1403317093.e0/11371610250.e0 ;
void G4FSALBogackiShampine45::PrepareConstants()
{
// --------------------------------------------------------
// COEFFICIENTS FOR INTERPOLANT bi WITH 11 STAGES
// --------------------------------------------------------
G4double bi[13][7], b[13]; //For bi[1][1] to bi[11][6] and b[1] to b[11]
for(int i=1; i<= 11; i++)
bi[i][1] = 0.0 ;
for(int i=1; i<=6; i++)
bi[2][i] = 0.0 ;
// Initialise all values of G4double bi[12][7]
for(int i=1; i<12; i++){
for(int j=1; j<7; j++){
bi[i][j] = 0.0 ;
}
}
bi[1][6] = -12134338393.0/1050809760.0 ,
bi[1][5] = -1620741229.0/50038560.0 ,
bi[1][4] = -2048058893.0/59875200.0 ,
@@ -486,80 +417,50 @@ void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
bi[11][4] = 117.0 ,
bi[11][3] = 59.0 ,
bi[11][2] = 12.0 ;
//
// for (int i = 1; i <= 11; i++) {
// bi[i][1] = 0.e0;
// }
// for (int i = 1; i <= 6; i++) {
// bi[2][i] = 0.e0;
// }
// bi[1][6] = -12134338393.e0/1050809760.e0;
// bi[1][5] = -1620741229.e0/50038560.e0;
// bi[1][4] = -2048058893.e0/59875200.e0;
// bi[1][3] = -87098480009.e0/5254048800.e0;
// bi[1][2] = -11513270273.e0/3502699200.e0;
// //C
// bi[3][6] = -33197340367.e0/1218433216.e0;
// bi[3][5] = -539868024987.e0/6092166080.e0;
// bi[3][4] = -39991188681.e0/374902528.e0;
// bi[3][3] = -69509738227.e0/1218433216.e0;
// bi[3][2] = -29327744613.e0/2436866432.e0;
// //C
// bi[4][6] = -284800997201.e0/19905339168.e0;
// bi[4][5] = -7896875450471.e0/165877826400.e0;
// bi[4][4] = -333945812879.e0/5671036800.e0;
// bi[4][3] = -16209923456237.e0/497633479200.e0;
// bi[4][2] = -2382590741699.e0/331755652800.e0;
// //C
// bi[5][6] = -540919.e0/741312.e0;
// bi[5][5] = -103626067.e0/43243200.e0;
// bi[5][4] = -633779.e0/211200.e0;
// bi[5][3] = -32406787.e0/18532800.e0;
// bi[5][2] = -36591193.e0/86486400.e0;
// //C
// bi[6][6] = 7157998304.e0/374350977.e0;
// bi[6][5] = 30405842464.e0/623918295.e0;
// bi[6][4] = 183022264.e0/5332635.e0;
// bi[6][3] = -3357024032.e0/1871754885.e0;
// bi[6][2] = -611586736.e0/89131185.e0;
// //C
// bi[7][6] = -138073.e0/9408.e0;
// bi[7][5] = -719433.e0/15680.e0;
// bi[7][4] = -1620541.e0/31360.e0;
// bi[7][3] = -385151.e0/15680.e0;
// bi[7][2] = -65403.e0/15680.e0;
// //C
// bi[8][6] = 1245.e0/64.e0;
// bi[8][5] = 3991.e0/64.e0;
// bi[8][4] = 4715.e0/64.e0;
// bi[8][3] = 2501.e0/64.e0;
// bi[8][2] = 149.e0/16.e0;
// bi[8][1] = 1.e0;
// //C
// bi[9][6] = 55.e0/3.e0;
// bi[9][5] = 71.e0;
// bi[9][4] = 103.e0;
// bi[9][3] = 199.e0/3.e0;
// bi[9][2] = 16.0e0;
// //C
// bi[10][6] = -1774004627.e0/75810735.e0;
// bi[10][5] = -1774004627.e0/25270245.e0;
// bi[10][4] = -26477681.e0/359975.e0;
// bi[10][3] = -11411880511.e0/379053675.e0;
// bi[10][2] = -423642896.e0/126351225.e0;
// //C
// bi[11][6] = 35.e0;
// bi[11][5] = 105.e0;
// bi[11][4] = 117.e0;
// bi[11][3] = 59.e0;
// bi[11][2] = 12.e0;
}
// ---------------------------------------------------------------------------------------
void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
const G4double dydx[],
G4double yOut[],
G4double Step,
G4double tau
)
{
const G4double
a91 = 455.0/6144.0 ,
a92 = 0.0 ,
a93 = 10256301.0/35409920.0 ,
a94 = 2307361.0/17971200.0 ,
a95 = -387.0/102400.0 ,
a96 = 73.0/5130.0 ,
a97 = -7267.0/215040.0 ,
a98 = 1.0/32.0 ,
a101 = -837888343715.0/13176988637184.0 ,
a102 = 30409415.0/52955362.0 ,
a103 = -48321525963.0/759168069632.0 ,
a104 = 8530738453321.0/197654829557760.0 ,
a105 = 1361640523001.0/1626788720640.0 ,
a106 = -13143060689.0/38604458898.0 ,
a107 = 18700221969.0/379584034816.0 ,
a108 = -5831595.0/847285792.0 ,
a109 = -5183640.0/26477681.0 ,
a111 = 98719073263.0/1551965184000.0 ,
a112 = 1307.0/123552.0 ,
a113 = 4632066559387.0/70181753241600.0 ,
a114 = 7828594302389.0/382182512025600.0 ,
a115 = 40763687.0/11070259200.0 ,
a116 = 34872732407.0/224610586200.0 ,
a117 = -2561897.0/30105600.0 ,
a118 = 1.0/10.0 ,
a119 = -1.0/10.0 ,
a1110 = -1403317093.0/11371610250.0 ;
const G4int numberOfVariables= this->GetNumberOfVariables();
// Saving yInput because yInput and yOut can be aliases for same array
for(int i=0;i<numberOfVariables;i++)
{
@@ -568,11 +469,8 @@ void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
// The number of variables to be integrated over
yOut[7] = yTemp[7] = yIn[7];
// calculating extra stages
for(int i=0; i<numberOfVariables; i++){
yTemp[i] = yIn[i] + Step*(a91*dydx[i] + a92*ak2[i] + a93*ak3[i] +
a94*ak4[i] + a95*ak5[i] + a96*ak6[i] +
@@ -598,7 +496,6 @@ void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
RightHandSide(yTemp, ak11);
G4double tau0 = tau;
// Calculating the polynomials :
for(int i=1; i<=11; i++){ //Here i is NOT the coordinate no. , it's stage no.
@@ -615,8 +512,7 @@ void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
b[4]*ak4[i] + b[5]*ak5[i] + b[6]*ak6[i] +
b[7]*ak7[i] + b[8]*ak8[i] + b[9]*ak9[i] +
b[10]*ak10[i] + b[11]*ak11[i] );
}
}
}
@@ -33,7 +33,6 @@
// G4FSALDormandPrince745.cc
// Geant4
//
//
// This is the source file of G4FSALDormandPrince745 class containing the
// definition of the stepper() method that evaluates one step in
// field propagation.
@@ -46,10 +45,15 @@
// 8/9 | 19372/6561 25360/2187 64448/6561 212/729
// 1 | 9017/3168 355/33 46732/5247 49/176 5103/18656
// 1 | 35/384 0 500/1113 125/192 2187/6784 11/84
// ----------f--------------------------------------------------------------
// ---------------------------------------------------------------------------
// 35/384 0 500/1113 125/192 2187/6784 11/84 0
// 5179/57600 0 7571/16695 393/640 92097/339200 187/2100 1/40
//
// Implementation by Somnath Banerjee - GSoC 2015
// Work supported by Google as part of Google Summer of Code 2015.
// Supervision / code review: John Apostolakis
//
// First version: June 2015 - Somnath Banerjee
#include "G4FSALDormandPrince745.hh"
#include "G4LineSection.hh"
@@ -59,7 +63,8 @@
G4FSALDormandPrince745::G4FSALDormandPrince745(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables){
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables)
{
const G4int numberOfVariables = noIntegrationVariables;
@@ -72,49 +77,59 @@ G4FSALDormandPrince745::G4FSALDormandPrince745(G4EquationOfMotion *EqRhs,
ak5 = new G4double[numberOfVariables];
ak6 = new G4double[numberOfVariables];
ak7 = new G4double[numberOfVariables];
// Also always allocate arrays for interpolation stages
ak8 = new G4double[numberOfVariables];
ak9 = new G4double[numberOfVariables];
yTemp = new G4double[numberOfVariables] ;
yIn = new G4double[numberOfVariables] ;
pseudoDydx_for_DistChord = new G4double[numberOfVariables];
fInitialDyDx = new G4double[numberOfVariables];
fLastInitialVector = new G4double[numberOfVariables] ;
fLastFinalVector = new G4double[numberOfVariables] ;
fLastDyDx = new G4double[numberOfVariables];
fMidVector = new G4double[numberOfVariables];
fMidError = new G4double[numberOfVariables];
fAuxStepper = nullptr;
if( primary )
{
fAuxStepper = new G4FSALDormandPrince745(EqRhs, numberOfVariables,
!primary);
}
fLastStepLength = -1.0;
}
//Destructor
G4FSALDormandPrince745::~G4FSALDormandPrince745(){
G4FSALDormandPrince745::~G4FSALDormandPrince745()
{
//clear all previously allocated memory for stepper and DistChord
delete[] ak2;
delete[] ak3;
delete[] ak4;
delete[] ak5;
delete[] ak6;
delete[] ak7;
delete[] ak2; ak2=nullptr;
delete[] ak3; ak3=nullptr;
delete[] ak4; ak4=nullptr;
delete[] ak5; ak5=nullptr;
delete[] ak6; ak6=nullptr;
delete[] ak7; ak7=nullptr;
delete[] ak8; ak8=nullptr;
delete[] ak9; ak9=nullptr;
delete[] yTemp;
delete[] yIn;
delete[] yTemp; yTemp= nullptr;
delete[] yIn; yIn= nullptr;
delete[] pseudoDydx_for_DistChord; pseudoDydx_for_DistChord= nullptr;
delete[] fInitialDyDx; fInitialDyDx= nullptr;
delete[] fLastInitialVector;
delete[] fLastFinalVector;
delete[] fLastDyDx;
delete[] fMidVector;
delete[] fMidError;
delete fAuxStepper;
delete[] pseudoDydx_for_DistChord;
delete[] fLastInitialVector; fLastInitialVector= nullptr;
delete[] fLastFinalVector; fLastFinalVector = nullptr;
delete[] fLastDyDx; fLastDyDx = nullptr;
delete[] fMidVector; fMidVector = nullptr;
delete[] fMidError; fMidError = nullptr;
delete fAuxStepper; fAuxStepper= nullptr;
}
@@ -167,73 +182,70 @@ void G4FSALDormandPrince745::Stepper(const G4double yInput[],
const G4int numberOfVariables= this->GetNumberOfVariables();
G4double *DyDx = new G4double[numberOfVariables];
// The number of variables to be integrated over
yOut[7] = yTemp[7] = yIn[7];
// Saving yInput because yInput and yOut can be aliases for same array
for(i=0;i<numberOfVariables;i++)
{
yIn[i]=yInput[i];
DyDx[i] = dydx[i];
yIn[i] = yInput[i];
fInitialDyDx[i] = dydx[i];
}
// Ensure that time is initialised - in case it is not integrated
yOut[7] = yTemp[7] = yInput[7];
// RightHandSide(yIn, DyDx) ;
// 1st Step - Not doing, getting passed
for(i=0;i<numberOfVariables;i++)
{
yTemp[i] = yIn[i] + b21*Step*DyDx[i] ;
yTemp[i] = yIn[i] + b21*Step*fInitialDyDx[i] ;
}
RightHandSide(yTemp, ak2) ; // 2nd Step
for(i=0;i<numberOfVariables;i++)
{
yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ;
yTemp[i] = yIn[i] + Step*(b31*fInitialDyDx[i] + b32*ak2[i]) ;
}
RightHandSide(yTemp, ak3) ; // 3rd Step
for(i=0;i<numberOfVariables;i++)
{
yTemp[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ;
yTemp[i] = yIn[i] + Step*(b41*fInitialDyDx[i] + b42*ak2[i] + b43*ak3[i]) ;
}
RightHandSide(yTemp, ak4) ; // 4th Step
for(i=0;i<numberOfVariables;i++)
{
yTemp[i] = yIn[i] + Step*(b51*DyDx[i] + b52*ak2[i] + b53*ak3[i] +
yTemp[i] = yIn[i] + Step*(b51*fInitialDyDx[i] + b52*ak2[i] + b53*ak3[i] +
b54*ak4[i]) ;
}
RightHandSide(yTemp, ak5) ; // 5th Step
for(i=0;i<numberOfVariables;i++)
{
yTemp[i] = yIn[i] + Step*(b61*DyDx[i] + b62*ak2[i] + b63*ak3[i] +
b64*ak4[i] + b65*ak5[i]) ;
yTemp[i] = yIn[i] + Step*(b61*fInitialDyDx[i] + b62*ak2[i] + b63*ak3[i] +
b64*ak4[i] + b65*ak5[i]) ;
}
RightHandSide(yTemp, ak6) ; // 6th Step
for(i=0;i<numberOfVariables;i++)
{
yOut[i] = yIn[i] + Step*(b71*DyDx[i] + b72*ak2[i] + b73*ak3[i] +
b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
yOut[i] = yIn[i] + Step*(b71*fInitialDyDx[i] + b72*ak2[i] + b73*ak3[i] +
b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
}
RightHandSide(yOut, ak7); //7th and Final step
for(i=0;i<numberOfVariables;i++)
{
yErr[i] = Step*(dc1*DyDx[i] + dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i] +
dc5*ak5[i] + dc6*ak6[i] + dc7*ak7[i] ) ;
yErr[i] = Step*(dc1*fInitialDyDx[i] + dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i] +
dc5*ak5[i] + dc6*ak6[i] + dc7*ak7[i] ) ;
// Store Input and Final values, for possible use in calculating chord
fLastInitialVector[i] = yIn[i] ;
fLastFinalVector[i] = yOut[i];
fLastDyDx[i] = DyDx[i];
fLastDyDx[i] = fInitialDyDx[i];
nextDydx[i] = ak7[i];
@@ -363,9 +375,6 @@ void G4FSALDormandPrince745::SetupInterpolate(const G4double yInput[],
yTemp[7] = yIn[7];
ak8 = new G4double[numberOfVariables];
ak9 = new G4double[numberOfVariables];
//Evaluate the extra stages :
for(int i=0;i<numberOfVariables;i++)
{
File diff suppressed because it is too large Load Diff
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4FieldManager.cc 104525 2017-06-02 07:22:58Z gcosmo $
// $Id: G4FieldManager.cc 107059 2017-11-01 14:58:16Z gcosmo $
//
// -------------------------------------------------------------------
@@ -156,10 +156,9 @@ void G4FieldManager::InitialiseFieldChangesEnergy()
G4bool G4FieldManager::SetDetectorField(G4Field *pDetectorField, int failMode )
{
G4MagInt_Driver* driver= 0;
G4MagIntegratorStepper* stepper=0;
G4EquationOfMotion* equation=0;
// G4bool compatibleField= false;
G4VIntegrationDriver* driver = nullptr;
G4EquationOfMotion* equation = nullptr;
// G4bool compatibleField= false;
G4bool ableToSet= false;
fDetectorField= pDetectorField;
@@ -171,16 +170,13 @@ G4bool G4FieldManager::SetDetectorField(G4Field *pDetectorField, int failMode )
{
failMode= std::max( failMode, 1) ; // If a chord finder exists, warn in case of error!
driver= fChordFinder->GetIntegrationDriver();
driver = fChordFinder->GetIntegrationDriver();
if( driver ){
stepper= driver->GetStepper();
if( stepper ){
equation= stepper->GetEquationOfMotion();
// Should check the compatibility between the field and the equation HERE
if( equation ) {
equation->SetFieldObj(pDetectorField);
ableToSet = true;
}
equation = driver->GetEquationOfMotion();
// Should check the compatibility between the field and the equation HERE
if( equation ) {
equation->SetFieldObj(pDetectorField);
ableToSet = true;
}
}
}
@@ -194,7 +190,6 @@ G4bool G4FieldManager::SetDetectorField(G4Field *pDetectorField, int failMode )
msg << "The problem encountered was the following: " << G4endl;
if( !fChordFinder ) { msg << " No ChordFinder. " ; }
else if( !driver) { msg << " No Integration Driver set. ";}
else if( !stepper ) { msg << " No Stepper found. " ; }
else if( !equation) { msg << " No Equation found. " ; }
// else if( !compatibleField ) { msg << " Field not compatible. ";}
else { msg << " Can NOT find reason for failure. ";}
@@ -0,0 +1,69 @@
// ********************************************************************
// * 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
#include "G4FieldUtils.hh"
namespace field_utils {
G4double relativeError(
const G4double y[],
const G4double yError[],
const G4double h,
const G4double errorTolerance)
{
// Accuracy for position
G4double error2 = getValue2(yError, Value3D::Position) / sqr(h);
// Accuracy for momentum
const G4double momentum2 = getValue2(y, Value3D::Momentum);
if (momentum2 > 0) {
const G4double momentumError2 =
getValue2(yError, Value3D::Momentum) / momentum2;
error2 = std::max(error2, momentumError2);
} else {
G4Exception("field_utils::relativeError","Field001",
JustWarning, "found case of zero momentum");
}
#if 0
// Accuracy for spin
const G4double spin2 = getValue2(y, Value3D::Spin);
if (spin2 > 0) {
const G4double spinError2 = getValue2(yError, Value3D::Spin) / spin2;
error2 = std::max(error2, spinError2);
}
#endif
return std::sqrt(error2) / errorTolerance;
}
} // field_utils
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4MagIntegratorDriver.cc 101384 2016-11-16 11:03:44Z gcosmo $
// $Id: G4MagIntegratorDriver.cc 107059 2017-11-01 14:58:16Z gcosmo $
//
//
//
@@ -76,7 +76,7 @@ G4MagInt_Driver::G4MagInt_Driver( G4double hminimum,
fNoVars( std::max( fNoIntegrationVariables, fMinNoVars )),
fStatisticsVerboseLevel(statisticsVerbose),
fNoTotalSteps(0), fNoBadSteps(0), fNoSmallSteps(0),
fNoInitialSmallSteps(0),
fNoInitialSmallSteps(0), fNoCalls(0),
fDyerr_max(0.0), fDyerr_mx2(0.0),
fDyerrPos_smTot(0.0), fDyerrPos_lgTot(0.0), fDyerrVel_lgTot(0.0),
fSumH_sm(0.0), fSumH_lg(0.0),
@@ -1053,3 +1053,31 @@ void G4MagInt_Driver::SetSmallestFraction(G4double newFraction)
<< " Value must be between 1.e-8 and 1.e-16" << G4endl;
}
}
void G4MagInt_Driver::GetDerivatives(const G4FieldTrack& y_curr, G4double* dydx) const
{
G4double ytemp[G4FieldTrack::ncompSVEC];
y_curr.DumpToArray(ytemp);
GetStepper()->RightHandSide(ytemp, dydx);
}
G4EquationOfMotion* G4MagInt_Driver::GetEquationOfMotion()
{
return pIntStepper->GetEquationOfMotion();
}
void G4MagInt_Driver::SetEquationOfMotion(G4EquationOfMotion *equation)
{
pIntStepper->SetEquationOfMotion(equation);
}
const G4MagIntegratorStepper* G4MagInt_Driver::GetStepper() const
{
return pIntStepper;
}
G4MagIntegratorStepper* G4MagInt_Driver::GetStepper()
{
return pIntStepper;
}
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4MagIntegratorStepper.cc 97598 2016-06-06 07:19:46Z gcosmo $
// $Id: G4MagIntegratorStepper.cc 105015 2017-07-04 11:44:23Z gcosmo $
//
// --------------------------------------------------------------------
@@ -42,8 +42,9 @@ G4MagIntegratorStepper::G4MagIntegratorStepper(G4EquationOfMotion* Equation,
: fEquation_Rhs(Equation),
fNoIntegrationVariables(num_integration_vars),
fNoStateVariables(std::max(num_state_vars,8)),
fNoRHSCalls( 0UL ),
fIntegrationOrder( -1 ), // Invalid value -- must be set by stepper !!!
fIsFSAL(isFSAL)
// , fIntegrationOrder( methodOrder )
{
}
@@ -24,15 +24,15 @@
// ********************************************************************
//
//
// $Id: G4NystromRK4.cc 66356 2012-12-18 09:02:32Z gcosmo $
// $Id: G4NystromRK4.cc 107821 2017-12-05 14:14:47Z gunter $
//
// History:
// - Created: I.Gavrilenko 15.05.2009 (as G4AtlasRK4)
// - Adaptations: J. Apostolakis May-Nov 2009
// -------------------------------------------------------------------
#include "G4NystromRK4.hh"
#include <iostream>
#include "G4NystromRK4.hh"
//////////////////////////////////////////////////////////////////
// Constructor - with optional distance ( has default value)
@@ -72,23 +72,37 @@ void
G4NystromRK4::Stepper
(const G4double P[],const G4double dPdS[],G4double Step,G4double Po[],G4double Err[])
{
G4double R[3] = { P[0], P[1] , P[2]};
const G4double perMillion = 1.0e-6;
G4double R[4] = { P[0], P[1] , P[2], P[7] }; // x, y, z, t
G4double A[3] = {dPdS[0], dPdS[1], dPdS[2]};
m_iPoint[0]=R[0]; m_iPoint[1]=R[1]; m_iPoint[2]=R[2];
const G4double one_sixth= 1./6.;
G4double S = Step ;
G4double S5 = .5*Step ;
G4double S4 = .25*Step ;
G4double S6 = Step * one_sixth; // Step / 6.;
constexpr G4double one_sixth= 1./6.;
const G4double S = Step ;
const G4double S5 = .5*Step ;
const G4double S4 = .25*Step ;
const G4double S6 = Step * one_sixth; // Step / 6.;
// Ensure that the location and cached field value are correct
getField( R );
// Ensure that the momentum is set correctly.
// John A added, in order to emulate effect of call to changed/derived RHS
// m_mom = sqrt(P[3]*P[3]+P[4]*P[4]+P[5]*P[5]);
// m_imom = 1./m_mom;
// m_cof = m_fEq->FCof()*m_imom;
// - Quick check momentum magnitude (squared) against previous value
G4double newmom2 = (P[3]*P[3]+P[4]*P[4]+P[5]*P[5]);
G4double oldmom2 = m_mom * m_mom;
if( std::fabs(newmom2 - oldmom2) > perMillion * oldmom2 ) {
m_mom = std::sqrt(newmom2) ;
m_imom = 1./m_mom;
m_cof = m_fEq->FCof()*m_imom;
}
#ifdef G4DEBUG_FIELD
CheckCachedMomemtum( P, m_mom );
CheckFieldPosition( P, m_fldPosition );
#endif
// Point 1
//
G4double K1[3] = { m_imom*dPdS[3], m_imom*dPdS[4], m_imom*dPdS[5] };
@@ -208,3 +222,51 @@ G4NystromRK4::ComputeRightHandSide(const G4double P[],G4double dPdS[])
dPdS[4] = m_cof*(P[5]*m_lastField[0]-P[3]*m_lastField[2]) ; // dPy/ds
dPdS[5] = m_cof*(P[3]*m_lastField[1]-P[4]*m_lastField[0]) ; // dPz/ds
}
////////////////////////////////////////////////////////////////////////////
// Check that the location is (almost) unmoved from 'last' field evaluation
////////////////////////////////////////////////////////////////////////////
G4bool
G4NystromRK4::CheckFieldPosition( const G4double Position[3],
const G4double lastPosition[3] )
{
G4bool ok= true;
G4double dx = Position[0] - lastPosition[0];
G4double dy = Position[1] - lastPosition[1];
G4double dz = Position[2] - lastPosition[2];
G4double distMag2 = dx*dx+dy*dy+dz*dz;
if( distMag2 > m_magdistance2) {
const G4double allowedDist = std::sqrt( m_magdistance2 );
G4double dist= std::sqrt( distMag2 );
G4cerr << " NystromRK4::Stepper> ERROR> Moved from correct field position by "
<< dist << "( larger than allowed = " << allowedDist << " ) "
<< G4endl;
ok= false;
}
return ok;
}
////////////////////////////////////////////////////
// Check magnitude of momentum against saved value
////////////////////////////////////////////////////
G4bool G4NystromRK4::CheckCachedMomemtum( const G4double PosMom[6],
G4double savedMom )
{
constexpr G4double perThousand = 1.0e-3;
G4bool ok= true;
G4double new_mom2= (PosMom[3]*PosMom[3]+PosMom[4]*PosMom[4]+PosMom[5]*PosMom[5]);
G4double new_mom= std::sqrt(new_mom2);
if( std::fabs(new_mom - savedMom ) > perThousand * savedMom ) {
G4cerr << " Nystrom::Stepper WARNING: momentum magnitude is invalid / has changed "
<< G4endl
<< " new value (p-mag) = " << new_mom << G4endl
<< " cached value (p-mag) = " << savedMom << G4endl;
if( savedMom > 0.0 ) {
G4cerr << " ratio (new/old) = " << new_mom / savedMom << G4endl;
}
ok= false;
}
return ok;
}
@@ -0,0 +1,180 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The Butcher table of the Higham & Hall 5(4)7 method is:
//
// 0 |
// 2/9 | 2/9
// 1/3 | 1/12 1/4
// 1/2 | 1/8 0 3/8
// 3/5 | 91/500 -27/100 78/125 8/125
// 1 | -11/20 27/20 12/5 -36/5 5
// 1 | 1/12 0 27/32 -4/3 125/96 5/48
//----------------------------------------------------------------------------
// 1/12 0 27/32 -4/3 125/96 5/48 0
// 2/15 0 27/80 -2/15 25/48 1/24 1/10
#include "G4RK547FEq1.hh"
#include "G4LineSection.hh"
#include "G4FieldUtils.hh"
using namespace field_utils;
namespace {
void copyArray(G4double dst[], const G4double src[])
{
memcpy(dst, src, sizeof(G4double) * G4FieldTrack::ncompSVEC);
}
} // namespace
G4RK547FEq1::G4RK547FEq1(G4EquationOfMotion* EqRhs, G4int integrationVariables)
: G4MagIntegratorStepper(EqRhs, integrationVariables)
{
}
void G4RK547FEq1::makeStep(
const G4double yInput[],
const G4double dydx[],
const G4double hstep,
G4double yOutput[],
G4double* dydxOutput,
G4double* yError) const
{
G4double yTemp[G4FieldTrack::ncompSVEC];
for (int i = GetNumberOfVariables(); i < GetNumberOfStateVariables(); ++i){
yOutput[i] = yTemp[i] = yInput[i];
}
G4double ak2[G4FieldTrack::ncompSVEC],
ak3[G4FieldTrack::ncompSVEC],
ak4[G4FieldTrack::ncompSVEC],
ak5[G4FieldTrack::ncompSVEC],
ak6[G4FieldTrack::ncompSVEC];
const G4double
b21 = 2./9.,
b31 = 1./12., b32 = 1./4.,
b41 = 1./8., b42 = 0., b43 = 3./8.,
b51 = 91./500., b52 = -27./100., b53 = 78./125., b54 = 8./125.,
b61 = -11./20., b62 = 27./20., b63 = 12./5.,
b64 = -36./5., b65 = 5.,
b71 = 1./12., b72 = 0., b73 = 27./32.,
b74 = -4./3., b75 = 125./96., b76 = 5./48.;
const G4double
dc1 = b71 - 2./15.,
dc2 = b72 - 0.,
dc3 = b73 - 27./80.,
dc4 = b74 + 2./15.,
dc5 = b75 - 25./48.,
dc6 = b76 - 1./24.,
dc7 = 0. - 1./10.;
//RightHandSide(yInput, dydx);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * b21 * dydx[i];
RightHandSide(yTemp, ak2);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b31 * dydx[i] + b32 * ak2[i]);
RightHandSide(yTemp, ak3);
for(int i = 0;i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b41 * dydx[i] + b42 * ak2[i] +
b43 * ak3[i]);
RightHandSide(yTemp, ak4);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b51 * dydx[i] + b52 * ak2[i] +
b53 * ak3[i] + b54 * ak4[i]);
RightHandSide(yTemp, ak5);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b61 * dydx[i] + b62 * ak2[i] +
b63 * ak3[i] + b64 * ak4[i] +
b65 * ak5[i]);
RightHandSide(yTemp, ak6);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yOutput[i] = yInput[i] + hstep * (b71 * dydx[i] + b72 * ak2[i] +
b73 * ak3[i] + b74 * ak4[i] +
b75 * ak5[i] + b76 * ak6[i]);
if (dydxOutput && yError) {
RightHandSide(yOutput, dydxOutput);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yError[i] = hstep * (dc1 * dydx[i] + dc2 * ak2[i] + dc3 * ak3[i] +
dc4 * ak4[i] + dc5 * ak5[i] + dc6 * ak6[i] +
dc7 * dydxOutput[i]);
}
}
void G4RK547FEq1::Stepper(
const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[])
{
copyArray(fyIn, yInput);
copyArray(fdydx, dydx);
fhstep = hstep;
makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOut, yError);
copyArray(yOutput, fyOut);
}
void G4RK547FEq1::Stepper(
const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[],
G4double dydxOutput[])
{
copyArray(fyIn, yInput);
copyArray(fdydx, dydx);
fhstep = hstep;
makeStep(fyIn,fdydx, fhstep, fyOut, fdydxOut, yError);
copyArray(yOutput, fyOut);
copyArray(dydxOutput, fdydxOut);
}
G4double G4RK547FEq1::DistChord() const
{
G4double yMid[G4FieldTrack::ncompSVEC];
makeStep(fyIn, fdydx, fhstep / 2., yMid);
const G4ThreeVector begin = makeVector(fyIn, Value3D::Position);
const G4ThreeVector mid = makeVector(yMid, Value3D::Position);
const G4ThreeVector end = makeVector(fyOut, Value3D::Position);
return G4LineSection::Distline(mid, begin, end);
}
@@ -0,0 +1,181 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The Butcher table of the Higham & Hall 5(4)7 method is:
//
// 0 |
// 2/13 | 2/13
// 2/13 | 3/52 9/52
// 5/9 | 12955/26244 -15925/8748 12350/6561
// 3/4 | -10383/52480 13923/10496 -176553/199424 505197/997120
// 1 | 1403/7236 -429/268 733330/309339 -7884/8911 104960/113967
// 1 | 181/2700 0 656903/1846800 19683/106400 34112/110565 67/800
//----------------------------------------------------------------------------------------------------------------------
// 181/2700 0 656903/1846800 19683/106400 34112/110565 67/800 0
// 11377/154575 0 35378291/105729300 343359/1522850 535952/1947645 134/17175 1/12
#include "G4RK547FEq2.hh"
#include "G4LineSection.hh"
#include "G4FieldUtils.hh"
using namespace field_utils;
namespace {
void copyArray(G4double dst[], const G4double src[])
{
memcpy(dst, src, sizeof(G4double) * G4FieldTrack::ncompSVEC);
}
} // namespace
G4RK547FEq2::G4RK547FEq2(G4EquationOfMotion* EqRhs, G4int integrationVariables)
: G4MagIntegratorStepper(EqRhs, integrationVariables)
{
}
void G4RK547FEq2::makeStep(
const G4double yInput[],
const G4double dydx[],
const G4double hstep,
G4double yOutput[],
G4double* dydxOutput,
G4double* yError) const
{
G4double yTemp[G4FieldTrack::ncompSVEC];
for (int i = GetNumberOfVariables(); i < GetNumberOfStateVariables(); ++i){
yOutput[i] = yTemp[i] = yInput[i];
}
G4double ak2[G4FieldTrack::ncompSVEC],
ak3[G4FieldTrack::ncompSVEC],
ak4[G4FieldTrack::ncompSVEC],
ak5[G4FieldTrack::ncompSVEC],
ak6[G4FieldTrack::ncompSVEC];
const G4double
b21 = 2./13.,
b31 = 3./52., b32 = 9./52.,
b41 = 12955./26244., b42 = -15925./8748., b43 = 12350./6561.,
b51 = -10383./52480., b52 = 13923./10496., b53 = -176553./199424.,
b54 = 505197./997120.,
b61 = 1403./7236., b62 = -429./268., b63 = 733330./309339.,
b64 = -7884./8911., b65 = 104960./113967.,
b71 = 181./2700., b72 = 0., b73 = 656903./1846800.,
b74 = 19683./106400., b75 = 34112./110565., b76 = 67./800.;
const G4double
dc1 = b71 - 11377./154575.,
dc2 = b72 - 0.,
dc3 = b73 - 35378291./105729300.,
dc4 = b74 - 343359./1522850.,
dc5 = b75 - 535952./1947645.,
dc6 = b76 - 134./17175.,
dc7 = 0. - 1./12.;
//RightHandSide(yInput, dydx);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * b21 * dydx[i];
RightHandSide(yTemp, ak2);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b31 * dydx[i] + b32 * ak2[i]);
RightHandSide(yTemp, ak3);
for(int i = 0;i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b41 * dydx[i] + b42 * ak2[i] +
b43 * ak3[i]);
RightHandSide(yTemp, ak4);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b51 * dydx[i] + b52 * ak2[i] +
b53 * ak3[i] + b54 * ak4[i]);
RightHandSide(yTemp, ak5);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b61 * dydx[i] + b62 * ak2[i] +
b63 * ak3[i] + b64 * ak4[i] +
b65 * ak5[i]);
RightHandSide(yTemp, ak6);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yOutput[i] = yInput[i] + hstep * (b71 * dydx[i] + b72 * ak2[i] +
b73 * ak3[i] + b74 * ak4[i] +
b75 * ak5[i] + b76 * ak6[i]);
if (dydxOutput && yError) {
RightHandSide(yOutput, dydxOutput);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yError[i] = hstep * (dc1 * dydx[i] + dc2 * ak2[i] + dc3 * ak3[i] +
dc4 * ak4[i] + dc5 * ak5[i] + dc6 * ak6[i] +
dc7 * dydxOutput[i]);
}
}
void G4RK547FEq2::Stepper(
const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[])
{
copyArray(fyIn, yInput);
copyArray(fdydx, dydx);
fhstep = hstep;
makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOut, yError);
copyArray(yOutput, fyOut);
}
void G4RK547FEq2::Stepper(
const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[],
G4double dydxOutput[])
{
copyArray(fyIn, yInput);
copyArray(fdydx, dydx);
fhstep = hstep;
makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOut, yError);
copyArray(yOutput, fyOut);
copyArray(dydxOutput, fdydxOut);
}
G4double G4RK547FEq2::DistChord() const
{
G4double yMid[G4FieldTrack::ncompSVEC];
makeStep(fyIn, fdydx, fhstep / 2., yMid);
const G4ThreeVector begin = makeVector(fyIn, Value3D::Position);
const G4ThreeVector mid = makeVector(yMid, Value3D::Position);
const G4ThreeVector end = makeVector(fyOut, Value3D::Position);
return G4LineSection::Distline(mid, begin, end);
}
@@ -0,0 +1,181 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// The Butcher table of the Higham & Hall 5(4)7 method is:
//
// 0 |
// 11/45 | 11/45
// 11/30 | 11/120 11/40
// 55/56 | 106865/87808 -408375/87808 193875/43904
// 9/10 | 79503/121000 -1053/440 147753/56870 27048/710875
// 1 | 89303/78045 -2025/473 994650/244541 -2547216/28122215 475/2967
// 1 | 1247/10890 0 57375/108053 -1229312/1962015 125/207 43/114
//---------------------------------------------------------------------------------------------------------------------
// 1247/10890 0 57375/108053 -1229312/1962015 125/207 43/114 0
// 21487/185130 0 963225/1836901 -39864832/33354255 2575/3519 4472/4845 -1/10
#include "G4RK547FEq3.hh"
#include "G4LineSection.hh"
#include "G4FieldUtils.hh"
using namespace field_utils;
namespace {
void copyArray(G4double dst[], const G4double src[])
{
memcpy(dst, src, sizeof(G4double) * G4FieldTrack::ncompSVEC);
}
} // namespace
G4RK547FEq3::G4RK547FEq3(G4EquationOfMotion* EqRhs, G4int integrationVariables)
: G4MagIntegratorStepper(EqRhs, integrationVariables)
{
}
void G4RK547FEq3::makeStep(
const G4double yInput[],
const G4double dydx[],
const G4double hstep,
G4double yOutput[],
G4double* dydxOutput,
G4double* yError) const
{
G4double yTemp[G4FieldTrack::ncompSVEC];
for (int i = GetNumberOfVariables(); i < GetNumberOfStateVariables(); ++i){
yOutput[i] = yTemp[i] = yInput[i];
}
G4double ak2[G4FieldTrack::ncompSVEC],
ak3[G4FieldTrack::ncompSVEC],
ak4[G4FieldTrack::ncompSVEC],
ak5[G4FieldTrack::ncompSVEC],
ak6[G4FieldTrack::ncompSVEC];
const G4double
b21 = 11./45.,
b31 = 11./120., b32 = 11./40.,
b41 = 106865./87808., b42 = -408375./87808., b43 = 193875./43904.,
b51 = 79503./121000., b52 = -1053./440., b53 = 147753./56870.,
b54 = 27048./710875.,
b61 = 89303./78045., b62 = -2025./473., b63 = 994650./244541.,
b64 = -2547216./28122215., b65 = 475./2967.,
b71 = 1247./10890., b72 = 0., b73 = 57375./108053.,
b74 = -1229312./1962015., b75 = 125./207., b76 = 43./114.;
const G4double
dc1 = b71 - 21487./185130.,
dc2 = b72 - 0.,
dc3 = b73 - 963225./1836901.,
dc4 = b74 + 39864832./33354255.,
dc5 = b75 - 2575./3519.,
dc6 = b76 - 4472./4845.,
dc7 = 0. + 1./10.;
//RightHandSide(yInput, dydx);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * b21 * dydx[i];
RightHandSide(yTemp, ak2);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b31 * dydx[i] + b32 * ak2[i]);
RightHandSide(yTemp, ak3);
for(int i = 0;i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b41 * dydx[i] + b42 * ak2[i] +
b43 * ak3[i]);
RightHandSide(yTemp, ak4);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b51 * dydx[i] + b52 * ak2[i] +
b53 * ak3[i] + b54 * ak4[i]);
RightHandSide(yTemp, ak5);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yTemp[i] = yInput[i] + hstep * (b61 * dydx[i] + b62 * ak2[i] +
b63 * ak3[i] + b64 * ak4[i] +
b65 * ak5[i]);
RightHandSide(yTemp, ak6);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yOutput[i] = yInput[i] + hstep * (b71 * dydx[i] + b72 * ak2[i] +
b73 * ak3[i] + b74 * ak4[i] +
b75 * ak5[i] + b76 * ak6[i]);
if (dydxOutput && yError) {
RightHandSide(yOutput, dydxOutput);
for(int i = 0; i < GetNumberOfVariables(); ++i)
yError[i] = hstep * (dc1 * dydx[i] + dc2 * ak2[i] + dc3 * ak3[i] +
dc4 * ak4[i] + dc5 * ak5[i] + dc6 * ak6[i] +
dc7 * dydxOutput[i]);
}
}
void G4RK547FEq3::Stepper(
const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[])
{
copyArray(fyIn, yInput);
copyArray(fdydx, dydx);
fhstep = hstep;
makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOut, yError);
copyArray(yOutput, fyOut);
}
void G4RK547FEq3::Stepper(
const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[],
G4double dydxOutput[])
{
copyArray(fyIn, yInput);
copyArray(fdydx, dydx);
fhstep = hstep;
makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOut, yError);
copyArray(yOutput, fyOut);
copyArray(dydxOutput, fdydxOut);
}
G4double G4RK547FEq3::DistChord() const
{
G4double yMid[G4FieldTrack::ncompSVEC];
makeStep(fyIn, fdydx, fhstep / 2., yMid);
const G4ThreeVector begin = makeVector(fyIn, Value3D::Position);
const G4ThreeVector mid = makeVector(yMid, Value3D::Position);
const G4ThreeVector end = makeVector(fyOut, Value3D::Position);
return G4LineSection::Distline(mid, begin, end);
}
@@ -55,7 +55,7 @@ G4TsitourasRK45::G4TsitourasRK45(G4EquationOfMotion *EqRhs,
fLastStepLength(0.), fAuxStepper(0)
{
const G4int numberOfVariables = noIntegrationVariables;
G4cout << "G4TsitourasRK45 constructor called." << G4endl;
// G4cout << "G4TsitourasRK45 constructor called." << G4endl;
ak2 = new G4double[numberOfVariables] ;
ak3 = new G4double[numberOfVariables] ;
@@ -35,7 +35,8 @@ G4VFSALIntegrationStepper::G4VFSALIntegrationStepper(G4EquationOfMotion* Equatio
G4int num_state_vars)
: fEquation_Rhs(Equation),
fNoIntegrationVariables(num_integration_vars),
fNoStateVariables(num_state_vars)
fNoStateVariables(num_state_vars),
fNoRHSCalls(0)
// fNumberOfVariables( std::max(num_var,fNoStateVariables) )
{
}