Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BFieldIntegrationDriver implementation
|
||||
//
|
||||
// Specialized integration driver for pure magnetic field
|
||||
//
|
||||
// Author: D.Sorokin
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BFieldIntegrationDriver.hh"
|
||||
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4FieldUtils.hh"
|
||||
#include "G4Exception.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "templates.hh"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
G4Mag_EqRhs* toMagneticEquation(G4EquationOfMotion* equation)
|
||||
{
|
||||
auto e = dynamic_cast<G4Mag_EqRhs*>(equation);
|
||||
|
||||
if (!e)
|
||||
{
|
||||
G4Exception("G4BFieldIntegrationDriver::G4BFieldIntegrationDriver",
|
||||
"GeomField0003", FatalErrorInArgument,
|
||||
"Works only with G4Mag_EqRhs");
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
G4BFieldIntegrationDriver::G4BFieldIntegrationDriver(
|
||||
std::unique_ptr<G4VIntegrationDriver> smallStepDriver,
|
||||
std::unique_ptr<G4VIntegrationDriver> largeStepDriver)
|
||||
: fSmallStepDriver(std::move(smallStepDriver)),
|
||||
fLargeStepDriver(std::move(largeStepDriver)),
|
||||
fCurrDriver(fSmallStepDriver.get()),
|
||||
fEquation(toMagneticEquation(fCurrDriver->GetEquationOfMotion()))
|
||||
{
|
||||
if (fSmallStepDriver->GetEquationOfMotion()
|
||||
!= fLargeStepDriver->GetEquationOfMotion())
|
||||
{
|
||||
G4Exception("G4BFieldIntegrationDriver Constructor:",
|
||||
"GeomField1001", FatalException, "different EoM");
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4BFieldIntegrationDriver::AdvanceChordLimited(G4FieldTrack& yCurrent,
|
||||
G4double stepMax,
|
||||
G4double epsStep,
|
||||
G4double chordDistance)
|
||||
{
|
||||
const G4double radius = CurvatureRadius(yCurrent);
|
||||
|
||||
G4VIntegrationDriver* driver = nullptr;
|
||||
if (chordDistance < 2 * radius)
|
||||
{
|
||||
stepMax = std::min(stepMax, twopi * radius);
|
||||
driver = fSmallStepDriver.get();
|
||||
++fSmallDriverSteps;
|
||||
} else
|
||||
{
|
||||
driver = fLargeStepDriver.get();
|
||||
++fLargeDriverSteps;
|
||||
}
|
||||
|
||||
if (driver != fCurrDriver)
|
||||
{
|
||||
driver->OnComputeStep();
|
||||
}
|
||||
|
||||
fCurrDriver = driver;
|
||||
|
||||
return fCurrDriver->AdvanceChordLimited(yCurrent, stepMax,
|
||||
epsStep, chordDistance);
|
||||
}
|
||||
|
||||
void
|
||||
G4BFieldIntegrationDriver::SetEquationOfMotion(G4EquationOfMotion* equation)
|
||||
{
|
||||
fEquation = toMagneticEquation(equation);
|
||||
fSmallStepDriver->SetEquationOfMotion(equation);
|
||||
fLargeStepDriver->SetEquationOfMotion(equation);
|
||||
}
|
||||
|
||||
G4double
|
||||
G4BFieldIntegrationDriver::CurvatureRadius(const G4FieldTrack& track) const
|
||||
{
|
||||
G4double field[G4Field::MAX_NUMBER_OF_COMPONENTS];
|
||||
|
||||
GetFieldValue(track, field);
|
||||
|
||||
const G4double Bmag2 = field[0] * field[0]
|
||||
+ field[1] * field[1]
|
||||
+ field[2] * field[2] ;
|
||||
if (Bmag2 == 0.0 )
|
||||
{
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
const G4double momentum2 = track.GetMomentum().mag2();
|
||||
const G4double fCof_inv = eplus / std::abs(fEquation->FCof());
|
||||
|
||||
return std::sqrt(momentum2 / Bmag2) * fCof_inv;
|
||||
}
|
||||
|
||||
void
|
||||
G4BFieldIntegrationDriver::GetFieldValue(const G4FieldTrack& track,
|
||||
G4double Field[] ) const
|
||||
{
|
||||
G4ThreeVector pos= track.GetPosition();
|
||||
G4double positionTime[4]= { pos.x(), pos.y(), pos.z(),
|
||||
track.GetLabTimeOfFlight() } ;
|
||||
|
||||
fEquation->GetFieldValue(positionTime, Field);
|
||||
}
|
||||
|
||||
void G4BFieldIntegrationDriver::PrintStatistics() const
|
||||
{
|
||||
const auto totSteps = fSmallDriverSteps + fLargeDriverSteps;
|
||||
const auto toFraction = [&](double value) { return value / totSteps * 100; };
|
||||
|
||||
G4cout << "============= G4BFieldIntegrationDriver statistics ===========\n"
|
||||
<< "total steps " << totSteps << " "
|
||||
<< "smallDriverSteps " << toFraction(fSmallDriverSteps) << " "
|
||||
<< "largeDriverSteps " << toFraction(fLargeDriverSteps) << "\n"
|
||||
<< "======================================\n";
|
||||
}
|
||||
@@ -23,41 +23,28 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Bogacki-Shampine - 4 - 3(2) non-FSAL implementation by Somnath Banerjee
|
||||
// Supervision / code review: John Apostolakis
|
||||
// G4BogackiShampine23 implementation
|
||||
//
|
||||
// Somnath's work was sponsored by Google as part of the Google Summer of
|
||||
// Code 2015, as part of the CERN / SFT organisation.p
|
||||
// ===================================================================
|
||||
// Bogacki-Shampine - 4 - 3(2) non-FSAL implementation
|
||||
//
|
||||
// Implementation of the method proposed in the publication
|
||||
// “A 3(2) pair of Runge - Kutta formulas,”
|
||||
// by P. Bogacki and L. F. Shampine,
|
||||
// Appl. Math. Lett., vol. 2, no. 4, pp. 321–325, Jan. 1989.
|
||||
// "A 3(2) pair of Runge - Kutta formulas"
|
||||
// by P. Bogacki and L. F. Shampine,
|
||||
// Appl. Math. Lett., vol. 2, no. 4, pp. 321-325, Jan. 1989.
|
||||
//
|
||||
// First version: 20 May 2015
|
||||
// The Bogacki shampine method has the following Butcher's tableau
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath Banerjee on 20 May 2015
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This contains the stepper function of the G4BogackiShampine23 class
|
||||
|
||||
The Bogacki shampine method has the following Butcher's tableau
|
||||
|
||||
0 |
|
||||
1/2|1/2
|
||||
3/4|0 3/4
|
||||
1 |2/9 1/3 4/9
|
||||
-------------------
|
||||
|2/9 1/3 4/9 0
|
||||
|7/24 1/4 1/3 1/8
|
||||
|
||||
*/
|
||||
// 0 |
|
||||
// 1/2|1/2
|
||||
// 3/4|0 3/4
|
||||
// 1 |2/9 1/3 4/9
|
||||
// -------------------
|
||||
// |2/9 1/3 4/9 0
|
||||
// |7/24 1/4 1/3 1/8
|
||||
//
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 20 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BogackiShampine23.hh"
|
||||
#include "G4LineSection.hh"
|
||||
@@ -66,10 +53,9 @@ The Bogacki shampine method has the following Butcher's tableau
|
||||
using namespace field_utils;
|
||||
|
||||
G4BogackiShampine23::G4BogackiShampine23(G4EquationOfMotion* EqRhs,
|
||||
G4int integrationVariables):
|
||||
G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
G4int integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
{
|
||||
|
||||
SetIntegrationOrder(3);
|
||||
SetFSAL(true);
|
||||
}
|
||||
@@ -83,38 +69,47 @@ void G4BogackiShampine23::makeStep(const G4double yInput[],
|
||||
{
|
||||
|
||||
G4double yTemp[G4FieldTrack::ncompSVEC];
|
||||
for(G4int i = GetNumberOfVariables(); i < GetNumberOfStateVariables(); ++i)
|
||||
for(G4int i = GetNumberOfVariables(); i < GetNumberOfStateVariables(); ++i)
|
||||
{
|
||||
yOutput[i] = yTemp[i] = yInput[i];
|
||||
|
||||
}
|
||||
|
||||
G4double ak2[G4FieldTrack::ncompSVEC],
|
||||
ak3[G4FieldTrack::ncompSVEC];
|
||||
|
||||
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 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 = - 1.0 / 8.0;
|
||||
const G4double dc1 = b41 - 7.0 / 24.0, dc2 = b42 - 1.0 / 4.0,
|
||||
dc3 = b43 - 1.0 / 3.0, dc4 = - 1.0 / 8.0;
|
||||
|
||||
// RightHandSide(yInput, dydx);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yTemp[i] = yInput[i] + b21 * hstep * dydx[i];
|
||||
// RightHandSide(yInput, dydx);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
{
|
||||
yTemp[i] = yInput[i] + b21 * hstep * dydx[i];
|
||||
}
|
||||
|
||||
RightHandSide(yTemp, ak2);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yTemp[i] = yInput[i] + hstep * (b31 * dydx[i] + b32 * ak2[i]);
|
||||
RightHandSide(yTemp, ak2);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
{
|
||||
yTemp[i] = yInput[i] + hstep * (b31 * dydx[i] + b32 * ak2[i]);
|
||||
}
|
||||
|
||||
RightHandSide(yTemp, ak3);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yOutput[i] = yInput[i] + hstep * (b41 * dydx[i] + b42 * ak2[i] + b43 * ak3[i]);
|
||||
RightHandSide(yTemp, ak3);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
{
|
||||
yOutput[i] = yInput[i] + hstep * (b41*dydx[i] + b42*ak2[i] + b43*ak3[i]);
|
||||
}
|
||||
|
||||
if (dydxOutput && yError) {
|
||||
RightHandSide(yOutput, dydxOutput);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yError[i] = hstep * (dc1 * dydx[i] + dc2 * ak2[i] +
|
||||
dc3 * ak3[i] + dc4 * dydxOutput[i]);
|
||||
|
||||
if (dydxOutput && yError)
|
||||
{
|
||||
RightHandSide(yOutput, dydxOutput);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
{
|
||||
yError[i] = hstep * (dc1 * dydx[i] + dc2 * ak2[i] +
|
||||
dc3 * ak3[i] + dc4 * dydxOutput[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,29 +23,17 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Bogacki-Shampine's RK 5(4) non-FSAL implementation by Somnath Banerjee
|
||||
// Supervision / code review: John Apostolakis
|
||||
// G4BogackiShampine45 implementation
|
||||
//
|
||||
// Somnath's work was sponsored by Google as part of the Google Summer of
|
||||
// Code 2015, as part of the CERN / SFT organisation.p
|
||||
//
|
||||
// First version: 25 May 2015
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath Banerjee on May-August 2015
|
||||
// Improvements by John Apostolakis, May 2016
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This is the source file of G4BogackiShampine45 class containing the
|
||||
// definition of the stepper() method that evaluates one step in
|
||||
// Bogacki-Shampine's RK 5(4) non-FSAL interpolation method
|
||||
// Definition of the stepper() method that evaluates one step in
|
||||
// field propagation.
|
||||
//
|
||||
// The Butcher table of the Bogacki-Shampine-8-4-5 method is:
|
||||
//
|
||||
// 0 |
|
||||
// 1/6 | 1/6
|
||||
// 2/9 | 2/27 4/27
|
||||
// 2/9 | 2/27 4/27
|
||||
// 3/7 | 183/1372 -162/343 1053/1372
|
||||
// 2/3 | 68/297 -4/11 42/143 1960/3861
|
||||
// 3/4 | 597/22528 81/352 63099/585728 58653/366080 4617/20480
|
||||
@@ -55,39 +43,40 @@
|
||||
// 587/8064 0 4440339/15491840 24353/124800 387/44800 2152/5985 7267/94080 0
|
||||
// 2479/34992 0 123/416 612941/3411720 43/1440 2272/6561 79937/1113912 3293/556956
|
||||
//
|
||||
// Do NOT re-indent the lines above - their meaning becomes lost
|
||||
// ********************************
|
||||
// Coefficients have been obtained from rksuite.f : http://www.netlib.org/ode/rksuite/
|
||||
|
||||
// Note on meaning of label "non-FSAL version":
|
||||
// This method calculates the deriviative dy/dx at the endpoint of the integration interval at each step.
|
||||
// as part of its evaluation of the endpoint and its error.
|
||||
// So this value is available to be returned, for re-use in case of a successful step.
|
||||
// ( This is done in a 'later' version using a refined interface. )
|
||||
// Coefficients have been obtained from:
|
||||
// http://www.netlib.org/ode/rksuite/
|
||||
//
|
||||
// Note on meaning of label "non-FSAL version":
|
||||
// This method calculates the deriviative dy/dx at the endpoint of the
|
||||
// integration interval at each step, as part of its evaluation of the
|
||||
// endpoint and its error. So this value is available to be returned,
|
||||
// for re-use in case of a successful step.
|
||||
// (This is done in a 'later' version using a refined interface).
|
||||
//
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, May-August 2015
|
||||
// Revision: John Apostolakis, CERN, May 2016
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "G4BogackiShampine45.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
G4bool G4BogackiShampine45::fPreparedConstants= false;
|
||||
G4bool G4BogackiShampine45::fPreparedConstants = false;
|
||||
G4double G4BogackiShampine45::bi[12][7];
|
||||
|
||||
//Constructor
|
||||
// Constructor
|
||||
//
|
||||
G4BogackiShampine45::G4BogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength(-1.0),
|
||||
fAuxStepper(nullptr),
|
||||
fPreparedInterpolation(false)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
|
||||
//New Chunk of memory being created for use by the stepper
|
||||
// New Chunk of memory being created for use by the stepper
|
||||
|
||||
//aki - for storing intermediate RHS
|
||||
// aki - for storing intermediate RHS
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
@@ -99,8 +88,9 @@ G4BogackiShampine45::G4BogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
ak10 = new G4double[numberOfVariables];
|
||||
ak11 = new G4double[numberOfVariables];
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
p[i]= new G4double[numberOfVariables];
|
||||
for (auto i = 0; i < 6; ++i)
|
||||
{
|
||||
p[i]= new G4double[numberOfVariables];
|
||||
}
|
||||
|
||||
assert ( GetNumberOfStateVariables() >= 8 );
|
||||
@@ -115,11 +105,13 @@ G4BogackiShampine45::G4BogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
fLastFinalVector = new G4double[numStateVars] ;
|
||||
fLastDyDx = new G4double[numberOfVariables]; // Only derivatives
|
||||
|
||||
fMidVector = new G4double[numberOfVariables]; // new G4double[numStateVars];
|
||||
fMidError = new G4double[numberOfVariables]; // new G4double[numStateVars];
|
||||
|
||||
fMidVector = new G4double[numberOfVariables];
|
||||
fMidError = new G4double[numberOfVariables];
|
||||
|
||||
if( ! fPreparedConstants )
|
||||
{
|
||||
PrepareConstants();
|
||||
}
|
||||
|
||||
if( primary )
|
||||
{
|
||||
@@ -127,56 +119,55 @@ G4BogackiShampine45::G4BogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
//
|
||||
G4BogackiShampine45::~G4BogackiShampine45()
|
||||
{
|
||||
// Clear all previously allocated memory for stepper and DistChord
|
||||
//
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
delete [] ak7;
|
||||
delete [] ak8;
|
||||
delete [] ak9;
|
||||
delete [] ak10;
|
||||
delete [] ak11;
|
||||
|
||||
//Destructor
|
||||
G4BogackiShampine45::~G4BogackiShampine45(){
|
||||
//clear all previously allocated memory for stepper and DistChord
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
delete[] ak7;
|
||||
delete[] ak8;
|
||||
delete[] ak9;
|
||||
delete[] ak10;
|
||||
delete[] ak11;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
delete[] p[i];
|
||||
for (auto i = 0; i < 6; ++i)
|
||||
{
|
||||
delete [] p[i];
|
||||
}
|
||||
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
}
|
||||
|
||||
// G4double* G4BogackiShampine45::getLastDydx(){
|
||||
// return ak8;
|
||||
// }
|
||||
|
||||
void
|
||||
G4BogackiShampine45::GetLastDydx( G4double dyDxLast[] )
|
||||
void G4BogackiShampine45::GetLastDydx( G4double dyDxLast[] )
|
||||
{
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
for(G4int i=0; i < numberOfVariables; i++ ){
|
||||
for(G4int i=0; i < numberOfVariables; ++i )
|
||||
{
|
||||
dyDxLast[i] = ak9[i];
|
||||
}
|
||||
}
|
||||
|
||||
//Stepper :
|
||||
|
||||
// Stepper
|
||||
//
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4BogackiShampine45::Stepper( const G4double yInput[],
|
||||
const G4double DyDx[],
|
||||
G4double Step,
|
||||
@@ -186,6 +177,7 @@ void G4BogackiShampine45::Stepper( const G4double yInput[],
|
||||
G4int i;
|
||||
|
||||
// Constants from the Butcher tableu
|
||||
//
|
||||
const G4double
|
||||
b21 = 1.0/6.0 ,
|
||||
b31 = 2.0/27.0 , b32 = 4.0/27.0,
|
||||
@@ -221,6 +213,7 @@ void G4BogackiShampine45::Stepper( const G4double yInput[],
|
||||
// taken and is used directly later (instead of defining the last row
|
||||
// of Butcher table in separate constants and taking the
|
||||
// difference)
|
||||
//
|
||||
const G4double
|
||||
dc1 = b81 - 2479.0 / 34992.0 ,
|
||||
dc2 = 0.0,
|
||||
@@ -231,73 +224,76 @@ void G4BogackiShampine45::Stepper( const G4double yInput[],
|
||||
dc7 = b87 - 79937.0 / 1113912.0,
|
||||
dc8 = - 3293.0 / 556956.0;
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// The number of variables to be integrated over
|
||||
//
|
||||
yOut[7] = yTemp[7] = yIn[7] = yInput[7];
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
// RightHandSide(yIn, dydx) ;
|
||||
// 1st Step - Not doing, getting passed
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*DyDx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*DyDx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b71*DyDx[i] + b72*ak2[i] + b73*ak3[i] +
|
||||
b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak7); //7th Step
|
||||
RightHandSide(yTemp, ak7); // 7th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b81*DyDx[i] + b82*ak2[i] + b83*ak3[i] +
|
||||
b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
|
||||
b87*ak7[i]);
|
||||
}
|
||||
RightHandSide(yOut, ak8); //8th Step - Final one Using FSAL
|
||||
RightHandSide(yOut, ak8); // 8th Step - Final one Using FSAL
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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] + dc8*ak8[i]) ;
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = DyDx[i];
|
||||
@@ -309,48 +305,51 @@ void G4BogackiShampine45::Stepper( const G4double yInput[],
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
//The following has not been tested
|
||||
|
||||
//The DistChord() function fot the class - must define it here.
|
||||
G4double G4BogackiShampine45::DistChord() const
|
||||
// DistChord
|
||||
//
|
||||
G4double G4BogackiShampine45::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector(fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
finalPoint = G4ThreeVector(fLastFinalVector[0],
|
||||
fLastFinalVector[1], fLastFinalVector[2]);
|
||||
|
||||
#if 1
|
||||
// Old method -- Do half a step using StepNoErr
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
|
||||
fMidVector, fMidError);
|
||||
//
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5*fLastStepLength,
|
||||
fMidVector, fMidError);
|
||||
#else
|
||||
// New method -- Using interpolation, requires only 3 extra stages (ie 3 extra field evaluations )
|
||||
// New method -- Using interpolation,
|
||||
// requires only 3 extra stages (ie 3 extra field evaluations )
|
||||
|
||||
// Use Interpolation, instead of auxiliary stepper to evaluate midpoint
|
||||
if( ! fPreparedInterpolation ) {
|
||||
G4BogackiShampine45 *cThis= const_cast<G4BogackiShampine45 *>(this);
|
||||
cThis-> SetupInterpolationHigh(); // ( fLastInitialVector, fLastDyDx, fLastStepLength );
|
||||
//
|
||||
if( ! fPreparedInterpolation )
|
||||
{
|
||||
G4BogackiShampine45* cThis = const_cast<G4BogackiShampine45 *>(this);
|
||||
cThis-> SetupInterpolationHigh();
|
||||
}
|
||||
//For calculating the output at the tau fraction of Step
|
||||
// For calculating the output at the tau fraction of Step
|
||||
//
|
||||
G4double tau = 0.5;
|
||||
// cThis->InterpolateHigh( /* fLastInitialVector, fLastDyDx, fLastStepLength, */, fMidVector, tau);
|
||||
// Old arguments: ( /*yInput, dydx, step,*/ yOut, tau );
|
||||
this->InterpolateHigh( tau, fMidVector );
|
||||
InterpolateHigh( tau, fMidVector );
|
||||
#endif
|
||||
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
// distance of Chord
|
||||
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distLine = G4LineSection::Distline( midPoint,initialPoint,finalPoint );
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
@@ -361,9 +360,9 @@ G4double G4BogackiShampine45::DistChord() const
|
||||
}
|
||||
|
||||
void G4BogackiShampine45::SetupInterpolationHigh()
|
||||
// ( const G4double *yInput, const G4double *dydx, const G4double Step)
|
||||
{
|
||||
//Coefficients for the additional stages :
|
||||
// Coefficients for the additional stages
|
||||
//
|
||||
const G4double
|
||||
a91 = 455.0/6144.0 ,
|
||||
a92 = 0.0 ,
|
||||
@@ -396,46 +395,50 @@ void G4BogackiShampine45::SetupInterpolationHigh()
|
||||
a1110 = -1403317093.0/11371610250.0 ;
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
|
||||
// const G4double *yIn= fLastInitialVector;
|
||||
const G4double *dydx= fLastDyDx;
|
||||
const G4double* dydx= fLastDyDx;
|
||||
const G4double Step = fLastStepLength;
|
||||
|
||||
yTemp[7] = yIn[7];
|
||||
|
||||
//Evaluate the extra stages :
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
// Evaluate the extra stages
|
||||
//
|
||||
for(G4int 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] +
|
||||
a97*ak7[i] + a98*ak8[i] );
|
||||
}
|
||||
|
||||
RightHandSide(yTemp, ak9); //9th stage
|
||||
RightHandSide(yTemp, ak9); // 9th stage
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(a101*dydx[i] + a102*ak2[i] + a103*ak3[i] +
|
||||
a104*ak4[i] + a105*ak5[i] + a106*ak6[i] +
|
||||
a107*ak7[i] + a108*ak8[i] + a109*ak9[i] );
|
||||
}
|
||||
|
||||
RightHandSide(yTemp, ak10); //10th stage
|
||||
RightHandSide(yTemp, ak10); // 10th stage
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(a111*dydx[i] + a112*ak2[i] + a113*ak3[i] +
|
||||
a114*ak4[i] + a115*ak5[i] + a116*ak6[i] +
|
||||
a117*ak7[i] + a118*ak8[i] + a119*ak9[i] +
|
||||
a1110*ak10[i] );
|
||||
}
|
||||
RightHandSide(yTemp, ak11); //11th stage
|
||||
RightHandSide(yTemp, ak11); // 11th stage
|
||||
|
||||
// In future we can restrict the number of variables interpolated
|
||||
int nwant = numberOfVariables;
|
||||
//
|
||||
G4int nwant = numberOfVariables;
|
||||
|
||||
// Form the coefficients of the interpolating polynomial in its shifted
|
||||
// and scaled form. The terms are grouped to minimize the errors
|
||||
// of the transformation, to cope with ill-conditioning. ( From RKSUITE )
|
||||
//
|
||||
for (int l = 0; l < nwant; l++) {
|
||||
// Form the coefficients of the interpolating polynomial in its shifted
|
||||
// and scaled form. The terms are grouped to minimize the errors
|
||||
// of the transformation, to cope with ill-conditioning. ( From RKSUITE )
|
||||
//
|
||||
for (G4int l = 0; l < nwant; ++l)
|
||||
{
|
||||
// Coefficient of tau^6
|
||||
p[5][l] = bi[5][6]*ak5[l] +
|
||||
((bi[10][6]*ak10[l] + bi[8][6]*ak8[l]) +
|
||||
@@ -467,25 +470,31 @@ void G4BogackiShampine45::SetupInterpolationHigh()
|
||||
bi[10][2]*ak10[l])+ ((bi[4][2]*ak4[l] +
|
||||
bi[11][2]*ak2[l]) + bi[7][2]*ak7[l]);
|
||||
}
|
||||
//
|
||||
// Scale all the coefficients by the step size.
|
||||
//
|
||||
for (int i = 0; i < 6; i++) {
|
||||
for (int l = 0; l < nwant; l++) {
|
||||
|
||||
// Scale all the coefficients by the step size.
|
||||
//
|
||||
for (G4int i = 0; i < 6; ++i)
|
||||
{
|
||||
for (G4int l = 0; l < nwant; ++l)
|
||||
{
|
||||
p[i][l] *= Step;
|
||||
}
|
||||
}
|
||||
|
||||
fPreparedInterpolation= true;
|
||||
fPreparedInterpolation = true;
|
||||
}
|
||||
|
||||
void G4BogackiShampine45::PrepareConstants()
|
||||
{
|
||||
for(int i=1; i<= 11; i++)
|
||||
for(auto i=1; i<= 11; ++i)
|
||||
{
|
||||
bi[i][1] = 0.0 ;
|
||||
}
|
||||
|
||||
for(int i=1; i<=6; i++)
|
||||
for(auto i=1; i<=6; ++i)
|
||||
{
|
||||
bi[2][i] = 0.0 ;
|
||||
}
|
||||
|
||||
bi[1][6] = -12134338393.0 / 1050809760.0 ,
|
||||
bi[1][5] = -1620741229.0 / 50038560.0 ,
|
||||
@@ -547,61 +556,68 @@ void G4BogackiShampine45::PrepareConstants()
|
||||
bi[11][4] = 117.0 ,
|
||||
bi[11][3] = 59.0 ,
|
||||
bi[11][2] = 12.0 ;
|
||||
fPreparedConstants= true;
|
||||
|
||||
fPreparedConstants = true;
|
||||
}
|
||||
|
||||
void G4BogackiShampine45::InterpolateHigh(G4double tau, G4double *yOut) const
|
||||
// ( const G4double *yInput, const G4double *dydx, const G4double Step, G4double *yOut, G4double tau)
|
||||
void G4BogackiShampine45::InterpolateHigh(G4double tau, G4double* yOut) const
|
||||
{
|
||||
G4int numberOfVariables = this->GetNumberOfVariables();
|
||||
assert( fPreparedConstants);
|
||||
G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
G4Exception("G4BogackiShampine45::InterpolateHigh()", "GeomField0001",
|
||||
FatalException, "Method is not yet validated.");
|
||||
FatalException, "Method is not yet validated.");
|
||||
|
||||
// const G4double *yIn= fLastInitialVector;
|
||||
// const G4double *dydx= fLastDyDx;
|
||||
const G4double Step = fLastStepLength;
|
||||
|
||||
// for(G4int i = 0; i< numberOfVariables; i++) yIn[i] = yInput[i];
|
||||
#if 1
|
||||
G4int nwant = numberOfVariables;
|
||||
const G4int norder= 6;
|
||||
G4int l, k;
|
||||
|
||||
for (l = 0; l < nwant; l++) {
|
||||
for (l = 0; l < nwant; ++l)
|
||||
{
|
||||
yOut[l] = p[norder-1][l] * tau;
|
||||
}
|
||||
for (k = norder - 2; k >= 1; k--) {
|
||||
for (l = 0; l < nwant; l++) {
|
||||
for (k = norder - 2; k >= 1; --k)
|
||||
{
|
||||
for (l = 0; l < nwant; ++l)
|
||||
{
|
||||
yOut[l] = ( yOut[l] + p[k][l] ) * tau;
|
||||
}
|
||||
}
|
||||
for (l = 0; l < nwant; l++) {
|
||||
for (l = 0; l < nwant; ++l)
|
||||
{
|
||||
yOut[l] = ( yOut[l] + Step * ak8[l] ) * tau + yIn[l];
|
||||
}
|
||||
// The derivative at the end-point is nextDydx[i] = ak8[i];
|
||||
#else
|
||||
// The scheme tries to do the same as the DormandPrince745 routine, but fails
|
||||
// The scheme tries to do the same as the DormandPrince745 routine,
|
||||
// but fails
|
||||
|
||||
G4double b[12];
|
||||
const G4double *dydx= fLastDyDx;
|
||||
const G4double* dydx = fLastDyDx;
|
||||
|
||||
G4double tau0 = tau;
|
||||
|
||||
for(int iStage=1; iStage<=11; iStage++){ // iStage = stage number
|
||||
for(G4int iStage=1; iStage<=11; ++iStage) // iStage = stage number
|
||||
{
|
||||
b[iStage] = 0.0;
|
||||
tau = tau0;
|
||||
for(int j=6; j>=1; j--){ // j reversed
|
||||
for(G4int j=6; j>=1; --j) // j reversed
|
||||
{
|
||||
b[iStage] += bi[iStage][j] * tau;
|
||||
tau *= tau0;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
yOut[i] = yIn[i] + Step*(b[1] * dydx[i] + b[2] * ak2[i] + b[3] * ak3[i] +
|
||||
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] );
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b[1]*dydx[i] + b[2]*ak2[i] + b[3]*ak3[i] +
|
||||
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] );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -22,14 +22,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4BulirschStoer class implementation
|
||||
// Based on bulirsch_stoer.hpp from boost
|
||||
//
|
||||
// Author: Dmitry Sorokin - GSoC 2016
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BulirschStoer.hh"
|
||||
|
||||
|
||||
@@ -23,29 +23,25 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4CachedMagneticField implementation
|
||||
//
|
||||
//
|
||||
// Author: J.Apostolakis, 20 July 2009.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4CachedMagneticField.hh"
|
||||
|
||||
G4CachedMagneticField::G4CachedMagneticField(G4MagneticField *pMagField,
|
||||
G4double distance)
|
||||
: G4MagneticField(),
|
||||
fLastLocation(DBL_MAX,DBL_MAX,DBL_MAX),
|
||||
fLastValue(DBL_MAX,DBL_MAX,DBL_MAX),
|
||||
fCountCalls(0), fCountEvaluations(0)
|
||||
G4CachedMagneticField::G4CachedMagneticField(G4MagneticField* pMagField,
|
||||
G4double distance)
|
||||
: G4MagneticField(), fpMagneticField(pMagField), fDistanceConst(distance),
|
||||
fLastLocation(DBL_MAX,DBL_MAX,DBL_MAX), fLastValue(DBL_MAX,DBL_MAX,DBL_MAX)
|
||||
{
|
||||
fpMagneticField= pMagField;
|
||||
fDistanceConst= distance;
|
||||
|
||||
// G4cout << " Cached-B-Field constructor> Distance = " << distance << G4endl;
|
||||
this->ClearCounts();
|
||||
ClearCounts();
|
||||
}
|
||||
|
||||
G4Field* G4CachedMagneticField::Clone() const
|
||||
{
|
||||
// Cannot use copy constructor: I need to clone the associated magnetic field
|
||||
// Cannot use copy constructor: need to clone the associated magnetic field
|
||||
|
||||
G4MagneticField* aF = static_cast<G4MagneticField*>(fpMagneticField->Clone());
|
||||
G4CachedMagneticField* cloned = new G4CachedMagneticField(aF, fDistanceConst);
|
||||
|
||||
@@ -62,54 +58,53 @@ void
|
||||
G4CachedMagneticField::ReportStatistics()
|
||||
{
|
||||
G4cout << " Cached field: " << G4endl
|
||||
<< " Number of calls: " << fCountCalls << G4endl
|
||||
<< " Number of evaluations : " << fCountEvaluations << G4endl;
|
||||
<< " Number of calls: " << fCountCalls << G4endl
|
||||
<< " Number of evaluations : " << fCountEvaluations << G4endl;
|
||||
}
|
||||
|
||||
G4CachedMagneticField::G4CachedMagneticField(const G4CachedMagneticField &rightCMF)
|
||||
G4CachedMagneticField::
|
||||
G4CachedMagneticField(const G4CachedMagneticField& rightCMF)
|
||||
: G4MagneticField(rightCMF)
|
||||
{
|
||||
fpMagneticField= rightCMF.fpMagneticField; // NOTE: sharing pointer here!
|
||||
fDistanceConst = rightCMF.fDistanceConst;
|
||||
fLastLocation = rightCMF.fLastLocation;
|
||||
fLastValue = rightCMF.fLastValue;
|
||||
this->ClearCounts();
|
||||
ClearCounts();
|
||||
}
|
||||
|
||||
G4CachedMagneticField& G4CachedMagneticField::operator = (const G4CachedMagneticField &p)
|
||||
G4CachedMagneticField&
|
||||
G4CachedMagneticField::operator = (const G4CachedMagneticField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
if (&p == this) { return *this; }
|
||||
G4MagneticField::operator=(p);
|
||||
fpMagneticField= p.fpMagneticField; // NOTE: sharing pointer here!
|
||||
fDistanceConst = p.fDistanceConst;
|
||||
fLastLocation = p.fLastLocation;
|
||||
fLastValue = p.fLastValue;
|
||||
this->ClearCounts();
|
||||
ClearCounts();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
G4CachedMagneticField::GetFieldValue( const G4double Point[4],
|
||||
G4double *Bfield ) const
|
||||
G4double* Bfield ) const
|
||||
{
|
||||
G4ThreeVector newLocation( Point[0], Point[1], Point[2] );
|
||||
|
||||
// G4cout << "Cache-B-field called at " << newLocation << G4endl;
|
||||
|
||||
G4double distSq= (newLocation-fLastLocation).mag2();
|
||||
fCountCalls++;
|
||||
if( distSq < fDistanceConst*fDistanceConst ) {
|
||||
++fCountCalls;
|
||||
if( distSq < fDistanceConst*fDistanceConst )
|
||||
{
|
||||
Bfield[0] = fLastValue.x();
|
||||
Bfield[1] = fLastValue.y();
|
||||
Bfield[2] = fLastValue.z();
|
||||
}else{
|
||||
// G4CachedMagneticField* thisNonC= const_cast<G4CachedMagneticField*>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
fpMagneticField->GetFieldValue( Point, Bfield );
|
||||
// G4cout << " Evaluating. " << G4endl;
|
||||
fCountEvaluations++;
|
||||
// thisNonC->
|
||||
fLastLocation= G4ThreeVector( Point[0], Point[1], Point[2] );
|
||||
// thisNonC->
|
||||
fLastValue= G4ThreeVector( Bfield[0], Bfield[1], Bfield[2] );
|
||||
++fCountEvaluations;
|
||||
fLastLocation = G4ThreeVector( Point[0], Point[1], Point[2] );
|
||||
fLastValue = G4ThreeVector( Bfield[0], Bfield[1], Bfield[2] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// G4CashKarpRKF45 implementation
|
||||
//
|
||||
// The Cash-Karp Runge-Kutta-Fehlberg 4/5 method is an embedded fourth
|
||||
// order method (giving fifth-order accuracy) for the solution of an ODE.
|
||||
@@ -32,8 +32,9 @@
|
||||
// It is used to integrate the equations of the motion of a particle
|
||||
// in a magnetic field.
|
||||
//
|
||||
// [ref. Numerical Recipes in C, 2nd Edition]
|
||||
// [ref. Numerical Recipes in C, 2nd Edition]
|
||||
//
|
||||
// Authors: J.Apostolakis, V.Grichine - 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4CashKarpRKF45.hh"
|
||||
@@ -42,12 +43,11 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
|
||||
//
|
||||
G4CashKarpRKF45::G4CashKarpRKF45(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength(0.), fAuxStepper(0)
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables =
|
||||
std::max( noIntegrationVariables,
|
||||
@@ -85,23 +85,23 @@ G4CashKarpRKF45::G4CashKarpRKF45(G4EquationOfMotion *EqRhs,
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4CashKarpRKF45::~G4CashKarpRKF45()
|
||||
{
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
// delete[] ak7;
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
// delete [] ak7;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ G4CashKarpRKF45::~G4CashKarpRKF45()
|
||||
// return an estimate of the local truncation error yErr[] using the
|
||||
// embedded 4th-order method. The user supplies routine
|
||||
// RightHandSide(y,dydx), which returns derivatives dydx for y .
|
||||
|
||||
//
|
||||
void
|
||||
G4CashKarpRKF45::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
@@ -125,100 +125,99 @@ G4CashKarpRKF45::Stepper(const G4double yInput[],
|
||||
{
|
||||
// const G4int nvar = 6 ;
|
||||
// const G4double a2 = 0.2 , a3 = 0.3 , a4 = 0.6 , a5 = 1.0 , a6 = 0.875;
|
||||
G4int i;
|
||||
G4int i;
|
||||
|
||||
const G4double b21 = 0.2 ,
|
||||
b31 = 3.0/40.0 , b32 = 9.0/40.0 ,
|
||||
b41 = 0.3 , b42 = -0.9 , b43 = 1.2 ,
|
||||
const G4double b21 = 0.2 ,
|
||||
b31 = 3.0/40.0 , b32 = 9.0/40.0 ,
|
||||
b41 = 0.3 , b42 = -0.9 , b43 = 1.2 ,
|
||||
|
||||
b51 = -11.0/54.0 , b52 = 2.5 , b53 = -70.0/27.0 ,
|
||||
b54 = 35.0/27.0 ,
|
||||
b51 = -11.0/54.0 , b52 = 2.5 , b53 = -70.0/27.0 ,
|
||||
b54 = 35.0/27.0 ,
|
||||
|
||||
b61 = 1631.0/55296.0 , b62 = 175.0/512.0 ,
|
||||
b63 = 575.0/13824.0 , b64 = 44275.0/110592.0 ,
|
||||
b65 = 253.0/4096.0 ,
|
||||
b61 = 1631.0/55296.0 , b62 = 175.0/512.0 ,
|
||||
b63 = 575.0/13824.0 , b64 = 44275.0/110592.0 ,
|
||||
b65 = 253.0/4096.0 ,
|
||||
|
||||
c1 = 37.0/378.0 , c3 = 250.0/621.0 , c4 = 125.0/594.0 ,
|
||||
c6 = 512.0/1771.0 ,
|
||||
dc5 = -277.0/14336.0 ;
|
||||
c1 = 37.0/378.0 , c3 = 250.0/621.0 , c4 = 125.0/594.0 ,
|
||||
c6 = 512.0/1771.0 , dc5 = -277.0/14336.0 ;
|
||||
|
||||
const G4double dc1 = c1 - 2825.0/27648.0 , dc3 = c3 - 18575.0/48384.0 ,
|
||||
dc4 = c4 - 13525.0/55296.0 , dc6 = c6 - 0.25 ;
|
||||
const G4double dc1 = c1 - 2825.0/27648.0 , dc3 = c3 - 18575.0/48384.0 ,
|
||||
dc4 = c4 - 13525.0/55296.0 , dc6 = c6 - 0.25 ;
|
||||
|
||||
// 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.]
|
||||
yOut[7] = yTemp[7] = yIn[7] = yInput[7];
|
||||
// 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.]
|
||||
yOut[7] = yTemp[7] = yIn[7] = yInput[7];
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
// The number of variables to be integrated over
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
// The number of variables to be integrated over
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
// RightHandSide(yIn, dydx) ; // 1st Step
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
// RightHandSide(yIn, dydx) ; // 1st Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*dydx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Step
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*dydx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
{
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*dydx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Step
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
{
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*dydx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th Step
|
||||
}
|
||||
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] +
|
||||
b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th Step
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*dydx[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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th 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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
{
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
// Accumulate increments with proper weights
|
||||
|
||||
//
|
||||
yOut[i] = yIn[i] + Step*(c1*dydx[i] + c3*ak3[i] + c4*ak4[i] + c6*ak6[i]) ;
|
||||
|
||||
// Estimate error as difference between 4th and
|
||||
// 5th order methods
|
||||
|
||||
yErr[i] = Step*(dc1*dydx[i] + dc3*ak3[i] + dc4*ak4[i] +
|
||||
dc5*ak5[i] + dc6*ak6[i]) ;
|
||||
// Estimate error as difference between 4th and 5th order methods
|
||||
//
|
||||
yErr[i] = Step*(dc1*dydx[i]
|
||||
+ dc3*ak3[i] + dc4*ak4[i] + dc5*ak5[i] + dc6*ak6[i]) ;
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = dydx[i];
|
||||
}
|
||||
// NormaliseTangentVector( yOut ); // Not wanted
|
||||
}
|
||||
// NormaliseTangentVector( yOut ); // Not wanted
|
||||
|
||||
fLastStepLength =Step;
|
||||
fLastStepLength = Step;
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
void
|
||||
G4CashKarpRKF45::StepWithEst( const G4double*,
|
||||
const G4double*,
|
||||
@@ -235,29 +234,30 @@ G4CashKarpRKF45::StepWithEst( const G4double*,
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
G4double G4CashKarpRKF45::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
fLastFinalVector[1], fLastFinalVector[2]);
|
||||
|
||||
// Do half a step using StepNoErr
|
||||
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
|
||||
fMidVector, fMidError );
|
||||
//
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx,
|
||||
0.5 * fLastStepLength, fMidVector, fMidError );
|
||||
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
// distance of Chord
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
@@ -269,5 +269,3 @@ G4double G4CashKarpRKF45::DistChord() const
|
||||
}
|
||||
return distChord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,13 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ChargeState implementation
|
||||
//
|
||||
// History
|
||||
// - First version: Apr 10, 2013 John Apostolakis, Peter Gumplinger
|
||||
// - Modified:
|
||||
//
|
||||
//
|
||||
//
|
||||
// Authors: J.Apostolakis, P.Gumplinger - 10 April 2013
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ChargeState.hh"
|
||||
@@ -39,8 +35,8 @@ void G4ChargeState::SetChargeSpinMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double electric_dipole_moment,
|
||||
G4double magnetic_charge )
|
||||
// Revise the charge and potentially all moments.
|
||||
// By default do not change mdm, edm, mag charge.
|
||||
// Revise the charge and potentially all moments.
|
||||
// By default do not change mdm, edm, mag charge.
|
||||
{
|
||||
fCharge = charge;
|
||||
fSpin = spin;
|
||||
|
||||
@@ -23,10 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ChordFinder implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// 25.02.97 - John Apostolakis - Design and implementation
|
||||
// Author: J.Apostolakis - Design and implementation - 25.02.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include <iomanip>
|
||||
@@ -55,21 +54,19 @@
|
||||
#include "G4InterpolationDriver.hh"
|
||||
// #include "G4FSALBogackiShampine45.hh"
|
||||
// #include "G4FSALDormandPrince745.hh"
|
||||
#include "G4HelixHeum.hh"
|
||||
#include "G4BFieldIntegrationDriver.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
// ..........................................................................
|
||||
|
||||
G4ChordFinder::G4ChordFinder(G4VIntegrationDriver* pIntegrationDriver)
|
||||
: fDefaultDeltaChord( 0.25 * mm ), // Parameters
|
||||
fDeltaChord( fDefaultDeltaChord ), // Internal parameters
|
||||
fStatsVerbose(0),
|
||||
fRegularStepperOwned(nullptr), // Dependent objects
|
||||
fEquation(0)
|
||||
: fDefaultDeltaChord(0.25 * mm), fIntgrDriver(pIntegrationDriver)
|
||||
{
|
||||
// Simple constructor -- it does not create equation
|
||||
fIntgrDriver= pIntegrationDriver;
|
||||
|
||||
fDeltaChord = fDefaultDeltaChord; // Parameters
|
||||
}
|
||||
|
||||
|
||||
@@ -77,22 +74,20 @@ G4ChordFinder::G4ChordFinder(G4VIntegrationDriver* pIntegrationDriver)
|
||||
|
||||
G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
G4double stepMinimum,
|
||||
G4MagIntegratorStepper* pItsStepper, // nullptr is default
|
||||
G4bool useFSALstepper ) // false by default
|
||||
: fDefaultDeltaChord( 0.25 * mm ), // Constants
|
||||
fDeltaChord( fDefaultDeltaChord ), // Parameters
|
||||
fStatsVerbose(0),
|
||||
// fRegularStepperOwned(nullptr), // Dependent objects
|
||||
fEquation(0)
|
||||
G4MagIntegratorStepper* pItsStepper,
|
||||
G4bool useFSALstepper )
|
||||
: fDefaultDeltaChord(0.25 * mm)
|
||||
{
|
||||
// Construct the Chord Finder
|
||||
// by creating in inverse order the Driver, the Stepper and EqRhs ...
|
||||
// Construct the Chord Finder
|
||||
// by creating in inverse order the Driver, the Stepper and EqRhs ...
|
||||
|
||||
fDeltaChord = fDefaultDeltaChord; // Parameters
|
||||
|
||||
using NewFsalStepperType = G4RK547FEq1; // or 2 or 3
|
||||
const char* NewFSALStepperName =
|
||||
"G4RK574FEq1> FSAL 4th/5th order 7-stage 'Equilibrium-type' #1.";
|
||||
using RegularStepperType =
|
||||
G4DormandPrince745; // DOPRI5 (MatLab) 5th order embedded method. High efficiency.
|
||||
G4DormandPrince745; // 5th order embedded method. High efficiency.
|
||||
// G4ClassicalRK4; // The old default
|
||||
// G4CashKarpRKF45; // First embedded method in G4
|
||||
// G4BogackiShampine45; // High efficiency 5th order embedded method
|
||||
@@ -104,7 +99,7 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
// "Nystrom stepper 4th order";
|
||||
|
||||
// Configurable
|
||||
G4bool forceFSALstepper= false; // Choice - true to enable !!
|
||||
G4bool forceFSALstepper = false; // Choice - true to enable !!
|
||||
G4bool recallFSALflag = useFSALstepper;
|
||||
useFSALstepper = forceFSALstepper || useFSALstepper;
|
||||
|
||||
@@ -118,12 +113,11 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
|
||||
// useHigherStepper = forceHigherEffiencyStepper || useHigherStepper;
|
||||
|
||||
G4Mag_EqRhs *pEquation = new G4Mag_UsualEqRhs(theMagField);
|
||||
G4Mag_EqRhs* pEquation = new G4Mag_UsualEqRhs(theMagField);
|
||||
fEquation = pEquation;
|
||||
|
||||
// G4MagIntegratorStepper* regularStepper = nullptr;
|
||||
// G4VFSALIntegrationStepper* fsalSepper = nullptr; // for new-type FSAL steppers only
|
||||
// NewFsalStepperType* fsalStepper = nullptr;
|
||||
// G4VFSALIntegrationStepper* fsalStepper = nullptr; // for FSAL steppers only
|
||||
// G4MagIntegratorStepper* oldFSALStepper = nullptr;
|
||||
|
||||
G4bool errorInStepperCreation = false;
|
||||
@@ -138,12 +132,12 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
}
|
||||
else if ( !useFSALstepper )
|
||||
{
|
||||
// RegularStepperType* regularStepper =nullptr; // To check the exception
|
||||
// RegularStepperType* regularStepper = nullptr; // To check the exception
|
||||
auto regularStepper = new RegularStepperType(pEquation);
|
||||
// *** ******************
|
||||
// *** ******************
|
||||
//
|
||||
// Alternative - for G4NystromRK4:
|
||||
// = new G4NystromRK4(pEquation, 0.1*millimeter ); // *clhep::millimeter );
|
||||
// = new G4NystromRK4(pEquation, 0.1*mm );
|
||||
fRegularStepperOwned = regularStepper;
|
||||
|
||||
if( regularStepper == nullptr )
|
||||
@@ -157,12 +151,20 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
}
|
||||
else
|
||||
{
|
||||
fIntgrDriver = new G4IntegrationDriver<RegularStepperType>(
|
||||
stepMinimum, regularStepper, regularStepper->GetNumberOfVariables());
|
||||
using SmallStepDriver = G4InterpolationDriver<G4DormandPrince745>;
|
||||
using LargeStepDriver = G4IntegrationDriver<G4HelixHeum>;
|
||||
|
||||
fLongStepper = std::unique_ptr<G4HelixHeum>(new G4HelixHeum(pEquation));
|
||||
|
||||
if( fIntgrDriver==nullptr)
|
||||
fIntgrDriver = new G4BFieldIntegrationDriver(
|
||||
std::unique_ptr<SmallStepDriver>(new SmallStepDriver(stepMinimum,
|
||||
regularStepper, regularStepper->GetNumberOfVariables())),
|
||||
std::unique_ptr<LargeStepDriver>(new LargeStepDriver(stepMinimum,
|
||||
fLongStepper.get(), regularStepper->GetNumberOfVariables())) );
|
||||
|
||||
if( fIntgrDriver == nullptr)
|
||||
{
|
||||
message << "Using G4IntegrationDriver with "
|
||||
message << "Using G4BFieldIntegrationDriver with "
|
||||
<< RegularStepperName << " type stepper " << G4endl;
|
||||
message << "Driver instantiation FAILED." << G4endl;
|
||||
G4Exception("G4ChordFinder::G4ChordFinder()",
|
||||
@@ -173,7 +175,7 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
else
|
||||
{
|
||||
auto fsalStepper= new NewFsalStepperType(pEquation);
|
||||
// ******************
|
||||
// *** ******************
|
||||
fNewFSALStepperOwned = fsalStepper;
|
||||
|
||||
if( fsalStepper == nullptr )
|
||||
@@ -188,12 +190,11 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
else
|
||||
{
|
||||
fIntgrDriver = new
|
||||
G4FSALIntegrationDriver<NewFsalStepperType>(stepMinimum,
|
||||
fsalStepper,
|
||||
fsalStepper->GetNumberOfVariables() );
|
||||
G4FSALIntegrationDriver<NewFsalStepperType>(stepMinimum, fsalStepper,
|
||||
fsalStepper->GetNumberOfVariables() );
|
||||
// ==== Create the driver which knows the class type
|
||||
|
||||
if( fIntgrDriver==nullptr )
|
||||
if( fIntgrDriver == nullptr )
|
||||
{
|
||||
message << "Using G4FSALIntegrationDriver with stepper type: "
|
||||
<< NewFSALStepperName << G4endl;
|
||||
@@ -210,9 +211,10 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
|
||||
// To test failure to create driver
|
||||
// delete fIntgrDriver;
|
||||
// fIntgrDriver= nullptr;
|
||||
// fIntgrDriver = nullptr;
|
||||
|
||||
// Detect and report Error conditions
|
||||
//
|
||||
if( errorInStepperCreation || (fIntgrDriver == nullptr ))
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
@@ -224,24 +226,27 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
}
|
||||
if (fIntgrDriver == nullptr )
|
||||
{
|
||||
errmsg << "ERROR> Failure to create Integration-Driver object." << G4endl
|
||||
<< " -------------------------------------------" << G4endl;
|
||||
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]
|
||||
<< " (request = " << BoolName[recallFSALflag]
|
||||
<< " force FSAL = " << BoolName[forceFSALstepper] << " )" << G4endl;
|
||||
<< " force FSAL = " << BoolName[forceFSALstepper] << " )"
|
||||
<< G4endl;
|
||||
errmsg << message.str();
|
||||
errmsg << "Aborting.";
|
||||
G4Exception("G4ChordFinder::G4ChordFinder() - constructor 2",
|
||||
"GeomField0003", FatalException, errmsg);
|
||||
}
|
||||
|
||||
assert( ( pItsStepper != nullptr )
|
||||
assert( ( pItsStepper != nullptr )
|
||||
|| ( fRegularStepperOwned != nullptr )
|
||||
|| ( fNewFSALStepperOwned != nullptr )
|
||||
|| ( fNewFSALStepperOwned != nullptr )
|
||||
);
|
||||
assert( fIntgrDriver != nullptr );
|
||||
}
|
||||
@@ -251,11 +256,11 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
|
||||
G4ChordFinder::~G4ChordFinder()
|
||||
{
|
||||
delete fEquation;
|
||||
delete fRegularStepperOwned;
|
||||
delete fNewFSALStepperOwned;
|
||||
delete fCachedField;
|
||||
delete fIntgrDriver;
|
||||
delete fEquation;
|
||||
delete fRegularStepperOwned;
|
||||
delete fNewFSALStepperOwned;
|
||||
delete fCachedField;
|
||||
delete fIntgrDriver;
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
@@ -267,7 +272,7 @@ G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
|
||||
const G4ThreeVector& CurrentE_Point,
|
||||
const G4ThreeVector& CurrentF_Point,
|
||||
const G4ThreeVector& PointG,
|
||||
G4bool first, G4double eps_step)
|
||||
G4bool first, G4double eps_step)
|
||||
{
|
||||
// ApproxCurvePointS is 2nd implementation of ApproxCurvePoint.
|
||||
// Use Brent Algorithm (or InvParabolic) when possible.
|
||||
@@ -279,7 +284,7 @@ G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
|
||||
// relative accuracy of each Step.
|
||||
|
||||
G4FieldTrack EndPoint(CurveA_PointVelocity);
|
||||
if(!first){EndPoint= ApproxCurveV;}
|
||||
if(!first) { EndPoint = ApproxCurveV; }
|
||||
|
||||
G4ThreeVector Point_A,Point_B;
|
||||
Point_A=CurveA_PointVelocity.GetPosition();
|
||||
@@ -308,14 +313,13 @@ G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
|
||||
yc=-(Point_B-PointG).mag();
|
||||
if(xb==0.)
|
||||
{
|
||||
EndPoint=
|
||||
ApproxCurvePointV(CurveA_PointVelocity, CurveB_PointVelocity,
|
||||
CurrentE_Point, eps_step);
|
||||
EndPoint = ApproxCurvePointV(CurveA_PointVelocity, CurveB_PointVelocity,
|
||||
CurrentE_Point, eps_step);
|
||||
return EndPoint;
|
||||
}
|
||||
}
|
||||
|
||||
const G4double tolerance= 1.e-12;
|
||||
const G4double tolerance = 1.e-12;
|
||||
if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance)
|
||||
{
|
||||
; // What to do for the moment: return the same point as at start
|
||||
@@ -332,10 +336,10 @@ G4ChordFinder::ApproxCurvePointS( const G4FieldTrack& CurveA_PointVelocity,
|
||||
}
|
||||
else
|
||||
{
|
||||
test_step=(test_step-xb);
|
||||
test_step = test_step - xb;
|
||||
curve=std::abs(EndPoint.GetCurveLength()
|
||||
-CurveB_PointVelocity.GetCurveLength());
|
||||
xb=(CurrentF_Point-Point_B).mag();
|
||||
xb = (CurrentF_Point-Point_B).mag();
|
||||
}
|
||||
|
||||
if(test_step<=0) { test_step=0.1*xb; }
|
||||
@@ -396,7 +400,7 @@ ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
|
||||
curve_length= CurveB_PointVelocity.GetCurveLength()
|
||||
- CurveA_PointVelocity.GetCurveLength();
|
||||
|
||||
G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
|
||||
G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step );
|
||||
if( curve_length < ABdist * (1. - integrationInaccuracyLimit) )
|
||||
{
|
||||
#ifdef G4DEBUG_FIELD
|
||||
@@ -424,7 +428,7 @@ ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
|
||||
// curve_length = ABdist;
|
||||
}
|
||||
|
||||
G4double new_st_length;
|
||||
G4double new_st_length;
|
||||
|
||||
if ( ABdist > 0.0 )
|
||||
{
|
||||
@@ -460,7 +464,7 @@ ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
|
||||
AE_fraction = 0.5; // Default value
|
||||
}
|
||||
|
||||
new_st_length= AE_fraction * curve_length;
|
||||
new_st_length = AE_fraction * curve_length;
|
||||
|
||||
if ( AE_fraction > 0.0 )
|
||||
{
|
||||
@@ -478,7 +482,4 @@ ApproxCurvePointV( const G4FieldTrack& CurveA_PointVelocity,
|
||||
return Current_PointVelocity;
|
||||
}
|
||||
|
||||
|
||||
// ...........................................................................
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ClassicalRK4 implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis, V.Grichine - 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ClassicalRK4.hh"
|
||||
@@ -33,7 +34,7 @@
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor sets the number of variables (default = 6)
|
||||
|
||||
//
|
||||
G4ClassicalRK4::
|
||||
G4ClassicalRK4(G4EquationOfMotion* EqRhs, G4int numberOfVariables)
|
||||
: G4MagErrorStepper(EqRhs, numberOfVariables)
|
||||
@@ -48,12 +49,12 @@ G4ClassicalRK4(G4EquationOfMotion* EqRhs, G4int numberOfVariables)
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4ClassicalRK4::~G4ClassicalRK4()
|
||||
{
|
||||
delete[] dydxm;
|
||||
delete[] dydxt;
|
||||
delete[] yt;
|
||||
delete [] dydxm;
|
||||
delete [] dydxt;
|
||||
delete [] yt;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -65,16 +66,16 @@ G4ClassicalRK4::~G4ClassicalRK4()
|
||||
// array from y. The user supplies the routine RightHandSide(x,y,dydx),
|
||||
// which returns derivatives dydx at x. The source is routine rk4 from
|
||||
// NRC p. 712-713 .
|
||||
|
||||
//
|
||||
void
|
||||
G4ClassicalRK4::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4ClassicalRK4::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
{
|
||||
const G4int nvar = this->GetNumberOfVariables(); // fNumberOfVariables();
|
||||
const G4int nvar = GetNumberOfVariables(); // fNumberOfVariables();
|
||||
G4int i;
|
||||
G4double hh = h*0.5 , h6 = h/6.0 ;
|
||||
G4double hh = h*0.5, h6 = h/6.0;
|
||||
|
||||
// Initialise time to t0, needed when it is not updated by the integration.
|
||||
// [ Note: Only for time dependent fields (usually electric)
|
||||
@@ -82,26 +83,26 @@ G4ClassicalRK4::DumbStepper( const G4double yIn[],
|
||||
yt[7] = yIn[7];
|
||||
yOut[7] = yIn[7];
|
||||
|
||||
for(i=0;i<nvar;i++)
|
||||
for(i=0; i<nvar; ++i)
|
||||
{
|
||||
yt[i] = yIn[i] + hh*dydx[i] ; // 1st Step K1=h*dydx
|
||||
}
|
||||
RightHandSide(yt,dydxt) ; // 2nd Step K2=h*dydxt
|
||||
|
||||
for(i=0;i<nvar;i++)
|
||||
for(i=0; i<nvar; ++i)
|
||||
{
|
||||
yt[i] = yIn[i] + hh*dydxt[i] ;
|
||||
}
|
||||
RightHandSide(yt,dydxm) ; // 3rd Step K3=h*dydxm
|
||||
|
||||
for(i=0;i<nvar;i++)
|
||||
for(i=0; i<nvar; ++i)
|
||||
{
|
||||
yt[i] = yIn[i] + h*dydxm[i] ;
|
||||
yt[i] = yIn[i] + h*dydxm[i] ;
|
||||
dydxm[i] += dydxt[i] ; // now dydxm=(K2+K3)/h
|
||||
}
|
||||
RightHandSide(yt,dydxt) ; // 4th Step K4=h*dydxt
|
||||
|
||||
for(i=0;i<nvar;i++) // Final RK4 output
|
||||
for(i=0; i<nvar; ++i) // Final RK4 output
|
||||
{
|
||||
yOut[i] = yIn[i]+h6*(dydx[i]+dydxt[i]+2.0*dydxm[i]); //+K1/6+K4/6+(K2+K3)/3
|
||||
}
|
||||
@@ -127,4 +128,3 @@ G4ClassicalRK4::StepWithEst( const G4double*,
|
||||
FatalException, "Method no longer used.");
|
||||
|
||||
} // end of StepWithEst ......................................................
|
||||
|
||||
|
||||
@@ -23,10 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ConstRK4 implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// - 18.09.2008 - J.Apostolakis, T.Nikitina - Created
|
||||
// Created: J.Apostolakis, T.Nikitina - 18.09.2008
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ConstRK4.hh"
|
||||
@@ -37,7 +36,7 @@
|
||||
//
|
||||
// Constructor sets the number of *State* variables (default = 8)
|
||||
// The number of variables integrated is always 6
|
||||
|
||||
//
|
||||
G4ConstRK4::G4ConstRK4(G4Mag_EqRhs* EqRhs, G4int numStateVariables)
|
||||
: G4MagErrorStepper(EqRhs, 6, numStateVariables)
|
||||
{
|
||||
@@ -87,11 +86,11 @@ G4ConstRK4::~G4ConstRK4()
|
||||
// array from y. The user supplies the routine RightHandSide(x,y,dydx),
|
||||
// which returns derivatives dydx at x. The source is routine rk4 from
|
||||
// NRC p. 712-713 .
|
||||
|
||||
void G4ConstRK4::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
//
|
||||
void G4ConstRK4::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
{
|
||||
G4double hh = h*0.5 , h6 = h/6.0 ;
|
||||
|
||||
@@ -151,7 +150,7 @@ G4ConstRK4::Stepper( const G4double yInput[],
|
||||
G4double yError [] )
|
||||
{
|
||||
const G4int nvar = 6; // number of variables integrated
|
||||
const G4int maxvar= GetNumberOfStateVariables();
|
||||
const G4int maxvar = GetNumberOfStateVariables();
|
||||
|
||||
// Correction for Richardson extrapolation
|
||||
G4double correction = 1. / ( (1 << IntegratorOrder()) -1 );
|
||||
@@ -159,10 +158,10 @@ G4ConstRK4::Stepper( const G4double yInput[],
|
||||
G4int i;
|
||||
|
||||
// Saving yInput because yInput and yOutput can be aliases for same array
|
||||
for (i=0; i<maxvar; i++) { yInitial[i]= yInput[i]; }
|
||||
for (i=0; i<maxvar; ++i) { yInitial[i]= yInput[i]; }
|
||||
|
||||
// Must copy the part of the state *not* integrated to the output
|
||||
for (i=nvar; i<maxvar; i++) { yOutput[i]= yInput[i]; }
|
||||
for (i=nvar; i<maxvar; ++i) { yOutput[i]= yInput[i]; }
|
||||
|
||||
// yInitial[7]= yInput[7]; // The time is typically needed
|
||||
yMiddle[7] = yInput[7]; // Copy the time from initial value
|
||||
@@ -186,7 +185,7 @@ G4ConstRK4::Stepper( const G4double yInput[],
|
||||
// Do a full Step
|
||||
//
|
||||
DumbStepper(yInitial, dydx, hstep, yOneStep);
|
||||
for(i=0;i<nvar;i++)
|
||||
for(i=0; i<nvar; ++i)
|
||||
{
|
||||
yError [i] = yOutput[i] - yOneStep[i] ;
|
||||
yOutput[i] += yError[i]*correction ;
|
||||
@@ -208,7 +207,7 @@ G4ConstRK4::Stepper( const G4double yInput[],
|
||||
// The method below is good only for angle deviations < 2 pi;
|
||||
// this restriction should not be a problem for the Runge Kutta methods,
|
||||
// which generally cannot integrate accurately for large angle deviations
|
||||
|
||||
//
|
||||
G4double G4ConstRK4::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DELPHIMagField implementation
|
||||
//
|
||||
// Created: V.Grichine - 03.02.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4DELPHIMagField.hh"
|
||||
@@ -34,10 +36,6 @@ G4DELPHIMagField::G4DELPHIMagField()
|
||||
{
|
||||
}
|
||||
|
||||
G4Field* G4DELPHIMagField::Clone() const
|
||||
{
|
||||
return new G4DELPHIMagField;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4DELPHIMagField::~G4DELPHIMagField()
|
||||
@@ -46,6 +44,12 @@ G4DELPHIMagField::~G4DELPHIMagField()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4Field* G4DELPHIMagField::Clone() const
|
||||
{
|
||||
return new G4DELPHIMagField;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4DELPHIMagField::GetFieldValue( const G4double yTrack[7],
|
||||
G4double B[3] ) const
|
||||
@@ -59,7 +63,8 @@ void G4DELPHIMagField::GetFieldValue( const G4double yTrack[7],
|
||||
G4double rz = z*std::sqrt(r2), r = std::sqrt(r2+a*a) ;
|
||||
G4double Br ;
|
||||
G4double P[8], Q[8] ;
|
||||
static G4ThreadLocal G4double c[8] = {
|
||||
static G4ThreadLocal G4double c[8] =
|
||||
{
|
||||
-9.26e-5, -3.51e-5, 2.94e-6, -1.10e-6,
|
||||
6.25e-8, -1.77e-8, -6.88e-10, -7.52e-11
|
||||
} ;
|
||||
@@ -85,7 +90,7 @@ void G4DELPHIMagField::GetFieldValue( const G4double yTrack[7],
|
||||
|
||||
Br = 0 ;
|
||||
B[2] = 1.2*tesla ; // the principal Bz value of DELPHI detector
|
||||
for(i=0;i<n;i++)
|
||||
for(i=0; i<n; ++i)
|
||||
{
|
||||
Br += c[i]*P[i] ;
|
||||
B[2] += c[i]*Q[i] ;
|
||||
|
||||
@@ -23,44 +23,28 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Dormand-Lockyer-McGorrigan-Prince-6-3-4 non-FSAL implementation
|
||||
// RK4(3)6FD - forced Non-FSAL
|
||||
// G4DoLoMcPriRK34 implementation
|
||||
//
|
||||
// Design/implementation by Somnath Banerjee
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
// Supervision / code review: John Apostolakis
|
||||
//
|
||||
// First version: 7 July 2015
|
||||
//
|
||||
// G4DoLoMcPriRK34.cc
|
||||
// Geant4
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath on 7 July 2015
|
||||
//
|
||||
// This is the source file of G4DoLoMcPriRK34 class containing the
|
||||
// definition of the Stepper() method that evaluates one Step in
|
||||
// field propagation.
|
||||
//
|
||||
// The Butcher table of the Dormand-Lockyer-McGorrigan-Prince-6-3-4 method is as follows :
|
||||
// [ to be added here ]
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 7 July 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4DoLoMcPriRK34.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
// Constructor
|
||||
G4DoLoMcPriRK34::G4DoLoMcPriRK34(G4EquationOfMotion *EqRhs,
|
||||
//
|
||||
G4DoLoMcPriRK34::G4DoLoMcPriRK34(G4EquationOfMotion* EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength( -1.0 ), fAuxStepper( nullptr )
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
|
||||
//New Chunk of memory being created for use by the Stepper
|
||||
// New Chunk of memory being created for use by the Stepper
|
||||
|
||||
//aki - for storing intermediate RHS
|
||||
// aki - for storing intermediate RHS
|
||||
//
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
@@ -75,150 +59,136 @@ G4DoLoMcPriRK34::G4DoLoMcPriRK34(G4EquationOfMotion *EqRhs,
|
||||
fLastDyDx = new G4double[numberOfVariables];
|
||||
|
||||
fMidVector = new G4double[numberOfVariables];
|
||||
fMidError = new G4double[numberOfVariables];
|
||||
fMidError = new G4double[numberOfVariables];
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4DoLoMcPriRK34(EqRhs, numberOfVariables,
|
||||
!primary);
|
||||
fAuxStepper = new G4DoLoMcPriRK34(EqRhs, numberOfVariables, !primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Destructor
|
||||
// Destructor
|
||||
//
|
||||
G4DoLoMcPriRK34::~G4DoLoMcPriRK34()
|
||||
{
|
||||
//clear all previously allocated memory for Stepper and DistChord
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
// clear all previously allocated memory for Stepper and DistChord
|
||||
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Stepper :
|
||||
|
||||
// Stepper
|
||||
//
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4DoLoMcPriRK34::Stepper(const G4double yInput[],
|
||||
const G4double DyDx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
const G4double DyDx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
{
|
||||
G4int i;
|
||||
|
||||
//The various constants defined on the basis of butcher tableu
|
||||
const G4double //G4double - only once
|
||||
// The various constants defined on the basis of butcher tableu
|
||||
//
|
||||
const G4double b21 = 7.0/27.0 ,
|
||||
b31 = 7.0/72.0 ,
|
||||
b32 = 7.0/24.0 ,
|
||||
|
||||
b21 = 7.0/27.0 ,
|
||||
b41 = 3043.0/3528.0 ,
|
||||
b42 = -3757.0/1176.0 ,
|
||||
b43 = 1445.0/441.0,
|
||||
|
||||
b51 = 17617.0/11662.0 ,
|
||||
b52 = -4023.0/686.0 ,
|
||||
b53 = 9372.0/1715.0 ,
|
||||
b54 = -66.0/595.0 ,
|
||||
|
||||
b61 = 29.0/238.0 ,
|
||||
b62 = 0.0 ,
|
||||
b63 = 216.0/385.0 ,
|
||||
b64 = 54.0/85.0 ,
|
||||
b65 = -7.0/22.0 ,
|
||||
|
||||
b31 = 7.0/72.0 ,
|
||||
b32 = 7.0/24.0 ,
|
||||
|
||||
b41 = 3043.0/3528.0 ,
|
||||
b42 = -3757.0/1176.0 ,
|
||||
b43 = 1445.0/441.0,
|
||||
|
||||
b51 = 17617.0/11662.0 ,
|
||||
b52 = -4023.0/686.0 ,
|
||||
b53 = 9372.0/1715.0 ,
|
||||
b54 = -66.0/595.0 ,
|
||||
|
||||
b61 = 29.0/238.0 ,
|
||||
b62 = 0.0 ,
|
||||
b63 = 216.0/385.0 ,
|
||||
b64 = 54.0/85.0 ,
|
||||
b65 = -7.0/22.0 ,
|
||||
|
||||
dc1 = 363.0/2975.0 - b61 ,
|
||||
dc2 = 0.0 - b62 ,
|
||||
dc3 = 981.0/1750.0 - b63,
|
||||
dc4 = 2709.0/4250.0 - b64 ,
|
||||
dc5 = -3.0/10.0 - b65 ,
|
||||
dc6 = -1.0/50.0 ; // end of declaration
|
||||
|
||||
|
||||
dc1 = 363.0/2975.0 - b61 ,
|
||||
dc2 = 0.0 - b62 ,
|
||||
dc3 = 981.0/1750.0 - b63,
|
||||
dc4 = 2709.0/4250.0 - b64 ,
|
||||
dc5 = -3.0/10.0 - b65 ,
|
||||
dc6 = -1.0/50.0 ; //end of declaration
|
||||
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// 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++)
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
// RightHandSide(yIn, DyDx) ; // 1st stage - Not doing, getting passed
|
||||
|
||||
|
||||
|
||||
// RightHandSide(yIn, DyDx) ;
|
||||
// 1st stage - Not doing, getting passed
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*DyDx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*DyDx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[i]) ;
|
||||
yTemp[i] = yIn[i] + Step*(b51*DyDx[i] + b52*ak2[i]
|
||||
+ b53*ak3[i] + b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b61*DyDx[i] + b62*ak2[i] + b63*ak3[i] +
|
||||
b64*ak4[i] + b65*ak5[i]) ;
|
||||
yOut[i] = yIn[i] + Step*(b61*DyDx[i] + b62*ak2[i] + b63*ak3[i]
|
||||
+ b64*ak4[i] + b65*ak5[i]) ;
|
||||
}
|
||||
RightHandSide(yOut, ak6) ; // 6th and Final stage
|
||||
|
||||
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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] ) ;
|
||||
|
||||
yErr[i] = Step*(dc1*DyDx[i] + dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i]
|
||||
+ dc5*ak5[i] + dc6*ak6[i] ) ;
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = DyDx[i];
|
||||
|
||||
|
||||
}
|
||||
|
||||
fLastStepLength = Step;
|
||||
@@ -226,83 +196,81 @@ void G4DoLoMcPriRK34::Stepper(const G4double yInput[],
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
//The following has not been tested
|
||||
|
||||
//The DistChord() function fot the class - must define it here.
|
||||
// DistChord
|
||||
//
|
||||
G4double G4DoLoMcPriRK34::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
fLastInitialVector[1], fLastInitialVector[2] );
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
fLastFinalVector[1], fLastFinalVector[2]);
|
||||
fLastFinalVector[1], fLastFinalVector[2] );
|
||||
|
||||
// Do half a Step using StepNoErr
|
||||
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
|
||||
fMidVector, fMidError );
|
||||
fMidVector, fMidError );
|
||||
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
// distance of Chord
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distChord = distLine;
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
distChord = (midPoint-initialPoint).mag();
|
||||
distChord = (midPoint-initialPoint).mag();
|
||||
}
|
||||
return distChord;
|
||||
}
|
||||
|
||||
void G4DoLoMcPriRK34::SetupInterpolation()
|
||||
{}
|
||||
|
||||
void G4DoLoMcPriRK34::SetupInterpolate( const G4double /* yInput */ [] ,
|
||||
const G4double /* dydx */ [] ,
|
||||
const G4double /* Step */ )
|
||||
{
|
||||
//Do Nothing
|
||||
}
|
||||
|
||||
void G4DoLoMcPriRK34::SetupInterpolate( const G4double /* yInput */ [] ,
|
||||
const G4double /* dydx */ [] ,
|
||||
const G4double /* Step */ )
|
||||
{
|
||||
// Do Nothing
|
||||
}
|
||||
|
||||
void G4DoLoMcPriRK34::Interpolate( G4double tau,
|
||||
G4double yOut[])
|
||||
G4double yOut[] )
|
||||
{
|
||||
Interpolate( fLastInitialVector, fLastDyDx, fLastStepLength, yOut, tau );
|
||||
Interpolate( fLastInitialVector, fLastDyDx, fLastStepLength, yOut, tau );
|
||||
}
|
||||
|
||||
// Function to evaluate the interpolation at tau fraction of the step
|
||||
//
|
||||
void G4DoLoMcPriRK34::Interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau ){
|
||||
G4double
|
||||
bf1, bf2, bf3, bf4, bf5, bf6;
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau )
|
||||
{
|
||||
G4double bf1, bf2, bf3, bf4, bf5, bf6;
|
||||
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
G4double
|
||||
tau_2 = tau*tau ,
|
||||
tau_3 = tau*tau_2;
|
||||
G4double tau_2 = tau*tau, tau_3 = tau*tau_2;
|
||||
|
||||
//Calculating the polynomials (coefficients for the respective stages)
|
||||
// Calculating the polynomials (coefficients for the respective stages)
|
||||
//
|
||||
bf1 = -(162.0*tau_3 - 504.0*tau_2 + 551.0*tau - 238.0)/238.0 ,
|
||||
bf2 = 0.0 ,
|
||||
bf3 = 27.0*tau*(27.0*tau_2 - 70.0*tau + 51.0 )/385.0 ,
|
||||
@@ -310,15 +278,9 @@ void G4DoLoMcPriRK34::Interpolate( const G4double yInput[],
|
||||
bf5 = 7.0*tau*(2232.0*tau_2 - 4166.0*tau + 1785.0 )/3278.0 ,
|
||||
bf6 = tau*(tau - 1.0)*(387.0*tau - 238.0)/149.0 ;
|
||||
|
||||
for( int i=0; i<numberOfVariables; i++){
|
||||
yOut[i] = yIn[i] + Step*tau*(bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i] +
|
||||
bf4*ak4[i] + bf5*ak5[i] + bf6*ak6[i] ) ;
|
||||
for( G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*tau*(bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i]
|
||||
+ bf4*ak4[i] + bf5*ak5[i] + bf6*ak6[i] ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-------Verified------- - hackabot
|
||||
|
||||
|
||||
@@ -23,104 +23,74 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DormandPrince745 implementation
|
||||
//
|
||||
// Class description:
|
||||
// DormandPrince7 - 5(4) non-FSAL
|
||||
// definition of the stepper() method that evaluates one step in
|
||||
// field propagation.
|
||||
// The coefficients and the algorithm have been adapted from
|
||||
//
|
||||
// DormandPrince7 - 5(4) non-FSAL
|
||||
// J. R. Dormand and P. J. Prince, "A family of embedded Runge-Kutta formulae"
|
||||
// Journal of computational and applied Math., vol.6, no.1, pp.19-26, 1980.
|
||||
//
|
||||
// This is the source file of G4DormandPrince745 class containing the
|
||||
// definition of the stepper() method that evaluates one step in
|
||||
// field propagation.
|
||||
// The coefficients and the algorithm have been adapted from
|
||||
//
|
||||
// Table 2 : Coefficients of RK5(4)7M
|
||||
// ---Ref---
|
||||
// J. R. Dormand and P. J. Prince, “A family of embedded Runge-Kutta formulae,”
|
||||
// Journal of computational and applied …, vol. 6, no. 1, pp. 19–26, 1980.
|
||||
// ------------------
|
||||
//
|
||||
// The Butcher table of the Dormand-Prince-7-4-5 method is as follows :
|
||||
// The Butcher table of the Dormand-Prince-7-4-5 method is as follows :
|
||||
//
|
||||
// 0 |
|
||||
// 1/5 | 1/5
|
||||
// 3/10| 3/40 9/40
|
||||
// 4/5 | 44/45 −56/15 32/9
|
||||
// 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
|
||||
// 3/10| 3/40 9/40
|
||||
// 4/5 | 44/45 56/15 32/9
|
||||
// 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
|
||||
// ------------------------------------------------------------------------
|
||||
// 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: 25 May 2015 - Somnath Banerjee
|
||||
// 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
|
||||
//
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 25 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4DormandPrince745.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace field_utils;
|
||||
|
||||
G4DormandPrince745::G4DormandPrince745(G4EquationOfMotion* equation,
|
||||
G4int noIntegrationVariables)
|
||||
: G4MagIntegratorStepper(equation, noIntegrationVariables)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[])
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[])
|
||||
{
|
||||
Stepper(yInput, dydx, hstep, yOutput, yError);
|
||||
copy(dydxOutput, ak7);
|
||||
Stepper(yInput, dydx, hstep, yOutput, yError);
|
||||
copy(dydxOutput, ak7);
|
||||
}
|
||||
|
||||
|
||||
// The coefficients and the algorithm have been adapted from
|
||||
// Table 2 : Coefficients of RK5(4)7M
|
||||
// ---Ref---
|
||||
// J. R. Dormand and P. J. Prince, “A family of embedded Runge-Kutta formulae,”
|
||||
// Journal of computational and applied …, vol. 6, no. 1, pp. 19–26, 1980.
|
||||
// ------------------
|
||||
|
||||
// The Butcher table of the Dormand-Prince-7-4-5 method is as follows :
|
||||
// Stepper
|
||||
//
|
||||
// 0 |
|
||||
// 1/5 | 1/5
|
||||
// 3/10| 3/40 9/40
|
||||
// 4/5 | 44/45 −56/15 32/9
|
||||
// 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
|
||||
// ------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
|
||||
//Stepper :
|
||||
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOut[],
|
||||
G4double yErr[])
|
||||
{
|
||||
//The various constants defined on the basis of butcher tableu
|
||||
const G4double
|
||||
b21 = 0.2,
|
||||
|
||||
b31 = 3.0 / 40.0, b32 = 9.0 / 40.0,
|
||||
|
||||
b41 = 44.0 / 45.0, b42 = -56.0 / 15.0, b43 = 32.0/9.0,
|
||||
|
||||
// The various constants defined on the basis of butcher tableu
|
||||
//
|
||||
const G4double b21 = 0.2,
|
||||
b31 = 3.0 / 40.0, b32 = 9.0 / 40.0,
|
||||
b41 = 44.0 / 45.0, b42 = -56.0 / 15.0, b43 = 32.0/9.0,
|
||||
|
||||
b51 = 19372.0 / 6561.0, b52 = -25360.0 / 2187.0, b53 = 64448.0 / 6561.0,
|
||||
b54 = -212.0 / 729.0,
|
||||
|
||||
@@ -152,18 +122,20 @@ void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
dc6 = -(b76 - 187.0 / 2100.0),
|
||||
dc7 = -(- 1.0 / 40.0);
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
State yTemp;
|
||||
|
||||
// The number of variables to be integrated over
|
||||
//
|
||||
yOut[7] = yTemp[7] = yInput[7];
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
//
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
fyIn[i] = yInput[i];
|
||||
}
|
||||
// RightHandSide(yIn, dydx);
|
||||
// RightHandSide(yIn, dydx); // Not done! 1st stage
|
||||
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
@@ -179,7 +151,8 @@ void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = fyIn[i] + hstep * (b41 * dydx[i] + b42 * ak2[i] + b43 * ak3[i]);
|
||||
yTemp[i] = fyIn[i] + hstep * (
|
||||
b41 * dydx[i] + b42 * ak2[i] + b43 * ak3[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak4); // 4th stage
|
||||
|
||||
@@ -204,7 +177,7 @@ void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
b71 * dydx[i] + b72 * ak2[i] + b73 * ak3[i] +
|
||||
b74 * ak4[i] + b75 * ak5[i] + b76 * ak6[i]);
|
||||
}
|
||||
RightHandSide(yOut, ak7); //7th and Final stage
|
||||
RightHandSide(yOut, ak7); // 7th and Final stage
|
||||
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
@@ -215,6 +188,7 @@ void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
) + 1.5e-18;
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fyOut[i] = yOut[i];
|
||||
fdydxIn[i] = dydx[i];
|
||||
}
|
||||
@@ -224,14 +198,15 @@ void G4DormandPrince745::Stepper(const G4double yInput[],
|
||||
|
||||
G4double G4DormandPrince745::DistChord() const
|
||||
{
|
||||
// Coefficients were taken from Some Practical Runge-Kutta Formulas by Lawrence F. Shampine, page 149, c*
|
||||
const G4double
|
||||
hf1 = 6025192743.0 / 30085553152.0,
|
||||
hf3 = 51252292925.0 / 65400821598.0,
|
||||
hf4 = - 2691868925.0 / 45128329728.0,
|
||||
hf5 = 187940372067.0 / 1594534317056.0,
|
||||
hf6 = - 1776094331.0 / 19743644256.0,
|
||||
hf7 = 11237099.0 / 235043384.0;
|
||||
// Coefficients were taken from Some Practical Runge-Kutta Formulas
|
||||
// by Lawrence F. Shampine, page 149, c*
|
||||
//
|
||||
const G4double hf1 = 6025192743.0 / 30085553152.0,
|
||||
hf3 = 51252292925.0 / 65400821598.0,
|
||||
hf4 = - 2691868925.0 / 45128329728.0,
|
||||
hf5 = 187940372067.0 / 1594534317056.0,
|
||||
hf6 = - 1776094331.0 / 19743644256.0,
|
||||
hf7 = 11237099.0 / 235043384.0;
|
||||
|
||||
G4ThreeVector mid;
|
||||
|
||||
@@ -248,21 +223,19 @@ G4double G4DormandPrince745::DistChord() const
|
||||
return G4LineSection::Distline(mid, begin, end);
|
||||
}
|
||||
|
||||
// The lower (4th) order interpolant given by Dormand and prince
|
||||
// "An RK 5(4) triple"
|
||||
//---Ref---
|
||||
// J. R. Dormand and P. J. Prince, “Runge-Kutta triples,”
|
||||
// Computers & Mathematics with Applications, vol. 12, no. 9,
|
||||
// pp. 1007–1017, 1986.
|
||||
//---------------------------
|
||||
void G4DormandPrince745::Interpolate4thOrder(G4double yOut[], G4double tau) const
|
||||
// The lower (4th) order interpolant given by Dormand and Prince:
|
||||
// J. R. Dormand and P. J. Prince, "Runge-Kutta triples"
|
||||
// Computers & Mathematics with Applications, vol. 12, no. 9,
|
||||
// pp. 1007-1017, 1986.
|
||||
//
|
||||
void G4DormandPrince745::
|
||||
Interpolate4thOrder(G4double yOut[], G4double tau) const
|
||||
{
|
||||
const G4int numberOfVariables = this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
const G4double
|
||||
tau2 = tau * tau,
|
||||
tau3 = tau * tau2,
|
||||
tau4 = tau2 * tau2;
|
||||
const G4double tau2 = tau * tau,
|
||||
tau3 = tau * tau2,
|
||||
tau4 = tau2 * tau2;
|
||||
|
||||
const G4double bf1 = 1.0 / 11282082432.0 * (
|
||||
157015080.0 * tau4 - 13107642775.0 * tau3 + 34969693132.0 * tau2 -
|
||||
@@ -295,180 +268,164 @@ void G4DormandPrince745::Interpolate4thOrder(G4double yOut[], G4double tau) cons
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Following interpolant of order 5 was given by Baker,Dormand,Gilmore, Prince :
|
||||
//---Ref---
|
||||
// T. S. Baker, J. R. Dormand, J. P. Gilmore, and P. J. Prince,
|
||||
// “Continuous approximation with embedded Runge-Kutta methods,”
|
||||
// Applied Numerical Mathematics, vol. 22, no. 1, pp. 51–62, 1996.
|
||||
//---------------------
|
||||
|
||||
// Calculating the extra stages for the interpolant :
|
||||
void G4DormandPrince745::SetupInterpolation_high()
|
||||
// T. S. Baker, J. R. Dormand, J. P. Gilmore, and P. J. Prince,
|
||||
// "Continuous approximation with embedded Runge-Kutta methods"
|
||||
// Applied Numerical Mathematics, vol. 22, no. 1, pp. 51-62, 1996.
|
||||
//
|
||||
// Calculating the extra stages for the interpolant
|
||||
//
|
||||
void G4DormandPrince745::SetupInterpolation5thOrder()
|
||||
{
|
||||
//Coefficients for the additional stages :
|
||||
const G4double
|
||||
b81 = 6245.0/62208.0 ,
|
||||
b82 = 0.0 ,
|
||||
b83 = 8875.0/103032.0 ,
|
||||
b84 = -125.0/1728.0 ,
|
||||
b85 = 801.0/13568.0 ,
|
||||
b86 = -13519.0/368064.0 ,
|
||||
b87 = 11105.0/368064.0 ,
|
||||
// Coefficients for the additional stages
|
||||
//
|
||||
const G4double b81 = 6245.0 / 62208.0,
|
||||
b82 = 0.0,
|
||||
b83 = 8875.0 / 103032.0,
|
||||
b84 = -125.0 / 1728.0,
|
||||
b85 = 801.0 / 13568.0,
|
||||
b86 = -13519.0 / 368064.0,
|
||||
b87 = 11105.0 / 368064.0,
|
||||
|
||||
b91 = 632855.0 / 4478976.0,
|
||||
b92 = 0.0,
|
||||
b93 = 4146875.0 / 6491016.0,
|
||||
b94 = 5490625.0 /14183424.0,
|
||||
b95 = -15975.0 / 108544.0,
|
||||
b96 = 8295925.0 / 220286304.0,
|
||||
b97 = -1779595.0 / 62938944.0,
|
||||
b98 = -805.0 / 4104.0;
|
||||
|
||||
b91 = 632855.0/4478976.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 4146875.0/6491016.0 ,
|
||||
b94 = 5490625.0/14183424.0 ,
|
||||
b95 = -15975.0/108544.0 ,
|
||||
b96 = 8295925.0/220286304.0 ,
|
||||
b97 = -1779595.0/62938944.0 ,
|
||||
b98 = -805.0/4104.0 ;
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4double *dydx = fdydxIn;
|
||||
const G4double Step = fLastStepLength;
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
State yTemp;
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
// for(int i=0;i<numberOfVariables;i++) { yIn[i]=yInput[i]; }
|
||||
// yTemp[7] = yIn[7];
|
||||
|
||||
//Evaluate the extra stages :
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
// Evaluate the extra stages
|
||||
//
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = fyIn[i] + Step*(b81*dydx[i] + b82*ak2[i] + b83*ak3[i] +
|
||||
b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
|
||||
b87*ak7[i]);
|
||||
yTemp[i] = fyIn[i] + fLastStepLength * (
|
||||
b81 * fdydxIn[i] + b82 * ak2[i] + b83 * ak3[i] +
|
||||
b84 * ak4[i] + b85 * ak5[i] + b86 * ak6[i] +
|
||||
b87 * ak7[i]
|
||||
);
|
||||
}
|
||||
RightHandSide(yTemp, ak8); //8th Stage
|
||||
RightHandSide(yTemp, ak8); // 8th Stage
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = fyIn[i] + Step*(b91*dydx[i] + b92*ak2[i] + b93*ak3[i] +
|
||||
b94*ak4[i] + b95*ak5[i] + b96*ak6[i] +
|
||||
b97*ak7[i] + b98*ak8[i] );
|
||||
yTemp[i] = fyIn[i] + fLastStepLength * (
|
||||
b91 * fdydxIn[i] + b92 * ak2[i] + b93 * ak3[i] +
|
||||
b94 * ak4[i] + b95 * ak5[i] + b96 * ak6[i] +
|
||||
b97 * ak7[i] + b98 * ak8[i]
|
||||
);
|
||||
}
|
||||
RightHandSide(yTemp, ak9); //9th Stage
|
||||
RightHandSide(yTemp, ak9); // 9th Stage
|
||||
}
|
||||
|
||||
|
||||
// Calculating the interpolated result yOut with the coefficients
|
||||
void G4DormandPrince745::Interpolate_high(G4double yOut[], G4double tau )
|
||||
//
|
||||
void G4DormandPrince745::
|
||||
Interpolate5thOrder(G4double yOut[], G4double tau) const
|
||||
{
|
||||
//Define the coefficients for the polynomials
|
||||
G4double bi[10][5], b[10];
|
||||
const G4int numberOfVariables = this->GetNumberOfVariables();
|
||||
// const G4double fullStep = fLastStepLength;
|
||||
|
||||
// If given requestedStep in argument:
|
||||
// G4double tau = requestedStep / fLastStepLength;
|
||||
// Define the coefficients for the polynomials
|
||||
//
|
||||
G4double bi[10][5];
|
||||
|
||||
// COEFFICIENTS OF bi[1]
|
||||
bi[1][0] = 1.0 ,
|
||||
bi[1][1] = -38039.0/7040.0 ,
|
||||
bi[1][2] = 125923.0/10560.0 ,
|
||||
bi[1][3] = -19683.0/1760.0 ,
|
||||
bi[1][4] = 3303.0/880.0 ,
|
||||
bi[1][0] = 1.0,
|
||||
bi[1][1] = -38039.0 / 7040.0,
|
||||
bi[1][2] = 125923.0 / 10560.0,
|
||||
bi[1][3] = -19683.0 / 1760.0,
|
||||
bi[1][4] = 3303.0 / 880.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[2]
|
||||
bi[2][0] = 0.0 ,
|
||||
bi[2][1] = 0.0 ,
|
||||
bi[2][2] = 0.0 ,
|
||||
bi[2][3] = 0.0 ,
|
||||
bi[2][4] = 0.0 ,
|
||||
bi[2][0] = 0.0,
|
||||
bi[2][1] = 0.0,
|
||||
bi[2][2] = 0.0,
|
||||
bi[2][3] = 0.0,
|
||||
bi[2][4] = 0.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[3]
|
||||
bi[3][0] = 0.0 ,
|
||||
bi[3][1] = -12500.0/4081.0 ,
|
||||
bi[3][2] = 205000.0/12243.0 ,
|
||||
bi[3][3] = -90000.0/4081.0 ,
|
||||
bi[3][4] = 36000.0/4081.0 ,
|
||||
bi[3][0] = 0.0,
|
||||
bi[3][1] = -12500.0 / 4081.0,
|
||||
bi[3][2] = 205000.0 / 12243.0,
|
||||
bi[3][3] = -90000.0 / 4081.0,
|
||||
bi[3][4] = 36000.0 / 4081.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[4]
|
||||
bi[4][0] = 0.0 ,
|
||||
bi[4][1] = -3125.0/704.0 ,
|
||||
bi[4][2] = 25625.0/1056.0 ,
|
||||
bi[4][3] = -5625.0/176.0 ,
|
||||
bi[4][4] = 1125.0/88.0 ,
|
||||
bi[4][0] = 0.0,
|
||||
bi[4][1] = -3125.0 / 704.0,
|
||||
bi[4][2] = 25625.0 / 1056.0,
|
||||
bi[4][3] = -5625.0 / 176.0,
|
||||
bi[4][4] = 1125.0 / 88.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[5]
|
||||
bi[5][0] = 0.0 ,
|
||||
bi[5][1] = 164025.0/74624.0 ,
|
||||
bi[5][2] = -448335.0/37312.0 ,
|
||||
bi[5][3] = 295245.0/18656.0 ,
|
||||
bi[5][4] = -59049.0/9328.0 ,
|
||||
bi[5][0] = 0.0,
|
||||
bi[5][1] = 164025.0 / 74624.0,
|
||||
bi[5][2] = -448335.0 / 37312.0,
|
||||
bi[5][3] = 295245.0 / 18656.0,
|
||||
bi[5][4] = -59049.0 / 9328.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[6]
|
||||
bi[6][0] = 0.0 ,
|
||||
bi[6][1] = -25.0/28.0 ,
|
||||
bi[6][2] = 205.0/42.0 ,
|
||||
bi[6][3] = -45.0/7.0 ,
|
||||
bi[6][4] = 18.0/7.0 ,
|
||||
bi[6][0] = 0.0,
|
||||
bi[6][1] = -25.0 / 28.0,
|
||||
bi[6][2] = 205.0 / 42.0,
|
||||
bi[6][3] = -45.0 / 7.0,
|
||||
bi[6][4] = 18.0 / 7.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[7]
|
||||
bi[7][0] = 0.0 ,
|
||||
bi[7][1] = -2.0/11.0 ,
|
||||
bi[7][2] = 73.0/55.0 ,
|
||||
bi[7][3] = -171.0/55.0 ,
|
||||
bi[7][4] = 108.0/55.0 ,
|
||||
bi[7][0] = 0.0,
|
||||
bi[7][1] = -2.0 / 11.0,
|
||||
bi[7][2] = 73.0 / 55.0,
|
||||
bi[7][3] = -171.0 / 55.0,
|
||||
bi[7][4] = 108.0 / 55.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[8]
|
||||
bi[8][0] = 0.0 ,
|
||||
bi[8][1] = 189.0/22.0 ,
|
||||
bi[8][2] = -1593.0/55.0 ,
|
||||
bi[8][3] = 3537.0/110.0 ,
|
||||
bi[8][4] = -648.0/55.0 ,
|
||||
bi[8][0] = 0.0,
|
||||
bi[8][1] = 189.0 / 22.0,
|
||||
bi[8][2] = -1593.0 / 55.0,
|
||||
bi[8][3] = 3537.0 / 110.0,
|
||||
bi[8][4] = -648.0 / 55.0,
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// COEFFICIENTS OF bi[9]
|
||||
bi[9][0] = 0.0 ,
|
||||
bi[9][1] = 351.0/110.0 ,
|
||||
bi[9][2] = -999.0/55.0 ,
|
||||
bi[9][3] = 2943.0/110.0 ,
|
||||
bi[9][4] = -648.0/55.0 ;
|
||||
bi[9][0] = 0.0,
|
||||
bi[9][1] = 351.0 / 110.0,
|
||||
bi[9][2] = -999.0 / 55.0,
|
||||
bi[9][3] = 2943.0 / 110.0,
|
||||
bi[9][4] = -648.0 / 55.0;
|
||||
// --------------------------------------------------------
|
||||
|
||||
// for(G4int i = 0; i< numberOfVariables; i++) { yIn[i] = yInput[i]; }
|
||||
|
||||
// Calculating the polynomials :
|
||||
#if 1
|
||||
for(int iStage=1; iStage<=9; iStage++){
|
||||
b[iStage] = 0;
|
||||
}
|
||||
|
||||
// Calculating the polynomials
|
||||
|
||||
G4double b[10];
|
||||
std::memset(b, 0.0, sizeof(b));
|
||||
|
||||
for(int j=0; j<=4; j++){
|
||||
G4double tauPower = 1.0;
|
||||
for(int iStage=1; iStage<=9; iStage++){
|
||||
b[iStage] += bi[iStage][j]*tauPower;
|
||||
G4double tauPower = 1.0;
|
||||
for(G4int j = 0; j <= 4; ++j)
|
||||
{
|
||||
for(G4int iStage = 1; iStage <= 9; ++iStage)
|
||||
{
|
||||
b[iStage] += bi[iStage][j] * tauPower;
|
||||
}
|
||||
tauPower *= tau;
|
||||
}
|
||||
#else
|
||||
G4double tau0 = tau;
|
||||
|
||||
for(int i=1; i<=9; i++){ //Here i is NOT the coordinate no. , it's stage no.
|
||||
b[i] = 0;
|
||||
tau = 1.0;
|
||||
for(int j=0; j<=4; j++){
|
||||
b[i] += bi[i][j]*tau;
|
||||
tau*=tau0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
G4double stepLen = fLastStepLength * tau;
|
||||
for(int i=0; i<numberOfVariables; i++){ //Here i IS the cooridnate no.
|
||||
yOut[i] = fyIn[i] + stepLen *(b[1]*fdydxIn[i] + b[2]*ak2[i] + b[3]*ak3[i] +
|
||||
b[4]*ak4[i] + b[5]*ak5[i] + b[6]*ak6[i] +
|
||||
b[7]*ak7[i] + b[8]*ak8[i] + b[9]*ak9[i] );
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
const G4double stepLen = fLastStepLength * tau;
|
||||
for(G4int i = 0; i < numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = fyIn[i] + stepLen * (
|
||||
b[1] * fdydxIn[i] + b[2] * ak2[i] + b[3] * ak3[i] +
|
||||
b[4] * ak4[i] + b[5] * ak5[i] + b[6] * ak6[i] +
|
||||
b[7] * ak7[i] + b[8] * ak8[i] + b[9] * ak9[i]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,38 +23,28 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// FDormand-Prince RK 6(5) FSAL implementation by Somnath Banerjee
|
||||
// Supervision / code review: John Apostolakis
|
||||
// G4DormandPrinceRK56 implementation
|
||||
//
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
//
|
||||
// First version: 26 June 2015
|
||||
//
|
||||
// G4DormandPrince745.cc
|
||||
// Geant4
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath on 26 June 2015
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 26 June 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4DormandPrinceRK56.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
//Constructor
|
||||
G4DormandPrinceRK56::G4DormandPrinceRK56(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength(-1.0), fAuxStepper(nullptr)
|
||||
// Constructor
|
||||
//
|
||||
G4DormandPrinceRK56::G4DormandPrinceRK56(G4EquationOfMotion* EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
|
||||
//New Chunk of memory being created for use by the stepper
|
||||
// New Chunk of memory being created for use by the stepper
|
||||
|
||||
//aki - for storing intermediate RHS
|
||||
// aki - for storing intermediate RHS
|
||||
//
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
@@ -65,6 +55,7 @@ G4DormandPrinceRK56::G4DormandPrinceRK56(G4EquationOfMotion *EqRhs,
|
||||
ak9 = new G4double[numberOfVariables];
|
||||
|
||||
// Memory for Additional stages
|
||||
//
|
||||
ak10 = new G4double[numberOfVariables];
|
||||
ak11 = new G4double[numberOfVariables];
|
||||
ak12 = new G4double[numberOfVariables];
|
||||
@@ -80,145 +71,136 @@ G4DormandPrinceRK56::G4DormandPrinceRK56(G4EquationOfMotion *EqRhs,
|
||||
fLastDyDx = new G4double[numStateVars];
|
||||
|
||||
fMidVector = new G4double[numStateVars];
|
||||
fMidError = new G4double[numStateVars];
|
||||
fMidError = new G4double[numStateVars];
|
||||
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4DormandPrinceRK56(EqRhs, numberOfVariables,
|
||||
!primary);
|
||||
fAuxStepper = new G4DormandPrinceRK56(EqRhs, numberOfVariables, !primary);
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
//
|
||||
G4DormandPrinceRK56::~G4DormandPrinceRK56()
|
||||
{
|
||||
// clear all previously allocated memory for stepper and DistChord
|
||||
|
||||
//Destructor
|
||||
G4DormandPrinceRK56::~G4DormandPrinceRK56(){
|
||||
//clear all previously allocated memory for stepper and DistChord
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
delete[] ak7;
|
||||
delete[] ak8;
|
||||
delete[] ak9;
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
delete [] ak7;
|
||||
delete [] ak8;
|
||||
delete [] ak9;
|
||||
|
||||
delete[] ak10;
|
||||
delete[] ak10_low;
|
||||
delete[] ak11;
|
||||
delete[] ak12;
|
||||
delete [] ak10;
|
||||
delete [] ak10_low;
|
||||
delete [] ak11;
|
||||
delete [] ak12;
|
||||
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Stepper :
|
||||
|
||||
// Stepper
|
||||
//
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4DormandPrinceRK56::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
// G4double nextDydx[] ) -- Output:
|
||||
// endpoint DyDx ( for future FSAL version )
|
||||
// endpoint DyDx ( for future FSAL version )
|
||||
{
|
||||
G4int i;
|
||||
|
||||
//The various constants defined on the basis of butcher tableu
|
||||
const G4double //G4double - only once
|
||||
|
||||
|
||||
// The various constants defined on the basis of butcher tableu
|
||||
// Old Coefficients from
|
||||
// Table 1. RK6(5)8M
|
||||
//---Ref---
|
||||
//[P. J. Prince and J. R. Dormand, “High order embedded Runge-Kutta formulae,”
|
||||
// Journal of Computational and Applied Mathematics, vol. 7, no. 1, pp. 67–75,
|
||||
// Dec. 1980.
|
||||
//----------------
|
||||
// P.J.Prince and J.R.Dormand, "High order embedded Runge-Kutta formulae"
|
||||
// Journal of Computational and Applied Math., vol.7, no.1, pp.67-75, 1980.
|
||||
//
|
||||
const G4double b21 = 1.0/10.0 ,
|
||||
b31 = -2.0/81.0 ,
|
||||
b32 = 20.0/81.0 ,
|
||||
|
||||
b41 = 615.0/1372.0 ,
|
||||
b42 = -270.0/343.0 ,
|
||||
b43 = 1053.0/1372.0 ,
|
||||
|
||||
b51 = 3243.0/5500.0 ,
|
||||
b52 = -54.0/55.0 ,
|
||||
b53 = 50949.0/71500.0 ,
|
||||
b54 = 4998.0/17875.0 ,
|
||||
|
||||
b61 = -26492.0/37125.0 ,
|
||||
b62 = 72.0/55.0 ,
|
||||
b63 = 2808.0/23375.0 ,
|
||||
b64 = -24206.0/37125.0 ,
|
||||
b65 = 338.0/459.0 ,
|
||||
|
||||
b71 = 5561.0/2376.0 ,
|
||||
b72 = -35.0/11.0 ,
|
||||
b73 = -24117.0/31603.0 ,
|
||||
b74 = 899983.0/200772.0 ,
|
||||
b75 = -5225.0/1836.0 ,
|
||||
b76 = 3925.0/4056.0 ,
|
||||
|
||||
b81 = 465467.0/266112.0 ,
|
||||
b82 = -2945.0/1232.0 ,
|
||||
b83 = -5610201.0/14158144.0 ,
|
||||
b84 = 10513573.0/3212352.0 ,
|
||||
b85 = -424325.0/205632.0 ,
|
||||
b86 = 376225.0/454272.0 ,
|
||||
b87 = 0.0 ,
|
||||
|
||||
c1 = 61.0/864.0 ,
|
||||
c2 = 0.0 ,
|
||||
c3 = 98415.0/321776.0 ,
|
||||
c4 = 16807.0/146016.0 ,
|
||||
c5 = 1375.0/7344.0 ,
|
||||
c6 = 1375.0/5408.0 ,
|
||||
c7 = -37.0/1120.0 ,
|
||||
c8 = 1.0/10.0 ,
|
||||
|
||||
b91 = 61.0/864.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 98415.0/321776.0 ,
|
||||
b94 = 16807.0/146016.0 ,
|
||||
b95 = 1375.0/7344.0 ,
|
||||
b96 = 1375.0/5408.0 ,
|
||||
b97 = -37.0/1120.0 ,
|
||||
b98 = 1.0/10.0 ,
|
||||
|
||||
b21 = 1.0/10.0 ,
|
||||
|
||||
b31 = -2.0/81.0 ,
|
||||
b32 = 20.0/81.0 ,
|
||||
|
||||
b41 = 615.0/1372.0 ,
|
||||
b42 = -270.0/343.0 ,
|
||||
b43 = 1053.0/1372.0 ,
|
||||
|
||||
b51 = 3243.0/5500.0 ,
|
||||
b52 = -54.0/55.0 ,
|
||||
b53 = 50949.0/71500.0 ,
|
||||
b54 = 4998.0/17875.0 ,
|
||||
|
||||
b61 = -26492.0/37125.0 ,
|
||||
b62 = 72.0/55.0 ,
|
||||
b63 = 2808.0/23375.0 ,
|
||||
b64 = -24206.0/37125.0 ,
|
||||
b65 = 338.0/459.0 ,
|
||||
|
||||
b71 = 5561.0/2376.0 ,
|
||||
b72 = -35.0/11.0 ,
|
||||
b73 = -24117.0/31603.0 ,
|
||||
b74 = 899983.0/200772.0 ,
|
||||
b75 = -5225.0/1836.0 ,
|
||||
b76 = 3925.0/4056.0 ,
|
||||
|
||||
b81 = 465467.0/266112.0 ,
|
||||
b82 = -2945.0/1232.0 ,
|
||||
b83 = -5610201.0/14158144.0 ,
|
||||
b84 = 10513573.0/3212352.0 ,
|
||||
b85 = -424325.0/205632.0 ,
|
||||
b86 = 376225.0/454272.0 ,
|
||||
b87 = 0.0 ,
|
||||
|
||||
c1 = 61.0/864.0 ,
|
||||
c2 = 0.0 ,
|
||||
c3 = 98415.0/321776.0 ,
|
||||
c4 = 16807.0/146016.0 ,
|
||||
c5 = 1375.0/7344.0 ,
|
||||
c6 = 1375.0/5408.0 ,
|
||||
c7 = -37.0/1120.0 ,
|
||||
c8 = 1.0/10.0 ,
|
||||
|
||||
b91 = 61.0/864.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 98415.0/321776.0 ,
|
||||
b94 = 16807.0/146016.0 ,
|
||||
b95 = 1375.0/7344.0 ,
|
||||
b96 = 1375.0/5408.0 ,
|
||||
b97 = -37.0/1120.0 ,
|
||||
b98 = 1.0/10.0 ,
|
||||
|
||||
dc1 = c1 - 821.0/10800.0 ,
|
||||
dc2 = c2 - 0.0 ,
|
||||
dc3 = c3 - 19683.0/71825,
|
||||
dc4 = c4 - 175273.0/912600.0 ,
|
||||
dc5 = c5 - 395.0/3672.0 ,
|
||||
dc6 = c6 - 785.0/2704.0 ,
|
||||
dc7 = c7 - 3.0/50.0 ,
|
||||
dc8 = c8 - 0.0 ,
|
||||
dc9 = 0.0;
|
||||
dc1 = c1 - 821.0/10800.0 ,
|
||||
dc2 = c2 - 0.0 ,
|
||||
dc3 = c3 - 19683.0/71825,
|
||||
dc4 = c4 - 175273.0/912600.0 ,
|
||||
dc5 = c5 - 395.0/3672.0 ,
|
||||
dc6 = c6 - 785.0/2704.0 ,
|
||||
dc7 = c7 - 3.0/50.0 ,
|
||||
dc8 = c8 - 0.0 ,
|
||||
dc9 = 0.0;
|
||||
|
||||
|
||||
// New Coefficients obtained from
|
||||
// Table 3 RK6(5)9FM with corrected coefficients
|
||||
//---Ref---
|
||||
// Table 3 RK6(5)9FM with corrected coefficients
|
||||
//
|
||||
// T. S. Baker, J. R. Dormand, J. P. Gilmore, and P. J. Prince,
|
||||
// “Continuous approximation with embedded Runge-Kutta methods,”
|
||||
// Applied Numerical Mathematics, vol. 22, no. 1, pp. 51–62, 1996.
|
||||
//------------------------------------
|
||||
|
||||
// "Continuous approximation with embedded Runge-Kutta methods"
|
||||
// Applied Numerical Mathematics, vol. 22, no. 1, pp. 51-62, 1996.
|
||||
//
|
||||
// b21 = 1.0/9.0 ,
|
||||
//
|
||||
// b31 = 1.0/24.0 ,
|
||||
@@ -273,101 +255,96 @@ void G4DormandPrinceRK56::Stepper(const G4double yInput[],
|
||||
// dc7 = 262119736669.0/345979336560.0 - b97,
|
||||
// dc8 = - 1.0/2.0 - b98 ,
|
||||
// dc9 = -101.0/2294.0 ;
|
||||
|
||||
|
||||
//end of declaration
|
||||
// end of declaration
|
||||
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// The number of variables to be integrated over
|
||||
//
|
||||
yOut[7] = yTemp[7] = yIn[7] = yInput[7];
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
// RightHandSide(yIn, dydx) ; // 1st Stage - Not doing, getting passed
|
||||
|
||||
|
||||
|
||||
// RightHandSide(yIn, dydx) ;
|
||||
// 1st Step - Not doing, getting passed
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*dydx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*dydx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*dydx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*dydx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b71*dydx[i] + b72*ak2[i] + b73*ak3[i] +
|
||||
b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak7); //7th Stage
|
||||
RightHandSide(yTemp, ak7); // 7th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b81*dydx[i] + b82*ak2[i] + b83*ak3[i] +
|
||||
b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
|
||||
b87*ak7[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak8); //8th Stage
|
||||
RightHandSide(yTemp, ak8); // 8th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b91*dydx[i] + b92*ak2[i] + b93*ak3[i] +
|
||||
b94*ak4[i] + b95*ak5[i] + b96*ak6[i] +
|
||||
b97*ak7[i] + b98*ak8[i] );
|
||||
}
|
||||
RightHandSide(yOut, ak9); //9th Stage
|
||||
RightHandSide(yOut, ak9); // 9th Stage
|
||||
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
|
||||
// Estimate error as difference between 5th and
|
||||
// 6th order methods
|
||||
|
||||
//
|
||||
yErr[i] = Step*( dc1*dydx[i] + dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i]
|
||||
+ dc5*ak5[i] + dc6*ak6[i] + dc7*ak7[i] + dc8*ak8[i]
|
||||
+ dc9*ak9[i] ) ;
|
||||
|
||||
// - Saving 'estimated' derivative at end-point
|
||||
// Saving 'estimated' derivative at end-point
|
||||
// nextDydx[i] = ak9[i];
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = dydx[i];
|
||||
|
||||
}
|
||||
|
||||
fLastStepLength = Step;
|
||||
@@ -375,16 +352,16 @@ void G4DormandPrinceRK56::Stepper(const G4double yInput[],
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
//The following has not been tested
|
||||
|
||||
//The DistChord() function fot the class - must define it here.
|
||||
// DistChord
|
||||
//
|
||||
G4double G4DormandPrinceRK56::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
@@ -398,12 +375,11 @@ G4double G4DormandPrinceRK56::DistChord() const
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
// distance of Chord
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distLine = G4LineSection::Distline( midPoint,initialPoint,finalPoint );
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
@@ -413,205 +389,195 @@ G4double G4DormandPrinceRK56::DistChord() const
|
||||
return distChord;
|
||||
}
|
||||
|
||||
|
||||
// The following interpolation scheme has been obtained from
|
||||
// Table 5. The RK6(5)9FM process and associated dense formula
|
||||
//---Ref---
|
||||
// J. R. Dormand, M. A. Lockyer, N. E. McGorrigan, and P. J. Prince,
|
||||
// “Global error estimation with runge-kutta triples,”
|
||||
// Computers & Mathematics with Applications, vol. 18, no. 9, pp. 835–846, 1989.
|
||||
//-----------------------------
|
||||
|
||||
//
|
||||
// J. R. Dormand, M. A. Lockyer, N. E. McGorrigan, and P. J. Prince,
|
||||
// "Global error estimation with runge-kutta triples"
|
||||
// Computers & Mathematics with Applications, vol.18, no.9, pp.835-846, 1989.
|
||||
//
|
||||
// Fifth order interpolant with one extra function evaluation per step
|
||||
|
||||
//
|
||||
void G4DormandPrinceRK56::SetupInterpolate_low( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step ){
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4double dydx[],
|
||||
const G4double Step )
|
||||
{
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
|
||||
G4double
|
||||
b_101 = 33797.0/460800.0 ,
|
||||
b_102 = 0. ,
|
||||
b_103 = 0. ,
|
||||
b_104 = 27757.0/70785.0 ,
|
||||
b_105 = 7923501.0/26329600.0 ,
|
||||
b_106 = -927.0/3760.0 ,
|
||||
b_107 = -3314760575.0/23165835264.0 ,
|
||||
b_108 = 2479.0/23040.0 ,
|
||||
b_109 = 1.0/64.0 ;
|
||||
G4double b_101 = 33797.0/460800.0 ,
|
||||
b_102 = 0. ,
|
||||
b_103 = 0. ,
|
||||
b_104 = 27757.0/70785.0 ,
|
||||
b_105 = 7923501.0/26329600.0 ,
|
||||
b_106 = -927.0/3760.0 ,
|
||||
b_107 = -3314760575.0/23165835264.0 ,
|
||||
b_108 = 2479.0/23040.0 ,
|
||||
b_109 = 1.0/64.0 ;
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b_101*dydx[i] + b_102*ak2[i] + b_103*ak3[i] +
|
||||
b_104*ak4[i] + b_105*ak5[i] + b_106*ak6[i] +
|
||||
b_107*ak7[i] + b_108*ak8[i] + b_109*ak9[i]);
|
||||
yTemp[i] = yIn[i] + Step*(b_101*dydx[i] + b_102*ak2[i] + b_103*ak3[i] +
|
||||
b_104*ak4[i] + b_105*ak5[i] + b_106*ak6[i] +
|
||||
b_107*ak7[i] + b_108*ak8[i] + b_109*ak9[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak10_low); //10th Stage
|
||||
RightHandSide(yTemp, ak10_low); // 10th Stage
|
||||
}
|
||||
|
||||
void G4DormandPrinceRK56::Interpolate_low( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau ){
|
||||
{
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau )
|
||||
{
|
||||
G4double bf1, bf4, bf5, bf6, bf7, bf8, bf9, bf10;
|
||||
|
||||
G4double
|
||||
bf1, bf4, bf5, bf6, bf7, bf8, bf9, bf10;
|
||||
|
||||
G4double tau0 = tau;
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
G4double tau0 = tau;
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
G4double
|
||||
tau_2 = tau0*tau0 ,
|
||||
tau_3 = tau0*tau_2,
|
||||
tau_4 = tau_2*tau_2;
|
||||
G4double tau_2 = tau0*tau0 ,
|
||||
tau_3 = tau0*tau_2,
|
||||
tau_4 = tau_2*tau_2;
|
||||
|
||||
//bf2 = bf3 = 0
|
||||
bf1 = (66480.0*tau_4 - 206243.0*tau_3 + 237786.0*tau_2 - 124793.0*tau + 28800.0)/28800.0 ,
|
||||
bf4 = -16.0*tau*(45312.0*tau_3 - 125933.0*tau_2 + 119706.0*tau -40973.0)/70785.0 ,
|
||||
bf5 = -2187.0*tau*(19440.0*tau_3 - 45743.0*tau_2 + 34786.0*tau - 9293.0)/1645600.0 ,
|
||||
bf6 = tau*(12864.0*tau_3 - 30653.0*tau_2 + 23786.0*tau - 6533.0)/705.0 ,
|
||||
bf7 = -5764801.0*tau*(16464.0*tau_3 - 32797.0*tau_2 + 17574.0*tau - 1927.0)/7239323520.0 ,
|
||||
bf8 = 37.0*tau*(336.0*tau_3 - 661.0*tau_2 + 342.0*tau -31.0)/1440.0 ,
|
||||
bf9 = tau*(tau-1.0)*(16.0*tau_2 - 15.0*tau +3.0)/4.0 ,
|
||||
bf10 = 8.0*tau*(tau - 1.0)*(tau - 1.0)*(2.0*tau - 1.0) ;
|
||||
// bf2 = bf3 = 0.0
|
||||
bf1 = (66480.0*tau_4-206243.0*tau_3+237786.0*tau_2-124793.0*tau+28800.0)
|
||||
/ 28800.0 ;
|
||||
bf4 = -16.0*tau*(45312.0*tau_3 - 125933.0*tau_2 + 119706.0*tau -40973.0)
|
||||
/ 70785.0 ;
|
||||
bf5 = -2187.0*tau*(19440.0*tau_3 - 45743.0*tau_2 + 34786.0*tau - 9293.0)
|
||||
/ 1645600.0 ;
|
||||
bf6 = tau*(12864.0*tau_3 - 30653.0*tau_2 + 23786.0*tau - 6533.0)
|
||||
/ 705.0 ;
|
||||
bf7 = -5764801.0*tau*(16464.0*tau_3 - 32797.0*tau_2 + 17574.0*tau - 1927.0)
|
||||
/ 7239323520.0 ;
|
||||
bf8 = 37.0*tau*(336.0*tau_3 - 661.0*tau_2 + 342.0*tau -31.0)
|
||||
/ 1440.0 ;
|
||||
bf9 = tau*(tau-1.0)*(16.0*tau_2 - 15.0*tau +3.0)
|
||||
/ 4.0 ;
|
||||
bf10 = 8.0*tau*(tau - 1.0)*(tau - 1.0)*(2.0*tau - 1.0) ;
|
||||
|
||||
for( int i=0; i<numberOfVariables; i++){
|
||||
yOut[i] = yIn[i] + Step*tau*( bf1*dydx[i] + bf4*ak4[i] + bf5*ak5[i] +
|
||||
bf6*ak6[i] + bf7*ak7[i] + bf8*ak8[i] +
|
||||
bf9*ak9[i] + bf10*ak10_low[i] ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
for( G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*tau*( bf1*dydx[i] + bf4*ak4[i] + bf5*ak5[i] +
|
||||
bf6*ak6[i] + bf7*ak7[i] + bf8*ak8[i] +
|
||||
bf9*ak9[i] + bf10*ak10_low[i] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
//The following scheme and set of coefficients have been obtained from
|
||||
//Table 2. Sixth order dense formula based on linear optimisation for RK6(5)9FM
|
||||
//with extra stages C1O= 1/2, C11 =1/6, c12= 5/12
|
||||
|
||||
//---Ref---
|
||||
// T. S. Baker, J. R. Dormand, J. P. Gilmore, and P. J. Prince,
|
||||
// “Continuous approximation with embedded Runge-Kutta methods,”
|
||||
// Applied Numerical Mathematics, vol. 22, no. 1, pp. 51–62, 1996.
|
||||
//--------------------
|
||||
|
||||
|
||||
// --- Sixth order interpolant with 3 additional stages per step ---
|
||||
|
||||
//Function for calculating the additional stages :
|
||||
// The following scheme and set of coefficients have been obtained from
|
||||
// Table 2. Sixth order dense formula based on linear optimisation for
|
||||
// RK6(5)9FM with extra stages C1O= 1/2, C11 =1/6, c12= 5/12
|
||||
//
|
||||
// T. S. Baker, J. R. Dormand, J. P. Gilmore, and P. J. Prince,
|
||||
// "Continuous approximation with embedded Runge-Kutta methods"
|
||||
// Applied Numerical Mathematics, vol. 22, no. 1, pp. 51-62, 1996.
|
||||
//
|
||||
// --- Sixth order interpolant with 3 additional stages per step ---
|
||||
//
|
||||
// Function for calculating the additional stages
|
||||
//
|
||||
void G4DormandPrinceRK56::SetupInterpolate_high( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step ){
|
||||
const G4double dydx[],
|
||||
const G4double Step )
|
||||
{
|
||||
// Coefficients for the additional stages
|
||||
//
|
||||
G4double b101 = 33797.0/460800.0 ,
|
||||
b102 = 0.0 ,
|
||||
b103 = 0.0 ,
|
||||
b104 = 27757.0/70785.0 ,
|
||||
b105 = 7923501.0/26329600.0 ,
|
||||
b106 = -927.0/3760.0 ,
|
||||
b107 = -3314760575.0/23165835264.0 ,
|
||||
b108 = 2479.0/23040.0 ,
|
||||
b109 = 1.0/64.0 ,
|
||||
|
||||
//Coefficients for the additional stages :
|
||||
b111 = 5843.0/76800.0 ,
|
||||
b112 = 0.0 ,
|
||||
b113 = 0.0 ,
|
||||
b114 = 464.0/2673.0 ,
|
||||
b115 = 353997.0/1196800.0 ,
|
||||
b116 = -15068.0/57105.0 ,
|
||||
b117 = -282475249.0/3644974080.0 ,
|
||||
b118 = 8678831.0/156245760.0 ,
|
||||
b119 = 116113.0/11718432.0 ,
|
||||
b1110 = -25.0/243.0 ,
|
||||
|
||||
G4double
|
||||
b101 = 33797.0/460800.0 ,
|
||||
b102 = 0.0 ,
|
||||
b103 = 0.0 ,
|
||||
b104 = 27757.0/70785.0 ,
|
||||
b105 = 7923501.0/26329600.0 ,
|
||||
b106 = -927.0/3760.0 ,
|
||||
b107 = -3314760575.0/23165835264.0 ,
|
||||
b108 = 2479.0/23040.0 ,
|
||||
b109 = 1.0/64.0 ,
|
||||
b121 = 15088049.0/199065600.0 ,
|
||||
b122 = 0.0 ,
|
||||
b123 = 0.0 ,
|
||||
b124 = 2.0/5.0 ,
|
||||
b125 = 92222037.0/268083200.0 ,
|
||||
b126 = -433420501.0/1528586640.0 ,
|
||||
b127 = -11549242677007.0/83630285291520.0 ,
|
||||
b128 = 2725085557.0/26167173120.0 ,
|
||||
b129 = 235429367.0/16354483200.0 ,
|
||||
b1210 = -90924917.0/1040739840.0 ,
|
||||
b1211 = -271149.0/21414400.0 ;
|
||||
|
||||
b111 = 5843.0/76800.0 ,
|
||||
b112 = 0.0 ,
|
||||
b113 = 0.0 ,
|
||||
b114 = 464.0/2673.0 ,
|
||||
b115 = 353997.0/1196800.0 ,
|
||||
b116 = -15068.0/57105.0 ,
|
||||
b117 = -282475249.0/3644974080.0 ,
|
||||
b118 = 8678831.0/156245760.0 ,
|
||||
b119 = 116113.0/11718432.0 ,
|
||||
b1110 = -25.0/243.0 ,
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
b121 = 15088049.0/199065600.0 ,
|
||||
b122 = 0.0 ,
|
||||
b123 = 0.0 ,
|
||||
b124 = 2.0/5.0 ,
|
||||
b125 = 92222037.0/268083200.0 ,
|
||||
b126 = -433420501.0/1528586640.0 ,
|
||||
b127 = -11549242677007.0/83630285291520.0 ,
|
||||
b128 = 2725085557.0/26167173120.0 ,
|
||||
b129 = 235429367.0/16354483200.0 ,
|
||||
b1210 = -90924917.0/1040739840.0 ,
|
||||
b1211 = -271149.0/21414400.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++)
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
yTemp[7] = yIn[7];
|
||||
|
||||
|
||||
|
||||
//Evaluate the extra stages :
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
// Evaluate the extra stages
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b101*dydx[i] + b102*ak2[i] + b103*ak3[i] +
|
||||
b104*ak4[i] + b105*ak5[i] + b106*ak6[i] +
|
||||
b107*ak7[i] + b108*ak8[i] + b109*ak9[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak10); //10th Stage
|
||||
RightHandSide(yTemp, ak10); // 10th Stage
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b111*dydx[i] + b112*ak2[i] + b113*ak3[i] +
|
||||
b114*ak4[i] + b115*ak5[i] + b116*ak6[i] +
|
||||
b117*ak7[i] + b118*ak8[i] + b119*ak9[i] +
|
||||
b1110*ak10[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak11); //11th Stage
|
||||
RightHandSide(yTemp, ak11); // 11th Stage
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b121*dydx[i] + b122*ak2[i] + b123*ak3[i] +
|
||||
b124*ak4[i] + b125*ak5[i] + b126*ak6[i] +
|
||||
b127*ak7[i] + b128*ak8[i] + b129*ak9[i] +
|
||||
b1210*ak10[i] + b1211*ak11[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak12); //12th Stage
|
||||
|
||||
RightHandSide(yTemp, ak12); // 12th Stage
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Function to interpolate to tau(passed in) fraction of the step
|
||||
// Function to interpolate to tau(passed in) fraction of the step
|
||||
//
|
||||
void G4DormandPrinceRK56::Interpolate_high( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau )
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau )
|
||||
{
|
||||
|
||||
//Define the coefficients for the polynomials
|
||||
// Define the coefficients for the polynomials
|
||||
//
|
||||
G4double bi[13][6], b[13];
|
||||
G4int numberOfVariables = this->GetNumberOfVariables();
|
||||
G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
|
||||
|
||||
// COEFFICIENTS OF bi[ 1]
|
||||
bi[1][0] = 1.0 ,
|
||||
bi[1][1] = -18487.0/2880.0 ,
|
||||
@@ -720,31 +686,34 @@ void G4DormandPrinceRK56::Interpolate_high( const G4double yInput[],
|
||||
bi[12][5] = -13824.0/175.0 ;
|
||||
// --------------------------------------------------------
|
||||
|
||||
|
||||
for(G4int i = 0; i< numberOfVariables; i++)
|
||||
for(G4int i = 0; i< numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i] = yInput[i];
|
||||
|
||||
}
|
||||
|
||||
G4double tau0 = tau;
|
||||
// Calculating the polynomials (coefficents for the respective stages) :
|
||||
|
||||
for(int i=1; i<=12; i++){ //Here i is NOT the coordinate no. , it's stage no.
|
||||
|
||||
// Calculating the polynomials (coefficents for the respective stages) :
|
||||
//
|
||||
for(auto i=1; i<=12; ++i) // i is NOT the coordinate no., it's stage no.
|
||||
{
|
||||
b[i] = 0;
|
||||
tau = 1.0;
|
||||
for(int j=0; j<=5; j++){
|
||||
for(auto j=0; j<=5; ++j)
|
||||
{
|
||||
b[i] += bi[i][j]*tau;
|
||||
tau*=tau0;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculating the interpolation at the fraction tau of the step using the polynomial
|
||||
// coefficients and the respective stages
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){ //Here i IS the cooridnate no.
|
||||
yOut[i] = yIn[i] + Step*tau0*(b[1]*dydx[i] + b[2]*ak2[i] + b[3]*ak3[i] +
|
||||
b[4]*ak4[i] + b[5]*ak5[i] + b[6]*ak6[i] +
|
||||
b[7]*ak7[i] + b[8]*ak8[i] + b[9]*ak9[i] +
|
||||
// Calculating the interpolation at the fraction tau of the step using
|
||||
// the polynomial coefficients and the respective stages
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i) // Here i IS the coordinate no.
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*tau0*(b[1]*dydx[i] + b[2]*ak2[i] + b[3]*ak3[i] +
|
||||
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] + b[12]*ak12[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//-----Verified--------- - hackabot
|
||||
|
||||
@@ -23,41 +23,33 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// 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
|
||||
// G4DormandPrinceRK78 implementation
|
||||
//
|
||||
// First version: 28 June 2015
|
||||
// Dormand-Prince 8(7)13M non-FSAL, based on RK scheme from:
|
||||
// P.J. Prince, J.R. Dormand, "High order embedded Runge-Kutta formulae",
|
||||
// Journal of Computational and Applied Mathematics, Volume 7, Issue 1, 1981,
|
||||
// Pages 67-75, ISSN 0377-0427, DOI: 10.1016/0771-050X(81)90010-3
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// History (condensed)
|
||||
// -----------------------------
|
||||
// 28 June 2015: First version created - S. Banerjee
|
||||
// 4 July 2017: Small fixes (Coverity issues) - J. Apostolakis
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 28 June 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4DormandPrinceRK78.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
//Constructor
|
||||
G4DormandPrinceRK78::G4DormandPrinceRK78(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength(-1.0), fAuxStepper(nullptr)
|
||||
// Constructor
|
||||
//
|
||||
G4DormandPrinceRK78::G4DormandPrinceRK78(G4EquationOfMotion* EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
|
||||
//New Chunk of memory being created for use by the stepper
|
||||
// New Chunk of memory being created for use by the stepper
|
||||
|
||||
//aki - for storing intermediate RHS
|
||||
// aki - for storing intermediate RHS
|
||||
//
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
@@ -85,303 +77,299 @@ G4DormandPrinceRK78::G4DormandPrinceRK78(G4EquationOfMotion *EqRhs,
|
||||
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4DormandPrinceRK78(EqRhs, numberOfVariables,
|
||||
!primary);
|
||||
fAuxStepper = new G4DormandPrinceRK78(EqRhs, numberOfVariables, !primary);
|
||||
}
|
||||
}
|
||||
|
||||
//Destructor
|
||||
G4DormandPrinceRK78::~G4DormandPrinceRK78(){
|
||||
//clear all previously allocated memory for stepper and DistChord
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
delete[] ak7;
|
||||
delete[] ak8;
|
||||
delete[] ak9;
|
||||
delete[] ak10;
|
||||
delete[] ak11;
|
||||
delete[] ak12;
|
||||
delete[] ak13;
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
// Destructor
|
||||
//
|
||||
G4DormandPrinceRK78::~G4DormandPrinceRK78()
|
||||
{
|
||||
// Clear all previously allocated memory for stepper and DistChord
|
||||
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
delete [] ak7;
|
||||
delete [] ak8;
|
||||
delete [] ak9;
|
||||
delete [] ak10;
|
||||
delete [] ak11;
|
||||
delete [] ak12;
|
||||
delete [] ak13;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// The following scheme and the set of coefficients have been obtained from
|
||||
//Table2. RK8(7)13M (Rational approximations
|
||||
//---Ref---
|
||||
// P. J. Prince and J. R. Dormand, “High order embedded Runge-Kutta formulae,”
|
||||
// Journal of Computational and Applied Mathematics,
|
||||
// vol. 7, no. 1, pp. 67–75, Dec. 1980.
|
||||
//------------------------------
|
||||
//Stepper :
|
||||
|
||||
// The following scheme and the set of coefficients have been obtained from
|
||||
// Table2. RK8(7)13M (Rational approximations) from:
|
||||
// P. J. Prince and J. R. Dormand, "High order embedded Runge-Kutta formulae"
|
||||
// Journal of Computational and Applied Math., vol.7, no.1, pp.67-75, 1980.
|
||||
//
|
||||
// Stepper :
|
||||
//
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4DormandPrinceRK78::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[])
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[])
|
||||
{
|
||||
G4int i;
|
||||
|
||||
//The various constants defined on the basis of butcher tableu
|
||||
//G4double - only once
|
||||
const G4double
|
||||
// The various constants defined on the basis of butcher tableu
|
||||
//
|
||||
const G4double b21 = 1.0/18,
|
||||
b31 = 1.0/48.0 ,
|
||||
b32 = 1.0/16.0 ,
|
||||
|
||||
b21 = 1.0/18,
|
||||
b41 = 1.0/32.0 ,
|
||||
b42 = 0.0 ,
|
||||
b43 = 3.0/32.0 ,
|
||||
|
||||
b31 = 1.0/48.0 ,
|
||||
b32 = 1.0/16.0 ,
|
||||
b51 = 5.0/16.0 ,
|
||||
b52 = 0.0 ,
|
||||
b53 = -75.0/64.0 ,
|
||||
b54 = 75.0/64.0 ,
|
||||
|
||||
b41 = 1.0/32.0 ,
|
||||
b42 = 0.0 ,
|
||||
b43 = 3.0/32.0 ,
|
||||
b61 = 3.0/80.0 ,
|
||||
b62 = 0.0 ,
|
||||
b63 = 0.0 ,
|
||||
b64 = 3.0/16.0 ,
|
||||
b65 = 3.0/20.0 ,
|
||||
|
||||
b51 = 5.0/16.0 ,
|
||||
b52 = 0.0 ,
|
||||
b53 = -75.0/64.0 ,
|
||||
b54 = 75.0/64.0 ,
|
||||
b71 = 29443841.0/614563906.0 ,
|
||||
b72 = 0.0 ,
|
||||
b73 = 0.0 ,
|
||||
b74 = 77736538.0/692538347.0 ,
|
||||
b75 = -28693883.0/1125000000.0 ,
|
||||
b76 = 23124283.0/1800000000.0 ,
|
||||
|
||||
b61 = 3.0/80.0 ,
|
||||
b62 = 0.0 ,
|
||||
b63 = 0.0 ,
|
||||
b64 = 3.0/16.0 ,
|
||||
b65 = 3.0/20.0 ,
|
||||
b81 = 16016141.0/946692911.0 ,
|
||||
b82 = 0.0 ,
|
||||
b83 = 0.0 ,
|
||||
b84 = 61564180.0/158732637.0 ,
|
||||
b85 = 22789713.0/633445777.0 ,
|
||||
b86 = 545815736.0/2771057229.0 ,
|
||||
b87 = -180193667.0/1043307555.0 ,
|
||||
|
||||
b71 = 29443841.0/614563906.0 ,
|
||||
b72 = 0.0 ,
|
||||
b73 = 0.0 ,
|
||||
b74 = 77736538.0/692538347.0 ,
|
||||
b75 = -28693883.0/1125000000.0 ,
|
||||
b76 = 23124283.0/1800000000.0 ,
|
||||
b91 = 39632708.0/573591083.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 0.0 ,
|
||||
b94 = -433636366.0/683701615.0 ,
|
||||
b95 = -421739975.0/2616292301.0 ,
|
||||
b96 = 100302831.0/723423059.0 ,
|
||||
b97 = 790204164.0/839813087.0 ,
|
||||
b98 = 800635310.0/3783071287.0 ,
|
||||
|
||||
b81 = 16016141.0/946692911.0 ,
|
||||
b82 = 0.0 ,
|
||||
b83 = 0.0 ,
|
||||
b84 = 61564180.0/158732637.0 ,
|
||||
b85 = 22789713.0/633445777.0 ,
|
||||
b86 = 545815736.0/2771057229.0 ,
|
||||
b87 = -180193667.0/1043307555.0 ,
|
||||
b101 = 246121993.0/1340847787.0 ,
|
||||
b102 = 0.0 ,
|
||||
b103 = 0.0 ,
|
||||
b104 = -37695042795.0/15268766246.0 ,
|
||||
b105 = -309121744.0/1061227803.0 ,
|
||||
b106 = -12992083.0/490766935.0 ,
|
||||
b107 = 6005943493.0/2108947869.0 ,
|
||||
b108 = 393006217.0/1396673457.0 ,
|
||||
b109 = 123872331.0/1001029789.0 ,
|
||||
|
||||
b91 = 39632708.0/573591083.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 0.0 ,
|
||||
b94 = -433636366.0/683701615.0 ,
|
||||
b95 = -421739975.0/2616292301.0 ,
|
||||
b96 = 100302831.0/723423059.0 ,
|
||||
b97 = 790204164.0/839813087.0 ,
|
||||
b98 = 800635310.0/3783071287.0 ,
|
||||
b111 = -1028468189.0/846180014.0 ,
|
||||
b112 = 0.0 ,
|
||||
b113 = 0.0 ,
|
||||
b114 = 8478235783.0/508512852.0 ,
|
||||
b115 = 1311729495.0/1432422823.0 ,
|
||||
b116 = -10304129995.0/1701304382.0 ,
|
||||
b117 = -48777925059.0/3047939560.0 ,
|
||||
b118 = 15336726248.0/1032824649.0 ,
|
||||
b119 = -45442868181.0/3398467696.0 ,
|
||||
b1110 = 3065993473.0/597172653.0 ,
|
||||
|
||||
b101 = 246121993.0/1340847787.0 ,
|
||||
b102 = 0.0 ,
|
||||
b103 = 0.0 ,
|
||||
b104 = -37695042795.0/15268766246.0 ,
|
||||
b105 = -309121744.0/1061227803.0 ,
|
||||
b106 = -12992083.0/490766935.0 ,
|
||||
b107 = 6005943493.0/2108947869.0 ,
|
||||
b108 = 393006217.0/1396673457.0 ,
|
||||
b109 = 123872331.0/1001029789.0 ,
|
||||
b121 = 185892177.0/718116043.0 ,
|
||||
b122 = 0.0 ,
|
||||
b123 = 0.0 ,
|
||||
b124 = -3185094517.0/667107341.0 ,
|
||||
b125 = -477755414.0/1098053517.0 ,
|
||||
b126 = -703635378.0/230739211.0 ,
|
||||
b127 = 5731566787.0/1027545527.0 ,
|
||||
b128 = 5232866602.0/850066563.0 ,
|
||||
b129 = -4093664535.0/808688257.0 ,
|
||||
b1210 = 3962137247.0/1805957418.0 ,
|
||||
b1211 = 65686358.0/487910083.0 ,
|
||||
|
||||
b111 = -1028468189.0/846180014.0 ,
|
||||
b112 = 0.0 ,
|
||||
b113 = 0.0 ,
|
||||
b114 = 8478235783.0/508512852.0 ,
|
||||
b115 = 1311729495.0/1432422823.0 ,
|
||||
b116 = -10304129995.0/1701304382.0 ,
|
||||
b117 = -48777925059.0/3047939560.0 ,
|
||||
b118 = 15336726248.0/1032824649.0 ,
|
||||
b119 = -45442868181.0/3398467696.0 ,
|
||||
b1110 = 3065993473.0/597172653.0 ,
|
||||
b131 = 403863854.0/491063109.0 ,
|
||||
b132 = 0.0 ,
|
||||
b133 = 0.0 ,
|
||||
b134 = -5068492393.0/434740067.0 ,
|
||||
b135 = -411421997.0/543043805.0 ,
|
||||
b136 = 652783627.0/914296604.0 ,
|
||||
b137 = 11173962825.0/925320556.0 ,
|
||||
b138 = -13158990841.0/6184727034.0 ,
|
||||
b139 = 3936647629.0/1978049680.0 ,
|
||||
b1310 = -160528059.0/685178525.0 ,
|
||||
b1311 = 248638103.0/1413531060.0 ,
|
||||
b1312 = 0.0 ,
|
||||
|
||||
b121 = 185892177.0/718116043.0 ,
|
||||
b122 = 0.0 ,
|
||||
b123 = 0.0 ,
|
||||
b124 = -3185094517.0/667107341.0 ,
|
||||
b125 = -477755414.0/1098053517.0 ,
|
||||
b126 = -703635378.0/230739211.0 ,
|
||||
b127 = 5731566787.0/1027545527.0 ,
|
||||
b128 = 5232866602.0/850066563.0 ,
|
||||
b129 = -4093664535.0/808688257.0 ,
|
||||
b1210 = 3962137247.0/1805957418.0 ,
|
||||
b1211 = 65686358.0/487910083.0 ,
|
||||
c1 = 14005451.0/335480064.0 ,
|
||||
// c2 = 0.0 ,
|
||||
// c3 = 0.0 ,
|
||||
// c4 = 0.0 ,
|
||||
// c5 = 0.0 ,
|
||||
c6 = -59238493.0/1068277825.0 ,
|
||||
c7 = 181606767.0/758867731.0 ,
|
||||
c8 = 561292985.0/797845732.0 ,
|
||||
c9 = -1041891430.0/1371343529.0 ,
|
||||
c10 = 760417239.0/1151165299.0 ,
|
||||
c11 = 118820643.0/751138087.0 ,
|
||||
c12 = - 528747749.0/2220607170.0 ,
|
||||
c13 = 1.0/4.0 ,
|
||||
|
||||
b131 = 403863854.0/491063109.0 ,
|
||||
b132 = 0.0 ,
|
||||
b133 = 0.0 ,
|
||||
b134 = -5068492393.0/434740067.0 ,
|
||||
b135 = -411421997.0/543043805.0 ,
|
||||
b136 = 652783627.0/914296604.0 ,
|
||||
b137 = 11173962825.0/925320556.0 ,
|
||||
b138 = -13158990841.0/6184727034.0 ,
|
||||
b139 = 3936647629.0/1978049680.0 ,
|
||||
b1310 = -160528059.0/685178525.0 ,
|
||||
b1311 = 248638103.0/1413531060.0 ,
|
||||
b1312 = 0.0 ,
|
||||
c_1 = 13451932.0/455176623.0 ,
|
||||
// c_2 = 0.0 ,
|
||||
// c_3 = 0.0 ,
|
||||
// c_4 = 0.0 ,
|
||||
// c_5 = 0.0 ,
|
||||
c_6 = -808719846.0/976000145.0 ,
|
||||
c_7 = 1757004468.0/5645159321.0 ,
|
||||
c_8 = 656045339.0/265891186.0 ,
|
||||
c_9 = -3867574721.0/1518517206.0 ,
|
||||
c_10 = 465885868.0/322736535.0 ,
|
||||
c_11 = 53011238.0/667516719.0 ,
|
||||
c_12 = 2.0/45.0 ,
|
||||
c_13 = 0.0 ,
|
||||
|
||||
c1 = 14005451.0/335480064.0 ,
|
||||
// c2 = 0.0 ,
|
||||
// c3 = 0.0 ,
|
||||
// c4 = 0.0 ,
|
||||
// c5 = 0.0 ,
|
||||
c6 = -59238493.0/1068277825.0 ,
|
||||
c7 = 181606767.0/758867731.0 ,
|
||||
c8 = 561292985.0/797845732.0 ,
|
||||
c9 = -1041891430.0/1371343529.0 ,
|
||||
c10 = 760417239.0/1151165299.0 ,
|
||||
c11 = 118820643.0/751138087.0 ,
|
||||
c12 = - 528747749.0/2220607170.0 ,
|
||||
c13 = 1.0/4.0 ,
|
||||
dc1 = c_1 - c1 ,
|
||||
// dc2 = c_2 - c2 ,
|
||||
// dc3 = c_3 - c3 ,
|
||||
// dc4 = c_4 - c4 ,
|
||||
// dc5 = c_5 - c5 ,
|
||||
dc6 = c_6 - c6 ,
|
||||
dc7 = c_7 - c7 ,
|
||||
dc8 = c_8 - c8 ,
|
||||
dc9 = c_9 - c9 ,
|
||||
dc10 = c_10 - c10 ,
|
||||
dc11 = c_11 - c11 ,
|
||||
dc12 = c_12 - c12 ,
|
||||
dc13 = c_13 - c13 ;
|
||||
//
|
||||
// end of declaration !
|
||||
|
||||
c_1 = 13451932.0/455176623.0 ,
|
||||
// c_2 = 0.0 ,
|
||||
// c_3 = 0.0 ,
|
||||
// c_4 = 0.0 ,
|
||||
// c_5 = 0.0 ,
|
||||
c_6 = -808719846.0/976000145.0 ,
|
||||
c_7 = 1757004468.0/5645159321.0 ,
|
||||
c_8 = 656045339.0/265891186.0 ,
|
||||
c_9 = -3867574721.0/1518517206.0 ,
|
||||
c_10 = 465885868.0/322736535.0 ,
|
||||
c_11 = 53011238.0/667516719.0 ,
|
||||
c_12 = 2.0/45.0 ,
|
||||
c_13 = 0.0 ,
|
||||
|
||||
dc1 = c_1 - c1 ,
|
||||
// dc2 = c_2 - c2 ,
|
||||
// dc3 = c_3 - c3 ,
|
||||
// dc4 = c_4 - c4 ,
|
||||
// dc5 = c_5 - c5 ,
|
||||
dc6 = c_6 - c6 ,
|
||||
dc7 = c_7 - c7 ,
|
||||
dc8 = c_8 - c8 ,
|
||||
dc9 = c_9 - c9 ,
|
||||
dc10 = c_10 - c10 ,
|
||||
dc11 = c_11 - c11 ,
|
||||
dc12 = c_12 - c12 ,
|
||||
dc13 = c_13 - c13 ;
|
||||
|
||||
//end of declaration !
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// The number of variables to be integrated over
|
||||
//
|
||||
yOut[7] = yTemp[7] = yIn[7] = yInput[7];
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
// RightHandSide(yIn, dydx) ; // 1st Stage - Not doing, getting passed
|
||||
|
||||
// RightHandSide(yIn, dydx) ;
|
||||
// 1st Stage - Not doing, getting passed
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*dydx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*dydx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*dydx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*dydx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b71*dydx[i] + b72*ak2[i] + b73*ak3[i] +
|
||||
b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak7); //7th Stage
|
||||
RightHandSide(yTemp, ak7); // 7th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b81*dydx[i] + b82*ak2[i] + b83*ak3[i] +
|
||||
b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
|
||||
b87*ak7[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak8); //8th Stage
|
||||
RightHandSide(yTemp, ak8); // 8th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b91*dydx[i] + b92*ak2[i] + b93*ak3[i] +
|
||||
b94*ak4[i] + b95*ak5[i] + b96*ak6[i] +
|
||||
b97*ak7[i] + b98*ak8[i] );
|
||||
}
|
||||
RightHandSide(yTemp, ak9); //9th Stage
|
||||
RightHandSide(yTemp, ak9); // 9th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b101*dydx[i] + b102*ak2[i] + b103*ak3[i] +
|
||||
b104*ak4[i] + b105*ak5[i] + b106*ak6[i] +
|
||||
b107*ak7[i] + b108*ak8[i] + b109*ak9[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak10); //10th Stage
|
||||
RightHandSide(yTemp, ak10); // 10th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b111*dydx[i] + b112*ak2[i] + b113*ak3[i] +
|
||||
b114*ak4[i] + b115*ak5[i] + b116*ak6[i] +
|
||||
b117*ak7[i] + b118*ak8[i] + b119*ak9[i] +
|
||||
b1110*ak10[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak11); //11th Stage
|
||||
RightHandSide(yTemp, ak11); // 11th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b121*dydx[i] + b122*ak2[i] + b123*ak3[i] +
|
||||
b124*ak4[i] + b125*ak5[i] + b126*ak6[i] +
|
||||
b127*ak7[i] + b128*ak8[i] + b129*ak9[i] +
|
||||
b1210*ak10[i] + b1211*ak11[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak12); //12th Stage
|
||||
RightHandSide(yTemp, ak12); // 12th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b131*dydx[i] + b132*ak2[i] + b133*ak3[i] +
|
||||
b134*ak4[i] + b135*ak5[i] + b136*ak6[i] +
|
||||
b137*ak7[i] + b138*ak8[i] + b139*ak9[i] +
|
||||
b1310*ak10[i] + b1311*ak11[i] + b1312*ak12[i]);
|
||||
yTemp[i] = yIn[i]+Step*(b131*dydx[i] + b132*ak2[i] + b133*ak3[i] +
|
||||
b134*ak4[i] + b135*ak5[i] + b136*ak6[i] +
|
||||
b137*ak7[i] + b138*ak8[i] + b139*ak9[i] +
|
||||
b1310*ak10[i] + b1311*ak11[i] + b1312*ak12[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak13); //13th and final Stage
|
||||
RightHandSide(yTemp, ak13); // 13th and final Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
// Accumulate increments with proper weights
|
||||
|
||||
@@ -391,36 +379,35 @@ void G4DormandPrinceRK78::Stepper(const G4double yInput[],
|
||||
c7*ak7[i] + c8*ak8[i] +c9*ak9[i] + c10*ak10[i]
|
||||
+ c11*ak11[i] + c12*ak12[i] + c13*ak13[i]) ;
|
||||
|
||||
// Estimate error as difference between 7th and
|
||||
// 8th order methods
|
||||
|
||||
// Estimate error as difference between 7th and 8th order methods
|
||||
//
|
||||
yErr[i] = Step*(dc1*dydx[i] + // dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i]
|
||||
// + dc5*ak5[i]
|
||||
+ dc6*ak6[i] + dc7*ak7[i] + dc8*ak8[i]
|
||||
+ dc9*ak9[i] + dc10*ak10[i] + dc11*ak11[i] + dc12*ak12[i]
|
||||
+ dc13*ak13[i] ) ;
|
||||
+ dc6*ak6[i] + dc7*ak7[i] + dc8*ak8[i]
|
||||
+ dc9*ak9[i] + dc10*ak10[i] + dc11*ak11[i] + dc12*ak12[i]
|
||||
+ dc13*ak13[i] ) ;
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = dydx[i];
|
||||
|
||||
|
||||
}
|
||||
|
||||
fLastStepLength = Step;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//The DistChord() function fot the class - must define it here.
|
||||
// DistChord
|
||||
//
|
||||
G4double G4DormandPrinceRK78::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
@@ -434,12 +421,11 @@ G4double G4DormandPrinceRK78::DistChord() const
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
// distance of Chord
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distLine = G4LineSection::Distline(midPoint, initialPoint, finalPoint);
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
@@ -448,9 +434,3 @@ G4double G4DormandPrinceRK78::DistChord() const
|
||||
}
|
||||
return distChord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//------Verified------- - hackabot
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ElectricField implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis - 04.11.2003
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ElectricField.hh"
|
||||
@@ -37,12 +38,12 @@ G4ElectricField::~G4ElectricField()
|
||||
{
|
||||
}
|
||||
|
||||
G4ElectricField::G4ElectricField(const G4ElectricField &p)
|
||||
G4ElectricField::G4ElectricField(const G4ElectricField& p)
|
||||
: G4ElectroMagneticField(p)
|
||||
{
|
||||
}
|
||||
|
||||
G4ElectricField& G4ElectricField::operator = (const G4ElectricField &p)
|
||||
G4ElectricField& G4ElectricField::operator = (const G4ElectricField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4ElectroMagneticField::operator=(p);
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ElectroMagneticField implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis, 12.11.1998
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ElectroMagneticField.hh"
|
||||
@@ -38,13 +39,13 @@ G4ElectroMagneticField::~G4ElectroMagneticField()
|
||||
{
|
||||
}
|
||||
|
||||
G4ElectroMagneticField::G4ElectroMagneticField(const G4ElectroMagneticField &r)
|
||||
G4ElectroMagneticField::G4ElectroMagneticField(const G4ElectroMagneticField& r)
|
||||
: G4Field( r ) // To allow extension to joint EM & g field
|
||||
{
|
||||
}
|
||||
|
||||
G4ElectroMagneticField&
|
||||
G4ElectroMagneticField::operator = (const G4ElectroMagneticField &p)
|
||||
G4ElectroMagneticField::operator = (const G4ElectroMagneticField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4Field::operator=(p);
|
||||
|
||||
@@ -23,15 +23,13 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4EqEMFieldWithEDM implementation
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
//
|
||||
// 19.02.2009 Kevin Lynch, based on G4EqEMFieldWithSpin
|
||||
// 06.11.2009 Hiromi Iinuma see:
|
||||
// http://hypernews.slac.stanford.edu/HyperNews/geant4/get/emfields/161.html
|
||||
//
|
||||
// Created: Kevin Lynch, 19.02.2009 - Based on G4EqEMFieldWithSpin
|
||||
// Modified: Hiromi Iinuma, 06.11.2009 - see:
|
||||
// http://hypernews.slac.stanford.edu/HyperNews/geant4/get/emfields/161.html
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EqEMFieldWithEDM.hh"
|
||||
@@ -41,7 +39,7 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4EqEMFieldWithEDM::G4EqEMFieldWithEDM(G4ElectroMagneticField *emField )
|
||||
G4EqEMFieldWithEDM::G4EqEMFieldWithEDM(G4ElectroMagneticField* emField )
|
||||
: G4EquationOfMotion( emField ), charge(0.), mass(0.), magMoment(0.),
|
||||
spin(0.), fElectroMagCof(0.), fMassCof(0.), omegac(0.),
|
||||
anomaly(0.0011659208), eta(0.), beta(0.), gamma(0.)
|
||||
@@ -57,7 +55,7 @@ G4EqEMFieldWithEDM::SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double particleMass)
|
||||
{
|
||||
charge = particleCharge.GetCharge();
|
||||
charge = particleCharge.GetCharge();
|
||||
mass = particleMass;
|
||||
magMoment = particleCharge.GetMagneticDipoleMoment();
|
||||
spin = particleCharge.GetSpin();
|
||||
@@ -82,8 +80,8 @@ G4EqEMFieldWithEDM::SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
|
||||
void
|
||||
G4EqEMFieldWithEDM::EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
|
||||
// Components of y:
|
||||
@@ -158,9 +156,9 @@ G4EqEMFieldWithEDM::EvaluateRhsGivenB(const G4double y[],
|
||||
else pcharge = charge;
|
||||
|
||||
G4ThreeVector dSpin(0.,0.,0.);
|
||||
if (Spin.mag2() != 0.) {
|
||||
dSpin =
|
||||
pcharge*omegac*( ucb*(Spin.cross(BField))-udb*(Spin.cross(u))
|
||||
if (Spin.mag2() != 0.)
|
||||
{
|
||||
dSpin = pcharge*omegac*( ucb*(Spin.cross(BField))-udb*(Spin.cross(u))
|
||||
// from Jackson
|
||||
// -uce*Spin.cross(u.cross(EField)) )
|
||||
// but this form has one less operation
|
||||
@@ -174,5 +172,5 @@ G4EqEMFieldWithEDM::EvaluateRhsGivenB(const G4double y[],
|
||||
dydx[10] = dSpin.y();
|
||||
dydx[11] = dSpin.z();
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,15 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4EqEMFieldWithSpin implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
//
|
||||
// 30.08.2007 Chris Gong, Peter Gumplinger
|
||||
// 14.02.2009 Kevin Lynch
|
||||
// 06.11.2009 Hiromi Iinuma
|
||||
//
|
||||
// Created: Chris Gong & Peter Gumplinger, 30.08.2007
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EqEMFieldWithSpin.hh"
|
||||
@@ -54,8 +48,8 @@ G4EqEMFieldWithSpin::~G4EqEMFieldWithSpin()
|
||||
|
||||
void
|
||||
G4EqEMFieldWithSpin::SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double particleMass)
|
||||
G4double MomentumXc,
|
||||
G4double particleMass)
|
||||
{
|
||||
charge = particleCharge.GetCharge();
|
||||
mass = particleMass;
|
||||
@@ -112,7 +106,7 @@ G4EqEMFieldWithSpin::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
G4double inverse_velocity = Energy * pModuleInverse / c_light;
|
||||
|
||||
G4double cof1 = fElectroMagCof*pModuleInverse ;
|
||||
G4double cof1 = fElectroMagCof*pModuleInverse ;
|
||||
|
||||
dydx[0] = y[3]*pModuleInverse ;
|
||||
dydx[1] = y[4]*pModuleInverse ;
|
||||
@@ -144,13 +138,19 @@ G4EqEMFieldWithSpin::EvaluateRhsGivenB(const G4double y[],
|
||||
G4ThreeVector Spin(y[9],y[10],y[11]);
|
||||
|
||||
G4double pcharge;
|
||||
if (charge == 0.) pcharge = 1.;
|
||||
else pcharge = charge;
|
||||
if (charge == 0.)
|
||||
{
|
||||
pcharge = 1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcharge = charge;
|
||||
}
|
||||
|
||||
G4ThreeVector dSpin(0.,0.,0.);
|
||||
if (Spin.mag2() != 0.) {
|
||||
dSpin =
|
||||
pcharge*omegac*( ucb*(Spin.cross(BField))-udb*(Spin.cross(u))
|
||||
if (Spin.mag2() != 0.)
|
||||
{
|
||||
dSpin = pcharge*omegac*( ucb*(Spin.cross(BField))-udb*(Spin.cross(u))
|
||||
// from Jackson
|
||||
// -uce*Spin.cross(u.cross(EField)) );
|
||||
// but this form has one less operation
|
||||
@@ -161,5 +161,5 @@ G4EqEMFieldWithSpin::EvaluateRhsGivenB(const G4double y[],
|
||||
dydx[10] = dSpin.y();
|
||||
dydx[11] = dSpin.z();
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,23 +23,28 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4EqGravityField implementation
|
||||
//
|
||||
// This is the right-hand side for equation of motion for a
|
||||
// massive particle in a gravitational field.
|
||||
// This is the right-hand side for equation of motion for a
|
||||
// massive particle in a gravitational field.
|
||||
//
|
||||
// History:
|
||||
// - 14.06.11 P.Gumplinger, Created.
|
||||
// -------------------------------------------------------------------
|
||||
// Adopted from G4EqMagElectricField.hh
|
||||
//
|
||||
// Thanks to Peter Fierlinger (PSI) and
|
||||
// A. Capra and A. Fontana (INFN Pavia)
|
||||
// Created: P.Gumplinger, 14.06.11 - Adopted from G4EqMagElectricField
|
||||
// Thanks to P.Fierlinger (PSI) and A.Capra and A.Fontana (INFN Pavia)
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EqGravityField.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
G4EqGravityField::G4EqGravityField(G4UniformGravityField* gField)
|
||||
: G4EquationOfMotion( gField )
|
||||
{
|
||||
}
|
||||
|
||||
G4EqGravityField::~G4EqGravityField()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4EqGravityField::SetChargeMomentumMass(G4ChargeState,
|
||||
G4double,
|
||||
@@ -51,7 +56,7 @@ G4EqGravityField::SetChargeMomentumMass(G4ChargeState,
|
||||
void
|
||||
G4EqGravityField::EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double G[],
|
||||
G4double dydx[] ) const
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
|
||||
// Components of y:
|
||||
@@ -75,6 +80,7 @@ G4EqGravityField::EvaluateRhsGivenB(const G4double y[],
|
||||
dydx[5] = G[2]*cof1*cof2/c_light;
|
||||
|
||||
// Lab Time of flight
|
||||
//
|
||||
dydx[7] = inverse_velocity;
|
||||
|
||||
return;
|
||||
|
||||
@@ -23,17 +23,15 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4EqMagElectricField implementation
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
//
|
||||
// The only case another is required is when using a moving reference
|
||||
// frame ... or extending the class to include additional forces,
|
||||
// e.g., an electric field
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
//
|
||||
// The only case another is required is when using a moving reference
|
||||
// frame ... or extending the class to include additional Forces,
|
||||
// eg an electric field
|
||||
//
|
||||
// 10.11.98 V.Grichine
|
||||
//
|
||||
// Created: V.Grichine, 10.11.1998
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EqMagElectricField.hh"
|
||||
@@ -41,9 +39,18 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4EqMagElectricField::G4EqMagElectricField(G4ElectroMagneticField* emField )
|
||||
: G4EquationOfMotion( emField )
|
||||
{
|
||||
}
|
||||
|
||||
G4EqMagElectricField::~G4EqMagElectricField()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4EqMagElectricField::SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double,
|
||||
G4double,
|
||||
G4double particleMass)
|
||||
{
|
||||
G4double pcharge = particleCharge.GetCharge();
|
||||
@@ -51,14 +58,11 @@ G4EqMagElectricField::SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
fMassCof = particleMass*particleMass ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
G4EqMagElectricField::EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
|
||||
// Components of y:
|
||||
// 0-2 dr/ds,
|
||||
// 3-5 dp/ds - momentum derivatives
|
||||
@@ -70,14 +74,10 @@ G4EqMagElectricField::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
G4double pModuleInverse = 1.0/std::sqrt(pSquared) ;
|
||||
|
||||
// G4double inverse_velocity = Energy * c_light * pModuleInverse;
|
||||
G4double inverse_velocity = Energy * pModuleInverse / c_light;
|
||||
|
||||
G4double cof1 = fElectroMagCof*pModuleInverse ;
|
||||
|
||||
// G4double vDotE = y[3]*Field[3] + y[4]*Field[4] + y[5]*Field[5] ;
|
||||
|
||||
|
||||
dydx[0] = y[3]*pModuleInverse ;
|
||||
dydx[1] = y[4]*pModuleInverse ;
|
||||
dydx[2] = y[5]*pModuleInverse ;
|
||||
@@ -91,6 +91,8 @@ G4EqMagElectricField::EvaluateRhsGivenB(const G4double y[],
|
||||
dydx[6] = 0.;//not used
|
||||
|
||||
// Lab Time of flight
|
||||
//
|
||||
dydx[7] = inverse_velocity;
|
||||
return ;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,36 +23,18 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4EquationOfMotion implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis, 1998
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EquationOfMotion.hh"
|
||||
|
||||
G4EquationOfMotion::G4EquationOfMotion(G4Field* pField)
|
||||
: itsField(pField)
|
||||
{
|
||||
}
|
||||
|
||||
G4EquationOfMotion::~G4EquationOfMotion()
|
||||
{}
|
||||
|
||||
void
|
||||
G4EquationOfMotion::EvaluateRhsReturnB( const G4double y[],
|
||||
G4double dydx[],
|
||||
G4double Field[] ) const
|
||||
{
|
||||
G4double PositionAndTime[4];
|
||||
|
||||
// Position
|
||||
PositionAndTime[0] = y[0];
|
||||
PositionAndTime[1] = y[1];
|
||||
PositionAndTime[2] = y[2];
|
||||
// Global Time
|
||||
PositionAndTime[3] = y[7]; // See G4FieldTrack::LoadFromArray
|
||||
|
||||
GetFieldValue(PositionAndTime, Field) ;
|
||||
EvaluateRhsGivenB( y, Field, dydx );
|
||||
}
|
||||
|
||||
#if HELP_THE_COMPILER
|
||||
void
|
||||
G4EquationOfMotion::doNothing()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ErrorMag_UsualEqRhs implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// Created: P.Arce, September 2004.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ErrorMag_UsualEqRhs.hh"
|
||||
@@ -45,6 +43,7 @@ G4ErrorMag_UsualEqRhs::~G4ErrorMag_UsualEqRhs()
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void
|
||||
G4ErrorMag_UsualEqRhs::EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
|
||||
@@ -23,17 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ExactHelixStepper implementation
|
||||
//
|
||||
//
|
||||
// Helix a-la-Explicity Euler: x_1 = x_0 + helix(h)
|
||||
// with helix(h) being a helix piece of length h
|
||||
// simplest approach for solving linear differential equations.
|
||||
// Take the current derivative and add it to the current position.
|
||||
//
|
||||
// As the field is assumed constant, an error is not calculated.
|
||||
//
|
||||
// Author: J. Apostolakis, 28 Jan 2005
|
||||
// Implementation adapted from ExplicitEuler of W.Wander
|
||||
// Author: J.Apostolakis, 28.01.2005.
|
||||
// Implementation adapted from ExplicitEuler by W.Wander
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ExactHelixStepper.hh"
|
||||
@@ -41,46 +34,50 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
G4ExactHelixStepper::G4ExactHelixStepper(G4Mag_EqRhs *EqRhs)
|
||||
G4ExactHelixStepper::G4ExactHelixStepper(G4Mag_EqRhs* EqRhs)
|
||||
: G4MagHelicalStepper(EqRhs),
|
||||
fBfieldValue(DBL_MAX, DBL_MAX, DBL_MAX),
|
||||
fPtrMagEqOfMot(EqRhs)
|
||||
fBfieldValue(DBL_MAX, DBL_MAX, DBL_MAX)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
G4ExactHelixStepper::~G4ExactHelixStepper() {}
|
||||
G4ExactHelixStepper::~G4ExactHelixStepper()
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
G4ExactHelixStepper::Stepper( const G4double yInput[],
|
||||
const G4double*,
|
||||
G4double hstep,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
G4double yErr[] )
|
||||
{
|
||||
const G4int nvar = 6;
|
||||
const G4int nvar = 6;
|
||||
|
||||
G4int i;
|
||||
G4ThreeVector Bfld_value;
|
||||
G4int i;
|
||||
G4ThreeVector Bfld_value;
|
||||
|
||||
MagFieldEvaluate(yInput, Bfld_value);
|
||||
AdvanceHelix(yInput, Bfld_value, hstep, yOut);
|
||||
MagFieldEvaluate(yInput, Bfld_value);
|
||||
AdvanceHelix(yInput, Bfld_value, hstep, yOut);
|
||||
|
||||
// We are assuming a constant field: helix is exact
|
||||
//
|
||||
for(i=0;i<nvar;i++)
|
||||
for(i=0; i<nvar; ++i)
|
||||
{
|
||||
yErr[i] = 0.0 ;
|
||||
}
|
||||
|
||||
fBfieldValue=Bfld_value;
|
||||
fBfieldValue = Bfld_value;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
G4ExactHelixStepper::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4ExactHelixStepper::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
{
|
||||
// Assuming a constant field: solution is a helix
|
||||
|
||||
@@ -120,6 +117,8 @@ G4ExactHelixStepper::DistChord() const
|
||||
return distChord;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
G4int
|
||||
G4ExactHelixStepper::IntegratorOrder() const
|
||||
{
|
||||
|
||||
@@ -23,15 +23,14 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ExplicitEuler implementation
|
||||
//
|
||||
// Explicit Euler: x_1 = x_0 + h * dx_0
|
||||
//
|
||||
// Most simple approach for solving linear differential equations.
|
||||
// Take the current derivative and add it to the current position.
|
||||
//
|
||||
// Explicit Euler: x_1 = x_0 + h * dx_0
|
||||
//
|
||||
// most simple approach for solving linear differential equations.
|
||||
// Take the current derivative and add it to the current position.
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
// Created: W.Wander <wwc@mit.edu>, 12.09.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ExplicitEuler.hh"
|
||||
@@ -40,7 +39,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
|
||||
//
|
||||
G4ExplicitEuler::G4ExplicitEuler(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables)
|
||||
: G4MagErrorStepper(EqRhs, numberOfVariables)
|
||||
@@ -51,7 +50,7 @@ G4ExplicitEuler::G4ExplicitEuler(G4EquationOfMotion* EqRhs,
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4ExplicitEuler::~G4ExplicitEuler()
|
||||
{
|
||||
}
|
||||
@@ -60,24 +59,21 @@ G4ExplicitEuler::~G4ExplicitEuler()
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
void
|
||||
G4ExplicitEuler::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
G4ExplicitEuler::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
const G4int numberOfVariables= GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// Initialise time to t0, needed when it is not updated by the integration.
|
||||
// yOut[7] = yIn[7]; // Better to set it to NaN; // TODO
|
||||
|
||||
G4int i;
|
||||
|
||||
for(i=0;i< numberOfVariables;i++)
|
||||
for(G4int i=0; i< numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + h*dydx[i] ; // 1st and only Step
|
||||
}
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,62 +23,50 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Bogacki-Shampine - 8 - 5(4) FSAL implementation by Somnath Banerjee
|
||||
// Supervision / code review: John Apostolakis
|
||||
// G4FSALBogackiShampine45 implementation
|
||||
//
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
//
|
||||
// First version: 26 May 2015
|
||||
// The Butcher table of the Bogacki-Shampine-8-4-5 method is as follows:
|
||||
//
|
||||
// History
|
||||
// -----------------------------
|
||||
// Created by Somnath on 26 May 2015
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Renamed to G4 standard naming
|
||||
// Plan is that this source file / class will be merged with the updated
|
||||
// BogackiShampine45 class, which contains improvements (May 2016)
|
||||
// J. Apostolakis, 31 May 2016
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 0 |
|
||||
// 1/6 | 1/6
|
||||
// 2/9 | 2/27 4/27
|
||||
// 3/7 | 183/1372 -162/343 1053/1372
|
||||
// 2/3 | 68/297 -4/11 42/143 1960/3861
|
||||
// 3/4 | 597/22528 81/352 63099/585728 58653/366080 4617/20480
|
||||
// 1 | 174197/959244 -30942/79937 8152137/19744439 666106/1039181 -29421/29068 482048/414219
|
||||
// 1 | 587/8064 0 4440339/15491840 24353/124800 387/44800 2152/5985 7267/94080
|
||||
// -------------------------------------------------------------------------------------------------------------------
|
||||
// 587/8064 0 4440339/15491840 24353/124800 387/44800 2152/5985 7267/94080 0
|
||||
// 2479/34992 0 123/416 612941/3411720 43/1440 2272/6561 79937/1113912 3293/556956
|
||||
//
|
||||
//
|
||||
//This is the source file of BogackiShampine45 class containing the
|
||||
//definition of the stepper() method that evaluates one step in
|
||||
//field propagation.
|
||||
//The Butcher table of the Bogacki-Shampine-8-4-5 method is as follows :
|
||||
//
|
||||
//0 |
|
||||
//1/6 | 1/6
|
||||
//2/9 | 2/27 4/27
|
||||
//3/7 | 183/1372 -162/343 1053/1372
|
||||
//2/3 | 68/297 -4/11 42/143 1960/3861
|
||||
//3/4 | 597/22528 81/352 63099/585728 58653/366080 4617/20480
|
||||
//1 | 174197/959244 -30942/79937 8152137/19744439 666106/1039181 -29421/29068 482048/414219
|
||||
//1 | 587/8064 0 4440339/15491840 24353/124800 387/44800 2152/5985 7267/94080
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// 587/8064 0 4440339/15491840 24353/124800 387/44800 2152/5985 7267/94080 0
|
||||
// 2479/34992 0 123/416 612941/3411720 43/1440 2272/6561 79937/1113912 3293/556956
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 26 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Plan is that this source file / class will be merged with the updated
|
||||
// BogackiShampine45 class, which contains improvements (May 2016)
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "G4FSALBogackiShampine45.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
G4bool G4FSALBogackiShampine45::fPreparedConstants= false;
|
||||
G4bool G4FSALBogackiShampine45::fPreparedConstants = false;
|
||||
G4double G4FSALBogackiShampine45::bi[12][7];
|
||||
|
||||
//Constructor
|
||||
G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength( -1.0 ), fAuxStepper( nullptr )
|
||||
// Constructor
|
||||
//
|
||||
G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion* EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
|
||||
//New Chunk of memory being created for use by the stepper
|
||||
// New Chunk of memory being created for use by the stepper
|
||||
|
||||
//aki - for storing intermediate RHS
|
||||
// aki - for storing intermediate RHS
|
||||
//
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
@@ -97,6 +85,7 @@ G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
GetNumberOfStateVariables() );
|
||||
|
||||
// Must ensure space extra 'state' variables exists - i.e. yIn[7]
|
||||
//
|
||||
yTemp = new G4double[numStateVars];
|
||||
yIn = new G4double[numStateVars] ;
|
||||
|
||||
@@ -113,207 +102,202 @@ G4FSALBogackiShampine45::G4FSALBogackiShampine45(G4EquationOfMotion *EqRhs,
|
||||
fMidError = new G4double[numberOfVariables];
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4FSALBogackiShampine45(EqRhs, numberOfVariables,
|
||||
!primary);
|
||||
fAuxStepper = new G4FSALBogackiShampine45(EqRhs, numberOfVariables,
|
||||
!primary);
|
||||
}
|
||||
if( ! fPreparedConstants )
|
||||
if( !fPreparedConstants )
|
||||
{
|
||||
PrepareConstants();
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
//
|
||||
G4FSALBogackiShampine45::~G4FSALBogackiShampine45()
|
||||
{
|
||||
// Clear all previously allocated memory for stepper and DistChord
|
||||
|
||||
//Destructor
|
||||
G4FSALBogackiShampine45::~G4FSALBogackiShampine45(){
|
||||
//clear all previously allocated memory for stepper and DistChord
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
delete[] ak7;
|
||||
delete[] ak8;
|
||||
delete[] ak9;
|
||||
delete[] ak10;
|
||||
delete[] ak11;
|
||||
delete[] DyDx;
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
delete [] ak7;
|
||||
delete [] ak8;
|
||||
delete [] ak9;
|
||||
delete [] ak10;
|
||||
delete [] ak11;
|
||||
delete [] DyDx;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
|
||||
delete[] pseudoDydx_for_DistChord;
|
||||
delete [] pseudoDydx_for_DistChord;
|
||||
}
|
||||
|
||||
|
||||
//Stepper :
|
||||
|
||||
// Stepper
|
||||
//
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4FSALBogackiShampine45::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[],
|
||||
G4double nextDydx[])
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[],
|
||||
G4double nextDydx[])
|
||||
{
|
||||
G4int i;
|
||||
|
||||
//The various constants defined on the basis of butcher tableu
|
||||
const G4double //G4double - only once
|
||||
// The various constants defined on the basis of butcher tableu
|
||||
|
||||
const G4double b21 = 1.0/6.0 ,
|
||||
b31 = 2.0/27.0 , b32 = 4.0/27.0,
|
||||
|
||||
b21 = 1.0/6.0 ,
|
||||
b31 = 2.0/27.0 , b32 = 4.0/27.0,
|
||||
b41 = 183.0/1372.0 , b42 = -162.0/343.0, b43 = 1053.0/1372.0,
|
||||
|
||||
b41 = 183.0/1372.0 , b42 = -162.0/343.0, b43 = 1053.0/1372.0,
|
||||
b51 = 68.0/297.0, b52 = -4.0/11.0,
|
||||
b53 = 42.0/143.0, b54 = 1960.0/3861.0,
|
||||
|
||||
b51 = 68.0/297.0, b52 = -4.0/11.0,
|
||||
b53 = 42.0/143.0, b54 = 1960.0/3861.0,
|
||||
b61 = 597.0/22528.0, b62 = 81.0/352.0,
|
||||
b63 = 63099.0/585728.0, b64 = 58653.0/366080.0,
|
||||
b65 = 4617.0/20480.0,
|
||||
|
||||
b61 = 597.0/22528.0, b62 = 81.0/352.0,
|
||||
b63 = 63099.0/585728.0, b64 = 58653.0/366080.0,
|
||||
b65 = 4617.0/20480.0,
|
||||
b71 = 174197.0/959244.0, b72 = -30942.0/79937.0,
|
||||
b73 = 8152137.0/19744439.0, b74 = 666106.0/1039181.0,
|
||||
b75 = -29421.0/29068.0, b76 = 482048.0/414219.0,
|
||||
|
||||
b71 = 174197.0/959244.0, b72 = -30942.0/79937.0,
|
||||
b73 = 8152137.0/19744439.0, b74 = 666106.0/1039181.0,
|
||||
b75 = -29421.0/29068.0, b76 = 482048.0/414219.0,
|
||||
|
||||
b81 = 587.0/8064.0, b82 = 0.0,
|
||||
b83 = 4440339.0/15491840.0, b84 = 24353.0/124800.0,
|
||||
b85 = 387.0/44800.0, b86 = 2152.0/5985.0,
|
||||
b87 = 7267.0/94080.0,
|
||||
b81 = 587.0/8064.0, b82 = 0.0,
|
||||
b83 = 4440339.0/15491840.0, b84 = 24353.0/124800.0,
|
||||
b85 = 387.0/44800.0, b86 = 2152.0/5985.0,
|
||||
b87 = 7267.0/94080.0,
|
||||
|
||||
|
||||
// c1 = 2479.0/34992.0,
|
||||
// c2 = 0.0,
|
||||
// c3 = 123.0/416.0,
|
||||
// c4 = 612941.0/3411720.0,
|
||||
// c5 = 43.0/1440.0,
|
||||
// c6 = 2272.0/6561.0,
|
||||
// c7 = 79937.0/1113912.0,
|
||||
// c8 = 3293.0/556956.0,
|
||||
// c1 = 2479.0/34992.0,
|
||||
// c2 = 0.0,
|
||||
// c3 = 123.0/416.0,
|
||||
// c4 = 612941.0/3411720.0,
|
||||
// c5 = 43.0/1440.0,
|
||||
// c6 = 2272.0/6561.0,
|
||||
// c7 = 79937.0/1113912.0,
|
||||
// c8 = 3293.0/556956.0,
|
||||
|
||||
//For the embedded higher order method only the difference of values
|
||||
// For the embedded higher order method only the difference of values
|
||||
// taken and is used directly later instead of defining the last row
|
||||
// of butcher table in a separate set of variables and taking the
|
||||
// difference there
|
||||
|
||||
dc1 = b81 - 2479.0/34992.0 ,
|
||||
dc2 = 0.0,
|
||||
dc3 = b83 - 123.0/416.0 ,
|
||||
dc4 = b84 - 612941.0/3411720.0,
|
||||
dc5 = b85 - 43.0/1440.0,
|
||||
dc6 = b86 - 2272.0/6561.0,
|
||||
dc7 = b87 - 79937.0/1113912.0,
|
||||
dc8 = -3293.0/556956.0; // end of declaration
|
||||
|
||||
|
||||
dc1 = b81 - 2479.0/34992.0 ,
|
||||
dc2 = 0.0,
|
||||
dc3 = b83 - 123.0/416.0 ,
|
||||
dc4 = b84 - 612941.0/3411720.0,
|
||||
dc5 = b85 - 43.0/1440.0,
|
||||
dc6 = b86 - 2272.0/6561.0,
|
||||
dc7 = b87 - 79937.0/1113912.0,
|
||||
dc8 = -3293.0/556956.0; //end of declaration
|
||||
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// 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++)
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
DyDx[i] = dydx[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++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*DyDx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*DyDx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b71*DyDx[i] + b72*ak2[i] + b73*ak3[i] +
|
||||
b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
|
||||
}
|
||||
RightHandSide(yTemp, ak7); //7th Step
|
||||
RightHandSide(yTemp, ak7); // 7th Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b81*DyDx[i] + b82*ak2[i] + b83*ak3[i] +
|
||||
b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
|
||||
b87*ak7[i]);
|
||||
}
|
||||
RightHandSide(yOut, ak8); //8th Step - Final one Using FSAL
|
||||
RightHandSide(yOut, ak8); // 8th Step - Final one Using FSAL
|
||||
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
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] + dc8*ak8[i]) ;
|
||||
|
||||
|
||||
//FSAL stepper : Must pass the last DyDx for the next step, here ak8
|
||||
// FSAL stepper : Must pass the last DyDx for the next step, here ak8
|
||||
//
|
||||
nextDydx[i] = ak8[i];
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = DyDx[i];
|
||||
|
||||
}
|
||||
|
||||
fLastStepLength = Step;
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
// DistChord
|
||||
//
|
||||
//G4double* G4FSALBogackiShampine45::getLastDydx(){
|
||||
// return ak8;
|
||||
//}
|
||||
|
||||
//The following has not been tested
|
||||
|
||||
//The DistChord() function fot the class - must define it here.
|
||||
G4double G4FSALBogackiShampine45::DistChord() const
|
||||
G4double G4FSALBogackiShampine45::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
@@ -322,17 +306,16 @@ G4double G4FSALBogackiShampine45::DistChord() const
|
||||
// Do half a step using StepNoErr
|
||||
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
|
||||
fMidVector, fMidError, pseudoDydx_for_DistChord );
|
||||
fMidVector, fMidError, pseudoDydx_for_DistChord );
|
||||
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2] );
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
// distance of Chord
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distLine = G4LineSection::Distline(midPoint, initialPoint, finalPoint);
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
@@ -342,17 +325,20 @@ G4double G4FSALBogackiShampine45::DistChord() const
|
||||
return distChord;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
// PrepareConstants
|
||||
//
|
||||
void G4FSALBogackiShampine45::PrepareConstants()
|
||||
{
|
||||
// --------------------------------------------------------
|
||||
// COEFFICIENTS FOR INTERPOLANT bi WITH 11 STAGES
|
||||
// --------------------------------------------------------
|
||||
|
||||
// Initialise all values of G4double bi[12][7]
|
||||
for(int i=1; i<12; i++){
|
||||
for(int j=1; j<7; j++){
|
||||
// Initialise all values of G4double bi[12][7]
|
||||
//
|
||||
for(auto i=1; i<12; ++i)
|
||||
{
|
||||
for(auto j=1; j<7; ++j)
|
||||
{
|
||||
bi[i][j] = 0.0 ;
|
||||
}
|
||||
}
|
||||
@@ -422,56 +408,58 @@ void G4FSALBogackiShampine45::PrepareConstants()
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double yOut[],
|
||||
G4double Step,
|
||||
G4double tau
|
||||
)
|
||||
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 ,
|
||||
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 ,
|
||||
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 ;
|
||||
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();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
// The number of variables to be integrated over
|
||||
//
|
||||
yOut[7] = yTemp[7] = yIn[7];
|
||||
|
||||
// calculating extra stages
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
// Calculating extra stages
|
||||
//
|
||||
for(G4int 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] +
|
||||
a97*ak7[i] + a98*ak8[i] );
|
||||
@@ -479,7 +467,8 @@ void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
|
||||
|
||||
RightHandSide(yTemp, ak9);
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(a101*dydx[i] + a102*ak2[i] + a103*ak3[i] +
|
||||
a104*ak4[i] + a105*ak5[i] + a106*ak6[i] +
|
||||
a107*ak7[i] + a108*ak8[i] + a109*ak9[i] );
|
||||
@@ -487,7 +476,8 @@ void G4FSALBogackiShampine45::interpolate( const G4double yInput[],
|
||||
|
||||
RightHandSide(yTemp, ak10);
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(a111*dydx[i] + a112*ak2[i] + a113*ak3[i] +
|
||||
a114*ak4[i] + a115*ak5[i] + a116*ak6[i] +
|
||||
a117*ak7[i] + a118*ak8[i] + a119*ak9[i] +
|
||||
@@ -497,24 +487,25 @@ 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.
|
||||
|
||||
// Calculating the polynomials
|
||||
//
|
||||
for(auto i=1; i<=11; ++i) // i is NOT the coordinate no., it's stage no.
|
||||
{
|
||||
b[i] = 0.0;
|
||||
tau = tau0;
|
||||
for(int j=1; j<=6; j++){
|
||||
for(auto j=1; j<=6; ++j)
|
||||
{
|
||||
b[i] += bi[i][j]*tau;
|
||||
tau*=tau0;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b[1]*dydx[i] + b[2]*ak2[i] + b[3]*ak3[i] +
|
||||
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] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,268 +23,249 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// DormandPrince7 - 5(4) implementation by Somnath Banerjee
|
||||
// Supervision / code review: John Apostolakis
|
||||
// G4FSALDormandPrince745 implementation
|
||||
//
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
// The Butcher table of the FDormand-Prince-7-4-5 method is as follows:
|
||||
//
|
||||
// First version: 25 May 2015
|
||||
// 0 |
|
||||
// 1/5 | 1/5
|
||||
// 3/10| 3/40 9/40
|
||||
// 4/5 | 44/45 56/15 32/9
|
||||
// 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
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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
|
||||
//
|
||||
// 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.
|
||||
// The Butcher table of the FDormand-Prince-7-4-5 method is as follows :
|
||||
//
|
||||
// 0 |
|
||||
// 1/5 | 1/5
|
||||
// 3/10| 3/40 9/40
|
||||
// 4/5 | 44/45 −56/15 32/9
|
||||
// 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
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 25 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4FSALDormandPrince745.hh"
|
||||
#include "G4LineSection.hh"
|
||||
#include <cmath>
|
||||
|
||||
//Constructor
|
||||
G4FSALDormandPrince745::G4FSALDormandPrince745(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables)
|
||||
// Constructor
|
||||
//
|
||||
G4FSALDormandPrince745::G4FSALDormandPrince745(G4EquationOfMotion* EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4VFSALIntegrationStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
// New Chunk of memory being created for use by the stepper
|
||||
|
||||
//New Chunk of memory being created for use by the stepper
|
||||
|
||||
//aki - for storing intermediate RHS
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
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];
|
||||
// aki - for storing intermediate RHS
|
||||
//
|
||||
ak2 = new G4double[numberOfVariables];
|
||||
ak3 = new G4double[numberOfVariables];
|
||||
ak4 = new G4double[numberOfVariables];
|
||||
ak5 = new G4double[numberOfVariables];
|
||||
ak6 = new G4double[numberOfVariables];
|
||||
ak7 = new G4double[numberOfVariables];
|
||||
|
||||
fInitialDyDx = new G4double[numberOfVariables];
|
||||
fLastInitialVector = new G4double[numberOfVariables] ;
|
||||
fLastFinalVector = new G4double[numberOfVariables] ;
|
||||
fLastDyDx = new G4double[numberOfVariables];
|
||||
// Also always allocate arrays for interpolation stages
|
||||
//
|
||||
ak8 = new G4double[numberOfVariables];
|
||||
ak9 = new G4double[numberOfVariables];
|
||||
|
||||
fMidVector = new G4double[numberOfVariables];
|
||||
fMidError = new G4double[numberOfVariables];
|
||||
yTemp = new G4double[numberOfVariables] ;
|
||||
yIn = new G4double[numberOfVariables] ;
|
||||
|
||||
fAuxStepper = nullptr;
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4FSALDormandPrince745(EqRhs, numberOfVariables,
|
||||
!primary);
|
||||
}
|
||||
fLastStepLength = -1.0;
|
||||
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];
|
||||
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4FSALDormandPrince745(EqRhs,numberOfVariables,!primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Destructor
|
||||
// Destructor
|
||||
//
|
||||
G4FSALDormandPrince745::~G4FSALDormandPrince745()
|
||||
{
|
||||
//clear all previously allocated memory for stepper and DistChord
|
||||
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; yTemp= nullptr;
|
||||
delete[] yIn; yIn= nullptr;
|
||||
// Clear all previously allocated memory for stepper and DistChord
|
||||
|
||||
delete[] pseudoDydx_for_DistChord; pseudoDydx_for_DistChord= nullptr;
|
||||
delete[] fInitialDyDx; fInitialDyDx= nullptr;
|
||||
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[] fLastInitialVector; fLastInitialVector= nullptr;
|
||||
delete[] fLastFinalVector; fLastFinalVector = nullptr;
|
||||
delete[] fLastDyDx; fLastDyDx = nullptr;
|
||||
delete[] fMidVector; fMidVector = nullptr;
|
||||
delete[] fMidError; fMidError = nullptr;
|
||||
delete [] yTemp; yTemp = nullptr;
|
||||
delete [] yIn; yIn = nullptr;
|
||||
|
||||
delete [] pseudoDydx_for_DistChord; pseudoDydx_for_DistChord = nullptr;
|
||||
delete [] fInitialDyDx; fInitialDyDx = nullptr;
|
||||
|
||||
delete fAuxStepper; fAuxStepper= nullptr;
|
||||
delete [] fLastInitialVector; fLastInitialVector = nullptr;
|
||||
delete [] fLastFinalVector; fLastFinalVector = nullptr;
|
||||
delete [] fLastDyDx; fLastDyDx = nullptr;
|
||||
delete [] fMidVector; fMidVector = nullptr;
|
||||
delete [] fMidError; fMidError = nullptr;
|
||||
|
||||
delete fAuxStepper; fAuxStepper = nullptr;
|
||||
}
|
||||
|
||||
|
||||
//Stepper :
|
||||
|
||||
// Stepper
|
||||
//
|
||||
// Passing in the value of yInput[],the first time dydx[] and Step length
|
||||
// Giving back yOut and yErr arrays for output and error respectively
|
||||
|
||||
//
|
||||
void G4FSALDormandPrince745::Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[],
|
||||
G4double nextDydx[]
|
||||
)
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[],
|
||||
G4double nextDydx[] )
|
||||
{
|
||||
G4int i;
|
||||
|
||||
//The various constants defined on the basis of butcher tableu
|
||||
const G4double //G4double - only once
|
||||
b21 = 0.2 ,
|
||||
|
||||
b31 = 3.0/40.0, b32 = 9.0/40.0 ,
|
||||
|
||||
b41 = 44.0/45.0, b42 = -56.0/15.0, b43 = 32.0/9.0,
|
||||
|
||||
b51 = 19372.0/6561.0, b52 = -25360.0/2187.0, b53 = 64448.0/6561.0,
|
||||
b54 = -212.0/729.0 ,
|
||||
|
||||
b61 = 9017.0/3168.0 , b62 = -355.0/33.0,
|
||||
b63 = 46732.0/5247.0 , b64 = 49.0/176.0 ,
|
||||
b65 = -5103.0/18656.0 ,
|
||||
|
||||
b71 = 35.0/384.0, b72 = 0.,
|
||||
b73 = 500.0/1113.0, b74 = 125.0/192.0,
|
||||
b75 = -2187.0/6784.0, b76 = 11.0/84.0,
|
||||
|
||||
// c1 = 35.0/384.0, c2 = .0,
|
||||
// c3 = 500.0/1113.0, c4 = 125.0/192.0,
|
||||
// c5 = -2187.0/6784.0, c6 = 11.0/84.0,
|
||||
// c7 = 0,
|
||||
|
||||
dc1 = b71 - 5179.0/57600.0,
|
||||
dc2 = b72 - .0,
|
||||
dc3 = b73 - 7571.0/16695.0,
|
||||
dc4 = b74 - 393.0/640.0,
|
||||
dc5 = b75 + 92097.0/339200.0,
|
||||
dc6 = b76 - 187.0/2100.0,
|
||||
dc7 = - 1.0/40.0 ; //end of declaration
|
||||
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
// The number of variables to be integrated over
|
||||
// The various constants defined on the basis of butcher tableu
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
const G4double b21 = 0.2 ,
|
||||
b31 = 3.0/40.0, b32 = 9.0/40.0 ,
|
||||
|
||||
b41 = 44.0/45.0, b42 = -56.0/15.0, b43 = 32.0/9.0,
|
||||
|
||||
b51 = 19372.0/6561.0, b52 = -25360.0/2187.0,
|
||||
b53 = 64448.0/6561.0, b54 = -212.0/729.0 ,
|
||||
|
||||
b61 = 9017.0/3168.0 , b62 = -355.0/33.0,
|
||||
b63 = 46732.0/5247.0 , b64 = 49.0/176.0 ,
|
||||
b65 = -5103.0/18656.0 ,
|
||||
|
||||
b71 = 35.0/384.0, b72 = 0.,
|
||||
b73 = 500.0/1113.0, b74 = 125.0/192.0,
|
||||
b75 = -2187.0/6784.0, b76 = 11.0/84.0,
|
||||
|
||||
// c1 = 35.0/384.0, c2 = .0,
|
||||
// c3 = 500.0/1113.0, c4 = 125.0/192.0,
|
||||
// c5 = -2187.0/6784.0, c6 = 11.0/84.0,
|
||||
// c7 = 0,
|
||||
|
||||
dc1 = b71 - 5179.0/57600.0,
|
||||
dc2 = b72 - .0,
|
||||
dc3 = b73 - 7571.0/16695.0,
|
||||
dc4 = b74 - 393.0/640.0,
|
||||
dc5 = b75 + 92097.0/339200.0,
|
||||
dc6 = b76 - 187.0/2100.0,
|
||||
dc7 = - 1.0/40.0 ; //end of declaration
|
||||
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
// The number of variables to be integrated over
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(i=0; i<numberOfVariables; ++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
|
||||
|
||||
// RightHandSide(yIn, DyDx) ;
|
||||
// 1st Step - Not doing, getting passed
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*fInitialDyDx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*fInitialDyDx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Step
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*fInitialDyDx[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++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*fInitialDyDx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[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++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b61*fInitialDyDx[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++)
|
||||
for(i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*(b71*fInitialDyDx[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++)
|
||||
for(i=0; i<numberOfVariables; ++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] ) ;
|
||||
|
||||
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] = fInitialDyDx[i];
|
||||
nextDydx[i] = ak7[i];
|
||||
|
||||
|
||||
}
|
||||
|
||||
fLastStepLength = Step;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
//The following has not been tested
|
||||
|
||||
//The DistChord() function fot the class - must define it here.
|
||||
G4double G4FSALDormandPrince745::DistChord() const
|
||||
// DistChord
|
||||
//
|
||||
G4double G4FSALDormandPrince745::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
// Store last initial and final points
|
||||
// (they will be overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector(fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
finalPoint = G4ThreeVector(fLastFinalVector[0],
|
||||
fLastFinalVector[1], fLastFinalVector[2]);
|
||||
|
||||
// Do half a step using StepNoErr
|
||||
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
|
||||
fMidVector, fMidError, pseudoDydx_for_DistChord );
|
||||
fMidVector, fMidError, pseudoDydx_for_DistChord );
|
||||
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
|
||||
midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2] );
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
// distance of Chord
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
distLine = G4LineSection::Distline( midPoint,initialPoint,finalPoint );
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
@@ -294,118 +275,122 @@ G4double G4FSALDormandPrince745::DistChord() const
|
||||
return distChord;
|
||||
}
|
||||
|
||||
// interpolate
|
||||
//
|
||||
void G4FSALDormandPrince745::interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double yOut[],
|
||||
G4double Step,
|
||||
G4double tau)
|
||||
{
|
||||
G4double bf1, bf2, bf3, bf4, bf5, bf6, bf7;
|
||||
|
||||
void G4FSALDormandPrince745::interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double yOut[],
|
||||
G4double Step,
|
||||
G4double tau){
|
||||
|
||||
G4double
|
||||
bf1, bf2, bf3, bf4, bf5, bf6, bf7;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
G4double tau0 = tau;
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0;i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
G4double
|
||||
tau_2 = tau0*tau0 ,
|
||||
tau_3 = tau0*tau_2,
|
||||
tau_4 = tau_2*tau_2;
|
||||
G4double tau_2 = tau0*tau0 ,
|
||||
tau_3 = tau0*tau_2,
|
||||
tau_4 = tau_2*tau_2;
|
||||
|
||||
bf1 = (157015080.0*tau_4 - 13107642775.0*tau_3+ 34969693132.0*tau_2- 32272833064.0*tau
|
||||
+ 11282082432.0)/11282082432.0,
|
||||
bf2 = 0.0 ,
|
||||
bf3 = - 100.0*tau*(15701508.0*tau_3 - 914128567.0*tau_2 + 2074956840.0*tau
|
||||
- 1323431896.0)/32700410799.0,
|
||||
bf4 = 25.0*tau*(94209048.0*tau_3- 1518414297.0*tau_2+ 2460397220.0*tau - 889289856.0)/5641041216.0 ,
|
||||
bf5 = -2187.0*tau*(52338360.0*tau_3 - 451824525.0*tau_2 + 687873124.0*tau - 259006536.0)/199316789632.0 ,
|
||||
bf6 = 11.0*tau*(106151040.0*tau_3- 661884105.0*tau_2 + 946554244.0*tau - 361440756.0)/2467955532.0 ,
|
||||
bf7 = tau*(1.0 - tau)*(8293050.0*tau_2 - 82437520.0*tau + 44764047.0)/ 29380423.0 ;
|
||||
bf1 = (157015080.0*tau_4 - 13107642775.0*tau_3
|
||||
+ 34969693132.0*tau_2- 32272833064.0*tau + 11282082432.0)
|
||||
/ 11282082432.0;
|
||||
bf2 = 0.0;
|
||||
bf3 = - 100.0*tau*(15701508.0*tau_3 - 914128567.0*tau_2
|
||||
+ 2074956840.0*tau - 1323431896.0) / 32700410799.0;
|
||||
bf4 = 25.0*tau*(94209048.0*tau_3- 1518414297.0*tau_2
|
||||
+ 2460397220.0*tau - 889289856.0)
|
||||
/ 5641041216.0;
|
||||
bf5 = -2187.0*tau*(52338360.0*tau_3 - 451824525.0*tau_2
|
||||
+ 687873124.0*tau - 259006536.0)
|
||||
/ 199316789632.0;
|
||||
bf6 = 11.0*tau*(106151040.0*tau_3- 661884105.0*tau_2
|
||||
+ 946554244.0*tau - 361440756.0)
|
||||
/ 2467955532.0;
|
||||
bf7 = tau*(1.0 - tau)*(8293050.0*tau_2 - 82437520.0*tau + 44764047.0)
|
||||
/ 29380423.0;
|
||||
|
||||
|
||||
for( int i=0; i<numberOfVariables; i++){
|
||||
yOut[i] = yIn[i] + Step*tau*(bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i] + bf4*ak4[i]
|
||||
+ bf5*ak5[i] + bf6*ak6[i] + bf7*ak7[i] ) ;
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*tau*(bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i]
|
||||
+ bf4*ak4[i] + bf5*ak5[i] + bf6*ak6[i]
|
||||
+ bf7*ak7[i] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// SetupInterpolate
|
||||
//
|
||||
void G4FSALDormandPrince745::SetupInterpolate(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step ){
|
||||
const G4double dydx[],
|
||||
const G4double Step )
|
||||
{
|
||||
// Coefficients for the additional stages
|
||||
//
|
||||
G4double b81 = 6245.0/62208.0 ,
|
||||
b82 = 0.0 ,
|
||||
b83 = 8875.0/103032.0 ,
|
||||
b84 = -125.0/1728.0 ,
|
||||
b85 = 801.0/13568.0 ,
|
||||
b86 = -13519.0/368064.0 ,
|
||||
b87 = 11105.0/368064.0 ,
|
||||
|
||||
//Coefficients for the additional stages :
|
||||
G4double
|
||||
b81 = 6245.0/62208.0 ,
|
||||
b82 = 0.0 ,
|
||||
b83 = 8875.0/103032.0 ,
|
||||
b84 = -125.0/1728.0 ,
|
||||
b85 = 801.0/13568.0 ,
|
||||
b86 = -13519.0/368064.0 ,
|
||||
b87 = 11105.0/368064.0 ,
|
||||
b91 = 632855.0/4478976.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 4146875.0/6491016.0 ,
|
||||
b94 = 5490625.0/14183424.0 ,
|
||||
b95 = -15975.0/108544.0 ,
|
||||
b96 = 8295925.0/220286304.0 ,
|
||||
b97 = -1779595.0/62938944.0 ,
|
||||
b98 = -805.0/4104.0 ;
|
||||
|
||||
b91 = 632855.0/4478976.0 ,
|
||||
b92 = 0.0 ,
|
||||
b93 = 4146875.0/6491016.0 ,
|
||||
b94 = 5490625.0/14183424.0 ,
|
||||
b95 = -15975.0/108544.0 ,
|
||||
b96 = 8295925.0/220286304.0 ,
|
||||
b97 = -1779595.0/62938944.0 ,
|
||||
b98 = -805.0/4104.0 ;
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
yIn[i] = yInput[i];
|
||||
}
|
||||
|
||||
yTemp[7] = yIn[7];
|
||||
yTemp[7] = yIn[7];
|
||||
|
||||
//Evaluate the extra stages :
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
// Evaluate the extra stages
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*( b81*dydx[i] + b82*ak2[i] + b83*ak3[i] +
|
||||
b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
|
||||
b87*ak7[i] );
|
||||
}
|
||||
RightHandSide( yTemp, ak8 ); //8th Stage
|
||||
RightHandSide( yTemp, ak8 ); // 8th Stage
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step * ( b91*dydx[i] + b92*ak2[i] + b93*ak3[i] +
|
||||
b94*ak4[i] + b95*ak5[i] + b96*ak6[i] +
|
||||
b97*ak7[i] + b98*ak8[i] );
|
||||
}
|
||||
RightHandSide( yTemp, ak9 ); //9th Stage
|
||||
|
||||
|
||||
|
||||
RightHandSide( yTemp, ak9 ); // 9th Stage
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Interpolate
|
||||
//
|
||||
void G4FSALDormandPrince745::Interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau ){
|
||||
//Define the coefficients for the polynomials
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau )
|
||||
{
|
||||
// Define the coefficients for the polynomials
|
||||
|
||||
G4double bi[10][5], b[10];
|
||||
G4int numberOfVariables = this->GetNumberOfVariables();
|
||||
G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// COEFFICIENTS OF bi[1]
|
||||
bi[1][0] = 1.0 ,
|
||||
@@ -478,35 +463,31 @@ void G4FSALDormandPrince745::Interpolate( const G4double yInput[],
|
||||
bi[9][3] = 2943.0/110.0 ,
|
||||
bi[9][4] = -648.0/55.0 ;
|
||||
// --------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
for(G4int i = 0; i< numberOfVariables; i++)
|
||||
for(G4int i = 0; i< numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i] = yInput[i];
|
||||
}
|
||||
|
||||
G4double tau0 = tau;
|
||||
// Calculating the polynomials :
|
||||
|
||||
for(int i=1; i<=9; i++){ //Here i is NOT the coordinate no. , it's stage no.
|
||||
|
||||
// Calculating the polynomials
|
||||
//
|
||||
for(auto i=1; i<=9; ++i) // i is NOT the coordinate no., it's stage no.
|
||||
{
|
||||
b[i] = 0;
|
||||
tau = 1.0;
|
||||
for(int j=0; j<=4; j++){
|
||||
for(auto j=0; j<=4; ++j)
|
||||
{
|
||||
b[i] += bi[i][j]*tau;
|
||||
tau*=tau0;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<numberOfVariables; i++){ //Here i IS the cooridnate no.
|
||||
for(G4int i=0; i<numberOfVariables; ++i) // Here i IS the coordinate no.
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*tau0*(b[1]*dydx[i] + b[2]*ak2[i] + b[3]*ak3[i] +
|
||||
b[4]*ak4[i] + b[5]*ak5[i] + b[6]*ak6[i] +
|
||||
b[7]*ak7[i] + b[8]*ak8[i] + b[9]*ak9[i] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,15 +23,15 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4Field implementation
|
||||
//
|
||||
// First implementation class for G4Field
|
||||
// J. Apostolakis, 4 Nov 2011 - to add fGravityActive data member
|
||||
// Created: John Apostolakis, 10.03.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4Field.hh"
|
||||
|
||||
G4Field::G4Field( G4bool gravityOn):
|
||||
fGravityActive( gravityOn )
|
||||
G4Field::G4Field( G4bool gravityOn )
|
||||
: fGravityActive( gravityOn )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ G4Field::~G4Field()
|
||||
{
|
||||
}
|
||||
|
||||
G4Field& G4Field::operator = (const G4Field &p)
|
||||
G4Field& G4Field::operator = (const G4Field& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
fGravityActive= p.fGravityActive;
|
||||
@@ -58,6 +58,7 @@ G4Field* G4Field::Clone() const
|
||||
<< "but Clone method called.\n"
|
||||
<< "Cannot continue;";
|
||||
G4Exception("G4Field::Clone", "GeomField004", FatalException,msg );
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldManager implementation
|
||||
//
|
||||
//
|
||||
// Author: John Apostolakis, 10.03.97 - design and implementation
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4FieldManager.hh"
|
||||
@@ -37,79 +38,91 @@
|
||||
G4double G4FieldManager::fDefault_Delta_One_Step_Value= 0.01 * millimeter;
|
||||
G4double G4FieldManager::fDefault_Delta_Intersection_Val= 0.001 * millimeter;
|
||||
|
||||
G4FieldManager::G4FieldManager(G4Field *detectorField,
|
||||
G4ChordFinder *pChordFinder,
|
||||
G4bool fieldChangesEnergy
|
||||
)
|
||||
G4FieldManager::G4FieldManager(G4Field* detectorField,
|
||||
G4ChordFinder* pChordFinder,
|
||||
G4bool fieldChangesEnergy )
|
||||
: fDetectorField(detectorField),
|
||||
fChordFinder(pChordFinder),
|
||||
fAllocatedChordFinder(false),
|
||||
fDelta_One_Step_Value( fDefault_Delta_One_Step_Value ),
|
||||
fDelta_One_Step_Value( fDefault_Delta_One_Step_Value ),
|
||||
fDelta_Intersection_Val( fDefault_Delta_Intersection_Val ),
|
||||
fEpsilonMin( fEpsilonMinDefault ),
|
||||
fEpsilonMax( fEpsilonMaxDefault)
|
||||
{
|
||||
if ( detectorField )
|
||||
fFieldChangesEnergy= detectorField->DoesFieldChangeEnergy();
|
||||
if ( detectorField != nullptr )
|
||||
{
|
||||
fFieldChangesEnergy = detectorField->DoesFieldChangeEnergy();
|
||||
}
|
||||
else
|
||||
fFieldChangesEnergy= fieldChangesEnergy;
|
||||
{
|
||||
fFieldChangesEnergy = fieldChangesEnergy;
|
||||
}
|
||||
|
||||
// Add to store
|
||||
//
|
||||
G4FieldManagerStore::Register(this);
|
||||
}
|
||||
|
||||
G4FieldManager::G4FieldManager(G4MagneticField *detectorField)
|
||||
G4FieldManager::G4FieldManager(G4MagneticField* detectorField)
|
||||
: fDetectorField(detectorField), fAllocatedChordFinder(true),
|
||||
fFieldChangesEnergy(false),
|
||||
fDelta_One_Step_Value( fDefault_Delta_One_Step_Value ),
|
||||
fDelta_Intersection_Val( fDefault_Delta_Intersection_Val ),
|
||||
fEpsilonMin( fEpsilonMinDefault ),
|
||||
fEpsilonMax( fEpsilonMaxDefault )
|
||||
{
|
||||
fChordFinder= new G4ChordFinder( detectorField );
|
||||
fChordFinder = new G4ChordFinder( detectorField );
|
||||
|
||||
// Add to store
|
||||
//
|
||||
G4FieldManagerStore::Register(this);
|
||||
}
|
||||
|
||||
G4FieldManager* G4FieldManager::Clone() const
|
||||
{
|
||||
G4Field* aField = 0;
|
||||
G4FieldManager* aFM = 0;
|
||||
G4ChordFinder* aCF = 0;
|
||||
G4Field* aField = nullptr;
|
||||
G4FieldManager* aFM = nullptr;
|
||||
G4ChordFinder* aCF = nullptr;
|
||||
try {
|
||||
if ( this->fDetectorField )
|
||||
aField = this->fDetectorField->Clone();
|
||||
if ( fDetectorField != nullptr )
|
||||
{
|
||||
aField = fDetectorField->Clone();
|
||||
}
|
||||
|
||||
//Create a new field manager, note that we do not set any chordfinder now.
|
||||
aFM = new G4FieldManager( aField , 0 , this->fFieldChangesEnergy );
|
||||
// Create a new field manager, note that we do not set
|
||||
// any chordfinder now
|
||||
//
|
||||
aFM = new G4FieldManager( aField , nullptr , fFieldChangesEnergy );
|
||||
|
||||
//Check if orignally we have the fAllocatedChordFinder variable set, in case, call chord
|
||||
//constructor
|
||||
if ( this->fAllocatedChordFinder )
|
||||
// Check if originally we have the fAllocatedChordFinder variable
|
||||
// set, in case, call chord constructor
|
||||
//
|
||||
if ( fAllocatedChordFinder )
|
||||
{
|
||||
aFM->CreateChordFinder( dynamic_cast<G4MagneticField*>(aField) );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Chord was specified by user, should we clone?
|
||||
//TODO: For the moment copy pointer, to be understood if cloning of ChordFinder is needed
|
||||
aCF = this->fChordFinder;/*->Clone*/
|
||||
// Chord was specified by user, should we clone?
|
||||
// TODO: For the moment copy pointer, to be understood
|
||||
// if cloning of ChordFinder is needed
|
||||
//
|
||||
aCF = fChordFinder; /*->Clone*/
|
||||
aFM->fChordFinder = aCF;
|
||||
}
|
||||
//Copy values of other variables
|
||||
aFM->fEpsilonMax = this->fEpsilonMax;
|
||||
aFM->fEpsilonMin = this->fEpsilonMin;
|
||||
// aFM->fDefault_Delta_Intersection_Val = this->fDefault_Delta_Intersection_Val; // now static
|
||||
// aFM->fDefault_Delta_One_Step_Value = this->fDefault_Delta_One_Step_Value; // now static
|
||||
aFM->fDelta_Intersection_Val = this->fDelta_Intersection_Val;
|
||||
aFM->fDelta_One_Step_Value = this->fDelta_One_Step_Value;
|
||||
//TODO: Should we really add to the store the cloned FM? Who will use this?
|
||||
|
||||
// Copy values of other variables
|
||||
|
||||
aFM->fEpsilonMax = fEpsilonMax;
|
||||
aFM->fEpsilonMin = fEpsilonMin;
|
||||
aFM->fDelta_Intersection_Val = fDelta_Intersection_Val;
|
||||
aFM->fDelta_One_Step_Value = fDelta_One_Step_Value;
|
||||
// TODO: Should we really add to the store the cloned FM?
|
||||
// Who will use this?
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
//Failed creating clone: probably user did not implement Clone method
|
||||
//in derived classes?
|
||||
//Perform clean-up after ourselves...
|
||||
// Failed creating clone: probably user did not implement Clone method
|
||||
// in derived classes?
|
||||
// Perform clean-up after ourselves...
|
||||
delete aField;
|
||||
delete aFM;
|
||||
delete aCF;
|
||||
@@ -121,84 +134,103 @@ G4FieldManager* G4FieldManager::Clone() const
|
||||
void G4FieldManager::ConfigureForTrack( const G4Track * )
|
||||
{
|
||||
// Default is to do nothing!
|
||||
;
|
||||
}
|
||||
|
||||
G4FieldManager::~G4FieldManager()
|
||||
{
|
||||
if( fAllocatedChordFinder ){
|
||||
if( fAllocatedChordFinder )
|
||||
{
|
||||
delete fChordFinder;
|
||||
}
|
||||
G4FieldManagerStore::DeRegister(this);
|
||||
}
|
||||
|
||||
void
|
||||
G4FieldManager::CreateChordFinder(G4MagneticField *detectorMagField)
|
||||
G4FieldManager::CreateChordFinder(G4MagneticField* detectorMagField)
|
||||
{
|
||||
if ( fAllocatedChordFinder )
|
||||
if ( fAllocatedChordFinder )
|
||||
{
|
||||
delete fChordFinder;
|
||||
fAllocatedChordFinder= false;
|
||||
}
|
||||
fAllocatedChordFinder = false;
|
||||
|
||||
if( detectorMagField ) {
|
||||
fChordFinder= new G4ChordFinder( detectorMagField );
|
||||
fAllocatedChordFinder= true;
|
||||
} else {
|
||||
if( detectorMagField != nullptr )
|
||||
{
|
||||
fChordFinder = new G4ChordFinder( detectorMagField );
|
||||
fAllocatedChordFinder = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fChordFinder = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void G4FieldManager::InitialiseFieldChangesEnergy()
|
||||
{
|
||||
if ( fDetectorField )
|
||||
fFieldChangesEnergy= fDetectorField->DoesFieldChangeEnergy();
|
||||
if ( fDetectorField != nullptr )
|
||||
{
|
||||
fFieldChangesEnergy = fDetectorField->DoesFieldChangeEnergy();
|
||||
}
|
||||
else
|
||||
fFieldChangesEnergy= false; // No field , no change!
|
||||
{
|
||||
fFieldChangesEnergy = false; // No field, no change!
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4FieldManager::SetDetectorField(G4Field *pDetectorField, int failMode )
|
||||
G4bool G4FieldManager::SetDetectorField(G4Field* pDetectorField,
|
||||
G4int failMode )
|
||||
{
|
||||
G4VIntegrationDriver* driver = nullptr;
|
||||
G4EquationOfMotion* equation = nullptr;
|
||||
// G4bool compatibleField= false;
|
||||
G4bool ableToSet= false;
|
||||
// G4bool compatibleField = false;
|
||||
G4bool ableToSet = false;
|
||||
|
||||
fDetectorField= pDetectorField;
|
||||
fDetectorField = pDetectorField;
|
||||
InitialiseFieldChangesEnergy();
|
||||
|
||||
// Must 'propagate' the field to the dependent classes
|
||||
//
|
||||
if( fChordFinder )
|
||||
if( fChordFinder != nullptr )
|
||||
{
|
||||
failMode= std::max( failMode, 1) ; // If a chord finder exists, warn in case of error!
|
||||
failMode= std::max( failMode, 1) ;
|
||||
// If a chord finder exists, warn in case of error!
|
||||
|
||||
driver = fChordFinder->GetIntegrationDriver();
|
||||
if( driver ){
|
||||
equation = driver->GetEquationOfMotion();
|
||||
// Should check the compatibility between the field and the equation HERE
|
||||
if( equation ) {
|
||||
equation->SetFieldObj(pDetectorField);
|
||||
ableToSet = true;
|
||||
}
|
||||
if( driver != nullptr )
|
||||
{
|
||||
equation = driver->GetEquationOfMotion();
|
||||
|
||||
// Should check the compatibility between the
|
||||
// field and the equation HERE
|
||||
|
||||
if( equation != nullptr )
|
||||
{
|
||||
equation->SetFieldObj(pDetectorField);
|
||||
ableToSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !ableToSet && (failMode > 0) )
|
||||
{
|
||||
// If this fails, report the issue !
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Unable to set the field in the dependent objects of G4FieldManager" << G4endl;
|
||||
msg << "All the dependent classes must be fully initialised, before it is possible to call this method." << G4endl;
|
||||
msg << "The problem encountered was the following: " << G4endl;
|
||||
if( !fChordFinder ) { msg << " No ChordFinder. " ; }
|
||||
else if( !driver) { msg << " No Integration Driver set. ";}
|
||||
else if( !equation) { msg << " No Equation found. " ; }
|
||||
// else if( !compatibleField ) { msg << " Field not compatible. ";}
|
||||
else { msg << " Can NOT find reason for failure. ";}
|
||||
msg << G4endl;
|
||||
G4ExceptionSeverity severity= (failMode != 1) ? FatalException : JustWarning ;
|
||||
G4Exception("G4FieldManager::SetDetectorField", "Geometry001",
|
||||
severity, msg);
|
||||
// If this fails, report the issue !
|
||||
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Unable to set the field in the dependent objects of G4FieldManager"
|
||||
<< G4endl;
|
||||
msg << "All the dependent classes must be fully initialised,"
|
||||
<< "before it is possible to call this method." << G4endl;
|
||||
msg << "The problem encountered was the following: " << G4endl;
|
||||
if( fChordFinder == nullptr ) { msg << " No ChordFinder. " ; }
|
||||
else if( driver == nullptr ) { msg << " No Integration Driver set. ";}
|
||||
else if( equation == nullptr ) { msg << " No Equation found. " ; }
|
||||
// else if( !compatibleField ) { msg << " Field not compatible. ";}
|
||||
else { msg << " Can NOT find reason for failure. ";}
|
||||
msg << G4endl;
|
||||
G4ExceptionSeverity severity = (failMode != 1)
|
||||
? FatalException : JustWarning ;
|
||||
G4Exception("G4FieldManager::SetDetectorField", "Geometry001",
|
||||
severity, msg);
|
||||
}
|
||||
return ableToSet;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldManagerStore implementation
|
||||
//
|
||||
//
|
||||
// G4FieldManagerStore
|
||||
//
|
||||
// Implementation for singleton container
|
||||
//
|
||||
// History:
|
||||
// 07.12.07 J.Apostolakis Adapted from G4LogicalVolumeStore
|
||||
// Author: J.Apostolakis, 07.12.2007 - Adapted from G4LogicalVolumeStore
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4Types.hh"
|
||||
@@ -41,7 +36,7 @@
|
||||
// Static class variables
|
||||
// ***************************************************************************
|
||||
//
|
||||
G4ThreadLocal G4FieldManagerStore* G4FieldManagerStore::fgInstance = 0;
|
||||
G4ThreadLocal G4FieldManagerStore* G4FieldManagerStore::fgInstance = nullptr;
|
||||
G4ThreadLocal G4bool G4FieldManagerStore::locked = false;
|
||||
|
||||
// ***************************************************************************
|
||||
@@ -62,7 +57,7 @@ G4FieldManagerStore::G4FieldManagerStore()
|
||||
G4FieldManagerStore::~G4FieldManagerStore()
|
||||
{
|
||||
Clean();
|
||||
fgInstance = 0;
|
||||
fgInstance = nullptr;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
@@ -79,7 +74,7 @@ void G4FieldManagerStore::Clean()
|
||||
size_t i=0;
|
||||
G4FieldManagerStore* store = GetInstance();
|
||||
|
||||
for(iterator pos=store->begin(); pos!=store->end(); pos++)
|
||||
for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
|
||||
{
|
||||
if (*pos) { delete *pos; }
|
||||
i++;
|
||||
@@ -87,9 +82,13 @@ void G4FieldManagerStore::Clean()
|
||||
|
||||
#ifdef G4GEOMETRY_DEBUG
|
||||
if (store->size() < i-1)
|
||||
{ G4cout << "No field managers deleted. Already deleted by user ?" << G4endl; }
|
||||
{
|
||||
G4cout << "No field managers deleted. Already deleted by user ?" << G4endl;
|
||||
}
|
||||
else
|
||||
{ G4cout << i-1 << " field managers deleted !" << G4endl; }
|
||||
{
|
||||
G4cout << i-1 << " field managers deleted !" << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
locked = false;
|
||||
@@ -113,7 +112,7 @@ void G4FieldManagerStore::DeRegister(G4FieldManager* pFieldMgr)
|
||||
{
|
||||
if (!locked) // Do not de-register if locked !
|
||||
{
|
||||
for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++)
|
||||
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
|
||||
{
|
||||
if (*i==pFieldMgr) // For LogVol was **i == *pLogVolume ... Reason?
|
||||
{
|
||||
@@ -130,7 +129,7 @@ void G4FieldManagerStore::DeRegister(G4FieldManager* pFieldMgr)
|
||||
//
|
||||
G4FieldManagerStore* G4FieldManagerStore::GetInstance()
|
||||
{
|
||||
if (!fgInstance)
|
||||
if (fgInstance == nullptr)
|
||||
{
|
||||
fgInstance = new G4FieldManagerStore;
|
||||
}
|
||||
@@ -153,12 +152,12 @@ G4FieldManagerStore* G4FieldManagerStore::GetInstanceIfExist()
|
||||
void
|
||||
G4FieldManagerStore::ClearAllChordFindersState()
|
||||
{
|
||||
G4ChordFinder *pChordFnd;
|
||||
G4ChordFinder* pChordFnd;
|
||||
|
||||
for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++)
|
||||
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
|
||||
{
|
||||
pChordFnd = (*i)->GetChordFinder();
|
||||
if( pChordFnd )
|
||||
if( pChordFnd != nullptr )
|
||||
{
|
||||
pChordFnd->ResetStepEstimate();
|
||||
}
|
||||
|
||||
@@ -23,21 +23,22 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldTrack implementation
|
||||
//
|
||||
//
|
||||
// Author: John Apostolakis, CERN - First version, 14.10.1996
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
std::ostream& operator<<( std::ostream& os, const G4FieldTrack& SixVec)
|
||||
{
|
||||
const G4double *SixV = SixVec.SixVector;
|
||||
const int precPos= 9; // For position
|
||||
const int precEp= 9; // For Energy / momentum
|
||||
const int precLen= 12; // For Length along track
|
||||
const int precSpin= 9; // For polarisation
|
||||
const int precTime= 6; // For time of flight
|
||||
const int oldpr= os.precision(precPos);
|
||||
const G4double* SixV = SixVec.SixVector;
|
||||
const G4int precPos= 9; // For position
|
||||
const G4int precEp= 9; // For Energy / momentum
|
||||
const G4int precLen= 12; // For Length along track
|
||||
const G4int precSpin= 9; // For polarisation
|
||||
const G4int precTime= 6; // For time of flight
|
||||
const G4int oldpr= os.precision(precPos);
|
||||
os << " ( ";
|
||||
os << " X= " << SixV[0] << " " << SixV[1] << " "
|
||||
<< SixV[2] << " "; // Position
|
||||
@@ -52,15 +53,24 @@ std::ostream& operator<<( std::ostream& os, const G4FieldTrack& SixVec)
|
||||
os.precision(6);
|
||||
os << " m0= " << SixVec.fRestMass_c2;
|
||||
os << " (Pdir-1)= " << SixVec.fMomentumDir.mag()-1.0;
|
||||
if( SixVec.fLabTimeOfFlight > 0.0 ) os.precision(precTime);
|
||||
else os.precision(3);
|
||||
if( SixVec.fLabTimeOfFlight > 0.0 )
|
||||
{
|
||||
os.precision(precTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
os.precision(3);
|
||||
}
|
||||
os << " t_lab= " << SixVec.fLabTimeOfFlight;
|
||||
os << " t_proper= " << SixVec.fProperTimeOfFlight ;
|
||||
G4ThreeVector pol= SixVec.GetPolarization();
|
||||
if( pol.mag2() > 0.0 ){
|
||||
if( pol.mag2() > 0.0 )
|
||||
{
|
||||
os.precision(precSpin);
|
||||
os << " PolV= " << pol; // SixVec.GetPolarization();
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
os << " PolV= (0,0,0) ";
|
||||
}
|
||||
os << " ) ";
|
||||
@@ -89,10 +99,9 @@ G4FieldTrack::G4FieldTrack( const G4ThreeVector& pPosition,
|
||||
// fPDGSpin( pdgSpin )
|
||||
{
|
||||
UpdateFourMomentum( kineticEnergy, pMomentumDirection );
|
||||
// Sets momentum direction as well.
|
||||
|
||||
SetPosition( pPosition );
|
||||
// Sets momentum direction as well.
|
||||
|
||||
SetPosition( pPosition );
|
||||
SetPolarization( vecPolarization );
|
||||
}
|
||||
|
||||
@@ -114,7 +123,7 @@ G4FieldTrack::G4FieldTrack( const G4ThreeVector& pPosition,
|
||||
fChargeState( DBL_MAX, DBL_MAX, -1.0 ) // charge not set
|
||||
{
|
||||
UpdateFourMomentum( kineticEnergy, pMomentumDirection );
|
||||
// Sets momentum direction as well.
|
||||
// Sets momentum direction as well.
|
||||
|
||||
SetPosition( pPosition );
|
||||
fChargeState.SetPDGSpin( pdgSpin );
|
||||
@@ -131,15 +140,15 @@ G4FieldTrack::G4FieldTrack( char ) // Nothing is set !!
|
||||
G4ThreeVector Zero(0.0, 0.0, 0.0);
|
||||
SetCurvePnt( Zero, Zero, 0.0 );
|
||||
SetPolarization( Zero );
|
||||
// fInitialMomentumMag= 0.00; // Invalid
|
||||
// fLastMomentumMag= 0.0;
|
||||
// fInitialMomentumMag = 0.00; // Invalid
|
||||
// fLastMomentumMag = 0.0;
|
||||
}
|
||||
|
||||
void G4FieldTrack::
|
||||
SetChargeAndMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment, // default= DBL_MAX - do not change
|
||||
G4double electric_dipole_moment, // ditto
|
||||
G4double magnetic_charge ) // ditto
|
||||
G4double magnetic_dipole_moment, // default = DBL_MAX
|
||||
G4double electric_dipole_moment, // ditto
|
||||
G4double magnetic_charge ) // ditto
|
||||
{
|
||||
fChargeState.SetChargesAndMoments( charge,
|
||||
magnetic_dipole_moment,
|
||||
@@ -148,7 +157,8 @@ void G4FieldTrack::
|
||||
|
||||
// NOTE: Leaves Spin unchanged !
|
||||
//
|
||||
// G4double pdgSpin= fChargeState.GetSpin(); // New Property of ChargeState (not well documented! )
|
||||
// G4double pdgSpin= fChargeState.GetSpin();
|
||||
// New Property of ChargeState (not well documented! )
|
||||
|
||||
// IDEA: Improve the implementation using handles
|
||||
// -- and handle to the old one (which can be shared by other copies) and
|
||||
@@ -160,49 +170,49 @@ void G4FieldTrack::
|
||||
|
||||
// Load values from array
|
||||
//
|
||||
// note that momentum direction must-be/is normalised
|
||||
|
||||
// Note that momentum direction must-be/is normalised
|
||||
//
|
||||
void G4FieldTrack::LoadFromArray(const G4double valArrIn[ncompSVEC],
|
||||
G4int noVarsIntegrated)
|
||||
{
|
||||
G4int i;
|
||||
|
||||
// Fill the variables not integrated with zero -- so it's clear !!
|
||||
//
|
||||
G4double valArr[ncompSVEC];
|
||||
for( i=0; i<noVarsIntegrated; i++){
|
||||
valArr[i]= valArrIn[i];
|
||||
for(G4int i=0; i<noVarsIntegrated; ++i)
|
||||
{
|
||||
valArr[i] = valArrIn[i];
|
||||
}
|
||||
for( i=noVarsIntegrated; i<ncompSVEC; i++) {
|
||||
valArr[i]= 0.0;
|
||||
for(G4int i=noVarsIntegrated; i<ncompSVEC; ++i)
|
||||
{
|
||||
valArr[i] = 0.0;
|
||||
}
|
||||
|
||||
SixVector[0]=valArr[0];
|
||||
SixVector[1]=valArr[1];
|
||||
SixVector[2]=valArr[2];
|
||||
SixVector[3]=valArr[3];
|
||||
SixVector[4]=valArr[4];
|
||||
SixVector[5]=valArr[5];
|
||||
SixVector[0] = valArr[0];
|
||||
SixVector[1] = valArr[1];
|
||||
SixVector[2] = valArr[2];
|
||||
SixVector[3] = valArr[3];
|
||||
SixVector[4] = valArr[4];
|
||||
SixVector[5] = valArr[5];
|
||||
|
||||
G4ThreeVector Momentum(valArr[3],valArr[4],valArr[5]);
|
||||
|
||||
G4double momentum_square= Momentum.mag2();
|
||||
fMomentumDir= Momentum.unit();
|
||||
|
||||
fKineticEnergy = momentum_square /
|
||||
(std::sqrt(momentum_square+fRestMass_c2*fRestMass_c2)
|
||||
+ fRestMass_c2 );
|
||||
// The above equation is stable for small and large momenta
|
||||
fKineticEnergy = momentum_square
|
||||
/ (std::sqrt(momentum_square+fRestMass_c2*fRestMass_c2)
|
||||
+ fRestMass_c2 );
|
||||
// The above equation is stable for small and large momenta
|
||||
|
||||
// The following components may or may not be
|
||||
// integrated over -- integration is optional
|
||||
// fKineticEnergy= valArr[6];
|
||||
// integrated over -- integration is optional
|
||||
// fKineticEnergy = valArr[6];
|
||||
|
||||
fLabTimeOfFlight=valArr[7];
|
||||
fProperTimeOfFlight=valArr[8];
|
||||
G4ThreeVector vecPolarization= G4ThreeVector(valArr[9],valArr[10],valArr[11]);
|
||||
fLabTimeOfFlight = valArr[7];
|
||||
fProperTimeOfFlight = valArr[8];
|
||||
G4ThreeVector vecPolarization= G4ThreeVector(valArr[9],valArr[10],valArr[11]);
|
||||
SetPolarization( vecPolarization );
|
||||
|
||||
// fMomentumDir=G4ThreeVector(valArr[13],valArr[14],valArr[15]);
|
||||
// fDistanceAlongCurve= valArr[];
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Helper namespace field_utils implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// Implementation by Dmitry Sorokin - GSoC 2017
|
||||
// Work supported by Google as part of Google Summer of Code 2017.
|
||||
// Supervision / code review: John Apostolakis
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4FieldUtils.hh"
|
||||
|
||||
@@ -39,71 +37,75 @@ namespace field_utils {
|
||||
|
||||
G4double absoluteError(const G4double y[],
|
||||
const G4double yError[],
|
||||
G4double hstep)
|
||||
G4double hstep)
|
||||
{
|
||||
const G4double momentum2 = getValue2(y, Value3D::Momentum);
|
||||
const G4double invMomentum2 = 1.0 / momentum2;
|
||||
const G4double positionError2 = getValue2(yError, Value3D::Position);
|
||||
const G4double momentumError2 = getValue2(yError, Value3D::Momentum);
|
||||
const G4double relativeMomentumError2 = momentumError2 * invMomentum2;
|
||||
const G4double momentum2 = getValue2(y, Value3D::Momentum);
|
||||
const G4double invMomentum2 = 1.0 / momentum2;
|
||||
const G4double positionError2 = getValue2(yError, Value3D::Position);
|
||||
const G4double momentumError2 = getValue2(yError, Value3D::Momentum);
|
||||
const G4double relativeMomentumError2 = momentumError2 * invMomentum2;
|
||||
|
||||
return std::max(std::sqrt(positionError2), std::sqrt(relativeMomentumError2) * hstep);
|
||||
return std::max(std::sqrt(positionError2),
|
||||
std::sqrt(relativeMomentumError2) * hstep);
|
||||
}
|
||||
|
||||
G4double relativeError2(const G4double y[],
|
||||
const G4double yerr[],
|
||||
G4double h,
|
||||
G4double eps_rel_max)
|
||||
G4double h,
|
||||
G4double eps_rel_max)
|
||||
{
|
||||
G4double errmax_sq;
|
||||
G4double errmax_sq;
|
||||
|
||||
G4double inv_eps_vel_sq = 1.0 / (eps_rel_max * eps_rel_max);
|
||||
G4double errvel_sq = 0.0; // square of momentum vector difference
|
||||
G4double inv_eps_vel_sq = 1.0 / (eps_rel_max * eps_rel_max);
|
||||
G4double errvel_sq = 0.0; // square of momentum vector difference
|
||||
|
||||
G4double eps_pos = eps_rel_max * h;
|
||||
G4double inv_eps_pos_sq = 1.0 / (eps_pos * eps_pos);
|
||||
G4double eps_pos = eps_rel_max * h;
|
||||
G4double inv_eps_pos_sq = 1.0 / (eps_pos * eps_pos);
|
||||
|
||||
// Evaluate accuracy
|
||||
G4double errpos_sq = getValue2(yerr, Value3D::Position);
|
||||
errpos_sq *= inv_eps_pos_sq; // Scale relative to required tolerance
|
||||
// Evaluate accuracy
|
||||
//
|
||||
G4double errpos_sq = getValue2(yerr, Value3D::Position);
|
||||
errpos_sq *= inv_eps_pos_sq; // Scale relative to required tolerance
|
||||
|
||||
// Accuracy for momentum
|
||||
G4double magvel_sq = getValue2(y, Value3D::Momentum);
|
||||
G4double sumerr_sq = getValue2(yerr, Value3D::Momentum);
|
||||
if (magvel_sq > 0.0)
|
||||
{
|
||||
errvel_sq = sumerr_sq / magvel_sq;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("field_utils::relativeError","Field001",
|
||||
JustWarning, "found case of zero momentum");
|
||||
errvel_sq = sumerr_sq;
|
||||
}
|
||||
errvel_sq *= inv_eps_vel_sq;
|
||||
errmax_sq = std::max(errpos_sq, errvel_sq);
|
||||
// Accuracy for momentum
|
||||
//
|
||||
G4double magvel_sq = getValue2(y, Value3D::Momentum);
|
||||
G4double sumerr_sq = getValue2(yerr, Value3D::Momentum);
|
||||
if (magvel_sq > 0.0)
|
||||
{
|
||||
errvel_sq = sumerr_sq / magvel_sq;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("field_utils::relativeError","Field001",
|
||||
JustWarning, "found case of zero momentum");
|
||||
errvel_sq = sumerr_sq;
|
||||
}
|
||||
errvel_sq *= inv_eps_vel_sq;
|
||||
errmax_sq = std::max(errpos_sq, errvel_sq);
|
||||
|
||||
return errmax_sq;
|
||||
return errmax_sq;
|
||||
}
|
||||
|
||||
G4double relativeError(
|
||||
const G4double y[],
|
||||
const G4double yError[],
|
||||
const G4double h,
|
||||
const G4double errorTolerance)
|
||||
G4double relativeError(const G4double y[],
|
||||
const G4double yError[],
|
||||
const G4double h,
|
||||
const G4double errorTolerance)
|
||||
{
|
||||
return std::sqrt(relativeError2(y, yError, h, errorTolerance));
|
||||
return std::sqrt(relativeError2(y, yError, h, errorTolerance));
|
||||
}
|
||||
|
||||
void copy(G4double dst[], const G4double src[], size_t size)
|
||||
{
|
||||
memcpy(dst, src, sizeof(G4double) * size);
|
||||
std::memcpy(dst, src, sizeof(G4double) * size);
|
||||
}
|
||||
|
||||
|
||||
G4double inverseCurvatureRadius(G4double particleCharge, G4double momentum, G4double BField)
|
||||
G4double inverseCurvatureRadius(G4double particleCharge,
|
||||
G4double momentum,
|
||||
G4double BField)
|
||||
{
|
||||
return -c_light * particleCharge * BField / momentum;
|
||||
return -c_light * particleCharge * BField / momentum;
|
||||
}
|
||||
|
||||
} // field_utils
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4HarmonicPolMagField implementation
|
||||
//
|
||||
//
|
||||
// Author: V.Grichine, 03.02.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4HarmonicPolMagField.hh"
|
||||
@@ -36,21 +37,20 @@ G4HarmonicPolMagField::G4HarmonicPolMagField()
|
||||
|
||||
G4HarmonicPolMagField* G4HarmonicPolMagField::Clone() const
|
||||
{
|
||||
return new G4HarmonicPolMagField;
|
||||
return new G4HarmonicPolMagField;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4HarmonicPolMagField::~G4HarmonicPolMagField()
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
void G4HarmonicPolMagField::GetFieldValue(const G4double yTrack[7],
|
||||
G4double B[3] ) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double a = 1.00 ; // mm -> m
|
||||
G4double x = a*yTrack[0], y = a*yTrack[1], z = a*yTrack[2] ;
|
||||
G4double x2 = x*x, y2 = y*y, z2 = z*z ;
|
||||
@@ -59,13 +59,13 @@ void G4HarmonicPolMagField::GetFieldValue(const G4double yTrack[7],
|
||||
static G4ThreadLocal G4double
|
||||
c[24] = {
|
||||
.010, .010, .010, // 3(0)
|
||||
.0001, .0001, .0001, .0001, .0001, // 5(1)
|
||||
.00001, .00001, .00001, .00001, .00001, .00001, .00001, // 7(2)
|
||||
.000001, .000001, .000001, .000001, .000001, .000001,
|
||||
.0000001, .0000001, .0000001 // 9(3)
|
||||
.0001, .0001, .0001, .0001, .0001, // 5(1)
|
||||
.00001, .00001, .00001, .00001, .00001, .00001, .00001, // 7(2)
|
||||
.000001, .000001, .000001, .000001, .000001, .000001,
|
||||
.0000001, .0000001, .0000001 // 9(3)
|
||||
} ; // total : 24
|
||||
|
||||
// for(i=0;i<24;i++)
|
||||
// for(auto i=0;i<24; ++i)
|
||||
// {
|
||||
// c[i] = 1.0*c[i] ;
|
||||
// }
|
||||
@@ -80,7 +80,7 @@ void G4HarmonicPolMagField::GetFieldValue(const G4double yTrack[7],
|
||||
B[1] = c[2]
|
||||
+c[5]*z + c[6]*x + 2*c[7]*y
|
||||
+c[10]*(z2-x2) + c[11]*xz +2*c[12]*yz +2*c[13]*xy + 3*c[14]*(y2-x2)
|
||||
+c[17]*(z3-3*x2*z) + c[18]*(x*z2-x3/3) +2*c[19]*y*(z2-x2)
|
||||
+c[17]*(z3-3*x2*z) + c[18]*(x*z2-x3/3) +2*c[19]*y*(z2-x2)
|
||||
+2*c[20]*xyz
|
||||
+3*c[21]*z*(y2-x2) + c[22]*(3*x*y2-x3) + 4*c[23]*(y3-3*x2*y) ;
|
||||
|
||||
@@ -90,7 +90,7 @@ void G4HarmonicPolMagField::GetFieldValue(const G4double yTrack[7],
|
||||
+4*c[15]*(z3-3*x2*z) + c[16]*(3*x*z2-x3) + 3*c[17]*(y*z2-x2*y)
|
||||
+2*c[18]*xyz
|
||||
+2*c[19]*z*(y2-x2) + c[20]*(x*y2-x3/3) + c[21]*(y3-3*x2*y) ;
|
||||
for(i=0;i<3;i++)
|
||||
for(auto i=0; i<3 ; ++i)
|
||||
{
|
||||
B[i] = 0.1*B[i] ;
|
||||
}
|
||||
|
||||
@@ -23,55 +23,67 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4HelixExplicitEuler implementation
|
||||
//
|
||||
// Helix Explicit Euler: x_1 = x_0 + helix(h)
|
||||
// with helix(h) being a helix piece of length h
|
||||
// most simple approach for solving linear differential equations.
|
||||
// with helix(h) being a helix piece of length h.
|
||||
// Most simple approach for solving linear differential equations.
|
||||
// Take the current derivative and add it to the current position.
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
// Author: W.Wander <wwc@mit.edu>, 12.09.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4HelixExplicitEuler.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
|
||||
void G4HelixExplicitEuler::Stepper( const G4double yInput[7],
|
||||
const G4double*,
|
||||
G4double Step,
|
||||
G4double yOut[7],
|
||||
G4double yErr[])
|
||||
|
||||
G4HelixExplicitEuler::G4HelixExplicitEuler(G4Mag_EqRhs* EqRhs)
|
||||
: G4MagHelicalStepper(EqRhs)
|
||||
{
|
||||
}
|
||||
|
||||
G4HelixExplicitEuler::~G4HelixExplicitEuler()
|
||||
{
|
||||
}
|
||||
|
||||
//Estimation of the Stepping Angle
|
||||
|
||||
void G4HelixExplicitEuler::Stepper( const G4double yInput[7],
|
||||
const G4double*,
|
||||
G4double Step,
|
||||
G4double yOut[7],
|
||||
G4double yErr[] )
|
||||
{
|
||||
// Estimation of the Stepping Angle
|
||||
//
|
||||
G4ThreeVector Bfld;
|
||||
MagFieldEvaluate(yInput, Bfld);
|
||||
|
||||
const G4int nvar = 6 ;
|
||||
G4int i;
|
||||
G4double yTemp[8], yIn[8] ;
|
||||
G4double yTemp[8], yIn[8] ;
|
||||
G4ThreeVector Bfld_midpoint;
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(i=0;i<nvar;i++) yIn[i]=yInput[i];
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yIn[i] = yInput[i];
|
||||
}
|
||||
|
||||
G4double h = Step * 0.5;
|
||||
G4double h = Step * 0.5;
|
||||
|
||||
// Do full step and two half steps
|
||||
G4double yTemp2[7];
|
||||
AdvanceHelix(yIn, Bfld, h, yTemp2,yTemp);
|
||||
MagFieldEvaluate(yTemp2, Bfld_midpoint) ;
|
||||
AdvanceHelix(yTemp2, Bfld_midpoint, h, yOut);
|
||||
|
||||
// Error estimation
|
||||
for(i=0;i<nvar;i++) {
|
||||
yErr[i] = yOut[i] - yTemp[i] ;
|
||||
}
|
||||
// Do full step and two half steps
|
||||
//
|
||||
G4double yTemp2[7];
|
||||
AdvanceHelix(yIn, Bfld, h, yTemp2,yTemp);
|
||||
MagFieldEvaluate(yTemp2, Bfld_midpoint) ;
|
||||
AdvanceHelix(yTemp2, Bfld_midpoint, h, yOut);
|
||||
SetAngCurve(GetAngCurve() * 2);
|
||||
|
||||
// Error estimation
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yErr[i] = yOut[i] - yTemp[i];
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4HelixExplicitEuler::DistChord() const
|
||||
@@ -83,28 +95,27 @@ G4double G4HelixExplicitEuler::DistChord() const
|
||||
G4double distChord;
|
||||
G4double Ang_curve=GetAngCurve();
|
||||
|
||||
|
||||
if(Ang_curve<=pi){
|
||||
distChord=GetRadHelix()*(1-std::cos(0.5*Ang_curve));
|
||||
}
|
||||
else
|
||||
if(Ang_curve<twopi){
|
||||
distChord=GetRadHelix()*(1+std::cos(0.5*(twopi-Ang_curve)));
|
||||
}
|
||||
else{
|
||||
distChord=2.*GetRadHelix();
|
||||
}
|
||||
|
||||
if(Ang_curve<=pi)
|
||||
{
|
||||
distChord=GetRadHelix()*(1-std::cos(0.5*Ang_curve));
|
||||
}
|
||||
else if(Ang_curve<twopi)
|
||||
{
|
||||
distChord=GetRadHelix()*(1+std::cos(0.5*(twopi-Ang_curve)));
|
||||
}
|
||||
else
|
||||
{
|
||||
distChord=2.*GetRadHelix();
|
||||
}
|
||||
|
||||
return distChord;
|
||||
|
||||
}
|
||||
void
|
||||
G4HelixExplicitEuler::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
|
||||
void G4HelixExplicitEuler::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
|
||||
AdvanceHelix(yIn, Bfld, h, yOut);
|
||||
|
||||
AdvanceHelix(yIn, Bfld, h, yOut);
|
||||
}
|
||||
|
||||
@@ -23,35 +23,41 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4HelixHeum implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// Simple Heum:
|
||||
// Simple Heum:
|
||||
// x_1 = x_0 + h *
|
||||
// 1/4 * dx(t0,x0) +
|
||||
// 3/4 * dx(t0+2/3*h, x0+2/3*h*(dx(t0+h/3,x0+h/3*dx(t0,x0))))
|
||||
//
|
||||
// Third order solver.
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
// Author: W.Wander <wwc@mit.edu>, 03/11/1998
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4HelixHeum.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
G4HelixHeum::G4HelixHeum(G4Mag_EqRhs* EqRhs)
|
||||
: G4MagHelicalStepper(EqRhs)
|
||||
{
|
||||
}
|
||||
|
||||
G4HelixHeum::~G4HelixHeum()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4HelixHeum::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
{
|
||||
const G4int nvar = 6 ;
|
||||
|
||||
G4ThreeVector Bfield_Temp, Bfield_Temp2;
|
||||
G4double yTemp[6], yAdd1[6], yAdd2[6] , yTemp2[6];
|
||||
|
||||
G4int i;
|
||||
|
||||
AdvanceHelix( yIn, Bfld, h, yAdd1 );
|
||||
|
||||
AdvanceHelix( yIn, Bfld, h/3.0, yTemp );
|
||||
@@ -63,7 +69,8 @@ G4HelixHeum::DumbStepper( const G4double yIn[],
|
||||
|
||||
AdvanceHelix( yIn, Bfield_Temp2, h, yAdd2 );
|
||||
|
||||
for( i = 0; i < nvar; i++ ) {
|
||||
for( G4int i = 0; i < nvar; ++i )
|
||||
{
|
||||
yOut[i] = ( 0.25 * yAdd1[i] + 0.75 * yAdd2[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4HelixImplicitEuler implementation
|
||||
//
|
||||
// Helix Implicit Euler:
|
||||
// x_1 = x_0 + 1/2 * ( helix(h,t_0,x_0)
|
||||
@@ -34,37 +33,49 @@
|
||||
// Take the output and its derivative. Add the mean of both derivatives
|
||||
// to form the final output
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
//
|
||||
// Author: W.Wander <wwc@mit.edu>, 03/11/1998
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#include "G4HelixImplicitEuler.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
G4HelixImplicitEuler::G4HelixImplicitEuler(G4Mag_EqRhs *EqRhs)
|
||||
: G4MagHelicalStepper(EqRhs)
|
||||
{
|
||||
}
|
||||
|
||||
G4HelixImplicitEuler::~G4HelixImplicitEuler()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4HelixImplicitEuler::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4HelixImplicitEuler::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
{
|
||||
const G4int nvar = 6 ;
|
||||
G4double yTemp[6], yTemp2[6];
|
||||
G4ThreeVector Bfld_endpoint;
|
||||
|
||||
G4int i;
|
||||
|
||||
// Step forward like in the explicit euler case
|
||||
//
|
||||
AdvanceHelix( yIn, Bfld, h, yTemp);
|
||||
|
||||
// now obtain the new field value at the new point
|
||||
//
|
||||
MagFieldEvaluate(yTemp, Bfld_endpoint);
|
||||
|
||||
// and also advance along a helix for this field value
|
||||
//
|
||||
AdvanceHelix( yIn, Bfld_endpoint, h, yTemp2);
|
||||
|
||||
// we take the average
|
||||
for( i = 0; i < nvar; i++ )
|
||||
// we take the average
|
||||
//
|
||||
for( G4int i = 0; i < nvar; ++i )
|
||||
{
|
||||
yOut[i] = 0.5 * ( yTemp[i] + yTemp2[i] );
|
||||
}
|
||||
|
||||
// NormaliseTangentVector( yOut );
|
||||
}
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
// use Stepper for small step(ClassicalRK4 by default)
|
||||
// Else use HelixExplicitEuler Stepper
|
||||
//
|
||||
// History:
|
||||
// Derived from ExactHelicalStepper 18/05/07
|
||||
//
|
||||
// Created: T.Nikitina, CERN - 18.05.2007, derived from G4ExactHelicalStepper
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#include "G4HelixMixedStepper.hh"
|
||||
@@ -52,7 +50,8 @@
|
||||
#include "G4SimpleHeum.hh"
|
||||
#include "G4RKG3_Stepper.hh"
|
||||
#include "G4NystromRK4.hh"
|
||||
// Additional potential stepper
|
||||
|
||||
// Additional potential steppers
|
||||
#include "G4DormandPrince745.hh"
|
||||
#include "G4BogackiShampine23.hh"
|
||||
#include "G4BogackiShampine45.hh"
|
||||
@@ -61,105 +60,122 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
G4HelixMixedStepper::
|
||||
G4HelixMixedStepper(G4Mag_EqRhs *EqRhs,
|
||||
G4HelixMixedStepper(G4Mag_EqRhs* EqRhs,
|
||||
G4int stepperNumber,
|
||||
G4double angleThreshold)
|
||||
: G4MagHelicalStepper(EqRhs), fNumCallsRK4(0), fNumCallsHelix(0)
|
||||
: G4MagHelicalStepper(EqRhs)
|
||||
{
|
||||
SetVerbose(1);
|
||||
if( angleThreshold < 0.0 ){
|
||||
fAngle_threshold= (1.0/3.0)*pi;
|
||||
}else{
|
||||
fAngle_threshold= angleThreshold;
|
||||
if( angleThreshold < 0.0 )
|
||||
{
|
||||
fAngle_threshold = (1.0/3.0)*pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
fAngle_threshold = angleThreshold;
|
||||
}
|
||||
|
||||
if(stepperNumber<0)
|
||||
stepperNumber=4; // Default is RK4 (original)
|
||||
// stepperNumber=745; // Default is DormandPrince745 (ie DoPri5)
|
||||
// stepperNumber=8; // Default is CashKarp
|
||||
{
|
||||
// stepperNumber = 4; // Default is RK4 (original)
|
||||
stepperNumber = 745; // Default is DormandPrince745 (ie DoPri5)
|
||||
// stepperNumber = 8; // Default is CashKarp
|
||||
}
|
||||
|
||||
fStepperNumber = stepperNumber; // Store the choice
|
||||
fRK4Stepper = SetupStepper(EqRhs, fStepperNumber);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
G4HelixMixedStepper::~G4HelixMixedStepper()
|
||||
{
|
||||
delete(fRK4Stepper);
|
||||
if (fVerbose>0){ PrintCalls();};
|
||||
delete fRK4Stepper;
|
||||
if (fVerbose>0) { PrintCalls(); }
|
||||
}
|
||||
|
||||
void G4HelixMixedStepper::Stepper( const G4double yInput[7],
|
||||
const G4double dydx[7],
|
||||
G4double Step,
|
||||
G4double yOut[7],
|
||||
G4double yErr[])
|
||||
// ---------------------------------------------------------------------------
|
||||
void G4HelixMixedStepper::Stepper( const G4double yInput[7],
|
||||
const G4double dydx[7],
|
||||
G4double Step,
|
||||
G4double yOut[7],
|
||||
G4double yErr[])
|
||||
{
|
||||
//Estimation of the Stepping Angle
|
||||
// Estimation of the Stepping Angle
|
||||
//
|
||||
G4ThreeVector Bfld;
|
||||
MagFieldEvaluate(yInput, Bfld);
|
||||
|
||||
G4double Bmag = Bfld.mag();
|
||||
const G4double *pIn = yInput+3;
|
||||
G4ThreeVector initVelocity= G4ThreeVector( pIn[0], pIn[1], pIn[2]);
|
||||
G4double velocityVal = initVelocity.mag();
|
||||
const G4double* pIn = yInput+3;
|
||||
G4ThreeVector initVelocity = G4ThreeVector( pIn[0], pIn[1], pIn[2] );
|
||||
G4double velocityVal = initVelocity.mag();
|
||||
|
||||
const G4double R_1=std::abs(GetInverseCurve(velocityVal,Bmag)); // curv= inverse Radius
|
||||
G4double Ang_curve= R_1 * Step;
|
||||
const G4double R_1 = std::abs(GetInverseCurve(velocityVal,Bmag));
|
||||
// curv = inverse Radius
|
||||
G4double Ang_curve = R_1 * Step;
|
||||
// SetAngCurve(Ang_curve);
|
||||
// SetCurve(std::abs(1/R_1)); // Move below, to avoid un-needed division if RK used
|
||||
|
||||
if(Ang_curve< fAngle_threshold)
|
||||
// SetCurve(std::abs(1/R_1));
|
||||
|
||||
if(Ang_curve < fAngle_threshold)
|
||||
{
|
||||
fNumCallsRK4++;
|
||||
++fNumCallsRK4;
|
||||
fRK4Stepper->Stepper(yInput,dydx,Step,yOut,yErr);
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr G4int nvar = 6 ;
|
||||
constexpr G4int nvarMax = 8 ;
|
||||
G4double yTemp[nvarMax], yIn[nvarMax], yTemp2[nvarMax];
|
||||
G4ThreeVector Bfld_midpoint;
|
||||
constexpr G4int nvar = 6 ;
|
||||
constexpr G4int nvarMax = 8 ;
|
||||
G4double yTemp[nvarMax], yIn[nvarMax], yTemp2[nvarMax];
|
||||
G4ThreeVector Bfld_midpoint;
|
||||
|
||||
SetAngCurve(Ang_curve);
|
||||
SetCurve(std::abs(1.0/R_1));
|
||||
fNumCallsHelix++;
|
||||
++fNumCallsHelix;
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(G4int i=0;i<nvar;i++) yIn[i]=yInput[i];
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
G4double halfS = Step * 0.5;
|
||||
|
||||
// 1. Do first half step and full step
|
||||
//
|
||||
AdvanceHelix(yIn, Bfld, halfS, yTemp, yTemp2); // yTemp2 for s=2*h (halfS)
|
||||
//**********
|
||||
|
||||
MagFieldEvaluate(yTemp, Bfld_midpoint) ;
|
||||
|
||||
// 2. Do second half step - with revised field
|
||||
// NOTE: Could avoid this call if 'Bfld_midpoint == Bfld'
|
||||
// or diff 'almost' zero
|
||||
//
|
||||
AdvanceHelix(yTemp, Bfld_midpoint, halfS, yOut);
|
||||
// Not requesting y at s=2*h (halfS)
|
||||
//**********
|
||||
// Not requesting y at s=2*h (halfS)
|
||||
|
||||
// 3. Estimate the integration error
|
||||
// should be (nearly) zero if Bfield= constant
|
||||
for(G4int i=0;i<nvar;i++) {
|
||||
yErr[i] = yOut[i] - yTemp2[i] ;
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yErr[i] = yOut[i] - yTemp2[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4HelixMixedStepper::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
// ---------------------------------------------------------------------------
|
||||
void G4HelixMixedStepper::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
AdvanceHelix(yIn, Bfld, h, yOut);
|
||||
}
|
||||
|
||||
G4double G4HelixMixedStepper::DistChord() const
|
||||
// ---------------------------------------------------------------------------
|
||||
G4double G4HelixMixedStepper::DistChord() const
|
||||
{
|
||||
// Implementation : must check whether h/R > 2 pi !!
|
||||
// If( h/R < pi) use G4LineSection::DistLine
|
||||
@@ -168,15 +184,18 @@ G4double G4HelixMixedStepper::DistChord() const
|
||||
G4double distChord;
|
||||
G4double Ang_curve=GetAngCurve();
|
||||
|
||||
if(Ang_curve<=pi){
|
||||
if(Ang_curve<=pi)
|
||||
{
|
||||
distChord=GetRadHelix()*(1-std::cos(0.5*Ang_curve));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Ang_curve<twopi){
|
||||
if(Ang_curve<twopi)
|
||||
{
|
||||
distChord=GetRadHelix()*(1+std::cos(0.5*(twopi-Ang_curve)));
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
distChord=2.*GetRadHelix();
|
||||
}
|
||||
}
|
||||
@@ -192,13 +211,14 @@ void G4HelixMixedStepper::PrintCalls()
|
||||
<< " and Number of calls to Helix = " << fNumCallsHelix << G4endl;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
G4MagIntegratorStepper*
|
||||
G4HelixMixedStepper::SetupStepper(G4Mag_EqRhs* pE, G4int StepperNumber)
|
||||
{
|
||||
G4MagIntegratorStepper* pStepper;
|
||||
if (fVerbose>0) G4cout << " G4HelixMixedStepper: ";
|
||||
switch ( StepperNumber )
|
||||
{
|
||||
{
|
||||
// Robust, classic method
|
||||
case 4:
|
||||
pStepper = new G4ClassicalRK4( pE );
|
||||
@@ -292,10 +312,13 @@ G4HelixMixedStepper::SetupStepper(G4Mag_EqRhs* pE, G4int StepperNumber)
|
||||
pStepper = new G4DormandPrince745( pE ); // Was G4ClassicalRK4( pE );
|
||||
if (fVerbose>0) G4cout << "G4DormandPrince745 (Default)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(fVerbose>0)
|
||||
{
|
||||
G4cout << " chosen as stepper for small steps in G4HelixMixedStepper."
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
return pStepper;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4HelixSimpleRunge implementation
|
||||
//
|
||||
// Simple Runge:
|
||||
// x_1 = x_0 + h * ( dx( t_0+h/2, x_0 + h/2 * dx( t_0, x_0) ) )
|
||||
@@ -33,17 +32,26 @@
|
||||
// Take the derivative at a position to be assumed at the middle of the
|
||||
// Step and add it to the current position.
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
// Author: W. Wander <wwc@mit.edu>, 03.12.1998
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#include "G4HelixSimpleRunge.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
G4HelixSimpleRunge::G4HelixSimpleRunge(G4Mag_EqRhs* EqRhs)
|
||||
: G4MagHelicalStepper(EqRhs)
|
||||
{
|
||||
}
|
||||
|
||||
G4HelixSimpleRunge::~G4HelixSimpleRunge()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4HelixSimpleRunge::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4HelixSimpleRunge::DumbStepper( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
const G4int nvar = 6 ;
|
||||
G4double yTemp[nvar]; // , yAdd[nvar];
|
||||
@@ -52,6 +60,7 @@ G4HelixSimpleRunge::DumbStepper( const G4double yIn[],
|
||||
AdvanceHelix( yIn, Bfld, 0.5 * h, yTemp);
|
||||
|
||||
// now obtain the new field value at the new point
|
||||
//
|
||||
MagFieldEvaluate(yTemp, Bfld_midpoint);
|
||||
|
||||
AdvanceHelix( yIn, Bfld_midpoint, h, yOut);
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4ImplicitEuler implementation
|
||||
//
|
||||
// Implicit Euler:
|
||||
//
|
||||
@@ -35,8 +34,7 @@
|
||||
// Take the output and its derivative. Add the mean of both derivatives
|
||||
// to form the final output.
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
//
|
||||
// Author: W. Wander <wwc@mit.edu>, 12.09.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ImplicitEuler.hh"
|
||||
@@ -46,11 +44,11 @@
|
||||
//
|
||||
// Constructor
|
||||
|
||||
G4ImplicitEuler::G4ImplicitEuler(G4EquationOfMotion *EqRhs,
|
||||
G4int numberOfVariables):
|
||||
G4MagErrorStepper(EqRhs, numberOfVariables)
|
||||
G4ImplicitEuler::G4ImplicitEuler(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables)
|
||||
: G4MagErrorStepper(EqRhs, numberOfVariables)
|
||||
{
|
||||
unsigned int noVariables= std::max(numberOfVariables,8); // For Time .. 7+1
|
||||
unsigned int noVariables = std::max(numberOfVariables,8); // For Time .. 7+1
|
||||
dydxTemp = new G4double[noVariables] ;
|
||||
yTemp = new G4double[noVariables] ;
|
||||
}
|
||||
@@ -59,40 +57,40 @@ G4MagErrorStepper(EqRhs, numberOfVariables)
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4ImplicitEuler::~G4ImplicitEuler()
|
||||
{
|
||||
delete[] dydxTemp;
|
||||
delete[] yTemp;
|
||||
delete [] dydxTemp;
|
||||
delete [] yTemp;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DumbStepper
|
||||
//
|
||||
|
||||
void
|
||||
G4ImplicitEuler::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4ImplicitEuler::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
G4int i;
|
||||
const G4int numberOfVariables= GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// Initialise time to t0, needed when it is not updated by the integration.
|
||||
//
|
||||
yTemp[7] = yOut[7] = yIn[7]; // Better to set it to NaN; // TODO
|
||||
|
||||
for( i = 0; i < numberOfVariables; i++ )
|
||||
for( G4int i = 0; i < numberOfVariables; ++i )
|
||||
{
|
||||
yTemp[i] = yIn[i] + h*dydx[i] ;
|
||||
}
|
||||
|
||||
RightHandSide(yTemp,dydxTemp);
|
||||
|
||||
for( i = 0; i < numberOfVariables; i++ )
|
||||
for( G4int i = 0; i < numberOfVariables; ++i )
|
||||
{
|
||||
yOut[i] = yIn[i] + 0.5 * h * ( dydx[i] + dydxTemp[i] );
|
||||
}
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4LineCurrentMagField implementation
|
||||
//
|
||||
// Author: V.Grichine, 03.02.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4LineCurrentMagField.hh"
|
||||
@@ -33,19 +36,20 @@ G4LineCurrentMagField::G4LineCurrentMagField(G4double pFieldConstant)
|
||||
fFieldConstant = pFieldConstant ;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
G4Field* G4LineCurrentMagField::Clone() const
|
||||
{
|
||||
return new G4LineCurrentMagField( fFieldConstant );
|
||||
return new G4LineCurrentMagField( fFieldConstant );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
G4LineCurrentMagField::~G4LineCurrentMagField()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
void G4LineCurrentMagField::GetFieldValue( const G4double yTrack[7],
|
||||
G4double B[3] ) const
|
||||
@@ -58,7 +62,7 @@ void G4LineCurrentMagField::GetFieldValue( const G4double yTrack[7],
|
||||
G4double Br = fFieldConstant/r;
|
||||
B[0] = -Br*y/r ;
|
||||
B[1] = Br*x/r ;
|
||||
B[2] = 0 ;
|
||||
B[2] = 0.0 ;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
@@ -23,12 +23,20 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4LineSection implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis, 1999
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
G4LineSection::G4LineSection( const G4ThreeVector& PntA,
|
||||
const G4ThreeVector& PntB )
|
||||
: EndpointA(PntA), VecAtoB(PntB-PntA)
|
||||
{
|
||||
fABdistanceSq = VecAtoB.mag2();
|
||||
}
|
||||
|
||||
G4double G4LineSection::Dist( G4ThreeVector OtherPnt ) const
|
||||
{
|
||||
G4double dist_sq;
|
||||
@@ -62,7 +70,7 @@ G4double G4LineSection::Dist( G4ThreeVector OtherPnt ) const
|
||||
}
|
||||
else // B is the closest point
|
||||
{
|
||||
G4ThreeVector EndpointB = EndpointA + VecAtoB;
|
||||
G4ThreeVector EndpointB = EndpointA + VecAtoB;
|
||||
G4ThreeVector VecBZ = OtherPnt - EndpointB;
|
||||
dist_sq = VecBZ.mag2();
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MagErrorStepper implementation
|
||||
//
|
||||
//
|
||||
// Author: W.Wander <wwc@mit.edu>, 09.12.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4MagErrorStepper.hh"
|
||||
@@ -32,88 +33,95 @@
|
||||
|
||||
G4MagErrorStepper::~G4MagErrorStepper()
|
||||
{
|
||||
delete[] yMiddle;
|
||||
delete[] dydxMid;
|
||||
delete[] yInitial;
|
||||
delete[] yOneStep;
|
||||
delete [] yMiddle;
|
||||
delete [] dydxMid;
|
||||
delete [] yInitial;
|
||||
delete [] yOneStep;
|
||||
}
|
||||
|
||||
void
|
||||
G4MagErrorStepper::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError [] )
|
||||
void G4MagErrorStepper::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError [] )
|
||||
{
|
||||
const G4int nvar = this->GetNumberOfVariables() ;
|
||||
const G4int maxvar= GetNumberOfStateVariables();
|
||||
const G4int nvar = GetNumberOfVariables();
|
||||
const G4int maxvar = GetNumberOfStateVariables();
|
||||
|
||||
G4int i;
|
||||
// correction for Richardson Extrapolation.
|
||||
//
|
||||
G4double correction = 1. / ( (1 << IntegratorOrder()) -1 );
|
||||
|
||||
// Saving yInput because yInput and yOutput can be aliases for same array
|
||||
|
||||
for(i=0;i<nvar;i++) yInitial[i]=yInput[i];
|
||||
yInitial[7]= yInput[7]; // Copy the time in case ... even if not really needed
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yInitial[i]=yInput[i];
|
||||
}
|
||||
yInitial[7] = yInput[7]; // Copy the time in case...even if not really needed
|
||||
yMiddle[7] = yInput[7]; // Copy the time from initial value
|
||||
yOneStep[7] = yInput[7]; // As it contributes to final value of yOutput ?
|
||||
// yOutput[7] = yInput[7]; // -> dumb stepper does it too for RK4
|
||||
for(i=nvar;i<maxvar;i++) yOutput[i]=yInput[i];
|
||||
|
||||
for(G4int i=nvar; i<maxvar; ++i)
|
||||
{
|
||||
yOutput[i]=yInput[i];
|
||||
}
|
||||
// yError[7] = 0.0;
|
||||
|
||||
G4double halfStep = hstep * 0.5;
|
||||
|
||||
// Do two half steps
|
||||
|
||||
//
|
||||
DumbStepper (yInitial, dydx, halfStep, yMiddle);
|
||||
RightHandSide(yMiddle, dydxMid);
|
||||
DumbStepper (yMiddle, dydxMid, halfStep, yOutput);
|
||||
|
||||
// Store midpoint, chord calculation
|
||||
|
||||
//
|
||||
fMidPoint = G4ThreeVector( yMiddle[0], yMiddle[1], yMiddle[2]);
|
||||
|
||||
// Do a full Step
|
||||
//
|
||||
DumbStepper(yInitial, dydx, hstep, yOneStep);
|
||||
for(i=0;i<nvar;i++) {
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yError [i] = yOutput[i] - yOneStep[i] ;
|
||||
yOutput[i] += yError[i]*correction ; // Provides accuracy increased
|
||||
// by 1 order via the
|
||||
// Richardson Extrapolation
|
||||
yOutput[i] += yError[i]*correction ;
|
||||
// Provides accuracy increased by 1 order via Richardson Extrapolation
|
||||
}
|
||||
|
||||
fInitialPoint = G4ThreeVector( yInitial[0], yInitial[1], yInitial[2]);
|
||||
fFinalPoint = G4ThreeVector( yOutput[0], yOutput[1], yOutput[2]);
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double
|
||||
G4MagErrorStepper::DistChord() const
|
||||
G4double G4MagErrorStepper::DistChord() const
|
||||
{
|
||||
// Estimate the maximum distance from the curve to the chord
|
||||
//
|
||||
// We estimate this using the distance of the midpoint to
|
||||
// chord (the line between
|
||||
// We estimate this using the distance of the midpoint to
|
||||
// chord (the line between
|
||||
//
|
||||
// Method below is good only for angle deviations < 2 pi,
|
||||
// This restriction should not a problem for the Runge cutta methods,
|
||||
// which generally cannot integrate accurately for large angle deviations.
|
||||
// Method below is good only for angle deviations < 2 pi,
|
||||
// This restriction should not a problem for the Runge cutta methods,
|
||||
// which generally cannot integrate accurately for large angle deviations.
|
||||
|
||||
G4double distLine, distChord;
|
||||
|
||||
if (fInitialPoint != fFinalPoint) {
|
||||
distLine= G4LineSection::Distline( fMidPoint, fInitialPoint, fFinalPoint );
|
||||
// This is a class method that gives distance of Mid
|
||||
// from the Chord between the Initial and Final points.
|
||||
if (fInitialPoint != fFinalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline(fMidPoint, fInitialPoint, fFinalPoint);
|
||||
// This is a class method that gives distance of Mid
|
||||
// from the Chord between the Initial and Final points.
|
||||
|
||||
distChord = distLine;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
distChord = (fMidPoint-fInitialPoint).mag();
|
||||
}
|
||||
|
||||
return distChord;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,13 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MagHelicalStepper implementation
|
||||
//
|
||||
// Given a purely magnetic field a better approach than adding a straight line
|
||||
// (as in the normal runge-kutta-methods) is to add helix segments to the
|
||||
// current position
|
||||
//
|
||||
// Created: J.Apostolakis, CERN - 05.11.1998
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
@@ -33,20 +38,14 @@
|
||||
#include "G4LineSection.hh"
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
|
||||
// given a purely magnetic field a better approach than adding a straight line
|
||||
// (as in the normal runge-kutta-methods) is to add helix segments to the
|
||||
// current position
|
||||
|
||||
|
||||
// Constant for determining unit conversion when using normal as integrand.
|
||||
//
|
||||
const G4double G4MagHelicalStepper::fUnitConstant = 0.299792458*(GeV/(tesla*m));
|
||||
|
||||
|
||||
G4MagHelicalStepper::G4MagHelicalStepper(G4Mag_EqRhs *EqRhs)
|
||||
: G4MagIntegratorStepper(EqRhs, 6), // integrate over 6 variables only !!
|
||||
// position & velocity
|
||||
fPtrMagEqOfMot(EqRhs), fAngCurve(0.), frCurve(0.), frHelix(0.)
|
||||
fPtrMagEqOfMot(EqRhs)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -55,11 +54,11 @@ G4MagHelicalStepper::~G4MagHelicalStepper()
|
||||
}
|
||||
|
||||
void
|
||||
G4MagHelicalStepper::AdvanceHelix( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yHelix[],
|
||||
G4double yHelix2[] )
|
||||
G4MagHelicalStepper::AdvanceHelix( const G4double yIn[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yHelix[],
|
||||
G4double yHelix2[] )
|
||||
{
|
||||
// const G4int nvar = 6;
|
||||
|
||||
@@ -79,12 +78,12 @@ G4MagHelicalStepper::AdvanceHelix( const G4double yIn[],
|
||||
G4ThreeVector positionMove, endTangent;
|
||||
|
||||
G4double Bmag = Bfld.mag();
|
||||
const G4double *pIn = yIn+3;
|
||||
G4ThreeVector initVelocity= G4ThreeVector( pIn[0], pIn[1], pIn[2]);
|
||||
const G4double* pIn = yIn+3;
|
||||
G4ThreeVector initVelocity = G4ThreeVector( pIn[0], pIn[1], pIn[2]);
|
||||
G4double velocityVal = initVelocity.mag();
|
||||
G4ThreeVector initTangent = (1.0/velocityVal) * initVelocity;
|
||||
|
||||
R_1=GetInverseCurve(velocityVal,Bmag);
|
||||
R_1 = GetInverseCurve(velocityVal,Bmag);
|
||||
|
||||
// for too small magnetic fields there is no curvature
|
||||
// (include momentum here) FIXME
|
||||
@@ -182,11 +181,9 @@ G4MagHelicalStepper::AdvanceHelix( const G4double yIn[],
|
||||
}
|
||||
}
|
||||
|
||||
// Use the midpoint method to get an error estimate and correction
|
||||
// modified from G4ClassicalRK4: W.Wander <wwc@mit.edu> 12/09/97
|
||||
//
|
||||
// Use the midpoint method to get an error estimate and correction
|
||||
// modified from G4ClassicalRK4: W.Wander <wwc@mit.edu> 12/09/97
|
||||
//
|
||||
|
||||
void
|
||||
G4MagHelicalStepper::Stepper( const G4double yInput[],
|
||||
const G4double*,
|
||||
@@ -196,8 +193,6 @@ G4MagHelicalStepper::Stepper( const G4double yInput[],
|
||||
{
|
||||
const G4int nvar = 6;
|
||||
|
||||
G4int i;
|
||||
|
||||
// correction for Richardson Extrapolation.
|
||||
// G4double correction = 1. / ( (1 << IntegratorOrder()) -1 );
|
||||
|
||||
@@ -205,27 +200,30 @@ G4MagHelicalStepper::Stepper( const G4double yInput[],
|
||||
G4ThreeVector Bfld_initial, Bfld_midpoint;
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
for(i=0;i<nvar;i++) { yIn[i]=yInput[i]; }
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
|
||||
G4double h = hstep * 0.5;
|
||||
|
||||
MagFieldEvaluate(yIn, Bfld_initial) ;
|
||||
|
||||
// Do two half steps
|
||||
|
||||
DumbStepper(yIn, Bfld_initial, h, yTemp);
|
||||
//
|
||||
DumbStepper(yIn, Bfld_initial, h, yTemp);
|
||||
MagFieldEvaluate(yTemp, Bfld_midpoint) ;
|
||||
DumbStepper(yTemp, Bfld_midpoint, h, yOut);
|
||||
|
||||
// Do a full Step
|
||||
|
||||
//
|
||||
h = hstep ;
|
||||
DumbStepper(yIn, Bfld_initial, h, yTemp);
|
||||
|
||||
// Error estimation
|
||||
|
||||
for(i=0;i<nvar;i++)
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yErr[i] = yOut[i] - yTemp[i] ;
|
||||
}
|
||||
|
||||
@@ -23,19 +23,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MagInt_Driver implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// Implementation for class G4MagInt_Driver
|
||||
// Tracking in space dependent magnetic field
|
||||
//
|
||||
// History of major changes:
|
||||
// 8 Nov 01 J. Apostolakis: Respect minimum step in AccurateAdvance
|
||||
// 27 Jul 99 J. Apostolakis: Ensured that AccurateAdvance does not loop
|
||||
// due to very small eps & step size (precision)
|
||||
// 28 Jan 98 W. Wander: Added ability for low order integrators
|
||||
// 7 Oct 96 V. Grichine First version
|
||||
// V.Grichine, 07.10.1996 - Created
|
||||
// W.Wander, 28.01.1998 - Added ability for low order integrators
|
||||
// J.Apostolakis, 08.11.2001 - Respect minimum step in AccurateAdvance
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include <iomanip>
|
||||
@@ -51,31 +43,18 @@
|
||||
// Constructor
|
||||
//
|
||||
G4MagInt_Driver::G4MagInt_Driver( G4double hminimum,
|
||||
G4MagIntegratorStepper *pStepper,
|
||||
G4MagIntegratorStepper* pStepper,
|
||||
G4int numComponents,
|
||||
G4int statisticsVerbose)
|
||||
: fSmallestFraction( 1.0e-12 ),
|
||||
fNoIntegrationVariables(numComponents),
|
||||
fMinNoVars(12),
|
||||
: fNoIntegrationVariables(numComponents),
|
||||
fNoVars( std::max( fNoIntegrationVariables, fMinNoVars )),
|
||||
fStatisticsVerboseLevel(statisticsVerbose),
|
||||
fNoTotalSteps(0), fNoBadSteps(0), fNoSmallSteps(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),
|
||||
fVerboseLevel(0)
|
||||
fStatisticsVerboseLevel(statisticsVerbose)
|
||||
{
|
||||
// In order to accomodate "Laboratory Time", which is [7], fMinNoVars=8
|
||||
// is required. For proper time of flight and spin, fMinNoVars must be 12
|
||||
|
||||
RenewStepperAndAdjust( pStepper );
|
||||
fMinimumStep= hminimum;
|
||||
|
||||
// The (default) maximum number of steps is Base
|
||||
// divided by the order of Stepper
|
||||
//
|
||||
fMaxStepBase = 250; // Was 5000
|
||||
fMinimumStep = hminimum;
|
||||
|
||||
fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
|
||||
#ifdef G4DEBUG_FIELD
|
||||
@@ -111,9 +90,9 @@ G4MagInt_Driver::~G4MagInt_Driver()
|
||||
|
||||
G4bool
|
||||
G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial )
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial )
|
||||
{
|
||||
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
|
||||
// values at y_current over hstep x2 with accuracy eps.
|
||||
@@ -121,12 +100,12 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
// interval. RightHandSide is the right-hand side of ODE system.
|
||||
// The source is similar to odeint routine from NRC p.721-722 .
|
||||
|
||||
G4int nstp, i, no_warnings=0;
|
||||
G4int nstp, i, no_warnings = 0;
|
||||
G4double x, hnext, hdid, h;
|
||||
|
||||
#ifdef G4DEBUG_FIELD
|
||||
static G4int dbg=1;
|
||||
static G4int nStpPr=50; // For debug printing of long integrations
|
||||
static G4int dbg = 1;
|
||||
static G4int nStpPr = 50; // For debug printing of long integrations
|
||||
G4double ySubStepStart[G4FieldTrack::ncompSVEC];
|
||||
G4FieldTrack yFldTrkStart(y_current);
|
||||
#endif
|
||||
@@ -138,9 +117,9 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
|
||||
G4double startCurveLength;
|
||||
|
||||
G4int noFullIntegr=0, noSmallIntegr = 0 ;
|
||||
static G4ThreadLocal G4int noGoodSteps =0 ; // Bad = chord > curve-len
|
||||
const G4int nvar= fNoVars;
|
||||
G4int noFullIntegr = 0, noSmallIntegr = 0;
|
||||
static G4ThreadLocal G4int noGoodSteps = 0; // Bad = chord > curve-len
|
||||
const G4int nvar = fNoVars;
|
||||
|
||||
G4FieldTrack yStartFT(y_current);
|
||||
|
||||
@@ -148,7 +127,7 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
//
|
||||
if( hstep <= 0.0 )
|
||||
{
|
||||
if(hstep==0.0)
|
||||
if( hstep == 0.0 )
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
@@ -186,10 +165,10 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
|
||||
x = x1;
|
||||
|
||||
for (i=0;i<nvar;i++) { y[i] = ystart[i]; }
|
||||
for ( i=0; i<nvar; ++i) { y[i] = ystart[i]; }
|
||||
|
||||
G4bool lastStep= false;
|
||||
nstp=1;
|
||||
nstp = 1;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -197,13 +176,13 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
|
||||
#ifdef G4DEBUG_FIELD
|
||||
G4double xSubStepStart= x;
|
||||
for (i=0;i<nvar;i++) { ySubStepStart[i] = y[i]; }
|
||||
for (i=0; i<nvar; ++i) { ySubStepStart[i] = y[i]; }
|
||||
yFldTrkStart.LoadFromArray(y, fNoIntegrationVariables);
|
||||
yFldTrkStart.SetCurveLength(x);
|
||||
#endif
|
||||
|
||||
pIntStepper->RightHandSide( y, dydx );
|
||||
fNoTotalSteps++;
|
||||
++fNoTotalSteps;
|
||||
|
||||
// Perform the Integration
|
||||
//
|
||||
@@ -211,7 +190,7 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
{
|
||||
OneGoodStep(y,dydx,x,h,eps,hdid,hnext) ;
|
||||
//--------------------------------------
|
||||
lastStepSucceeded= (hdid == h);
|
||||
lastStepSucceeded = (hdid == h);
|
||||
#ifdef G4DEBUG_FIELD
|
||||
if (dbg>2)
|
||||
{
|
||||
@@ -227,17 +206,17 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
yFldTrk.LoadFromArray(y, fNoIntegrationVariables);
|
||||
yFldTrk.SetCurveLength( x );
|
||||
|
||||
QuickAdvance( yFldTrk, dydx, h, UNKNOWN_CURVATURE_RADIUS, dchord_step, dyerr_len );
|
||||
QuickAdvance( yFldTrk, dydx, h, dchord_step, dyerr_len );
|
||||
//-----------------------------------------------------
|
||||
|
||||
yFldTrk.DumpToArray(y);
|
||||
|
||||
#ifdef G4FLD_STATS
|
||||
fNoSmallSteps++;
|
||||
if ( dyerr_len > fDyerr_max) { fDyerr_max= dyerr_len; }
|
||||
++fNoSmallSteps;
|
||||
if ( dyerr_len > fDyerr_max ) { fDyerr_max = dyerr_len; }
|
||||
fDyerrPos_smTot += dyerr_len;
|
||||
fSumH_sm += h; // Length total for 'small' steps
|
||||
if (nstp<=1) { fNoInitialSmallSteps++; }
|
||||
if (nstp<=1) { ++fNoInitialSmallSteps; }
|
||||
#endif
|
||||
#ifdef G4DEBUG_FIELD
|
||||
if (dbg>1)
|
||||
@@ -258,18 +237,18 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
"Integration Step became Zero!");
|
||||
}
|
||||
dyerr = dyerr_len / h;
|
||||
hdid= h;
|
||||
hdid = h;
|
||||
x += hdid;
|
||||
|
||||
// Compute suggested new step
|
||||
hnext= ComputeNewStepSize( dyerr/eps, h);
|
||||
hnext = ComputeNewStepSize( dyerr/eps, h);
|
||||
|
||||
// .. hnext= ComputeNewStepSize_WithinLimits( dyerr/eps, h);
|
||||
lastStepSucceeded= (dyerr<= eps);
|
||||
lastStepSucceeded = (dyerr<= eps);
|
||||
}
|
||||
|
||||
if (lastStepSucceeded) { noFullIntegr++; }
|
||||
else { noSmallIntegr++; }
|
||||
if (lastStepSucceeded) { ++noFullIntegr; }
|
||||
else { ++noSmallIntegr; }
|
||||
|
||||
G4ThreeVector EndPos( y[0], y[1], y[2] );
|
||||
|
||||
@@ -280,8 +259,8 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4cout << "MagIntDrv: " ;
|
||||
G4cout << "hdid=" << std::setw(12) << hdid << " "
|
||||
<< "hnext=" << std::setw(12) << hnext << " "
|
||||
<< "hstep=" << std::setw(12) << hstep << " (requested) "
|
||||
<< G4endl;
|
||||
<< "hstep=" << std::setw(12) << hstep << " (requested) "
|
||||
<< G4endl;
|
||||
PrintStatus( ystart, x1, y, x, h, (nstp==nStpPr) ? -nstp: nstp);
|
||||
}
|
||||
#endif
|
||||
@@ -290,7 +269,7 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double endPointDist= (EndPos-StartPos).mag();
|
||||
if ( endPointDist >= hdid*(1.+perMillion) )
|
||||
{
|
||||
fNoBadSteps++;
|
||||
++fNoBadSteps;
|
||||
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
@@ -306,12 +285,12 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
|
||||
}
|
||||
#endif
|
||||
no_warnings++;
|
||||
++no_warnings;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
noGoodSteps ++;
|
||||
++noGoodSteps;
|
||||
}
|
||||
// #endif
|
||||
|
||||
@@ -336,7 +315,7 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
WarnSmallStepSize( hnext, hstep, h, x-x1, nstp );
|
||||
PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
|
||||
}
|
||||
no_warnings++;
|
||||
++no_warnings;
|
||||
}
|
||||
#endif
|
||||
// Make sure that the next step is at least Hmin.
|
||||
@@ -365,7 +344,7 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
<< G4endl
|
||||
<< " Integration step 'h' became "
|
||||
<< h << " due to roundoff. " << G4endl
|
||||
<< " Calculated as difference of x2= "<< x2 << " and x=" << x
|
||||
<< " Calculated as difference of x2= "<< x2 << " and x=" << x
|
||||
<< " Forcing termination of advance." << G4endl;
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
@@ -378,9 +357,9 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
// Have we reached the end ?
|
||||
// --> a better test might be x-x2 > an_epsilon
|
||||
|
||||
succeeded= (x>=x2); // If it was a "forced" last step
|
||||
succeeded = (x>=x2); // If it was a "forced" last step
|
||||
|
||||
for (i=0;i<nvar;i++) { yEnd[i] = y[i]; }
|
||||
for (i=0; i<nvar; ++i) { yEnd[i] = y[i]; }
|
||||
|
||||
// Put back the values.
|
||||
y_current.LoadFromArray( yEnd, fNoIntegrationVariables );
|
||||
@@ -388,7 +367,7 @@ G4MagInt_Driver::AccurateAdvance(G4FieldTrack& y_current,
|
||||
|
||||
if(nstp > fMaxNoSteps)
|
||||
{
|
||||
no_warnings++;
|
||||
++no_warnings;
|
||||
succeeded = false;
|
||||
#ifdef G4DEBUG_FIELD
|
||||
if (dbg)
|
||||
@@ -417,8 +396,8 @@ G4MagInt_Driver::WarnSmallStepSize( G4double hnext, G4double hstep,
|
||||
G4double h, G4double xDone,
|
||||
G4int nstp)
|
||||
{
|
||||
static G4ThreadLocal G4int noWarningsIssued =0;
|
||||
const G4int maxNoWarnings = 10; // Number of verbose warnings
|
||||
static G4ThreadLocal G4int noWarningsIssued = 0;
|
||||
const G4int maxNoWarnings = 10; // Number of verbose warnings
|
||||
std::ostringstream message;
|
||||
if( (noWarningsIssued < maxNoWarnings) || fVerboseLevel > 10 )
|
||||
{
|
||||
@@ -439,7 +418,7 @@ G4MagInt_Driver::WarnSmallStepSize( G4double hnext, G4double hstep,
|
||||
}
|
||||
G4Exception("G4MagInt_Driver::WarnSmallStepSize()", "GeomField1001",
|
||||
JustWarning, message);
|
||||
noWarningsIssued++;
|
||||
++noWarningsIssued;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
@@ -447,27 +426,27 @@ G4MagInt_Driver::WarnSmallStepSize( G4double hnext, G4double hstep,
|
||||
void
|
||||
G4MagInt_Driver::WarnTooManyStep( G4double x1start,
|
||||
G4double x2end,
|
||||
G4double xCurrent)
|
||||
G4double xCurrent )
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "The number of steps used in the Integration driver"
|
||||
<< " (Runge-Kutta) is too many." << G4endl
|
||||
<< "Integration of the interval was not completed !" << G4endl
|
||||
<< "Only a " << (xCurrent-x1start)*100/(x2end-x1start)
|
||||
<< " % fraction of it was done.";
|
||||
G4Exception("G4MagInt_Driver::WarnTooManyStep()", "GeomField1001",
|
||||
JustWarning, message);
|
||||
std::ostringstream message;
|
||||
message << "The number of steps used in the Integration driver"
|
||||
<< " (Runge-Kutta) is too many." << G4endl
|
||||
<< "Integration of the interval was not completed !" << G4endl
|
||||
<< "Only a " << (xCurrent-x1start)*100/(x2end-x1start)
|
||||
<< " % fraction of it was done.";
|
||||
G4Exception("G4MagInt_Driver::WarnTooManyStep()", "GeomField1001",
|
||||
JustWarning, message);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
void
|
||||
G4MagInt_Driver::WarnEndPointTooFar (G4double endPointDist,
|
||||
G4double h ,
|
||||
G4double eps,
|
||||
G4int dbg)
|
||||
G4double h ,
|
||||
G4double eps,
|
||||
G4int dbg)
|
||||
{
|
||||
static G4ThreadLocal G4double maxRelError=0.0;
|
||||
static G4ThreadLocal G4double maxRelError = 0.0;
|
||||
G4bool isNewMax, prNewMax;
|
||||
|
||||
isNewMax = endPointDist > (1.0 + maxRelError) * h;
|
||||
@@ -479,7 +458,7 @@ G4MagInt_Driver::WarnEndPointTooFar (G4double endPointDist,
|
||||
{
|
||||
static G4ThreadLocal G4int noWarnings = 0;
|
||||
std::ostringstream message;
|
||||
if( (noWarnings ++ < 10) || (dbg>2) )
|
||||
if( (noWarnings++ < 10) || (dbg>2) )
|
||||
{
|
||||
message << "The integration produced an end-point which " << G4endl
|
||||
<< "is further from the start-point than the curve length."
|
||||
@@ -529,22 +508,20 @@ G4MagInt_Driver::OneGoodStep( G4double y[], // InOut
|
||||
|
||||
G4double inv_eps_vel_sq = 1.0 / (eps_rel_max*eps_rel_max);
|
||||
|
||||
G4double errpos_sq=0.0; // square of displacement error
|
||||
G4double errvel_sq=0.0; // square of momentum vector difference
|
||||
G4double errspin_sq=0.0; // square of spin vector difference
|
||||
|
||||
G4int iter;
|
||||
G4double errpos_sq = 0.0; // square of displacement error
|
||||
G4double errvel_sq = 0.0; // square of momentum vector difference
|
||||
G4double errspin_sq = 0.0; // square of spin vector difference
|
||||
|
||||
static G4ThreadLocal G4int tot_no_trials=0;
|
||||
const G4int max_trials=100;
|
||||
|
||||
G4ThreeVector Spin(y[9],y[10],y[11]);
|
||||
G4double spin_mag2 =Spin.mag2() ;
|
||||
G4bool hasSpin= (spin_mag2 > 0.0);
|
||||
G4double spin_mag2 = Spin.mag2();
|
||||
G4bool hasSpin = (spin_mag2 > 0.0);
|
||||
|
||||
for (iter=0; iter<max_trials ;iter++)
|
||||
for (G4int iter=0; iter<max_trials; ++iter)
|
||||
{
|
||||
tot_no_trials++;
|
||||
++tot_no_trials;
|
||||
pIntStepper-> Stepper(y,dydx,h,ytemp,yerr);
|
||||
// *******
|
||||
G4double eps_pos = eps_rel_max * std::max(h, fMinimumStep);
|
||||
@@ -586,7 +563,7 @@ G4MagInt_Driver::OneGoodStep( G4double y[], // InOut
|
||||
if ( errmax_sq <= 1.0 ) { break; } // Step succeeded.
|
||||
|
||||
// Step failed; compute the size of retrial Step.
|
||||
htemp = GetSafety()*h* std::pow( errmax_sq, 0.5*GetPshrnk() );
|
||||
htemp = GetSafety() * h * std::pow( errmax_sq, 0.5*GetPshrnk() );
|
||||
|
||||
if (htemp >= 0.1*h) { h = htemp; } // Truncation error too large,
|
||||
else { h = 0.1*h; } // reduce stepsize, but no more
|
||||
@@ -617,7 +594,7 @@ G4MagInt_Driver::OneGoodStep( G4double y[], // InOut
|
||||
}
|
||||
x += (hdid = h);
|
||||
|
||||
for(G4int k=0;k<fNoIntegrationVariables;k++) { y[k] = ytemp[k]; }
|
||||
for(G4int k=0; k<fNoIntegrationVariables; ++k) { y[k] = ytemp[k]; }
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -626,18 +603,18 @@ G4MagInt_Driver::OneGoodStep( G4double y[], // InOut
|
||||
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy
|
||||
//
|
||||
G4bool G4MagInt_Driver::QuickAdvance(
|
||||
G4FieldTrack& y_posvel, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq )
|
||||
G4bool G4MagInt_Driver::QuickAdvance(G4FieldTrack& y_posvel, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq )
|
||||
{
|
||||
G4Exception("G4MagInt_Driver::QuickAdvance()", "GeomField0001",
|
||||
FatalException, "Not yet implemented.");
|
||||
|
||||
// Use the parameters of this method, to please compiler
|
||||
//
|
||||
dchord_step = dyerr_pos_sq = hstep * hstep * dydx[0];
|
||||
dyerr_mom_rel_sq = y_posvel.GetPosition().mag2();
|
||||
return true;
|
||||
@@ -645,13 +622,11 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
G4bool G4MagInt_Driver::QuickAdvance(
|
||||
G4FieldTrack& y_posvel, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double /*inverseCurvatureRadius*/,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr )
|
||||
G4bool G4MagInt_Driver::QuickAdvance(G4FieldTrack& y_posvel, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr )
|
||||
{
|
||||
G4double dyerr_pos_sq, dyerr_mom_rel_sq;
|
||||
G4double yerr_vec[G4FieldTrack::ncompSVEC],
|
||||
@@ -659,8 +634,8 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
G4double s_start;
|
||||
G4double dyerr_mom_sq, vel_mag_sq, inv_vel_mag_sq;
|
||||
|
||||
static G4ThreadLocal G4int no_call=0;
|
||||
no_call ++;
|
||||
static G4ThreadLocal G4int no_call = 0;
|
||||
++no_call;
|
||||
|
||||
// Move data into array
|
||||
y_posvel.DumpToArray( yarrin ); // yarrin <== y_posvel
|
||||
@@ -705,7 +680,7 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
// sqr(yerr_vec[3])+sqr(yerr_vec[4])+sqr(yerr_vec[5]));
|
||||
|
||||
// Set suggested new step
|
||||
hstep= ComputeNewStepSize( dyerr_len, hstep);
|
||||
hstep = ComputeNewStepSize( dyerr_len, hstep);
|
||||
#endif
|
||||
|
||||
if( dyerr_pos_sq > ( dyerr_mom_rel_sq * sqr(hstep) ) )
|
||||
@@ -724,13 +699,12 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#ifdef QUICK_ADV_ARRAY_IN_AND_OUT
|
||||
G4bool G4MagInt_Driver::QuickAdvance(
|
||||
G4double yarrin[], // In
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double yarrout[],
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr ) // In length
|
||||
G4bool G4MagInt_Driver::QuickAdvance(G4double yarrin[], // In
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double yarrout[],
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr ) // In length
|
||||
{
|
||||
G4Exception("G4MagInt_Driver::QuickAdvance()", "GeomField0001",
|
||||
FatalException, "Not yet implemented.");
|
||||
@@ -741,8 +715,8 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// This method computes new step sizes - but does not limit changes to
|
||||
// within certain factors
|
||||
// This method computes new step sizes - but does not limit changes to
|
||||
// within certain factors
|
||||
//
|
||||
G4double G4MagInt_Driver::
|
||||
ComputeNewStepSize(G4double errMaxNorm, // max error (normalised)
|
||||
@@ -810,12 +784,12 @@ G4MagInt_Driver::ComputeNewStepSize_WithinLimits(
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void G4MagInt_Driver::PrintStatus( const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
G4int subStepNo)
|
||||
void G4MagInt_Driver::PrintStatus( const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
G4int subStepNo )
|
||||
// Potentially add as arguments:
|
||||
// <dydx> - as Initial Force
|
||||
// stepTaken(hdid) - last step taken
|
||||
@@ -835,11 +809,10 @@ void G4MagInt_Driver::PrintStatus( const G4double* StartArr,
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void G4MagInt_Driver::PrintStatus(
|
||||
const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
G4int subStepNo)
|
||||
void G4MagInt_Driver::PrintStatus(const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
G4int subStepNo)
|
||||
{
|
||||
G4int verboseLevel= fVerboseLevel;
|
||||
const G4int noPrecision = 5;
|
||||
@@ -899,16 +872,15 @@ void G4MagInt_Driver::PrintStatus(
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void G4MagInt_Driver::PrintStat_Aux(
|
||||
const G4FieldTrack& aFieldTrack,
|
||||
G4double requestStep,
|
||||
G4double step_len,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVeloc_StartCurr)
|
||||
void G4MagInt_Driver::PrintStat_Aux(const G4FieldTrack& aFieldTrack,
|
||||
G4double requestStep,
|
||||
G4double step_len,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVeloc_StartCurr)
|
||||
{
|
||||
const G4ThreeVector Position= aFieldTrack.GetPosition();
|
||||
const G4ThreeVector UnitVelocity= aFieldTrack.GetMomentumDir();
|
||||
const G4ThreeVector Position = aFieldTrack.GetPosition();
|
||||
const G4ThreeVector UnitVelocity = aFieldTrack.GetMomentumDir();
|
||||
|
||||
if( subStepNo >= 0)
|
||||
{
|
||||
@@ -934,11 +906,11 @@ void G4MagInt_Driver::PrintStat_Aux(
|
||||
G4cout << std::setw( 7) << aFieldTrack.GetKineticEnergy();
|
||||
G4cout << std::setw(12) << step_len << " ";
|
||||
|
||||
static G4ThreadLocal G4double oldCurveLength= 0.0;
|
||||
static G4ThreadLocal G4double oldSubStepLength= 0.0;
|
||||
static G4ThreadLocal G4int oldSubStepNo= -1;
|
||||
static G4ThreadLocal G4double oldCurveLength = 0.0;
|
||||
static G4ThreadLocal G4double oldSubStepLength = 0.0;
|
||||
static G4ThreadLocal G4int oldSubStepNo = -1;
|
||||
|
||||
G4double subStep_len=0.0;
|
||||
G4double subStep_len = 0.0;
|
||||
if( curveLen > oldCurveLength )
|
||||
{
|
||||
subStep_len= curveLen - oldCurveLength;
|
||||
@@ -967,8 +939,8 @@ void G4MagInt_Driver::PrintStat_Aux(
|
||||
|
||||
void G4MagInt_Driver::PrintStatisticsReport()
|
||||
{
|
||||
G4int noPrecBig= 6;
|
||||
G4int oldPrec= G4cout.precision(noPrecBig);
|
||||
G4int noPrecBig = 6;
|
||||
G4int oldPrec = G4cout.precision(noPrecBig);
|
||||
|
||||
G4cout << "G4MagInt_Driver Statistics of steps undertaken. " << G4endl;
|
||||
G4cout << "G4MagInt_Driver: Number of Steps: "
|
||||
@@ -1004,8 +976,9 @@ GetDerivatives(const G4FieldTrack& y_curr, G4double* dydx) const
|
||||
{
|
||||
G4double ytemp[G4FieldTrack::ncompSVEC];
|
||||
y_curr.DumpToArray(ytemp);
|
||||
pIntStepper->RightHandSide(ytemp, dydx); // Avoid virtual call for GetStepper
|
||||
// Was: GetStepper()->ComputeRightHandSide(ytemp, dydx);
|
||||
pIntStepper->RightHandSide(ytemp, dydx);
|
||||
// Avoid virtual call for GetStepper
|
||||
// Was: GetStepper()->ComputeRightHandSide(ytemp, dydx);
|
||||
}
|
||||
|
||||
void G4MagInt_Driver::GetDerivatives(const G4FieldTrack& track,
|
||||
@@ -1038,7 +1011,7 @@ G4MagIntegratorStepper* G4MagInt_Driver::GetStepper()
|
||||
}
|
||||
|
||||
void G4MagInt_Driver::
|
||||
RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper)
|
||||
RenewStepperAndAdjust(G4MagIntegratorStepper* pItsStepper)
|
||||
{
|
||||
pIntStepper = pItsStepper;
|
||||
ReSetParameters();
|
||||
|
||||
@@ -23,28 +23,24 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MagIntegratorStepper implementation
|
||||
//
|
||||
//
|
||||
// Author: J.Apostolakis, CERN - 15.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
// Constructor for stepper abstract base class.
|
||||
//
|
||||
|
||||
G4MagIntegratorStepper::G4MagIntegratorStepper(G4EquationOfMotion* Equation,
|
||||
G4int num_integration_vars,
|
||||
G4int num_state_vars,
|
||||
bool isFSAL
|
||||
// , G4int methodOrder
|
||||
)
|
||||
//
|
||||
G4MagIntegratorStepper::
|
||||
G4MagIntegratorStepper( G4EquationOfMotion* Equation,
|
||||
G4int num_integration_vars,
|
||||
G4int num_state_vars,
|
||||
G4bool isFSAL )
|
||||
: 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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,17 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4Mag_EqRhs implementation
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion
|
||||
// in a pure Magnetic Field .
|
||||
//
|
||||
// Other that might be required are:
|
||||
// i) is when using a moving reference frame ... or
|
||||
// ii) extending for other forces, eg an electric field
|
||||
//
|
||||
// J. Apostolakis, January 13th, 1997
|
||||
//
|
||||
// Created: J.Apostolakis, CERN - 13.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4MagneticField.hh"
|
||||
@@ -44,22 +36,22 @@
|
||||
|
||||
const G4double G4Mag_EqRhs::fUnitConstant = 0.299792458 * (GeV/(tesla*m));
|
||||
|
||||
// Constructor Implementation
|
||||
//
|
||||
G4Mag_EqRhs::G4Mag_EqRhs( G4MagneticField *magField )
|
||||
: G4EquationOfMotion(magField), fCof_val(0.)
|
||||
G4Mag_EqRhs::G4Mag_EqRhs( G4MagneticField* magField )
|
||||
: G4EquationOfMotion(magField)
|
||||
{
|
||||
}
|
||||
|
||||
G4Mag_EqRhs::~G4Mag_EqRhs()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4Mag_EqRhs::SetChargeMomentumMass( G4ChargeState particleCharge,
|
||||
G4double, // MomentumXc
|
||||
G4double, // MomentumXc
|
||||
G4double ) // particleMass
|
||||
{
|
||||
G4double pcharge = particleCharge.GetCharge();
|
||||
fCof_val = pcharge*eplus*c_light ; // B must be in Tesla
|
||||
// fCof_val = fUnitConstant*pcharge/MomentumXc; // B must be in Tesla
|
||||
// fCof_val = fUnitConstant*pcharge/MomentumXc; // B must be in Tesla
|
||||
// fMass = particleMass;
|
||||
}
|
||||
|
||||
G4Mag_EqRhs::~G4Mag_EqRhs() { }
|
||||
|
||||
@@ -23,16 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4Mag_SpinEqRhs implementation
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
// This version of the right-hand side includes the three components
|
||||
// of the particle's spin.
|
||||
//
|
||||
// J. Apostolakis, February 8th, 1999
|
||||
// P. Gumplinger, February 8th, 1999
|
||||
// D. Cote-Ahern, P. Gumplinger, April 11th, 2001
|
||||
//
|
||||
// Created: J.Apostolakis, P.Gumplinger - 08.02.1999
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4Mag_SpinEqRhs.hh"
|
||||
@@ -42,8 +35,7 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
G4Mag_SpinEqRhs::G4Mag_SpinEqRhs( G4MagneticField* MagField )
|
||||
: G4Mag_EqRhs( MagField ), charge(0.), mass(0.), magMoment(0.),
|
||||
spin(0.), omegac(0.), anomaly(0.0011659208), beta(0.), gamma(0.)
|
||||
: G4Mag_EqRhs( MagField )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -91,11 +83,14 @@ G4Mag_SpinEqRhs::EvaluateRhsGivenB( const G4double y[],
|
||||
dydx[1] = y[4] * inv_momentum_magnitude; // (d/ds)y = Vy/V
|
||||
dydx[2] = y[5] * inv_momentum_magnitude; // (d/ds)z = Vz/V
|
||||
|
||||
if (charge == 0.) {
|
||||
if (charge == 0.)
|
||||
{
|
||||
dydx[3] = 0.;
|
||||
dydx[4] = 0.;
|
||||
dydx[5] = 0.;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dydx[3] = cof*(y[4]*B[2] - y[5]*B[1]) ; // Ax = a*(Vy*Bz - Vz*By)
|
||||
dydx[4] = cof*(y[5]*B[0] - y[3]*B[2]) ; // Ay = a*(Vz*Bx - Vx*Bz)
|
||||
dydx[5] = cof*(y[3]*B[1] - y[4]*B[0]) ; // Az = a*(Vx*By - Vy*Bx)
|
||||
@@ -115,17 +110,24 @@ G4Mag_SpinEqRhs::EvaluateRhsGivenB( const G4double y[],
|
||||
G4ThreeVector Spin(y[9],y[10],y[11]);
|
||||
|
||||
G4double pcharge;
|
||||
if (charge == 0.) pcharge = 1.;
|
||||
else pcharge = charge;
|
||||
|
||||
G4ThreeVector dSpin(0.,0.,0.);
|
||||
if (Spin.mag2() != 0.) {
|
||||
dSpin = pcharge*omegac*(ucb*(Spin.cross(BField))-udb*(Spin.cross(u)));
|
||||
if (charge == 0.)
|
||||
{
|
||||
pcharge = 1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcharge = charge;
|
||||
}
|
||||
|
||||
dydx[ 9] = dSpin.x();
|
||||
G4ThreeVector dSpin(0.,0.,0.);
|
||||
if (Spin.mag2() != 0.)
|
||||
{
|
||||
dSpin = pcharge*omegac*(ucb*(Spin.cross(BField))-udb*(Spin.cross(u)));
|
||||
}
|
||||
|
||||
dydx[9] = dSpin.x();
|
||||
dydx[10] = dSpin.y();
|
||||
dydx[11] = dSpin.z();
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,30 +23,29 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4Mag_UsualEqRhs implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// This is the 'standard' right-hand side for the equation of motion
|
||||
// of a charged particle in a magnetic field.
|
||||
//
|
||||
// Initial version: J. Apostolakis, January 13th, 1997
|
||||
//
|
||||
// Created: J.Apostolakis, CERN - 13.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4Mag_UsualEqRhs.hh"
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
#include "globals.hh" // For DBL_MAX
|
||||
#include "globals.hh"
|
||||
|
||||
G4Mag_UsualEqRhs::G4Mag_UsualEqRhs( G4MagneticField* MagField )
|
||||
: G4Mag_EqRhs( MagField ) {}
|
||||
: G4Mag_EqRhs( MagField )
|
||||
{
|
||||
}
|
||||
|
||||
G4Mag_UsualEqRhs::~G4Mag_UsualEqRhs() {}
|
||||
G4Mag_UsualEqRhs::~G4Mag_UsualEqRhs()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4Mag_UsualEqRhs::EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
G4double momentum_mag_square = y[3]*y[3] + y[4]*y[4] + y[5]*y[5];
|
||||
G4double inv_momentum_magnitude = 1.0 / std::sqrt( momentum_mag_square );
|
||||
@@ -61,14 +60,13 @@ G4Mag_UsualEqRhs::EvaluateRhsGivenB( const G4double y[],
|
||||
dydx[4] = cof*(y[5]*B[0] - y[3]*B[2]) ; // Ay = a*(Vz*Bx - Vx*Bz)
|
||||
dydx[5] = cof*(y[3]*B[1] - y[4]*B[0]) ; // Az = a*(Vx*By - Vy*Bx)
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4Mag_UsualEqRhs::
|
||||
SetChargeMomentumMass( G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass)
|
||||
G4Mag_UsualEqRhs::SetChargeMomentumMass( G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass )
|
||||
|
||||
{
|
||||
G4Mag_EqRhs::SetChargeMomentumMass( particleCharge, MomentumXc, mass);
|
||||
|
||||
@@ -23,14 +23,15 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MagneticField implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis, CERN - 13.01.1996
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
G4MagneticField::G4MagneticField()
|
||||
: G4Field( false ) // No gravitational field (default)
|
||||
: G4Field( false ) // No gravitational field (default)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -38,12 +39,12 @@ G4MagneticField::~G4MagneticField()
|
||||
{
|
||||
}
|
||||
|
||||
G4MagneticField::G4MagneticField(const G4MagneticField & )
|
||||
: G4Field( false )
|
||||
G4MagneticField::G4MagneticField(const G4MagneticField& )
|
||||
: G4Field( false )
|
||||
{
|
||||
}
|
||||
|
||||
G4MagneticField& G4MagneticField::operator = (const G4MagneticField &p)
|
||||
G4MagneticField& G4MagneticField::operator = (const G4MagneticField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4Field::operator=(p);
|
||||
|
||||
@@ -22,14 +22,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ModifiedMidpoint implementation
|
||||
//
|
||||
//
|
||||
// G4ModifiedMidpoint implementation
|
||||
// Based on modified_midpoint.hpp from boost
|
||||
//
|
||||
// Author: Dmitry Sorokin - GSoC 2016
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ModifiedMidpoint.hh"
|
||||
#include "G4FieldUtils.hh"
|
||||
@@ -62,6 +59,7 @@ void G4ModifiedMidpoint::DoStep( const G4double yIn[], const G4double dydyIn[],
|
||||
const G4double h2 = 2 * h;
|
||||
|
||||
// y1 = yIn + h * dydx
|
||||
//
|
||||
for (G4int i = 0; i < fnvar; ++i)
|
||||
{
|
||||
y1[i] = yIn[i] + h * dydyIn[i];
|
||||
@@ -73,6 +71,7 @@ void G4ModifiedMidpoint::DoStep( const G4double yIn[], const G4double dydyIn[],
|
||||
|
||||
// general step
|
||||
// yTemp = y1; y1 = y0 + h2 * dydx; y0 = yTemp
|
||||
//
|
||||
for (G4int i = 1; i < fsteps; ++i)
|
||||
{
|
||||
copy(yTemp, y1);
|
||||
@@ -87,6 +86,7 @@ void G4ModifiedMidpoint::DoStep( const G4double yIn[], const G4double dydyIn[],
|
||||
|
||||
// last step
|
||||
// yOut = 0.5 * (y0 + y1 + h * dydx)
|
||||
//
|
||||
for (G4int i = 0; i < fnvar; ++i)
|
||||
{
|
||||
yOut[i] = 0.5 * (y0[i] + y1[i] + h * dydx[i]);
|
||||
@@ -116,6 +116,7 @@ void G4ModifiedMidpoint::DoStep( const G4double yIn[], const G4double dydxIn[],
|
||||
|
||||
// result of first step already gives approximation
|
||||
// at the center of the interval
|
||||
//
|
||||
if(fsteps == 2)
|
||||
{
|
||||
copy(yMid, y1);
|
||||
@@ -125,6 +126,7 @@ void G4ModifiedMidpoint::DoStep( const G4double yIn[], const G4double dydxIn[],
|
||||
|
||||
// general step
|
||||
// yTemp = y1; y1 = y0 + h2 * dydx; y0 = yTemp
|
||||
//
|
||||
for (G4int i = 1; i < fsteps; ++i)
|
||||
{
|
||||
copy(yTemp, y1);
|
||||
@@ -145,6 +147,7 @@ void G4ModifiedMidpoint::DoStep( const G4double yIn[], const G4double dydxIn[],
|
||||
|
||||
// last step
|
||||
// yOut = 0.5 * (y0 + y1 + h * dydx)
|
||||
//
|
||||
for (G4int i = 0; i < fnvar; ++i)
|
||||
{
|
||||
yOut[i] = 0.5 * (y0[i] + y1[i] + h * derivs[fsteps-1][i]);
|
||||
|
||||
@@ -23,16 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MonopoleEq implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// This is the right-hand side for equation of motion for a
|
||||
// magnetic charge in a combined Electro-Magnetic field
|
||||
//
|
||||
// d(p_c)/ds=g{c-energyB_ - p_c x E}/pc
|
||||
//
|
||||
// 17.11.09 V.Grichine
|
||||
//
|
||||
// Created: V.Grichine, 17.11.2009
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4MonopoleEq.hh"
|
||||
@@ -40,9 +33,18 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4MonopoleEq::G4MonopoleEq(G4ElectroMagneticField* emField )
|
||||
: G4EquationOfMotion( emField )
|
||||
{
|
||||
}
|
||||
|
||||
G4MonopoleEq::~G4MonopoleEq()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
G4MonopoleEq::SetChargeMomentumMass(G4ChargeState particleCharge, // e+ units
|
||||
G4double,
|
||||
G4double,
|
||||
G4double particleMass)
|
||||
{
|
||||
G4double pcharge = particleCharge.GetCharge();
|
||||
@@ -52,12 +54,10 @@ G4MonopoleEq::SetChargeMomentumMass(G4ChargeState particleCharge, // e+ units
|
||||
fMassCof = particleMass*particleMass ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
G4MonopoleEq::EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
|
||||
// Components of y:
|
||||
@@ -71,13 +71,10 @@ G4MonopoleEq::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
G4double pModuleInverse = 1.0/std::sqrt(pSquared) ;
|
||||
|
||||
// G4double inverse_velocity = Energy * c_light * pModuleInverse;
|
||||
G4double inverse_velocity = Energy * pModuleInverse / c_light;
|
||||
|
||||
G4double cof1 = fElectroMagCof*pModuleInverse ;
|
||||
|
||||
// G4double vDotE = y[3]*Field[3] + y[4]*Field[4] + y[5]*Field[5] ;
|
||||
|
||||
dydx[0] = y[3]*pModuleInverse ;
|
||||
dydx[1] = y[4]*pModuleInverse ;
|
||||
dydx[2] = y[5]*pModuleInverse ;
|
||||
@@ -88,9 +85,11 @@ G4MonopoleEq::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
dydx[5] = cof1*(cof2*Field[2] - (y[3]*Field[4] - y[4]*Field[3])) ;
|
||||
|
||||
dydx[6] = 0.;//not used
|
||||
dydx[6] = 0.; //not used
|
||||
|
||||
// Lab Time of flight
|
||||
//
|
||||
dydx[7] = inverse_velocity;
|
||||
return ;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4NystromRK4 implmentation
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// - Created: I.Gavrilenko 15.05.2009 (as G4AtlasRK4)
|
||||
// - Adaptations: J.Apostolakis May-Nov 2009
|
||||
// Created: I.Gavrilenko, 15.05.2009 (as G4AtlasRK4)
|
||||
// Adaptations: J.Apostolakis, November 2009
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4NystromRK4.hh"
|
||||
@@ -39,22 +38,18 @@
|
||||
|
||||
using namespace field_utils;
|
||||
|
||||
namespace {
|
||||
|
||||
G4bool notEquals(G4double p1, G4double p2)
|
||||
namespace
|
||||
{
|
||||
return std::fabs(p1 - p2) > perMillion * p2;
|
||||
}
|
||||
constexpr G4int INTEGRATED_COMPONENTS = 6;
|
||||
G4bool notEquals(G4double p1, G4double p2)
|
||||
{
|
||||
return std::fabs(p1 - p2) > perMillion * p2;
|
||||
}
|
||||
constexpr G4int INTEGRATED_COMPONENTS = 6;
|
||||
} // namespace
|
||||
|
||||
|
||||
G4NystromRK4::G4NystromRK4(G4Mag_EqRhs* equation, G4double distanceConstField)
|
||||
: G4MagIntegratorStepper(equation, INTEGRATED_COMPONENTS),
|
||||
fMomentum(0),
|
||||
fMomentum2(0),
|
||||
fInverseMomentum(0),
|
||||
fCoefficient(0)
|
||||
: G4MagIntegratorStepper(equation, INTEGRATED_COMPONENTS)
|
||||
{
|
||||
if (distanceConstField > 0)
|
||||
{
|
||||
@@ -192,38 +187,37 @@ G4double G4NystromRK4::DistChord() const
|
||||
|
||||
void G4NystromRK4::SetDistanceForConstantField(G4double length)
|
||||
{
|
||||
if (!GetField())
|
||||
{
|
||||
G4Exception("G4NystromRK4::SetDistanceForConstantField","Nystrom 001",
|
||||
JustWarning, "Provided field is not G4CachedMagneticField. Changing field type.");
|
||||
if (GetField() == nullptr)
|
||||
{
|
||||
G4Exception("G4NystromRK4::SetDistanceForConstantField",
|
||||
"Nystrom 001", JustWarning,
|
||||
"Provided field is not G4CachedMagneticField. Changing field type.");
|
||||
|
||||
fCachedField = std::unique_ptr<G4CachedMagneticField>(
|
||||
new G4CachedMagneticField(
|
||||
dynamic_cast<G4MagneticField*>(GetEquationOfMotion()->GetFieldObj()),
|
||||
length));
|
||||
fCachedField = std::unique_ptr<G4CachedMagneticField>(
|
||||
new G4CachedMagneticField(
|
||||
dynamic_cast<G4MagneticField*>(GetEquationOfMotion()->GetFieldObj()),
|
||||
length));
|
||||
|
||||
GetEquationOfMotion()->SetFieldObj(fCachedField.get());
|
||||
}
|
||||
|
||||
GetField()->SetConstDistance(length);
|
||||
GetEquationOfMotion()->SetFieldObj(fCachedField.get());
|
||||
}
|
||||
GetField()->SetConstDistance(length);
|
||||
}
|
||||
|
||||
G4double G4NystromRK4::GetDistanceForConstantField() const
|
||||
{
|
||||
if (!GetField())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetField()->GetConstDistance();
|
||||
if (GetField() == nullptr)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
return GetField()->GetConstDistance();
|
||||
}
|
||||
|
||||
G4CachedMagneticField* G4NystromRK4::GetField()
|
||||
{
|
||||
return dynamic_cast<G4CachedMagneticField*>(GetEquationOfMotion()->GetFieldObj());
|
||||
return dynamic_cast<G4CachedMagneticField*>(GetEquationOfMotion()->GetFieldObj());
|
||||
}
|
||||
|
||||
const G4CachedMagneticField* G4NystromRK4::GetField() const
|
||||
{
|
||||
return const_cast<G4NystromRK4*>(this)->GetField();
|
||||
return const_cast<G4NystromRK4*>(this)->GetField();
|
||||
}
|
||||
|
||||
@@ -23,59 +23,67 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4QuadrupoleMagField implementation
|
||||
//
|
||||
//
|
||||
// 03.02.1997, V.Grichine - Created
|
||||
// 11.05.2012, B.Riese - Allow displaced origin and rotation
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4QuadrupoleMagField.hh"
|
||||
#include "G4RotationMatrix.hh"
|
||||
|
||||
static G4RotationMatrix IdentityMatrix;
|
||||
namespace
|
||||
{
|
||||
G4RotationMatrix IdentityMatrix;
|
||||
}
|
||||
|
||||
G4QuadrupoleMagField::G4QuadrupoleMagField(G4double pGradient)
|
||||
{
|
||||
fGradient = pGradient ;
|
||||
fOrigin = G4ThreeVector( 0.0, 0.0, 0.0) ;
|
||||
fGradient = pGradient;
|
||||
fpMatrix = &IdentityMatrix;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4QuadrupoleMagField::G4QuadrupoleMagField(G4double pGradient,
|
||||
G4ThreeVector pOrigin,
|
||||
G4RotationMatrix* pMatrix)
|
||||
{
|
||||
fGradient = pGradient ;
|
||||
fOrigin = pOrigin ;
|
||||
fpMatrix = pMatrix ;
|
||||
fGradient = pGradient ;
|
||||
fOrigin = pOrigin ;
|
||||
fpMatrix = pMatrix ;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4Field* G4QuadrupoleMagField::Clone() const
|
||||
{
|
||||
return new G4QuadrupoleMagField(fGradient, fOrigin, fpMatrix);
|
||||
return new G4QuadrupoleMagField(fGradient, fOrigin, fpMatrix);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4QuadrupoleMagField::~G4QuadrupoleMagField()
|
||||
{
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
void G4QuadrupoleMagField::GetFieldValue( const G4double y[7],
|
||||
G4double B[3] ) const
|
||||
// with displaced origin and rotation
|
||||
{
|
||||
G4ThreeVector r_global = G4ThreeVector(
|
||||
y[0] - fOrigin.x(),
|
||||
y[1] - fOrigin.y(),
|
||||
y[2] - fOrigin.z());
|
||||
// with displaced origin and rotation
|
||||
|
||||
G4ThreeVector r_global = G4ThreeVector(y[0] - fOrigin.x(),
|
||||
y[1] - fOrigin.y(),
|
||||
y[2] - fOrigin.z());
|
||||
|
||||
const G4ThreeVector r_local = (*fpMatrix) * r_global;
|
||||
const G4ThreeVector B_local( fGradient * r_local.y(),fGradient * r_local.x(),0);
|
||||
const G4ThreeVector B_local( fGradient * r_local.y(),
|
||||
fGradient * r_local.x(), 0);
|
||||
const G4ThreeVector B_global = fpMatrix->inverse() * B_local;
|
||||
|
||||
B[0] = B_global.x() ;
|
||||
B[1] = B_global.y() ;
|
||||
B[2] = B_global.z() ;
|
||||
B[0] = B_global.x();
|
||||
B[1] = B_global.y();
|
||||
B[2] = B_global.z();
|
||||
}
|
||||
|
||||
@@ -23,11 +23,13 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4RK547FEq1 implementation
|
||||
//
|
||||
// The Butcher table of the Higham & Hall 5(4)7 method is:
|
||||
//
|
||||
// 0 |
|
||||
// 2/9 | 2/9
|
||||
// 1/3 | 1/12 1/4
|
||||
// 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
|
||||
@@ -35,6 +37,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4RK547FEq1.hh"
|
||||
#include "G4LineSection.hh"
|
||||
@@ -42,22 +48,21 @@
|
||||
|
||||
using namespace field_utils;
|
||||
|
||||
|
||||
G4RK547FEq1::G4RK547FEq1(G4EquationOfMotion* EqRhs, G4int integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
{
|
||||
}
|
||||
|
||||
void G4RK547FEq1::makeStep(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double* dydxOutput,
|
||||
G4double* yError) const
|
||||
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){
|
||||
for (G4int i=GetNumberOfVariables(); i<GetNumberOfStateVariables(); ++i)
|
||||
{
|
||||
yOutput[i] = yTemp[i] = yInput[i];
|
||||
}
|
||||
|
||||
@@ -67,70 +72,68 @@ void G4RK547FEq1::makeStep(
|
||||
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 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.;
|
||||
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)
|
||||
// RightHandSide(yInput, dydx);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yTemp[i] = yInput[i] + hstep * b21 * dydx[i];
|
||||
|
||||
RightHandSide(yTemp, ak2);
|
||||
for(int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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) {
|
||||
if (dydxOutput && yError)
|
||||
{
|
||||
RightHandSide(yOutput, dydxOutput);
|
||||
for(int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
for(G4int 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[])
|
||||
void G4RK547FEq1::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[] )
|
||||
{
|
||||
copy(fyIn, yInput);
|
||||
copy(fdydx, dydx);
|
||||
@@ -141,13 +144,12 @@ void G4RK547FEq1::Stepper(
|
||||
copy(yOutput, fyOut);
|
||||
}
|
||||
|
||||
void G4RK547FEq1::Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[])
|
||||
void G4RK547FEq1::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[] )
|
||||
{
|
||||
copy(fyIn, yInput);
|
||||
copy(fdydx, dydx);
|
||||
|
||||
@@ -23,11 +23,13 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4RK547FEq2 implementation
|
||||
//
|
||||
// The Butcher table of the Higham & Hall 5(4)7 method is:
|
||||
//
|
||||
// 0 |
|
||||
// 2/13 | 2/13
|
||||
// 2/13 | 3/52 9/52
|
||||
// 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
|
||||
@@ -35,6 +37,10 @@
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 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
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4RK547FEq2.hh"
|
||||
#include "G4LineSection.hh"
|
||||
@@ -42,22 +48,21 @@
|
||||
|
||||
using namespace field_utils;
|
||||
|
||||
|
||||
G4RK547FEq2::G4RK547FEq2(G4EquationOfMotion* EqRhs, G4int integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
{
|
||||
}
|
||||
|
||||
void G4RK547FEq2::makeStep(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double* dydxOutput,
|
||||
G4double* yError) const
|
||||
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){
|
||||
for (G4int i=GetNumberOfVariables(); i<GetNumberOfStateVariables(); ++i)
|
||||
{
|
||||
yOutput[i] = yTemp[i] = yInput[i];
|
||||
}
|
||||
|
||||
@@ -67,71 +72,70 @@ void G4RK547FEq2::makeStep(
|
||||
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 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.;
|
||||
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)
|
||||
// RightHandSide(yInput, dydx);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yTemp[i] = yInput[i] + hstep * b21 * dydx[i];
|
||||
|
||||
RightHandSide(yTemp, ak2);
|
||||
for(int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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) {
|
||||
if (dydxOutput && yError)
|
||||
{
|
||||
RightHandSide(yOutput, dydxOutput);
|
||||
for(int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
for(G4int 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[])
|
||||
void G4RK547FEq2::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[] )
|
||||
{
|
||||
copy(fyIn, yInput);
|
||||
copy(fdydx, dydx);
|
||||
@@ -142,13 +146,12 @@ void G4RK547FEq2::Stepper(
|
||||
copy(yOutput, fyOut);
|
||||
}
|
||||
|
||||
void G4RK547FEq2::Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[])
|
||||
void G4RK547FEq2::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[] )
|
||||
{
|
||||
copy(fyIn, yInput);
|
||||
copy(fdydx, dydx);
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4RK547FEq3 implementation
|
||||
//
|
||||
// The Butcher table of the Higham & Hall 5(4)7 method is:
|
||||
//
|
||||
// 0 |
|
||||
@@ -35,6 +37,10 @@
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// 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
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4RK547FEq3.hh"
|
||||
#include "G4LineSection.hh"
|
||||
@@ -42,22 +48,21 @@
|
||||
|
||||
using namespace field_utils;
|
||||
|
||||
|
||||
G4RK547FEq3::G4RK547FEq3(G4EquationOfMotion* EqRhs, G4int integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
: G4MagIntegratorStepper(EqRhs, integrationVariables)
|
||||
{
|
||||
}
|
||||
|
||||
void G4RK547FEq3::makeStep(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double* dydxOutput,
|
||||
G4double* yError) const
|
||||
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){
|
||||
for (G4int i=GetNumberOfVariables(); i<GetNumberOfStateVariables(); ++i)
|
||||
{
|
||||
yOutput[i] = yTemp[i] = yInput[i];
|
||||
}
|
||||
|
||||
@@ -67,71 +72,71 @@ void G4RK547FEq3::makeStep(
|
||||
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 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.;
|
||||
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)
|
||||
// RightHandSide(yInput, dydx);
|
||||
for(G4int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
yTemp[i] = yInput[i] + hstep * b21 * dydx[i];
|
||||
|
||||
RightHandSide(yTemp, ak2);
|
||||
for(int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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)
|
||||
for(G4int 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) {
|
||||
if (dydxOutput && yError)
|
||||
{
|
||||
RightHandSide(yOutput, dydxOutput);
|
||||
for(int i = 0; i < GetNumberOfVariables(); ++i)
|
||||
for(G4int 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[])
|
||||
void G4RK547FEq3::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[] )
|
||||
{
|
||||
copy(fyIn, yInput);
|
||||
copy(fdydx, dydx);
|
||||
@@ -142,13 +147,12 @@ void G4RK547FEq3::Stepper(
|
||||
copy(yOutput, fyOut);
|
||||
}
|
||||
|
||||
void G4RK547FEq3::Stepper(
|
||||
const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[])
|
||||
void G4RK547FEq3::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double dydxOutput[] )
|
||||
{
|
||||
copy(fyIn, yInput);
|
||||
copy(fdydx, dydx);
|
||||
|
||||
@@ -23,16 +23,17 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4RKG3_Stepper implementation
|
||||
//
|
||||
//
|
||||
// Created: J.Apostolakis, V.Grichine - 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4RKG3_Stepper.hh"
|
||||
#include "G4LineSection.hh"
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
|
||||
G4RKG3_Stepper::G4RKG3_Stepper(G4Mag_EqRhs *EqRhs)
|
||||
: G4MagIntegratorStepper(EqRhs,6), hStep(0.)
|
||||
G4RKG3_Stepper::G4RKG3_Stepper(G4Mag_EqRhs* EqRhs)
|
||||
: G4MagIntegratorStepper(EqRhs,6)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,57 +41,62 @@ G4RKG3_Stepper::~G4RKG3_Stepper()
|
||||
{
|
||||
}
|
||||
|
||||
void G4RKG3_Stepper::Stepper( const G4double yInput[8],
|
||||
const G4double dydx[6],
|
||||
G4double Step,
|
||||
G4double yOut[8],
|
||||
G4double yErr[])
|
||||
void G4RKG3_Stepper::Stepper( const G4double yInput[8],
|
||||
const G4double dydx[6],
|
||||
G4double Step,
|
||||
G4double yOut[8],
|
||||
G4double yErr[] )
|
||||
{
|
||||
G4double B[3];
|
||||
G4int nvar = 6 ;
|
||||
G4int i;
|
||||
G4double by15 = 1. / 15. ; // was 0.066666666 ;
|
||||
|
||||
G4double yTemp[8], dydxTemp[6], yIn[8] ;
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(i=0;i<nvar;i++) yIn[i]=yInput[i];
|
||||
G4double yTemp[8], dydxTemp[6], yIn[8];
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
//
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
}
|
||||
yIn[6] = yInput[6];
|
||||
yIn[7] = yInput[7];
|
||||
G4double h = Step * 0.5;
|
||||
hStep=Step;
|
||||
// Do two half steps
|
||||
hStep = Step;
|
||||
// Do two half steps
|
||||
|
||||
StepNoErr(yIn, dydx,h, yTemp,B) ;
|
||||
|
||||
//Store Bfld for DistChord Calculation
|
||||
for(i=0;i<3;i++)BfldIn[i]=B[i];
|
||||
|
||||
// RightHandSide(yTemp,dydxTemp) ;
|
||||
// Store Bfld for DistChord Calculation
|
||||
//
|
||||
for(auto i=0; i<3; ++i)
|
||||
{
|
||||
BfldIn[i] = B[i];
|
||||
}
|
||||
// RightHandSide(yTemp,dydxTemp) ;
|
||||
|
||||
GetEquationOfMotion()->EvaluateRhsGivenB(yTemp,B,dydxTemp) ;
|
||||
StepNoErr(yTemp,dydxTemp,h,yOut,B);
|
||||
|
||||
// Store midpoint, chord calculation
|
||||
|
||||
fyMidPoint = G4ThreeVector( yTemp[0], yTemp[1], yTemp[2]);
|
||||
fyMidPoint = G4ThreeVector(yTemp[0], yTemp[1], yTemp[2]);
|
||||
|
||||
// Do a full Step
|
||||
|
||||
//
|
||||
h *= 2 ;
|
||||
StepNoErr(yIn,dydx,h,yTemp,B);
|
||||
for(i=0;i<nvar;i++)
|
||||
for(G4int i=0; i<nvar; ++i)
|
||||
{
|
||||
yErr[i] = yOut[i] - yTemp[i] ;
|
||||
yOut[i] += yErr[i]*by15 ; // Provides 5th order of accuracy
|
||||
}
|
||||
|
||||
//Store values for DistChord method
|
||||
|
||||
// Store values for DistChord method
|
||||
//
|
||||
fyInitial = G4ThreeVector( yIn[0], yIn[1], yIn[2]);
|
||||
fpInitial = G4ThreeVector( yIn[3], yIn[4], yIn[5]);
|
||||
fyFinal = G4ThreeVector( yOut[0], yOut[1], yOut[2]);
|
||||
|
||||
// NormaliseTangentVector( yOut ); // Deleted
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -99,7 +105,7 @@ void G4RKG3_Stepper::Stepper( const G4double yInput[8],
|
||||
// geometry based on naive similarity with the case of uniform magnetic field.
|
||||
// B1[3] is input and is the first magnetic field values
|
||||
// B2[3] is output and is the final magnetic field values.
|
||||
|
||||
//
|
||||
void G4RKG3_Stepper::StepWithEst( const G4double*,
|
||||
const G4double*,
|
||||
G4double,
|
||||
@@ -116,99 +122,93 @@ void G4RKG3_Stepper::StepWithEst( const G4double*,
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
|
||||
// Integrator RK Stepper from G3 with only two field evaluation per Step.
|
||||
// It is used in propagation initial Step by small substeps after solution
|
||||
// error and delta geometry considerations. B[3] is magnetic field which
|
||||
// is passed from substep to substep.
|
||||
|
||||
//
|
||||
void G4RKG3_Stepper::StepNoErr(const G4double tIn[8],
|
||||
const G4double dydx[6],
|
||||
G4double Step,
|
||||
G4double tOut[8],
|
||||
G4double B[3] ) // const
|
||||
G4double B[3] )
|
||||
|
||||
{
|
||||
|
||||
// Copy and edit the routine above, to delete alpha2, beta2, ...
|
||||
G4double K1[7],K2[7],K3[7],K4[7] ;
|
||||
G4double tTemp[8], yderiv[6] ;
|
||||
// Copy and edit the routine above, to delete alpha2, beta2, ...
|
||||
//
|
||||
G4double K1[7], K2[7], K3[7], K4[7];
|
||||
G4double tTemp[8]={0.0}, yderiv[6]={0.0};
|
||||
|
||||
// Need Momentum value to give correct values to the coefficients in equation
|
||||
// Integration on unit velocity, but tIn[3,4,5] is momentum
|
||||
G4double mom,inverse_mom;
|
||||
G4int i ;
|
||||
const G4double c1=0.5,c2=0.125,c3=1./6.;
|
||||
// Need Momentum value to give correct values to the coefficients in
|
||||
// equation. Integration on unit velocity, but tIn[3,4,5] is momentum
|
||||
|
||||
G4double mom, inverse_mom;
|
||||
const G4double c1=0.5, c2=0.125, c3=1./6.;
|
||||
|
||||
// GetEquationOfMotion()->EvaluateRhsReturnB(tIn,dydx,B1) ;
|
||||
// Correction for momentum not a velocity
|
||||
// Need the protection !!! must be not zero
|
||||
mom=std::sqrt(tIn[3]*tIn[3]+tIn[4]*tIn[4]+tIn[5]*tIn[5]);
|
||||
inverse_mom=1./mom;
|
||||
for(i=0;i<3;i++)
|
||||
// Need the protection !!! must be not zero
|
||||
//
|
||||
mom = std::sqrt(tIn[3]*tIn[3]+tIn[4]*tIn[4]+tIn[5]*tIn[5]);
|
||||
inverse_mom = 1./mom;
|
||||
for(auto i=0; i<3; ++i)
|
||||
{
|
||||
K1[i] = Step * dydx[i+3]*inverse_mom;
|
||||
tTemp[i] = tIn[i] + Step*(c1*tIn[i+3]*inverse_mom + c2*K1[i]) ;
|
||||
tTemp[i+3] = tIn[i+3] + c1*K1[i]*mom ;
|
||||
|
||||
}
|
||||
|
||||
GetEquationOfMotion()->EvaluateRhsReturnB(tTemp,yderiv,B) ;
|
||||
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
for(auto i=0; i<3; ++i)
|
||||
{
|
||||
K2[i] = Step * yderiv[i+3]*inverse_mom;
|
||||
tTemp[i+3] = tIn[i+3] + c1*K2[i]*mom ;
|
||||
}
|
||||
|
||||
// Given B, calculate yderiv !
|
||||
// Given B, calculate yderiv !
|
||||
//
|
||||
GetEquationOfMotion()->EvaluateRhsGivenB(tTemp,B,yderiv) ;
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
for(auto i=0; i<3; ++i)
|
||||
{
|
||||
K3[i] = Step * yderiv[i+3]*inverse_mom;
|
||||
tTemp[i] = tIn[i] + Step*(tIn[i+3]*inverse_mom + c1*K3[i]) ;
|
||||
tTemp[i+3] = tIn[i+3] + K3[i]*mom ;
|
||||
}
|
||||
|
||||
|
||||
// Calculates y-deriv(atives) & returns B too!
|
||||
// Calculates y-deriv(atives) & returns B too!
|
||||
//
|
||||
GetEquationOfMotion()->EvaluateRhsReturnB(tTemp,yderiv,B) ;
|
||||
|
||||
|
||||
for(i=0;i<3;i++) // Output trajectory vector
|
||||
for(auto i=0; i<3; ++i) // Output trajectory vector
|
||||
{
|
||||
K4[i] = Step * yderiv[i+3]*inverse_mom;
|
||||
tOut[i] = tIn[i] + Step*(tIn[i+3]*inverse_mom+ (K1[i] + K2[i] + K3[i])*c3) ;
|
||||
tOut[i] = tIn[i] + Step*(tIn[i+3]*inverse_mom+ (K1[i]+K2[i]+K3[i])*c3) ;
|
||||
tOut[i+3] = tIn[i+3] + mom*(K1[i] + 2*K2[i] + 2*K3[i] +K4[i])*c3 ;
|
||||
}
|
||||
tOut[6] = tIn[6];
|
||||
tOut[7] = tIn[7];
|
||||
// NormaliseTangentVector( tOut );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
G4double G4RKG3_Stepper::DistChord() const
|
||||
{
|
||||
G4double G4RKG3_Stepper::DistChord() const
|
||||
{
|
||||
// Soon: must check whether h/R > 2 pi !!
|
||||
// Method below is good only for < 2 pi
|
||||
// Method below is good only for < 2 pi
|
||||
|
||||
G4double distChord,distLine;
|
||||
|
||||
if (fyInitial != fyFinal) {
|
||||
distLine= G4LineSection::Distline(fyMidPoint,fyInitial,fyFinal );
|
||||
|
||||
distChord = distLine;
|
||||
}else{
|
||||
if (fyInitial != fyFinal)
|
||||
{
|
||||
distLine = G4LineSection::Distline(fyMidPoint,fyInitial,fyFinal);
|
||||
distChord = distLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
distChord = (fyMidPoint-fyInitial).mag();
|
||||
}
|
||||
|
||||
|
||||
return distChord;
|
||||
|
||||
}
|
||||
|
||||
return distChord;
|
||||
}
|
||||
|
||||
@@ -23,13 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4RepleteEofM implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
//
|
||||
// 08.04.2013 Peter Gumplinger
|
||||
//
|
||||
// Created: P.Gumplinger, 08.04.2013
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4RepleteEofM.hh"
|
||||
@@ -42,12 +38,7 @@
|
||||
|
||||
|
||||
G4RepleteEofM::G4RepleteEofM( G4Field* field, G4int nvar )
|
||||
: G4EquationOfMotion( field ), fNvar(nvar),
|
||||
fBfield(false), fEfield(false), fGfield(false),
|
||||
fgradB(false), fSpin(false),
|
||||
charge(0.), mass(0.), magMoment(0.), spin(0.),
|
||||
ElectroMagCof(0.), omegac(0.), anomaly(0.),
|
||||
beta(0.), gamma(0.)
|
||||
: G4EquationOfMotion( field ), fNvar(nvar)
|
||||
{
|
||||
fGfield = field->IsGravityActive();
|
||||
}
|
||||
@@ -83,9 +74,9 @@ G4RepleteEofM::SetChargeMomentumMass(G4ChargeState particleCharge, // e+ units
|
||||
}
|
||||
|
||||
void
|
||||
G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
G4RepleteEofM::EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
|
||||
// Components of y:
|
||||
@@ -139,8 +130,10 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
// Force due to B field - Field[0,1,2]
|
||||
|
||||
if (fBfield) {
|
||||
if (charge != 0.) {
|
||||
if (fBfield)
|
||||
{
|
||||
if (charge != 0.)
|
||||
{
|
||||
dydx[3] += cof1*(y[4]*field[2] - y[5]*field[1]);
|
||||
dydx[4] += cof1*(y[5]*field[0] - y[3]*field[2]);
|
||||
dydx[5] += cof1*(y[3]*field[1] - y[4]*field[0]);
|
||||
@@ -149,18 +142,23 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
// add force due to E field - Field[3,4,5]
|
||||
|
||||
if (!fBfield) {
|
||||
if (!fBfield)
|
||||
{
|
||||
field[3] = Field[0];
|
||||
field[4] = Field[1];
|
||||
field[5] = Field[2];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
field[3] = Field[3];
|
||||
field[4] = Field[4];
|
||||
field[5] = Field[5];
|
||||
}
|
||||
|
||||
if (fEfield) {
|
||||
if (charge != 0.) {
|
||||
if (fEfield)
|
||||
{
|
||||
if (charge != 0.)
|
||||
{
|
||||
dydx[3] += cof1*cof2*field[3];
|
||||
dydx[4] += cof1*cof2*field[4];
|
||||
dydx[5] += cof1*cof2*field[5];
|
||||
@@ -169,27 +167,33 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
|
||||
// add force due to gravity field - Field[6,7,8]
|
||||
|
||||
if (!fBfield && !fEfield) {
|
||||
if (!fBfield && !fEfield)
|
||||
{
|
||||
field[6] = Field[0];
|
||||
field[7] = Field[1];
|
||||
field[8] = Field[2];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
field[6] = Field[6];
|
||||
field[7] = Field[7];
|
||||
field[8] = Field[8];
|
||||
}
|
||||
|
||||
if (fGfield) {
|
||||
if (mass > 0.) {
|
||||
if (fGfield)
|
||||
{
|
||||
if (mass > 0.)
|
||||
{
|
||||
dydx[3] += field[6]*cof2*cof3/c_light;
|
||||
dydx[4] += field[7]*cof2*cof3/c_light;
|
||||
dydx[5] += field[8]*cof2*cof3/c_light;
|
||||
}
|
||||
}
|
||||
|
||||
// add force due to ∇(µ⋅B) == (µ⋅∇)B when (∇xB) = 0
|
||||
// add force
|
||||
|
||||
if (!fBfield && !fEfield && !fGfield) {
|
||||
if (!fBfield && !fEfield && !fGfield)
|
||||
{
|
||||
field[9] = Field[0];
|
||||
field[10] = Field[1];
|
||||
field[11] = Field[2];
|
||||
@@ -199,7 +203,9 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
field[15] = Field[6];
|
||||
field[16] = Field[7];
|
||||
field[17] = Field[8];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
field[9] = Field[9];
|
||||
field[10] = Field[10];
|
||||
field[11] = Field[11];
|
||||
@@ -211,36 +217,27 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
field[17] = Field[17];
|
||||
}
|
||||
|
||||
if (fgradB) {
|
||||
if (magMoment != 0.) {
|
||||
|
||||
// field[ 9] == dB_x/dx; field[10] == dB_y/dx; field[11] == dB_z/dx
|
||||
// field[12] == dB_x/dy; field[13] == dB_y/dy; field[14] == dB_z/dy
|
||||
// field[15] == dB_x/dz; field[16] == dB_y/dz; field[17] == dB_z/dz
|
||||
|
||||
// G4cout << "y[9]: " << y[9] << " y[10]: " << y[10] << " y[11]: " << y[11] << G4endl;
|
||||
// G4cout << "field[9]: " << field[9] << " field[10]: " << field[10] << " field[11]: " << field[11] << G4endl;
|
||||
// G4cout << "field[12]: " << field[12] << " field[13]: " << field[13] << " field[14]: " << field[14] << G4endl;
|
||||
// G4cout << "field[15]: " << field[15] << " field[16]: " << field[16] << " field[17]: " << field[17] << G4endl;
|
||||
// G4cout << "inv_momentum_magnitdue: " << inv_momentum_magnitude << " Energy: " << Energy << G4endl;
|
||||
|
||||
if (fgradB)
|
||||
{
|
||||
if (magMoment != 0.)
|
||||
{
|
||||
dydx[3] += magMoment*(y[9]*field[ 9]+y[10]*field[10]+y[11]*field[11])
|
||||
*inv_momentum_magnitude*Energy;
|
||||
dydx[4] += magMoment*(y[9]*field[12]+y[10]*field[13]+y[11]*field[14])
|
||||
*inv_momentum_magnitude*Energy;
|
||||
dydx[5] += magMoment*(y[9]*field[15]+y[10]*field[16]+y[11]*field[17])
|
||||
*inv_momentum_magnitude*Energy;
|
||||
|
||||
// G4cout << "dydx[3,4,5] " << dydx[3] << " " << dydx[4] << " " << dydx[5] << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
dydx[6] = 0.; //not used
|
||||
dydx[6] = 0.; // not used
|
||||
|
||||
// Lab Time of flight
|
||||
//
|
||||
dydx[7] = inverse_velocity;
|
||||
|
||||
if (fNvar == 12) {
|
||||
if (fNvar == 12)
|
||||
{
|
||||
dydx[ 8] = 0.; //not used
|
||||
|
||||
dydx[ 9] = 0.;
|
||||
@@ -248,16 +245,18 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
dydx[11] = 0.;
|
||||
}
|
||||
|
||||
if (fSpin) {
|
||||
// G4cout << "y[9,10,11] " << y[9] << " " << y[10] << " " << y[11] << G4endl;
|
||||
if (fSpin)
|
||||
{
|
||||
G4ThreeVector BField(0.,0.,0.);
|
||||
if (fBfield) {
|
||||
if (fBfield)
|
||||
{
|
||||
G4ThreeVector F(field[0],field[1],field[2]);
|
||||
BField = F;
|
||||
}
|
||||
|
||||
G4ThreeVector EField(0.,0.,0.);
|
||||
if (fEfield) {
|
||||
if (fEfield)
|
||||
{
|
||||
G4ThreeVector F(field[3],field[4],field[5]);
|
||||
EField = F;
|
||||
}
|
||||
@@ -278,26 +277,26 @@ G4RepleteEofM::EvaluateRhsGivenB(const G4double y[],
|
||||
else pcharge = charge;
|
||||
|
||||
G4ThreeVector dSpin(0.,0.,0);
|
||||
if (Spin.mag2() != 0.) {
|
||||
if (fBfield) {
|
||||
if (Spin.mag2() != 0.)
|
||||
{
|
||||
if (fBfield)
|
||||
{
|
||||
dSpin =
|
||||
pcharge*omegac*( ucb*(Spin.cross(BField))-udb*(Spin.cross(u)) );
|
||||
}
|
||||
if (fEfield) {
|
||||
dSpin -=
|
||||
// from Jackson
|
||||
// -uce*Spin.cross(u.cross(EField)) );
|
||||
// but this form has one less operation
|
||||
pcharge*omegac*( uce*(u*(Spin*EField) - EField*(Spin*u)) );
|
||||
if (fEfield)
|
||||
{
|
||||
dSpin -= pcharge*omegac*( uce*(u*(Spin*EField) - EField*(Spin*u)) );
|
||||
// from Jackson
|
||||
// -uce*Spin.cross(u.cross(EField)) );
|
||||
// but this form has one less operation
|
||||
}
|
||||
}
|
||||
|
||||
dydx[ 9] = dSpin.x();
|
||||
dydx[10] = dSpin.y();
|
||||
dydx[11] = dSpin.z();
|
||||
|
||||
// G4cout << "dydx[9,10,11] " << dydx[9] << " " << dydx[10] << " " << dydx[11] << G4endl;
|
||||
}
|
||||
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4SextupoleMagField implementation
|
||||
// by H. Burkhardt 23/10/2019
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4SextupoleMagField.hh"
|
||||
#include "G4RotationMatrix.hh"
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
G4RotationMatrix IdentityMatrix;
|
||||
}
|
||||
|
||||
G4SextupoleMagField::G4SextupoleMagField(G4double pGradient)
|
||||
{
|
||||
fGradient = pGradient;
|
||||
fpMatrix = &IdentityMatrix;
|
||||
}
|
||||
|
||||
G4SextupoleMagField::G4SextupoleMagField(G4double pGradient,
|
||||
G4ThreeVector pOrigin,
|
||||
G4RotationMatrix* pMatrix)
|
||||
{
|
||||
fGradient = pGradient ;
|
||||
fOrigin = pOrigin ;
|
||||
fpMatrix = pMatrix ;
|
||||
}
|
||||
|
||||
G4Field* G4SextupoleMagField::Clone() const
|
||||
{
|
||||
return new G4SextupoleMagField(fGradient, fOrigin, fpMatrix);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4SextupoleMagField::~G4SextupoleMagField()
|
||||
{
|
||||
}
|
||||
|
||||
void G4SextupoleMagField::GetFieldValue( const G4double y[4],
|
||||
G4double B[3] ) const
|
||||
// with displaced origin and rotation
|
||||
{
|
||||
G4ThreeVector r_global = G4ThreeVector(
|
||||
y[0] - fOrigin.x(),
|
||||
y[1] - fOrigin.y(),
|
||||
y[2] - fOrigin.z());
|
||||
|
||||
const G4ThreeVector r_local = (*fpMatrix) * r_global;
|
||||
const G4ThreeVector B_local( fGradient * r_local.x() * r_local.y(),fGradient * ( std::pow(r_local.x(),2) - std::pow(r_local.y(),2) )/2 ,0);
|
||||
const G4ThreeVector B_global = fpMatrix->inverse() * B_local;
|
||||
|
||||
B[0] = B_global.x() ;
|
||||
B[1] = B_global.y() ;
|
||||
B[2] = B_global.z() ;
|
||||
}
|
||||
@@ -23,16 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4SimpleHeum implementation
|
||||
//
|
||||
//
|
||||
// Simple Heum:
|
||||
// x_1 = x_0 + h *
|
||||
// 1/4 * dx(t0,x0) +
|
||||
// 3/4 * dx(t0+2/3*h, x0+2/3*h*(dx(t0+h/3,x0+h/3*dx(t0,x0))))
|
||||
//
|
||||
// Third order solver.
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
// Created: W.Wander <wwc@mit.edu>, 12/09/1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4SimpleHeum.hh"
|
||||
@@ -41,10 +34,10 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
|
||||
G4SimpleHeum::G4SimpleHeum(G4EquationOfMotion *EqRhs, G4int num_variables):
|
||||
G4MagErrorStepper(EqRhs, num_variables),
|
||||
fNumberOfVariables(num_variables)
|
||||
//
|
||||
G4SimpleHeum::G4SimpleHeum(G4EquationOfMotion* EqRhs, G4int num_variables)
|
||||
: G4MagErrorStepper(EqRhs, num_variables),
|
||||
fNumberOfVariables(num_variables)
|
||||
{
|
||||
dydxTemp = new G4double[fNumberOfVariables] ;
|
||||
dydxTemp2 = new G4double[fNumberOfVariables] ;
|
||||
@@ -52,46 +45,43 @@ G4SimpleHeum::G4SimpleHeum(G4EquationOfMotion *EqRhs, G4int num_variables):
|
||||
yTemp2 = new G4double[fNumberOfVariables] ;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4SimpleHeum::~G4SimpleHeum()
|
||||
{
|
||||
delete[] dydxTemp;
|
||||
delete[] dydxTemp2;
|
||||
delete[] yTemp;
|
||||
delete[] yTemp2;
|
||||
delete [] dydxTemp;
|
||||
delete [] dydxTemp2;
|
||||
delete [] yTemp;
|
||||
delete [] yTemp2;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DumbStepper
|
||||
//
|
||||
|
||||
void
|
||||
G4SimpleHeum::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
G4SimpleHeum::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
G4int i;
|
||||
for( i = 0; i < fNumberOfVariables; i++ )
|
||||
for( G4int i = 0; i < fNumberOfVariables; ++i )
|
||||
{
|
||||
yTemp[i] = yIn[i] + (1.0/3.0) * h * dydx[i] ;
|
||||
}
|
||||
|
||||
RightHandSide(yTemp,dydxTemp);
|
||||
|
||||
for( i = 0; i < fNumberOfVariables; i++ )
|
||||
for( G4int i = 0; i < fNumberOfVariables; ++i )
|
||||
{
|
||||
yTemp2[i] = yIn[i] + (2.0/3.0) * h * dydxTemp[i] ;
|
||||
}
|
||||
|
||||
RightHandSide(yTemp2,dydxTemp2);
|
||||
|
||||
for( i = 0; i < fNumberOfVariables; i++ )
|
||||
for( G4int i = 0; i < fNumberOfVariables; ++i )
|
||||
{
|
||||
yOut[i] = yIn[i] + h * (0.25 * dydx[i] + 0.75 * dydxTemp2[i]);
|
||||
}
|
||||
|
||||
@@ -23,18 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4SimpleRunge implementation
|
||||
//
|
||||
//
|
||||
// Simple Runge:
|
||||
//
|
||||
// x_1 = x_0 + h * ( dx( t_0+h/2, x_0 + h/2 * dx( t_0, x_0) ) )
|
||||
//
|
||||
// Second order solver.
|
||||
// Takes the derivative at a position to be assumed at the middle of the
|
||||
// Step and adds it to the current position.
|
||||
//
|
||||
//
|
||||
// W.Wander <wwc@mit.edu> 12/09/97
|
||||
// Created: W.Wander <wwc@mit.edu>, 12/09/1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4SimpleRunge.hh"
|
||||
@@ -43,53 +34,51 @@
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
|
||||
//
|
||||
G4SimpleRunge::G4SimpleRunge(G4EquationOfMotion* EqRhs, G4int numberOfVariables)
|
||||
: G4MagErrorStepper(EqRhs, numberOfVariables),
|
||||
fNumberOfVariables(numberOfVariables)
|
||||
{
|
||||
|
||||
unsigned int noVariables= std::max(numberOfVariables,
|
||||
GetNumberOfStateVariables());
|
||||
GetNumberOfStateVariables());
|
||||
// To deal with Time >= 7+1
|
||||
dydxTemp = new G4double[noVariables] ;
|
||||
yTemp = new G4double[noVariables] ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4SimpleRunge::~G4SimpleRunge()
|
||||
{
|
||||
delete[] dydxTemp;
|
||||
delete[] yTemp;
|
||||
delete [] dydxTemp;
|
||||
delete [] yTemp;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DumbStepper
|
||||
//
|
||||
|
||||
void
|
||||
G4SimpleRunge::DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[])
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] )
|
||||
{
|
||||
// Initialise time to t0, needed when it is not updated by the integration.
|
||||
yTemp[7] = yOut[7] = yIn[7]; // Better to set it to NaN; // TODO
|
||||
//
|
||||
yTemp[7] = yOut[7] = yIn[7];
|
||||
|
||||
G4int i;
|
||||
|
||||
for( i = 0; i < fNumberOfVariables; i++ )
|
||||
for( G4int i = 0; i < fNumberOfVariables; ++i )
|
||||
{
|
||||
yTemp[i] = yIn[i] + 0.5 * h*dydx[i] ;
|
||||
}
|
||||
|
||||
RightHandSide(yTemp,dydxTemp);
|
||||
|
||||
for( i = 0; i < fNumberOfVariables; i++ )
|
||||
for( G4int i = 0; i < fNumberOfVariables; ++i )
|
||||
{
|
||||
yOut[i] = yIn[i] + h * ( dydxTemp[i] );
|
||||
}
|
||||
|
||||
@@ -23,12 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4TrialsCounter implementation
|
||||
//
|
||||
// class G4TrialsCounter
|
||||
//
|
||||
// Class inline implementation
|
||||
//
|
||||
// Author: Dec 8, 2006 John Apostolakis
|
||||
// Author: John Apostolakis, CERN - 08.12.2006
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4TrialsCounter.hh"
|
||||
@@ -37,8 +34,7 @@
|
||||
G4TrialsCounter::G4TrialsCounter( const G4String& nameStats,
|
||||
const G4String& description,
|
||||
G4bool printOnExit )
|
||||
: fName(nameStats), fDescription(description),
|
||||
fStatsVerbose(printOnExit), fPrinted(false)
|
||||
: fName(nameStats), fDescription(description), fStatsVerbose(printOnExit)
|
||||
{
|
||||
ClearCounts();
|
||||
}
|
||||
@@ -52,6 +48,7 @@ void
|
||||
G4TrialsCounter::PrintStatistics()
|
||||
{
|
||||
// Print Statistics
|
||||
//
|
||||
G4cout << "G4TrialsCounter::PrintStatistics()" << G4endl
|
||||
<< "Report of counts for " << fDescription << " : " << G4endl;
|
||||
G4cout << "Stats for '" << fName << "' > "
|
||||
@@ -60,23 +57,23 @@ G4TrialsCounter::PrintStatistics()
|
||||
<< " Max-trial= " << fmaxTrials
|
||||
<< " no-max= " << fNoTimesMaxTrials
|
||||
<< G4endl;
|
||||
fPrinted= true;
|
||||
fPrinted = true;
|
||||
}
|
||||
|
||||
void G4TrialsCounter::ClearCounts()
|
||||
{
|
||||
fTotalNoTrials= 0;
|
||||
fNumberCalls = 0;
|
||||
fmaxTrials = 0; // Maximum --> so only unsigned ints expected
|
||||
fNoTimesMaxTrials=0;
|
||||
fTotalNoTrials = 0;
|
||||
fNumberCalls = 0;
|
||||
fmaxTrials = 0; // Maximum --> so only unsigned ints expected
|
||||
fNoTimesMaxTrials = 0;
|
||||
}
|
||||
|
||||
G4int
|
||||
G4TrialsCounter::ReturnTotals( G4int& calls, G4int& maxTrials, G4int& numMaxT )
|
||||
{
|
||||
calls = fNumberCalls;
|
||||
maxTrials= fmaxTrials;
|
||||
numMaxT = fNoTimesMaxTrials;
|
||||
calls = fNumberCalls;
|
||||
maxTrials = fmaxTrials;
|
||||
numMaxT = fNoTimesMaxTrials;
|
||||
|
||||
return fTotalNoTrials;
|
||||
}
|
||||
|
||||
@@ -23,22 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4TsitourasRK45 implementation
|
||||
//
|
||||
// Tsitouras - 5(4) RK steppers ( non-FSAL version )
|
||||
//
|
||||
// Implements RK tableau from 'Table 1' of
|
||||
// C. Tsitouras, “Runge–Kutta pairs of order 5(4) satisfying only
|
||||
// the first column simplifying assumption,”
|
||||
// Computers & Mathematics with Applications,
|
||||
// vol. 62, no. 2, pp. 770–775, 2011.
|
||||
//
|
||||
// Adaptation / Geant4 implementation by Somnath Banerjee
|
||||
// Supervision / code review: John Apostolakis
|
||||
//
|
||||
// Sponsored by Google in Google Summer of Code 2015.
|
||||
//
|
||||
// First version: 12 June 2015
|
||||
//
|
||||
// Author: Somnath Banerjee, Google Summer of Code 2015, 11.06.2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4TsitourasRK45.hh"
|
||||
@@ -47,15 +35,13 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
|
||||
//
|
||||
G4TsitourasRK45::G4TsitourasRK45(G4EquationOfMotion *EqRhs,
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
|
||||
fLastStepLength(0.), fAuxStepper(0)
|
||||
G4int noIntegrationVariables,
|
||||
G4bool primary)
|
||||
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
|
||||
{
|
||||
const G4int numberOfVariables = noIntegrationVariables;
|
||||
// G4cout << "G4TsitourasRK45 constructor called." << G4endl;
|
||||
|
||||
ak2 = new G4double[numberOfVariables] ;
|
||||
ak3 = new G4double[numberOfVariables] ;
|
||||
@@ -65,12 +51,11 @@ G4TsitourasRK45::G4TsitourasRK45(G4EquationOfMotion *EqRhs,
|
||||
ak7 = new G4double[numberOfVariables] ;
|
||||
ak8 = new G4double[numberOfVariables] ;
|
||||
|
||||
|
||||
// Must ensure space extra 'state' variables exists - i.e. yIn[7]
|
||||
//
|
||||
const G4int numStateMax = std::max(GetNumberOfStateVariables(), 8);
|
||||
const G4int numStateVars = std::max(noIntegrationVariables,
|
||||
numStateMax );
|
||||
// GetNumberOfStateVariables() );
|
||||
|
||||
yTemp = new G4double[numStateVars] ;
|
||||
yIn = new G4double[numStateVars] ;
|
||||
@@ -82,6 +67,7 @@ G4TsitourasRK45::G4TsitourasRK45(G4EquationOfMotion *EqRhs,
|
||||
|
||||
fMidVector = new G4double[numberOfVariables];
|
||||
fMidError = new G4double[numberOfVariables];
|
||||
|
||||
if( primary )
|
||||
{
|
||||
fAuxStepper = new G4TsitourasRK45(EqRhs, numberOfVariables, !primary);
|
||||
@@ -91,162 +77,159 @@ G4TsitourasRK45::G4TsitourasRK45(G4EquationOfMotion *EqRhs,
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
|
||||
//
|
||||
G4TsitourasRK45::~G4TsitourasRK45()
|
||||
{
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
delete[] ak7;
|
||||
delete[] ak8;
|
||||
delete [] ak2;
|
||||
delete [] ak3;
|
||||
delete [] ak4;
|
||||
delete [] ak5;
|
||||
delete [] ak6;
|
||||
delete [] ak7;
|
||||
delete [] ak8;
|
||||
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
delete [] yTemp;
|
||||
delete [] yIn;
|
||||
|
||||
delete[] fLastInitialVector;
|
||||
delete[] fLastFinalVector;
|
||||
delete[] fLastDyDx;
|
||||
delete[] fMidVector;
|
||||
delete[] fMidError;
|
||||
delete [] fLastInitialVector;
|
||||
delete [] fLastFinalVector;
|
||||
delete [] fLastDyDx;
|
||||
delete [] fMidVector;
|
||||
delete [] fMidError;
|
||||
|
||||
delete fAuxStepper;
|
||||
}
|
||||
|
||||
//The following coefficients have been obtained from
|
||||
// The following coefficients have been obtained from
|
||||
// Table 1: The Coefficients of the new pair
|
||||
//---Ref---
|
||||
// C. Tsitouras, “Runge–Kutta pairs of order 5(4) satisfying only
|
||||
// the first column simplifying assumption,”
|
||||
// Computers & Mathematics with Applications,
|
||||
// vol. 62, no. 2, pp. 770–775, 2011.
|
||||
//-----------------------------------
|
||||
// A corresponding matlab code was also found @ http://users.ntua.gr/tsitoura/new54.m
|
||||
|
||||
//
|
||||
// C. Tsitouras, "Runge–Kutta pairs of order 5(4) satisfying only
|
||||
// the first column simplifying assumption"
|
||||
// Computers & Mathematics with Applications, vol.62, no.2, pp.770-775, 2011.
|
||||
//
|
||||
// A corresponding matlab code was also found at:
|
||||
// http://users.ntua.gr/tsitoura/new54.m
|
||||
//
|
||||
// Doing a step
|
||||
//
|
||||
void
|
||||
G4TsitourasRK45::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[])
|
||||
G4TsitourasRK45::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
{
|
||||
G4int i;
|
||||
const G4double b21 = 0.161 ,
|
||||
b31 = -0.00848065549235698854 ,
|
||||
b32 = 0.335480655492356989 ,
|
||||
|
||||
b41 = 2.89715305710549343 ,
|
||||
b42 = -6.35944848997507484 ,
|
||||
b43 = 4.36229543286958141 ,
|
||||
|
||||
const G4double
|
||||
b21 = 0.161 ,
|
||||
|
||||
b31 = -0.00848065549235698854 ,
|
||||
b32 = 0.335480655492356989 ,
|
||||
|
||||
b41 = 2.89715305710549343 ,
|
||||
b42 = -6.35944848997507484 ,
|
||||
b43 = 4.36229543286958141 ,
|
||||
b51 = 5.325864828439257,
|
||||
b52 = -11.748883564062828,
|
||||
b53 = 7.49553934288983621 ,
|
||||
b54 = -0.09249506636175525,
|
||||
|
||||
b51 = 5.325864828439257,
|
||||
b52 = -11.748883564062828,
|
||||
b53 = 7.49553934288983621 ,
|
||||
b54 = -0.09249506636175525,
|
||||
b61 = 5.8614554429464200,
|
||||
b62 = -12.9209693178471093 ,
|
||||
b63 = 8.1593678985761586 ,
|
||||
b64 = -0.071584973281400997,
|
||||
b65 = -0.0282690503940683829,
|
||||
|
||||
b61 = 5.8614554429464200,
|
||||
b62 = -12.9209693178471093 ,
|
||||
b63 = 8.1593678985761586 ,
|
||||
b64 = -0.071584973281400997,
|
||||
b65 = -0.0282690503940683829,
|
||||
b71 = 0.0964607668180652295 ,
|
||||
b72 = 0.01,
|
||||
b73 = 0.479889650414499575,
|
||||
b74 = 1.37900857410374189,
|
||||
b75 = -3.2900695154360807,
|
||||
b76 = 2.32471052409977398,
|
||||
|
||||
// c1 = 0.001780011052226 ,
|
||||
// c2 = 0.000816434459657 ,
|
||||
// c3 = -0.007880878010262 ,
|
||||
// c4 = 0.144711007173263 ,
|
||||
// c5 = -0.582357165452555 ,
|
||||
// c6 = 0.458082105929187 ,
|
||||
// c7 = 1.0/66.0 ;
|
||||
|
||||
dc1 = 0.0935237485818927066 - b71 , // - 0.001780011052226,
|
||||
dc2 = 0.00865288314156636761 - b72, // - 0.000816434459657,
|
||||
dc3 = 0.492893099131431868 - b73 , // + 0.007880878010262,
|
||||
dc4 = 1.14023541226785810 - b74 , // 0.144711007173263,
|
||||
dc5 = - 2.3291801924393646 - b75, // + 0.582357165452555,
|
||||
dc6 = 1.56887504931661552 - b76 , // - 0.458082105929187,
|
||||
dc7 = 0.025; //- 1.0/66.0 ;
|
||||
|
||||
b71 = 0.0964607668180652295 ,
|
||||
b72 = 0.01,
|
||||
b73 = 0.479889650414499575,
|
||||
b74 = 1.37900857410374189,
|
||||
b75 = -3.2900695154360807,
|
||||
b76 = 2.32471052409977398,
|
||||
// dc1 = -3.0/1280.0,
|
||||
// dc2 = 0.0,
|
||||
// dc3 = 6561.0/632320.0,
|
||||
// dc4 = -343.0/20800.0,
|
||||
// dc5 = 243.0/12800.0,
|
||||
// dc6 = -1.0/95.0,
|
||||
// dc7 = 0.0 ;
|
||||
|
||||
// c1 = 0.001780011052226 ,
|
||||
// c2 = 0.000816434459657 ,
|
||||
// c3 = -0.007880878010262 ,
|
||||
// c4 = 0.144711007173263 ,
|
||||
// c5 = -0.582357165452555 ,
|
||||
// c6 = 0.458082105929187 ,
|
||||
// c7 = 1.0/66.0 ;
|
||||
|
||||
dc1 = 0.0935237485818927066 - b71 , // - 0.001780011052226,
|
||||
dc2 = 0.00865288314156636761 - b72, // - 0.000816434459657,
|
||||
dc3 = 0.492893099131431868 - b73 , // + 0.007880878010262,
|
||||
dc4 = 1.14023541226785810 - b74 , // 0.144711007173263,
|
||||
dc5 = - 2.3291801924393646 - b75, // + 0.582357165452555,
|
||||
dc6 = 1.56887504931661552 - b76 , // - 0.458082105929187,
|
||||
dc7 = 0.025; //- 1.0/66.0 ;
|
||||
|
||||
// dc1 = -3.0/1280.0,
|
||||
// dc2 = 0.0,
|
||||
// dc3 = 6561.0/632320.0,
|
||||
// dc4 = -343.0/20800.0,
|
||||
// dc5 = 243.0/12800.0,
|
||||
// dc6 = -1.0/95.0,
|
||||
// dc7 = 0.0 ;
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
// The number of variables to be integrated over
|
||||
//
|
||||
yOut[7] = yTemp[7] = yIn[7] = yInput[7];
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
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++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + b21*Step*dydx[i] ;
|
||||
}
|
||||
RightHandSide(yTemp, ak2) ; // 2nd Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b31*dydx[i] + b32*ak2[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak3) ; // 3rd Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b41*dydx[i] + b42*ak2[i] + b43*ak3[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak4) ; // 4th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yTemp[i] = yIn[i] + Step*(b51*dydx[i] + b52*ak2[i] + b53*ak3[i] +
|
||||
b54*ak4[i]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak5) ; // 5th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(G4int 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]) ;
|
||||
}
|
||||
RightHandSide(yTemp, ak6) ; // 6th Stage
|
||||
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(G4int 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]);
|
||||
}
|
||||
RightHandSide(yOut, ak7); //7th Stage
|
||||
RightHandSide(yOut, ak7); // 7th Stage
|
||||
|
||||
//Calculate the error in the step:
|
||||
for(i=0;i<numberOfVariables;i++)
|
||||
for(G4int 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] ) ;
|
||||
|
||||
// Store Input and Final values, for possible use in calculating chord
|
||||
//
|
||||
fLastInitialVector[i] = yIn[i] ;
|
||||
fLastFinalVector[i] = yOut[i];
|
||||
fLastDyDx[i] = dydx[i];
|
||||
@@ -257,68 +240,74 @@ G4TsitourasRK45::Stepper( const G4double yInput[],
|
||||
return ;
|
||||
}
|
||||
|
||||
void G4TsitourasRK45::SetupInterpolation() // (const G4double *yInput, const G4double *dydx, const G4double Step)
|
||||
void G4TsitourasRK45::SetupInterpolation()
|
||||
// (const G4double *yInput, const G4double *dydx, const G4double Step)
|
||||
{
|
||||
//Nothing to be done
|
||||
// Nothing to be done
|
||||
}
|
||||
|
||||
|
||||
void G4TsitourasRK45::Interpolate(const G4double *yInput, const G4double *dydx, const G4double Step, G4double *yOut, G4double tau){
|
||||
|
||||
|
||||
void G4TsitourasRK45::Interpolate(const G4double* yInput,
|
||||
const G4double* dydx,
|
||||
const G4double Step,
|
||||
G4double* yOut,
|
||||
G4double tau)
|
||||
{
|
||||
G4double bf1, bf2, bf3, bf4, bf5, bf6, bf7;
|
||||
// Coefficients for all the seven stages.
|
||||
// Coefficients for all the seven stages.
|
||||
|
||||
const G4int numberOfVariables= this->GetNumberOfVariables();
|
||||
const G4int numberOfVariables = GetNumberOfVariables();
|
||||
|
||||
G4double tau0 = tau;
|
||||
|
||||
for(int i=0;i<numberOfVariables;i++)
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yIn[i]=yInput[i];
|
||||
yIn[i] = yInput[i];
|
||||
}
|
||||
|
||||
G4double
|
||||
tau_2 = tau0*tau0 ;
|
||||
// tau_3 = tau0*tau_2,
|
||||
// tau_4 = tau_2*tau_2;
|
||||
G4double tau_2 = tau0*tau0 ;
|
||||
// tau_3 = tau0*tau_2,
|
||||
// tau_4 = tau_2*tau_2;
|
||||
|
||||
bf1 = -1.0530884977290216*tau*(tau - 1.3299890189751412)*(tau_2 -
|
||||
1.4364028541716351*tau + 0.7139816917074209),
|
||||
1.4364028541716351*tau + 0.7139816917074209);
|
||||
bf2 = 0.1017*tau_2*(tau_2 - 2.1966568338249754*tau +
|
||||
1.2949852507374631),
|
||||
1.2949852507374631);
|
||||
bf3 = 2.490627285651252793*tau_2*(tau_2 - 2.38535645472061657*tau
|
||||
+ 1.57803468208092486) ,
|
||||
+ 1.57803468208092486);
|
||||
bf4 = -16.54810288924490272*(tau - 1.21712927295533244)*
|
||||
(tau - 0.61620406037800089)*tau_2,
|
||||
(tau - 0.61620406037800089)*tau_2;
|
||||
bf5 = 47.37952196281928122*(tau - 1.203071208372362603)*
|
||||
(tau - 0.658047292653547382)*tau_2,
|
||||
(tau - 0.658047292653547382)*tau_2;
|
||||
bf6 = -34.87065786149660974*(tau - 1.2)*(tau -
|
||||
0.666666666666666667)*tau_2,
|
||||
0.666666666666666667)*tau_2;
|
||||
bf7 = 2.5*(tau - 1.0)*(tau - 0.6)*tau_2;
|
||||
|
||||
//Putting together the coefficients calculated as the respective stage coefficients
|
||||
for( int i=0; i<numberOfVariables; i++){
|
||||
yOut[i] = yIn[i] + Step*( bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i] + bf4*ak4[i]
|
||||
+ bf5*ak5[i] + bf6*ak6[i] + bf7*ak7[i] ) ;
|
||||
// Putting together the coefficients calculated as the respective
|
||||
// stage coefficients
|
||||
//
|
||||
for(G4int i=0; i<numberOfVariables; ++i)
|
||||
{
|
||||
yOut[i] = yIn[i] + Step*( bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i]
|
||||
+ bf4*ak4[i] + bf5*ak5[i] + bf6*ak6[i]
|
||||
+ bf7*ak7[i] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4TsitourasRK45::DistChord() const
|
||||
{
|
||||
G4double distLine, distChord;
|
||||
G4ThreeVector initialPoint, finalPoint, midPoint;
|
||||
|
||||
// Store last initial and final points (they will be overwritten in self-Stepper call!)
|
||||
// Store last initial and final points (they will be
|
||||
// overwritten in self-Stepper call!)
|
||||
//
|
||||
initialPoint = G4ThreeVector( fLastInitialVector[0],
|
||||
fLastInitialVector[1], fLastInitialVector[2]);
|
||||
finalPoint = G4ThreeVector( fLastFinalVector[0],
|
||||
fLastFinalVector[1], fLastFinalVector[2]);
|
||||
|
||||
// Do half a step using StepNoErr
|
||||
|
||||
//
|
||||
fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
|
||||
fMidVector, fMidError );
|
||||
|
||||
@@ -326,8 +315,7 @@ G4double G4TsitourasRK45::DistChord() const
|
||||
|
||||
// Use stored values of Initial and Endpoint + new Midpoint to evaluate
|
||||
// distance of Chord
|
||||
|
||||
|
||||
//
|
||||
if (initialPoint != finalPoint)
|
||||
{
|
||||
distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint );
|
||||
|
||||
@@ -23,32 +23,28 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4UniformElectricField implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// Class for creation of uniform Electric Field
|
||||
//
|
||||
// 30.1.97 V.Grichine
|
||||
//
|
||||
// Created: V.Grichine, 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4UniformElectricField.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
G4UniformElectricField::G4UniformElectricField(const G4ThreeVector FieldVector )
|
||||
G4UniformElectricField::
|
||||
G4UniformElectricField(const G4ThreeVector& FieldVector)
|
||||
{
|
||||
fFieldComponents[0] = 0.0;
|
||||
fFieldComponents[1] = 0.0;
|
||||
fFieldComponents[2] = 0.0;
|
||||
fFieldComponents[3] = FieldVector.x();
|
||||
fFieldComponents[4] = FieldVector.y();
|
||||
fFieldComponents[5] = FieldVector.z();
|
||||
fFieldComponents[0] = 0.0;
|
||||
fFieldComponents[1] = 0.0;
|
||||
fFieldComponents[2] = 0.0;
|
||||
fFieldComponents[3] = FieldVector.x();
|
||||
fFieldComponents[4] = FieldVector.y();
|
||||
fFieldComponents[5] = FieldVector.z();
|
||||
}
|
||||
|
||||
G4UniformElectricField::G4UniformElectricField(G4double vField,
|
||||
G4double vTheta,
|
||||
G4double vPhi )
|
||||
G4double vPhi)
|
||||
{
|
||||
if ( (vField<0) || (vTheta<0) || (vTheta>pi) || (vPhi<0) || (vPhi>twopi) )
|
||||
{
|
||||
@@ -64,47 +60,48 @@ G4UniformElectricField::G4UniformElectricField(G4double vField,
|
||||
fFieldComponents[5] = vField*std::cos(vTheta) ;
|
||||
}
|
||||
|
||||
G4Field* G4UniformElectricField::Clone() const
|
||||
{
|
||||
return new G4UniformElectricField( G4ThreeVector(fFieldComponents[3],
|
||||
fFieldComponents[4],
|
||||
fFieldComponents[5]) );
|
||||
}
|
||||
|
||||
G4UniformElectricField::~G4UniformElectricField()
|
||||
{
|
||||
}
|
||||
|
||||
G4UniformElectricField::G4UniformElectricField (const G4UniformElectricField &p)
|
||||
G4UniformElectricField::
|
||||
G4UniformElectricField (const G4UniformElectricField& p)
|
||||
: G4ElectricField(p)
|
||||
{
|
||||
for (G4int i=0; i<6; i++)
|
||||
for (auto i=0; i<6; ++i)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
}
|
||||
|
||||
G4UniformElectricField&
|
||||
G4UniformElectricField::operator = (const G4UniformElectricField &p)
|
||||
G4UniformElectricField::operator = (const G4UniformElectricField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4ElectricField::operator=(p);
|
||||
for (G4int i=0; i<6; i++)
|
||||
for (auto i=0; i<6; ++i)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
G4Field* G4UniformElectricField::Clone() const
|
||||
{
|
||||
return new G4UniformElectricField( G4ThreeVector(fFieldComponents[3],
|
||||
fFieldComponents[4],
|
||||
fFieldComponents[5]));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void G4UniformElectricField::GetFieldValue (const G4double[4],
|
||||
G4double *fieldBandE ) const
|
||||
G4double* fieldBandE) const
|
||||
{
|
||||
fieldBandE[0]= 0.0;
|
||||
fieldBandE[1]= 0.0;
|
||||
fieldBandE[2]= 0.0;
|
||||
fieldBandE[3]= fFieldComponents[3] ;
|
||||
fieldBandE[4]= fFieldComponents[4] ;
|
||||
fieldBandE[5]= fFieldComponents[5] ;
|
||||
fieldBandE[0] = 0.0;
|
||||
fieldBandE[1] = 0.0;
|
||||
fieldBandE[2] = 0.0;
|
||||
fieldBandE[3] = fFieldComponents[3];
|
||||
fieldBandE[4] = fFieldComponents[4];
|
||||
fieldBandE[5] = fFieldComponents[5];
|
||||
}
|
||||
|
||||
@@ -23,79 +23,73 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4UniformGravityField implementation
|
||||
//
|
||||
// Class for creation of Uniform Gravitation Field.
|
||||
//
|
||||
// Created: P.Gumplinger, 14.06.2011 - Adapted from G4UniformElectricField
|
||||
// Thanks to P.Fierlinger (PSI), A.Capra and A.Fontana (INFN Pavia)
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// History:
|
||||
// - 14.06.11 P.Gumplinger, Created.
|
||||
// -------------------------------------------------------------------
|
||||
// Adopted from G4UniformElectricField.hh
|
||||
//
|
||||
// Thanks to Peter Fierlinger (PSI) and
|
||||
// A. Capra and A. Fontana (INFN Pavia)
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
#include "G4UniformGravityField.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
// Construct from a 3-vector
|
||||
G4UniformGravityField::G4UniformGravityField(const G4ThreeVector FieldVector)
|
||||
//
|
||||
G4UniformGravityField::G4UniformGravityField(const G4ThreeVector& FieldVector)
|
||||
: G4Field ( true ) // Gravity flag *on*
|
||||
{
|
||||
fFieldComponents[0] = FieldVector.x();
|
||||
fFieldComponents[1] = FieldVector.y();
|
||||
fFieldComponents[2] = FieldVector.z();
|
||||
fFieldComponents[0] = FieldVector.x();
|
||||
fFieldComponents[1] = FieldVector.y();
|
||||
fFieldComponents[2] = FieldVector.z();
|
||||
}
|
||||
|
||||
// Construct from a double > default = -9.81 m*s^-2
|
||||
G4UniformGravityField::G4UniformGravityField(const G4double gy )
|
||||
G4UniformGravityField::G4UniformGravityField(const G4double gy)
|
||||
: G4Field ( true )
|
||||
{
|
||||
fFieldComponents[0] = 0.0;
|
||||
fFieldComponents[1] = gy;
|
||||
fFieldComponents[2] = 0.0;
|
||||
}
|
||||
|
||||
G4Field* G4UniformGravityField::Clone() const
|
||||
{
|
||||
return new G4UniformGravityField( G4ThreeVector(fFieldComponents[0],
|
||||
fFieldComponents[1],
|
||||
fFieldComponents[2]) );
|
||||
fFieldComponents[0] = 0.0;
|
||||
fFieldComponents[1] = gy;
|
||||
fFieldComponents[2] = 0.0;
|
||||
}
|
||||
|
||||
G4UniformGravityField::~G4UniformGravityField()
|
||||
{
|
||||
}
|
||||
|
||||
G4UniformGravityField::G4UniformGravityField (const G4UniformGravityField &p)
|
||||
: G4Field(p)
|
||||
G4UniformGravityField::G4UniformGravityField (const G4UniformGravityField& p)
|
||||
: G4Field(p)
|
||||
{
|
||||
for (G4int i=0; i<3; i++)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
for (auto i=0; i<3; ++i)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
}
|
||||
|
||||
G4UniformGravityField&
|
||||
G4UniformGravityField::operator = (const G4UniformGravityField &p)
|
||||
G4UniformGravityField::operator = (const G4UniformGravityField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4Field::operator=(p);
|
||||
for (G4int i=0; i<3; i++)
|
||||
for (auto i=0; i<3; ++i)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
G4Field* G4UniformGravityField::Clone() const
|
||||
{
|
||||
return new G4UniformGravityField( G4ThreeVector(fFieldComponents[0],
|
||||
fFieldComponents[1],
|
||||
fFieldComponents[2]) );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
void G4UniformGravityField::GetFieldValue (const G4double [4],
|
||||
G4double *G ) const
|
||||
G4double* G ) const
|
||||
{
|
||||
G[0]= fFieldComponents[0] ;
|
||||
G[1]= fFieldComponents[1] ;
|
||||
G[2]= fFieldComponents[2] ;
|
||||
G[0]= fFieldComponents[0];
|
||||
G[1]= fFieldComponents[1];
|
||||
G[2]= fFieldComponents[2];
|
||||
}
|
||||
|
||||
@@ -23,13 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4UniformMagField implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// Class for creation of uniform Magnetic Field
|
||||
//
|
||||
// 30.1.97 V.Grichine
|
||||
//
|
||||
// Created: V.Grichine, 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4UniformMagField.hh"
|
||||
@@ -37,34 +33,58 @@
|
||||
|
||||
G4UniformMagField::G4UniformMagField(const G4ThreeVector& FieldVector )
|
||||
{
|
||||
fFieldComponents[0] = FieldVector.x();
|
||||
fFieldComponents[1] = FieldVector.y();
|
||||
fFieldComponents[2] = FieldVector.z();
|
||||
fFieldComponents[0] = FieldVector.x();
|
||||
fFieldComponents[1] = FieldVector.y();
|
||||
fFieldComponents[2] = FieldVector.z();
|
||||
}
|
||||
|
||||
G4UniformMagField::~G4UniformMagField()
|
||||
{
|
||||
}
|
||||
|
||||
G4UniformMagField::G4UniformMagField (const G4UniformMagField& p)
|
||||
: G4MagneticField(p)
|
||||
{
|
||||
for (auto i=0; i<3; ++i)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
}
|
||||
|
||||
G4UniformMagField& G4UniformMagField::operator = (const G4UniformMagField& p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4MagneticField::operator=(p);
|
||||
for (auto i=0; i<3; ++i)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
G4Field* G4UniformMagField::Clone() const
|
||||
{
|
||||
return new G4UniformMagField( G4ThreeVector(fFieldComponents[0],
|
||||
fFieldComponents[1],
|
||||
fFieldComponents[2]) );
|
||||
return new G4UniformMagField( G4ThreeVector(fFieldComponents[0],
|
||||
fFieldComponents[1],
|
||||
fFieldComponents[2]) );
|
||||
}
|
||||
|
||||
void
|
||||
G4UniformMagField::SetFieldValue(const G4ThreeVector& newFieldVector )
|
||||
{
|
||||
fFieldComponents[0] = newFieldVector.x();
|
||||
fFieldComponents[1] = newFieldVector.y();
|
||||
fFieldComponents[2] = newFieldVector.z();
|
||||
fFieldComponents[0] = newFieldVector.x();
|
||||
fFieldComponents[1] = newFieldVector.y();
|
||||
fFieldComponents[2] = newFieldVector.z();
|
||||
}
|
||||
|
||||
G4UniformMagField::G4UniformMagField(G4double vField,
|
||||
G4double vTheta,
|
||||
G4double vPhi )
|
||||
G4double vPhi)
|
||||
{
|
||||
if ( (vField<0) || (vTheta<0) || (vTheta>pi) || (vPhi<0) || (vPhi>twopi) )
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "ERROR in G4UniformMagField::G4UniformMagField(double, double, double) : "
|
||||
msg << "ERROR in G4UniformMagField::G4UniformMagField() : "
|
||||
<< "Invalid parameter(s). " << std::endl;
|
||||
msg << " Expected " << std::endl;
|
||||
|
||||
@@ -83,45 +103,21 @@ G4UniformMagField::G4UniformMagField(G4double vField,
|
||||
if ( (vPhi<0) || (vPhi>twopi) ) { msg << " <------ Erroneous "; }
|
||||
|
||||
G4Exception("G4UniformMagField::G4UniformMagField()",
|
||||
"GeomField0002", FatalException, msg ); // "Invalid parameters.") ;
|
||||
"GeomField0002", FatalException, msg );
|
||||
}
|
||||
fFieldComponents[0] = vField*std::sin(vTheta)*std::cos(vPhi) ;
|
||||
fFieldComponents[1] = vField*std::sin(vTheta)*std::sin(vPhi) ;
|
||||
fFieldComponents[2] = vField*std::cos(vTheta) ;
|
||||
}
|
||||
|
||||
G4UniformMagField::~G4UniformMagField()
|
||||
{
|
||||
}
|
||||
|
||||
G4UniformMagField::G4UniformMagField (const G4UniformMagField &p)
|
||||
: G4MagneticField(p)
|
||||
{
|
||||
for (G4int i=0; i<3; i++)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
}
|
||||
|
||||
G4UniformMagField& G4UniformMagField::operator = (const G4UniformMagField &p)
|
||||
{
|
||||
if (&p == this) return *this;
|
||||
G4MagneticField::operator=(p);
|
||||
for (G4int i=0; i<3; i++)
|
||||
{
|
||||
fFieldComponents[i] = p.fFieldComponents[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void G4UniformMagField::GetFieldValue (const G4double [4],
|
||||
G4double *B ) const
|
||||
G4double* B) const
|
||||
{
|
||||
B[0]= fFieldComponents[0] ;
|
||||
B[1]= fFieldComponents[1] ;
|
||||
B[2]= fFieldComponents[2] ;
|
||||
B[0]= fFieldComponents[0];
|
||||
B[1]= fFieldComponents[1];
|
||||
B[2]= fFieldComponents[2];
|
||||
}
|
||||
|
||||
G4ThreeVector G4UniformMagField::GetConstantFieldValue() const
|
||||
@@ -129,5 +125,5 @@ G4ThreeVector G4UniformMagField::GetConstantFieldValue() const
|
||||
G4ThreeVector B(fFieldComponents[0],
|
||||
fFieldComponents[1],
|
||||
fFieldComponents[2]);
|
||||
return B;
|
||||
return B;
|
||||
}
|
||||
|
||||
@@ -23,34 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
|
||||
// G4VFSALIntegrationStepper implementation
|
||||
//
|
||||
// Author: Somnath Banerjee, Google Summer of Code 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4VFSALIntegrationStepper.hh"
|
||||
|
||||
// Constructor for stepper abstract base class.
|
||||
//
|
||||
|
||||
G4VFSALIntegrationStepper::G4VFSALIntegrationStepper(G4EquationOfMotion* Equation,
|
||||
G4int num_integration_vars,
|
||||
G4int num_state_vars)
|
||||
// Constructor for stepper abstract base class
|
||||
//
|
||||
G4VFSALIntegrationStepper::
|
||||
G4VFSALIntegrationStepper( G4EquationOfMotion* Equation,
|
||||
G4int num_integration_vars,
|
||||
G4int num_state_vars )
|
||||
: fEquation_Rhs(Equation),
|
||||
fNoIntegrationVariables(num_integration_vars),
|
||||
fNoStateVariables(num_state_vars),
|
||||
fNoRHSCalls(0)
|
||||
// fNumberOfVariables( std::max(num_var,fNoStateVariables) )
|
||||
fNoStateVariables(num_state_vars)
|
||||
{
|
||||
}
|
||||
|
||||
void G4VFSALIntegrationStepper::increasefNORHSCalls(){
|
||||
// std::cout<<"Yeah, I was called!";
|
||||
fNoRHSCalls++;
|
||||
}
|
||||
|
||||
|
||||
void G4VFSALIntegrationStepper::RightHandSide( const double y[], double dydx[] )
|
||||
void G4VFSALIntegrationStepper::increasefNORHSCalls()
|
||||
{
|
||||
fEquation_Rhs-> RightHandSide(y, dydx);
|
||||
increasefNORHSCalls();
|
||||
++fNoRHSCalls;
|
||||
}
|
||||
|
||||
|
||||
void G4VFSALIntegrationStepper::RightHandSide( const G4double y[],
|
||||
G4double dydx[] )
|
||||
{
|
||||
fEquation_Rhs->RightHandSide(y, dydx);
|
||||
increasefNORHSCalls();
|
||||
}
|
||||
|
||||
@@ -23,37 +23,18 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4VIntegrationDriver implementation
|
||||
//
|
||||
// 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
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
|
||||
void G4VIntegrationDriver::RenewStepperAndAdjust(G4MagIntegratorStepper *)
|
||||
{
|
||||
G4Exception("G4VIntegrationDriver::RenewStepperAndAdjust", "Geometry001", FatalException,
|
||||
"This method exists only for the original G4MagIntegratorDriver class. "
|
||||
" Not defined for other classes derived from G4VIntegrationDriver");
|
||||
}
|
||||
|
||||
G4double G4VIntegrationDriver::GetInverseCurvatureRadius(const G4FieldTrack& /*track*/,
|
||||
G4double /*field*/[]) const
|
||||
{
|
||||
return UNKNOWN_CURVATURE_RADIUS;
|
||||
G4Exception("G4VIntegrationDriver::RenewStepperAndAdjust",
|
||||
"Geometry001", FatalException,
|
||||
"This method exists only for the original G4MagIntegratorDriver class. "
|
||||
"Not defined for other classes derived from G4VIntegrationDriver");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user