Import Geant4 10.5.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2018-06-29 10:58:11 +02:00
parent fe81a77428
commit 6aa23be517
1581 changed files with 124288 additions and 83758 deletions
@@ -0,0 +1,135 @@
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: $
//
// Description:
// G4BulirschStoer class implementation by Dmitry Sorokin
// Implementation is based on bulirsch_stoer.hpp from boost
//
// The Bulirsch-Stoer is a controlled driver that adjusts both step size
// and order of the method. The algorithm uses the modified midpoint and
// a polynomial extrapolation compute the solution.
// Implementation by Dmitry Sorokin - GSoC 2016
// Work supported by Google as part of Google Summer of Code 2016.
// Supervision / code review: John Apostolakis
//
///////////////////////////////////////////////////////////////////////////////
#ifndef G4BULIRSCH_STOER_HH
#define G4BULIRSCH_STOER_HH
#include "G4ModifiedMidpoint.hh"
#include "G4FieldTrack.hh"
class G4BulirschStoer
{
public:
enum class step_result
{
success,
fail
};
G4BulirschStoer( G4EquationOfMotion* equation, G4int nvar,
G4double eps_rel, G4double max_dt = DBL_MAX);
inline void set_max_dt(G4double max_dt);
inline void set_max_relative_error(G4double eps_rel);
// Stepper method
//
step_result try_step(const G4double in[], const G4double dxdt[],
G4double& t, G4double out[], G4double& dt);
// Reset the internal state of the stepper
//
void reset();
inline void SetEquationOfMotion(G4EquationOfMotion* equation);
inline G4EquationOfMotion* GetEquationOfMotion();
inline G4int GetNumberOfVariables() const;
private:
const static G4int m_k_max = 8;
void extrapolate(size_t k, G4double xest[]);
G4double calc_h_opt(G4double h, G4double error, size_t k) const;
G4bool set_k_opt(size_t k, G4double& dt);
G4bool in_convergence_window(G4int k) const;
G4bool should_reject(G4double error, G4int k) const;
// Number of vars to be integrated
G4int fnvar;
// Relative tolerance
G4double m_eps_rel;
// Modified midpoint algorithm
G4ModifiedMidpoint m_midpoint;
G4bool m_last_step_rejected;
G4bool m_first;
G4double m_dt_last;
// G4double m_t_last;
// Max allowed time step
G4double m_max_dt;
G4int m_current_k_opt;
// G4double m_xnew[G4FieldTrack::ncompSVEC];
G4double m_err[G4FieldTrack::ncompSVEC];
// G4double m_dxdt[G4FieldTrack::ncompSVEC];
// Stores the successive interval counts
G4int m_interval_sequence[m_k_max+1];
// Extrapolation coeffs (Nevilles algorithm)
G4double m_coeff[m_k_max+1][m_k_max];
// Costs for interval count
G4int m_cost[m_k_max+1];
// Sequence of states for extrapolation
G4double m_table[m_k_max][G4FieldTrack::ncompSVEC];
// Optimal step size
G4double h_opt[m_k_max+1];
// Work per unit step
G4double work[m_k_max+1];
};
#include "G4BulirschStoer.icc"
#endif
@@ -0,0 +1,49 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
inline void G4BulirschStoer::set_max_dt(G4double max_dt)
{
m_max_dt = max_dt;
}
inline void G4BulirschStoer::set_max_relative_error(G4double eps_rel)
{
m_eps_rel = eps_rel;
}
inline void G4BulirschStoer::SetEquationOfMotion(G4EquationOfMotion* equation)
{
m_midpoint.SetEquationOfMotion(equation);
}
inline G4EquationOfMotion* G4BulirschStoer::GetEquationOfMotion()
{
return m_midpoint.GetEquationOfMotion();
}
inline G4int G4BulirschStoer::GetNumberOfVariables() const
{
return fnvar;
}
@@ -0,0 +1,128 @@
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: $
//
// Helper namespace 'magneticfield'
//
// Description:
// class G4IntegrationDriver<G4BulirschStoer> implementation by Dmitry Sorokin
// This driver class uses Bulirsch-Stoer method to integrate
// the equation of motion
//
// Implementation by Dmitry Sorokin - GSoC 2016
// Work supported by Google as part of Google Summer of Code 2016.
// Supervision / code review: John Apostolakis
//
///////////////////////////////////////////////////////////////////////////////
#ifndef G4BULIRSCH_STOER_DRIVER_HH
#define G4BULIRSCH_STOER_DRIVER_HH
#include "G4IntegrationDriver.hh"
#include "G4BulirschStoer.hh"
template <>
class G4IntegrationDriver<G4BulirschStoer>: public G4VIntegrationDriver {
public:
G4IntegrationDriver(
G4double hminimum,
G4BulirschStoer* stepper,
G4int numberOfComponents = 6,
G4int statisticsVerbosity = 1);
~G4IntegrationDriver() = default;
G4IntegrationDriver(const G4IntegrationDriver&) = delete;
G4IntegrationDriver& operator=(const G4IntegrationDriver&) = delete;
virtual G4bool AccurateAdvance(
G4FieldTrack& track,
G4double stepLen,
G4double eps,
G4double beginStep = 0) override;
virtual G4bool QuickAdvance(
G4FieldTrack& y_val,
const G4double dydx[],
G4double hstep,
G4double& missDist,
G4double& dyerr) override;
void OneGoodStep(
G4double y[],
const G4double dydx[],
G4double& curveLength,
G4double htry,
G4double eps,
G4double& hdid,
G4double& hnext);
virtual void GetDerivatives(
const G4FieldTrack& track,
G4double dydx[]) const override;
virtual void SetVerboseLevel(G4int level) override;
virtual G4int GetVerboseLevel() const override;
virtual G4double ComputeNewStepSize(
G4double errMaxNorm, // normalised error
G4double hstepCurrent) override; // current step size
virtual G4EquationOfMotion* GetEquationOfMotion() override;
const G4EquationOfMotion* GetEquationOfMotion() const;
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
virtual const G4MagIntegratorStepper* GetStepper() const override;
virtual G4MagIntegratorStepper* GetStepper() override;
private:
G4int GetNumberOfVarialbles() const;
G4double fMinimumStep;
G4double fVerbosity;
G4ModifiedMidpoint fMidpointMethod;
G4BulirschStoer* bulirschStoer;
G4double yIn[G4FieldTrack::ncompSVEC],
yMid[G4FieldTrack::ncompSVEC],
yMid2[G4FieldTrack::ncompSVEC],
yOut[G4FieldTrack::ncompSVEC],
yOut2[G4FieldTrack::ncompSVEC],
yError[G4FieldTrack::ncompSVEC];
G4double dydxCurrent[G4FieldTrack::ncompSVEC];
G4double yCurrent[G4FieldTrack::ncompSVEC];
G4double derivs[2][6][G4FieldTrack::ncompSVEC];
const G4int interval_sequence[2];
};
#include "G4BulirschStoerDriver.icc"
#endif
@@ -0,0 +1,386 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4LineSection.hh"
#include "G4FieldUtils.hh"
G4IntegrationDriver<G4BulirschStoer>::G4IntegrationDriver(
G4double hminimum,
G4BulirschStoer* stepper,
G4int numberOfComponents,
G4int statisticsVerbosity)
: fMinimumStep(hminimum)
, fVerbosity(statisticsVerbosity)
, fMidpointMethod(
stepper->GetEquationOfMotion(), stepper->GetNumberOfVariables())
, bulirschStoer(stepper)
, interval_sequence{2,4}
{
assert(stepper->GetNumberOfVariables() == numberOfComponents);
}
G4bool G4IntegrationDriver<G4BulirschStoer>::AccurateAdvance(
G4FieldTrack& track,
G4double hstep,
G4double eps,
G4double hinitial)
{
G4int fNoTotalSteps = 0;
G4int fMaxNoSteps = 10000;
G4double fNoBadSteps = 0;
G4double fSmallestFraction = 1.0e-12;
// Driver with adaptive stepsize control. Integrate starting
// values at y_current over hstep x2 with accuracy eps.
// On output ystart is replaced by values at the end of the integration
// interval. RightHandSide is the right-hand side of ODE system.
// The source is similar to odeint routine from NRC p.721-722 .
// Ensure that hstep > 0
if(hstep == 0)
{
std::ostringstream message;
message << "Proposed step is zero; hstep = " << hstep << " !";
G4Exception("G4IntegrationDriver<G4BulirschStoer>::AccurateAdvance()",
"GeomField1001", JustWarning, message);
return true;
}
if(hstep < 0)
{
std::ostringstream message;
message << "Invalid run condition." << G4endl
<< "Proposed step is negative; hstep = " << hstep << "." << G4endl
<< "Requested step cannot be negative! Aborting event.";
G4Exception("G4IntegrationDriver<G4BulirschStoer>::AccurateAdvance()",
"GeomField0003", EventMustBeAborted, message);
return false;
}
//init first step size
G4double h;
if ( (hinitial > 0) && (hinitial < hstep)
&& (hinitial > perMillion * hstep) )
{
h = hinitial;
}
else // Initial Step size "h" defaults to the full interval
{
h = hstep;
}
//integration variables
track.DumpToArray(yCurrent);
//copy non-integration variables to out array
memcpy(yOut + GetNumberOfVarialbles(),
yCurrent + GetNumberOfVarialbles(),
sizeof(G4double) * (G4FieldTrack::ncompSVEC - GetNumberOfVarialbles()));
G4double startCurveLength = track.GetCurveLength();
G4double curveLength = startCurveLength;
G4double endCurveLength = startCurveLength + hstep;
//loop variables
G4int nstp = 1, no_warnings = 0;
G4double hnext, hdid;
G4bool succeeded = true, lastStepSucceeded;
G4int noFullIntegr = 0, noSmallIntegr = 0 ;
static G4ThreadLocal G4int noGoodSteps = 0 ; // Bad = chord > curve-len
G4bool lastStep = false;
//BulirschStoer->reset();
G4FieldTrack yFldTrk(track);
do
{
G4ThreeVector StartPos(yCurrent[0], yCurrent[1], yCurrent[2]);
GetEquationOfMotion()->RightHandSide(yCurrent, dydxCurrent);
fNoTotalSteps++;
// Perform the Integration
if(h == 0){
G4Exception("G4IntegrationDriver<G4BulirschStoer>::AccurateAdvance()",
"GeomField0003", FatalException,
"Integration Step became Zero!");
}
else if(h > fMinimumStep){
//step size if Ok
OneGoodStep(yCurrent,dydxCurrent,curveLength,h,eps,hdid,hnext);
lastStepSucceeded = (hdid == h);
}
else{
// for small steps call QuickAdvance for speed
G4double dchord_step, dyerr, dyerr_len; // What to do with these ?
yFldTrk.LoadFromArray(yCurrent, G4FieldTrack::ncompSVEC);
yFldTrk.SetCurveLength(curveLength);
QuickAdvance(yFldTrk, dydxCurrent, h, dchord_step, dyerr_len);
yFldTrk.DumpToArray(yCurrent);
dyerr = dyerr_len / h;
hdid = h;
curveLength += hdid;
// Compute suggested new step
//hnext = ComputeNewStepSize(dyerr/eps, h);
hnext = h;
//hnext= ComputeNewStepSize_WithinLimits( dyerr/eps, h);
lastStepSucceeded = (dyerr <= eps);
}
lastStepSucceeded ? ++noFullIntegr : ++noSmallIntegr;
G4ThreeVector EndPos(yCurrent[0], yCurrent[1], yCurrent[2]);
// Check the endpoint
G4double endPointDist = (EndPos - StartPos).mag();
if (endPointDist >= hdid*(1. + perMillion))
{
++fNoBadSteps;
// Issue a warning only for gross differences -
// we understand how small difference occur.
if (endPointDist >= hdid*(1.+perThousand))
{
++no_warnings;
}
}
else
{
++noGoodSteps;
}
// Avoid numerous small last steps
if((h < eps * hstep) || (h < fSmallestFraction * startCurveLength))
{
// No more integration -- the next step will not happen
lastStep = true;
}
else
{
// Check the proposed next stepsize
if(std::fabs(hnext) < fMinimumStep)
{
// Make sure that the next step is at least Hmin.
h = fMinimumStep;
}
else
{
h = hnext;
}
// Ensure that the next step does not overshoot
if (curveLength + h > endCurveLength)
{
h = endCurveLength - curveLength;
}
if (h == 0)
{
// Cannot progress - accept this as last step - by default
lastStep = true;
}
}
} while (((nstp++) <= fMaxNoSteps) && (curveLength < endCurveLength) && (!lastStep));
// Have we reached the end ?
// --> a better test might be x-x2 > an_epsilon
succeeded = (curveLength >= endCurveLength); // If it was a "forced" last step
//copy integrated vars to output array
memcpy(yOut, yCurrent, sizeof(G4double) * GetNumberOfVarialbles());
// upload new state
track.LoadFromArray(yOut, G4FieldTrack::ncompSVEC);
track.SetCurveLength(curveLength);
if(nstp > fMaxNoSteps) {
++no_warnings;
succeeded = false;
}
return succeeded;
}
G4bool G4IntegrationDriver<G4BulirschStoer>::QuickAdvance(
G4FieldTrack& track,
const G4double dydx[],
G4double hstep,
G4double& missDist,
G4double& dyerr)
{
const auto nvar = fMidpointMethod.GetNumberOfVariables();
track.DumpToArray(yIn);
const G4double curveLength = track.GetCurveLength();
fMidpointMethod.SetSteps(interval_sequence[0]);
fMidpointMethod.DoStep(yIn, dydx, yOut, hstep, yMid, derivs[0]);
fMidpointMethod.SetSteps(interval_sequence[1]);
fMidpointMethod.DoStep(yIn, dydx, yOut2, hstep, yMid2, derivs[1]);
//extrapolation
static const G4double coeff =
1. / (sqr(static_cast<G4double>(interval_sequence[1]) /
static_cast<G4double>(interval_sequence[0])) - 1.);
for (G4int i = 0; i < nvar; ++i) {
yOut[i] = yOut2[i] + (yOut2[i] - yOut[i]) * coeff;
yMid[i] = yMid2[i] + (yMid2[i] - yMid[i]) * coeff;
}
//calc chord lenght
const auto mid = field_utils::makeVector(yMid, field_utils::Value3D::Position);
const auto in = field_utils::makeVector(yIn, field_utils::Value3D::Position);
const auto out = field_utils::makeVector(yOut, field_utils::Value3D::Position);
missDist = G4LineSection::Distline(mid, in, out);
//calc error
for (G4int i = 0; i < nvar; ++i){
yError[i] = yOut[i] - yOut2[i];
}
dyerr = hstep * field_utils::relativeError(yOut, yError, hstep);
//copy non-integrated variables to output array
memcpy(yOut + nvar,
yIn + nvar,
sizeof(G4double) * (G4FieldTrack::ncompSVEC - nvar));
//set new state
track.LoadFromArray(yOut, G4FieldTrack::ncompSVEC);
track.SetCurveLength(curveLength + hstep);
return true;
}
void G4IntegrationDriver<G4BulirschStoer>::OneGoodStep(
G4double y[],
const G4double dydx[],
G4double& curveLength,
G4double htry,
G4double eps,
G4double& hdid,
G4double& hnext)
{
hnext = htry;
G4double curveLengthBegin = curveLength;
// set maximum allowed error
bulirschStoer->set_max_relative_error(eps);
while (true) {
auto res = bulirschStoer->try_step(y, dydx, curveLength, yOut, hnext);
if (res == G4BulirschStoer::step_result::success) {
break;
}
}
memcpy(y, yOut, sizeof(G4double) * GetNumberOfVarialbles());
hdid = curveLength - curveLengthBegin;
}
void G4IntegrationDriver<G4BulirschStoer>::GetDerivatives(
const G4FieldTrack& track,
G4double dydx[]) const
{
G4double y[G4FieldTrack::ncompSVEC];
track.DumpToArray(y);
GetEquationOfMotion()->RightHandSide(y, dydx);
}
void G4IntegrationDriver<G4BulirschStoer>::SetVerboseLevel(G4int level)
{
fVerbosity = level;
}
G4int G4IntegrationDriver<G4BulirschStoer>::GetVerboseLevel() const
{
return fVerbosity;
}
G4double G4IntegrationDriver<G4BulirschStoer>::ComputeNewStepSize(
G4double /* errMaxNorm*/,
G4double hstepCurrent)
{
return hstepCurrent;
}
G4EquationOfMotion* G4IntegrationDriver<G4BulirschStoer>::GetEquationOfMotion()
{
assert(bulirschStoer->GetEquationOfMotion() ==
fMidpointMethod.GetEquationOfMotion());
return bulirschStoer->GetEquationOfMotion();
}
const G4EquationOfMotion* G4IntegrationDriver<G4BulirschStoer>::GetEquationOfMotion() const
{
return const_cast<G4IntegrationDriver<G4BulirschStoer>*>(this)->
GetEquationOfMotion();
}
void G4IntegrationDriver<G4BulirschStoer>::SetEquationOfMotion(
G4EquationOfMotion* equation)
{
bulirschStoer->SetEquationOfMotion(equation);
fMidpointMethod.SetEquationOfMotion(equation);
}
G4int G4IntegrationDriver<G4BulirschStoer>::GetNumberOfVarialbles() const
{
assert(bulirschStoer->GetNumberOfVariables() ==
fMidpointMethod.GetNumberOfVariables());
return bulirschStoer->GetNumberOfVariables();
}
const G4MagIntegratorStepper* G4IntegrationDriver<G4BulirschStoer>::GetStepper() const
{
return nullptr;
}
G4MagIntegratorStepper* G4IntegrationDriver<G4BulirschStoer>::GetStepper()
{
return nullptr;
}
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4FSALIntegrationDriver.hh 107164 2017-11-03 12:11:45Z gcosmo $
// $Id: G4FSALIntegrationDriver.hh 109569 2018-05-02 07:08:33Z gcosmo $
//
//
// class G4FSALIntegrationDriver
@@ -106,10 +106,12 @@ public:
G4double GetPshrnk() const;
G4double GetPgrow() const;
virtual void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper) override;
// Sets a new stepper pItsStepper for this driver. Then it calls
// ReSetParameters to reset its parameters accordingly.
void RenewStepperAndAdjust(T *pItsStepper);
inline void RenewStepperAndAdjustStrict(T *pItsStepper);
// i) sets the exponents (pgrow & pshrnk),
// using the current Stepper's order,
// ii) sets the safety
@@ -160,7 +162,7 @@ private:
// The (default) maximum number of steps is Base
// divided by the order of Stepper
static constexpr G4int fMaxStepBase = 250;
G4int fMaxStepBase;
// Parameters used to grow and shrink trial stepsize.
G4double safety;
@@ -171,10 +173,6 @@ private:
G4double errorConstraintShrink;
G4double errorConstraintGrow;
// Maximum stepsize increase/decrease factors.
static constexpr G4double max_stepping_increase = 5;
static constexpr G4double max_stepping_decrease = 0.1;
T* pIntStepper;
// Step Statistics
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4FSALIntegrationDriver.icc 107495 2017-11-16 13:51:06Z gcosmo $
// $Id: G4FSALIntegrationDriver.icc 110753 2018-06-12 15:44:03Z gcosmo $
//
//
// class G4FSALIntegrationDriver
@@ -47,11 +47,9 @@
template <class T>
G4FSALIntegrationDriver<T>::G4FSALIntegrationDriver (
G4double hminimum,
T* pStepper,
G4int numComponents,
G4int statisticsVerbose)
G4FSALIntegrationDriver<T>::
G4FSALIntegrationDriver ( G4double hminimum, T* pStepper,
G4int numComponents, G4int statisticsVerbose )
: fSmallestFraction(1e-12),
fNoTotalSteps(0),
fNoBadSteps(0),
@@ -59,24 +57,31 @@ G4FSALIntegrationDriver<T>::G4FSALIntegrationDriver (
fVerboseLevel(statisticsVerbose),
fNoQuickAvanceCalls(0)
{
if (numComponents != pStepper->GetNumberOfVariables()) {
if (numComponents != pStepper->GetNumberOfVariables())
{
std::ostringstream message;
message << "Driver's number of integrated components " << numComponents
<< " != Stepper's number of components " << pStepper->GetNumberOfVariables();
G4Exception("G4FSALIntegrationDriver","001", FatalException, message);
message << "Driver's number of integrated components "
<< numComponents
<< " != Stepper's number of components "
<< pStepper->GetNumberOfVariables();
G4Exception("G4FSALIntegrationDriver","GeomField0002",
FatalException, message);
}
RenewStepperAndAdjust(pStepper);
fMinimumStep = hminimum;
fMaxStepBase = 250;
fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
}
template <class T>
G4FSALIntegrationDriver<T>::~G4FSALIntegrationDriver()
{
if( fVerboseLevel > 0 )
G4cout << "G4FSALIntegration Driver Stats: "
<< "#QuickAdvance " << fNoQuickAvanceCalls
<< " #AccurateAdvance " << fNoTotalSteps << G4endl;
#ifdef G4VERBOSE
if( fVerboseLevel > 0 )
G4cout << "G4FSALIntegration Driver Stats: "
<< "#QuickAdvance " << fNoQuickAvanceCalls
<< " - #AccurateAdvance " << fNoTotalSteps << G4endl;
#endif
}
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
@@ -85,13 +90,12 @@ G4FSALIntegrationDriver<T>::~G4FSALIntegrationDriver()
// interval. RightHandSide is the right-hand side of ODE system.
// The source is similar to odeint routine from NRC p.721-722 .
template <class T>
G4bool G4FSALIntegrationDriver<T>::AccurateAdvance(
G4FieldTrack& track,
G4double hstep,
G4double eps,
G4double hinitial)
G4bool G4FSALIntegrationDriver<T>::
AccurateAdvance( G4FieldTrack& track, G4double hstep,
G4double eps, G4double hinitial )
{
if (hstep < GetMinimumStep()) {
if (hstep < GetMinimumStep())
{
G4double dchord_step = 0, dyerr = 0;
G4double dydx[G4FieldTrack::ncompSVEC];
GetDerivatives(track, dydx);
@@ -113,13 +117,15 @@ G4bool G4FSALIntegrationDriver<T>::AccurateAdvance(
G4double h = hstep;
if (hinitial > perMillion * hstep && hinitial < hstep) {
if (hinitial > perMillion * hstep && hinitial < hstep)
{
h = hinitial;
}
pIntStepper->RightHandSide(y, dydx);
for (G4int iter = 0; iter < fMaxNoSteps; ++iter) {
for (G4int iter = 0; iter < fMaxNoSteps; ++iter)
{
const G4ThreeVector StartPos =
field_utils::makeVector(y, field_utils::Value3D::Position);
@@ -131,16 +137,17 @@ G4bool G4FSALIntegrationDriver<T>::AccurateAdvance(
CheckStep(EndPos, StartPos, hdid);
G4double restCurveLength = endCurveLength - curveLength;
if (restCurveLength < GetSmallestFraction() * hstep) {
if (restCurveLength < GetSmallestFraction() * hstep)
{
succeeded = true;
break;
}
h = std::min(hnext, restCurveLength);
}
if (succeeded) {
if (succeeded)
{
track.LoadFromArray(y, pIntStepper->GetNumberOfVariables());
track.SetCurveLength(track.GetCurveLength() + curveLength);
}
@@ -150,9 +157,11 @@ G4bool G4FSALIntegrationDriver<T>::AccurateAdvance(
// Step failed; compute the size of retrial Step.
template <class T>
G4double G4FSALIntegrationDriver<T>::ShrinkStepSize(G4double h, G4double error) const
G4double G4FSALIntegrationDriver<T>::
ShrinkStepSize(G4double h, G4double error) const
{
if (error > errorConstraintShrink) {
if (error > errorConstraintShrink)
{
return max_stepping_decrease * h;
}
return GetSafety() * h * std::pow(error, GetPshrnk());
@@ -160,7 +169,8 @@ G4double G4FSALIntegrationDriver<T>::ShrinkStepSize(G4double h, G4double error)
// Compute size of next Step
template<class T>
G4double G4FSALIntegrationDriver<T>::GrowStepSize(G4double h, G4double error) const
G4double G4FSALIntegrationDriver<T>::
GrowStepSize(G4double h, G4double error) const
{
if (error < errorConstraintGrow) {
return max_stepping_increase * h;
@@ -180,15 +190,14 @@ G4double G4FSALIntegrationDriver<T>::GrowStepSize(G4double h, G4double error) co
// Edition, by William H. Press, Saul A. Teukolsky, William T.
// Vetterling, and Brian P. Flannery (Cambridge University Press 1992),
// 16.2 Adaptive StepSize Control for Runge-Kutta, p. 719
//
template <class T>
void G4FSALIntegrationDriver<T>::OneGoodStep(
G4double y[],
G4double dydx[],
G4double& curveLength, // InOut
G4double htry,
G4double eps_rel_max,
G4double& hdid, // Out
G4double& hnext) // Out
void G4FSALIntegrationDriver<T>::
OneGoodStep( G4double y[], G4double dydx[],
G4double& curveLength, // InOut
G4double htry, G4double eps_rel_max,
G4double& hdid, // Out
G4double& hnext ) // Out
{
G4double error = DBL_MAX;
@@ -202,16 +211,15 @@ void G4FSALIntegrationDriver<T>::OneGoodStep(
static G4ThreadLocal G4int tot_no_trials = 0;
const G4int max_trials = 100;
for (G4int iter = 0; iter < max_trials; ++iter) {
for (G4int iter = 0; iter < max_trials; ++iter)
{
++tot_no_trials;
pIntStepper->Stepper(y, dydx, hstep, yOut, yError, dydxOut);
error = field_utils::relativeError(y, yError, hstep, eps_rel_max);
// Step succeeded.
if (error <= 1) {
break;
}
if (error <= 1) break;
hstep = ShrinkStepSize(hstep, error);
}
@@ -219,33 +227,34 @@ void G4FSALIntegrationDriver<T>::OneGoodStep(
hnext = GrowStepSize(hstep, error);
curveLength += (hdid = hstep);
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k) {
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k)
{
y[k] = yOut[k];
dydx[k] = dydxOut[k];
}
}
template <class T>
G4bool G4FSALIntegrationDriver<T>::QuickAdvance(
G4FieldTrack& fieldTrack,
const G4double dydxIn[],
G4double hstep,
G4double& dchord_step,
G4double& dyerr)
G4bool G4FSALIntegrationDriver<T>::
QuickAdvance( G4FieldTrack& fieldTrack, const G4double dydxIn[],
G4double hstep, G4double& dchord_step, G4double& dyerr )
{
++fNoQuickAvanceCalls;
if (hstep == 0) {
if (hstep == 0)
{
std::ostringstream message;
message << "Proposed step is zero; hstep = " << hstep << " !";
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
"GeomField1001", JustWarning, message);
return true;
}
if (hstep < 0) {
if (hstep < 0)
{
std::ostringstream message;
message << "Invalid run condition." << G4endl
<< "Proposed step is negative; hstep = " << hstep << "." << G4endl
<< "Proposed step is negative; hstep = "
<< hstep << "." << G4endl
<< "Requested step cannot be negative! Aborting event.";
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
"GeomField0003", EventMustBeAborted, message);
@@ -271,18 +280,21 @@ G4bool G4FSALIntegrationDriver<T>::QuickAdvance(
}
template <class T>
G4double G4FSALIntegrationDriver<T>::ComputeNewStepSize(
G4double errMaxNorm, // max error (normalised)
G4double hstepCurrent) // current step size
G4double G4FSALIntegrationDriver<T>::
ComputeNewStepSize( G4double errMaxNorm, // max error (normalised)
G4double hstepCurrent ) // current step size
{
if (errMaxNorm > 1) {
if (errMaxNorm > 1)
{
return ShrinkStepSize(hstepCurrent, errMaxNorm);
} else if(errMaxNorm >= 0) {
}
else if(errMaxNorm >= 0)
{
return GrowStepSize(hstepCurrent, errMaxNorm);
}
G4Exception("G4FSALIntegrationDriver::ConputeNewStepSize", "Field002",
FatalException, "error is negative");
G4Exception("G4FSALIntegrationDriver::ConputeNewStepSize", "GeomField0003",
FatalException, "Error is negative!");
return max_stepping_increase * hstepCurrent;
}
@@ -290,12 +302,18 @@ G4double G4FSALIntegrationDriver<T>::ComputeNewStepSize(
template <class T>
void G4FSALIntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
{
if( newFraction > 1.e-16 && newFraction < 1e-8 ) {
if( newFraction > 1.e-16 && newFraction < 1e-8 )
{
fSmallestFraction = newFraction;
} else {
G4cerr << "Warning: SmallestFraction not changed. " << G4endl
<< " Proposed value was " << newFraction << G4endl
<< " Value must be between 1.e-8 and 1.e-16" << G4endl;
}
else
{
std::ostringstream message;
message << "Smallest Fraction not changed. " << G4endl
<< " Proposed value was " << newFraction << G4endl
<< " Value must be between 1.e-8 and 1.e-16";
G4Exception("G4FSALIntegrationDriver::SetSmallestFraction()",
"GeomField1001", JustWarning, message);
}
}
@@ -315,14 +333,22 @@ void G4FSALIntegrationDriver<T>::CheckStep(
++fNoTotalSteps;
const G4double endPointDist = (posOut - posIn).mag();
if (endPointDist >= hdid * (1. + perMillion)) {
if (endPointDist >= hdid * (1. + perMillion))
{
++fNoBadSteps;
#ifdef G4DEBUG_FIELD
// Issue a warning only for gross differences -
// we understand how small difference occur.
if (endPointDist >= hdid * (1. + perThousand)){
G4cout << "WARNING: endPointDist >= hdid!" << G4endl;
if (endPointDist >= hdid * (1. + perThousand))
{
G4Exception("G4FSALIntegrationDriver::CheckStep()",
"GeomField1002", JustWarning,
"endPointDist >= hdid!");
}
} else {
#endif
}
else
{
++fNoGoodSteps;
}
}
@@ -384,10 +410,27 @@ void G4FSALIntegrationDriver<T>::SetSafety(G4double val)
}
template <class T>
void G4FSALIntegrationDriver<T>::RenewStepperAndAdjust(T* stepper)
void G4FSALIntegrationDriver<T>::
RenewStepperAndAdjust(G4MagIntegratorStepper* stepper)
{
pIntStepper = stepper;
ReSetParameters();
T* ourStepper= dynamic_cast<T*>(stepper);
if ( ourStepper )
{
RenewStepperAndAdjustStrict( ourStepper );
}
else
{
G4Exception("G4FSALIntegrationDriver::RenewStepperAndAdjust()",
"GeomField0002", FatalException,
"The type of the stepper provided is incorrect for this templated driver");
}
}
template <class T>
void G4FSALIntegrationDriver<T>::RenewStepperAndAdjustStrict(T* stepper)
{
pIntStepper = stepper;
ReSetParameters();
}
template <class T>
@@ -454,7 +497,8 @@ G4EquationOfMotion* G4FSALIntegrationDriver<T>::GetEquationOfMotion()
}
template <class T>
void G4FSALIntegrationDriver<T>::SetEquationOfMotion(G4EquationOfMotion* equation)
void G4FSALIntegrationDriver<T>::
SetEquationOfMotion(G4EquationOfMotion* equation)
{
pIntStepper->SetEquationOfMotion(equation);
}
@@ -102,9 +102,11 @@ public:
G4double GetPshrnk() const;
G4double GetPgrow() const;
virtual void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper) override;
// Sets a new stepper pItsStepper for this driver. Then it calls
// ReSetParameters to reset its parameters accordingly.
void RenewStepperAndAdjust(T *pItsStepper);
inline void RenewStepperAndAdjustStrict(T *pItsStepper);
// i) sets the exponents (pgrow & pshrnk),
// using the current Stepper's order,
@@ -154,7 +156,7 @@ private:
// The (default) maximum number of steps is Base
// divided by the order of Stepper
static constexpr G4int fMaxStepBase = 250;
G4int fMaxStepBase;
// Parameters used to grow and shrink trial stepsize.
G4double safety;
@@ -165,10 +167,6 @@ private:
G4double errorConstraintShrink;
G4double errorConstraintGrow;
// Maximum stepsize increase/decrease factors.
static constexpr G4double max_stepping_increase = 5;
static constexpr G4double max_stepping_decrease = 0.1;
T* pIntStepper;
// Step Statistics
@@ -48,11 +48,9 @@
template <class T>
G4IntegrationDriver<T>::G4IntegrationDriver (
G4double hminimum,
T* pStepper,
G4int numComponents,
G4int statisticsVerbose)
G4IntegrationDriver<T>::
G4IntegrationDriver ( G4double hminimum, T* pStepper,
G4int numComponents, G4int statisticsVerbose )
: fSmallestFraction(1e-12),
fNoTotalSteps(0),
fNoBadSteps(0),
@@ -60,23 +58,32 @@ G4IntegrationDriver<T>::G4IntegrationDriver (
fVerboseLevel(statisticsVerbose),
fNoQuickAvanceCalls(0)
{
if (numComponents != pStepper->GetNumberOfVariables()) {
if (numComponents != pStepper->GetNumberOfVariables())
{
std::ostringstream message;
message << "Driver's number of integrated components " << numComponents
<< " != Stepper's number of components " << pStepper->GetNumberOfVariables();
G4Exception("G4IntegrationDriver","001", FatalException, message);
message << "Driver's number of integrated components "
<< numComponents
<< " != Stepper's number of components "
<< pStepper->GetNumberOfVariables();
G4Exception("G4IntegrationDriver","GeomField0002",
FatalException, message);
}
RenewStepperAndAdjust(pStepper);
RenewStepperAndAdjustStrict(pStepper);
fMinimumStep = hminimum;
fMaxStepBase = 250;
fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
}
template <class T>
G4IntegrationDriver<T>::~G4IntegrationDriver()
{
#ifdef G4VERBOSE
if( fVerboseLevel > 0 )
G4cout << "G4Integration Driver Stats: #QuickAdvance " << fNoQuickAvanceCalls
<< " #AccurateAdvance " << fNoTotalSteps << G4endl;
G4cout << "G4Integration Driver Stats: "
<< "#QuickAdvance " << fNoQuickAvanceCalls
<< " - #AccurateAdvance " << fNoTotalSteps << G4endl;
#endif
delete pIntStepper;
}
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
@@ -84,14 +91,14 @@ G4IntegrationDriver<T>::~G4IntegrationDriver()
// On output ystart is replaced by values at the end of the integration
// interval. RightHandSide is the right-hand side of ODE system.
// The source is similar to odeint routine from NRC p.721-722 .
//
template <class T>
G4bool G4IntegrationDriver<T>::AccurateAdvance(
G4FieldTrack& track,
G4double hstep,
G4double eps,
G4double hinitial)
G4bool G4IntegrationDriver<T>::
AccurateAdvance( G4FieldTrack& track, G4double hstep,
G4double eps, G4double hinitial )
{
if (hstep < GetMinimumStep()) {
if (hstep < GetMinimumStep())
{
G4double dchord_step = 0, dyerr = 0;
G4double dydx[G4FieldTrack::ncompSVEC];
GetDerivatives(track, dydx);
@@ -109,7 +116,8 @@ G4bool G4IntegrationDriver<T>::AccurateAdvance(
G4double endCurveLength = hstep;
G4double h = hstep;
if (hinitial > perMillion * hstep && hinitial < hstep) {
if (hinitial > perMillion * hstep && hinitial < hstep)
{
h = hinitial;
}
@@ -127,7 +135,8 @@ G4bool G4IntegrationDriver<T>::AccurateAdvance(
CheckStep(EndPos, StartPos, hdid);
G4double restCurveLength = endCurveLength - curveLength;
if (restCurveLength < GetSmallestFraction() * hstep) {
if (restCurveLength < GetSmallestFraction() * hstep)
{
succeeded = true;
break;
}
@@ -135,7 +144,8 @@ G4bool G4IntegrationDriver<T>::AccurateAdvance(
h = std::min(hnext, restCurveLength);
}
if (succeeded) {
if (succeeded)
{
track.LoadFromArray(y, pIntStepper->GetNumberOfVariables());
track.SetCurveLength(track.GetCurveLength() + curveLength);
}
@@ -144,20 +154,23 @@ G4bool G4IntegrationDriver<T>::AccurateAdvance(
}
// Step failed; compute the size of retrial Step.
template <class T>
G4double G4IntegrationDriver<T>::ShrinkStepSize(G4double h, G4double error) const
template <class T> G4double G4IntegrationDriver<T>::
ShrinkStepSize(G4double h, G4double error) const
{
if (error > errorConstraintShrink) {
if (error > errorConstraintShrink)
{
return max_stepping_decrease * h;
}
return GetSafety() * h * std::pow(error, GetPshrnk());
}
// Compute size of next Step
template<class T>
G4double G4IntegrationDriver<T>::GrowStepSize(G4double h, G4double error) const
//
template<class T> G4double G4IntegrationDriver<T>::
GrowStepSize(G4double h, G4double error) const
{
if (error < errorConstraintGrow) {
if (error < errorConstraintGrow)
{
return max_stepping_increase * h;
}
return GetSafety() * h * std::pow(error, GetPgrow());
@@ -175,15 +188,14 @@ G4double G4IntegrationDriver<T>::GrowStepSize(G4double h, G4double error) const
// Edition, by William H. Press, Saul A. Teukolsky, William T.
// Vetterling, and Brian P. Flannery (Cambridge University Press 1992),
// 16.2 Adaptive StepSize Control for Runge-Kutta, p. 719
//
template <class T>
void G4IntegrationDriver<T>::OneGoodStep(
G4double y[],
const G4double dydx[],
G4double& curveLength, // InOut
G4double htry,
G4double eps_rel_max,
G4double& hdid, // Out
G4double& hnext) // Out
void G4IntegrationDriver<T>::
OneGoodStep( G4double y[], const G4double dydx[],
G4double& curveLength, // InOut
G4double htry, G4double eps_rel_max,
G4double& hdid, // Out
G4double& hnext) // Out
{
G4double error = DBL_MAX;
@@ -195,16 +207,15 @@ void G4IntegrationDriver<T>::OneGoodStep(
static G4ThreadLocal G4int tot_no_trials = 0;
const G4int max_trials = 100;
for (G4int iter = 0; iter < max_trials; ++iter) {
for (G4int iter = 0; iter < max_trials; ++iter)
{
++tot_no_trials;
pIntStepper->Stepper(y, dydx, hstep, ytemp, yerror);
error = field_utils::relativeError(y, yerror, hstep, eps_rel_max);
// Step succeeded.
if (error <= 1) {
break;
}
if (error <= 1) break;
hstep = ShrinkStepSize(hstep, error);
}
@@ -212,32 +223,33 @@ void G4IntegrationDriver<T>::OneGoodStep(
hnext = GrowStepSize(hstep, error);
curveLength += (hdid = hstep);
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k) {
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k)
{
y[k] = ytemp[k];
}
}
template <class T>
G4bool G4IntegrationDriver<T>::QuickAdvance(
G4FieldTrack& fieldTrack,
const G4double dydx[],
G4double hstep,
G4double& dchord_step,
G4double& dyerr)
G4bool G4IntegrationDriver<T>::
QuickAdvance( G4FieldTrack& fieldTrack, const G4double dydx[],
G4double hstep, G4double& dchord_step, G4double& dyerr )
{
++fNoQuickAvanceCalls;
if (hstep == 0) {
if (hstep == 0)
{
std::ostringstream message;
message << "Proposed step is zero; hstep = " << hstep << " !";
G4Exception("G4IntegrationDriver ::QuickAdvance()",
"GeomField1001", JustWarning, message);
"GeomField1001", JustWarning, message);
return true;
}
if (hstep < 0) {
if (hstep < 0)
{
std::ostringstream message;
message << "Invalid run condition." << G4endl
<< "Proposed step is negative; hstep = " << hstep << "." << G4endl
<< "Proposed step is negative; hstep = "
<< hstep << "." << G4endl
<< "Requested step cannot be negative! Aborting event.";
G4Exception("G4IntegrationDriver ::QuickAdvance()",
"GeomField0003", EventMustBeAborted, message);
@@ -262,18 +274,21 @@ G4bool G4IntegrationDriver<T>::QuickAdvance(
}
template <class T>
G4double G4IntegrationDriver<T>::ComputeNewStepSize(
G4double errMaxNorm, // max error (normalised)
G4double hstepCurrent) // current step size
G4double G4IntegrationDriver<T>::
ComputeNewStepSize( G4double errMaxNorm, // max error (normalised)
G4double hstepCurrent ) // current step size
{
if (errMaxNorm > 1) {
if (errMaxNorm > 1)
{
return ShrinkStepSize(hstepCurrent, errMaxNorm);
} else if (errMaxNorm >= 0) {
}
else if (errMaxNorm >= 0)
{
return GrowStepSize(hstepCurrent, errMaxNorm);
}
G4Exception("G4IntegrationDriver::ConputeNewStepSize", "Field002",
FatalException, "error is negative");
G4Exception("G4IntegrationDriver::ConputeNewStepSize", "GeomField0003",
FatalException, "Error is negative!");
return max_stepping_increase * hstepCurrent;
}
@@ -281,18 +296,24 @@ G4double G4IntegrationDriver<T>::ComputeNewStepSize(
template <class T>
void G4IntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
{
if( newFraction > 1.e-16 && newFraction < 1e-8 ) {
if( newFraction > 1.e-16 && newFraction < 1e-8 )
{
fSmallestFraction = newFraction;
} else {
G4cerr << "Warning: SmallestFraction not changed. " << G4endl
<< " Proposed value was " << newFraction << G4endl
<< " Value must be between 1.e-8 and 1.e-16" << G4endl;
}
else
{
std::ostringstream message;
message << "Smallest Fraction not changed. " << G4endl
<< " Proposed value was " << newFraction << G4endl
<< " Value must be between 1.e-8 and 1.e-16";
G4Exception("G4IntegrationDriver::SetSmallestFraction()",
"GeomField1001", JustWarning, message);
}
}
template <class T>
void G4IntegrationDriver<T>::GetDerivatives(
const G4FieldTrack& track, G4double dydx[]) const
void G4IntegrationDriver<T>::
GetDerivatives( const G4FieldTrack& track, G4double dydx[] ) const
{
G4double y[G4FieldTrack::ncompSVEC];
track.DumpToArray(y);
@@ -300,20 +321,29 @@ void G4IntegrationDriver<T>::GetDerivatives(
}
template <class T>
void G4IntegrationDriver<T>::CheckStep(
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid)
void G4IntegrationDriver<T>::
CheckStep( const G4ThreeVector& posIn,
const G4ThreeVector& posOut, G4double hdid)
{
++fNoTotalSteps;
const G4double endPointDist = (posOut - posIn).mag();
if (endPointDist >= hdid * (1. + perMillion)) {
if (endPointDist >= hdid * (1. + perMillion))
{
++fNoBadSteps;
#ifdef G4DEBUG_FIELD
// Issue a warning only for gross differences -
// we understand how small difference occur.
if (endPointDist >= hdid * (1. + perThousand)){
G4cout << "WARNING: endPointDist >= hdid!" << G4endl;
if (endPointDist >= hdid * (1. + perThousand))
{
G4Exception("G4IntegrationDriver::CheckStep()",
"GeomField1002", JustWarning,
"endPointDist >= hdid!");
}
} else {
#endif
}
else
{
++fNoGoodSteps;
}
}
@@ -374,11 +404,27 @@ void G4IntegrationDriver<T>::SetSafety(G4double val)
UpdateErrorConstraints();
}
template <class T>
void G4IntegrationDriver<T>::RenewStepperAndAdjust(T* stepper)
template <class T> void G4IntegrationDriver<T>::
RenewStepperAndAdjust(G4MagIntegratorStepper* stepper)
{
pIntStepper = stepper;
ReSetParameters();
T* ourStepper= dynamic_cast<T*>(stepper);
if ( ourStepper )
{
RenewStepperAndAdjustStrict( ourStepper );
}
else
{
G4Exception("G4IntegrationDriver::RenewStepperAndAdjust()",
"GeomField0002", FatalException,
"The type of the stepper provided is incorrect for this templated driver");
}
}
template <class T>
void G4IntegrationDriver<T>::RenewStepperAndAdjustStrict(T* stepper)
{
pIntStepper = stepper;
ReSetParameters();
}
template <class T>
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4MagIntegratorDriver.hh 107059 2017-11-01 14:58:16Z gcosmo $
// $Id: G4MagIntegratorDriver.hh 109569 2018-05-02 07:08:33Z gcosmo $
//
//
// class G4MagInt_Driver
@@ -100,7 +100,7 @@ public: // with description
virtual G4EquationOfMotion* GetEquationOfMotion() override;
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
inline void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper);
virtual void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper) override;
// Sets a new stepper pItsStepper for this driver. Then it calls
// ReSetParameters to reset its parameters accordingly.
@@ -218,7 +218,7 @@ private:
const G4int fNoVars; // Full number of variable
G4int fMaxNoSteps;
static const G4int fMaxStepBase;
G4int fMaxStepBase;
G4double safety;
G4double pshrnk; // exponent for shrinking
@@ -226,10 +226,6 @@ private:
G4double errcon;
// Parameters used to grow and shrink trial stepsize.
static const G4double max_stepping_increase;
static const G4double max_stepping_decrease;
// Maximum stepsize increase/decrease factors.
G4int fStatisticsVerboseLevel;
// ---------------------------------------------------------------
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4MagIntegratorDriver.icc 107059 2017-11-01 14:58:16Z gcosmo $
// $Id: G4MagIntegratorDriver.icc 109569 2018-05-02 07:08:33Z gcosmo $
//
// --------------------------------------------------------------------
@@ -106,13 +106,6 @@ void G4MagInt_Driver::SetErrcon(G4double val)
errcon=val;
}
inline
void G4MagInt_Driver::RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper)
{
pIntStepper = pItsStepper;
ReSetParameters();
}
inline
G4int G4MagInt_Driver::GetMaxNoSteps() const
{
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4MagneticField.hh 66356 2012-12-18 09:02:32Z gcosmo $
// $Id: G4MagneticField.hh 108823 2018-03-09 11:03:44Z gcosmo $
//
//
// class G4MagneticField
@@ -41,9 +41,9 @@
#define G4MAGNETIC_FIELD_DEF
#include "G4Types.hh"
#include "G4ElectroMagneticField.hh"
#include "G4Field.hh"
class G4MagneticField : public G4ElectroMagneticField
class G4MagneticField : public G4Field
{
public: // with description
@@ -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. *
// ********************************************************************
//
//
// $Id: $
//
//
// Description:
// Modified midpoint method implementation
// Implementation is based on modified_midpoint.hpp from boost odeint
// Implementation by Dmitry Sorokin - GSoC 2016
// Work supported by Google as part of Google Summer of Code 2016.
// Supervision / code review: John Apostolakis
//
///////////////////////////////////////////////////////////////////////////////
#ifndef G4MODIFIED_MIDPOINT_HH
#define G4MODIFIED_MIDPOINT_HH
#include "G4Types.hh"
#include "G4EquationOfMotion.hh"
#include "G4FieldTrack.hh"
class G4ModifiedMidpoint
{
public:
G4ModifiedMidpoint( G4EquationOfMotion* equation,
G4int nvar = 6, G4int steps = 2 );
~G4ModifiedMidpoint() = default;
void DoStep( const G4double yIn[], const G4double dydxIn[],
G4double yOut[], G4double hstep) const;
void DoStep( const G4double yIn[], const G4double dydxIn[],
G4double yOut[], G4double hstep, G4double yMid[],
G4double derivs[][G4FieldTrack::ncompSVEC]) const;
inline void SetSteps(G4int steps);
inline G4int GetSteps() const;
inline void SetEquationOfMotion(G4EquationOfMotion* equation);
inline G4EquationOfMotion* GetEquationOfMotion();
inline G4int GetNumberOfVariables() const;
private:
void copy(G4double dst[], const G4double src[]) const;
private:
G4EquationOfMotion* fEquation;
G4int fnvar;
G4int fsteps;
};
#include "G4ModifiedMidpoint.icc"
#endif
@@ -0,0 +1,49 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
inline void G4ModifiedMidpoint::SetSteps(G4int steps)
{
fsteps = steps;
}
inline G4int G4ModifiedMidpoint::GetSteps() const
{
return fsteps;
}
inline void G4ModifiedMidpoint::SetEquationOfMotion(G4EquationOfMotion* equation)
{
fEquation = equation;
}
inline G4EquationOfMotion* G4ModifiedMidpoint::GetEquationOfMotion()
{
return fEquation;
}
inline G4int G4ModifiedMidpoint::GetNumberOfVariables() const
{
return fnvar;
}
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4UniformMagField.hh 96751 2016-05-04 09:39:38Z gcosmo $
// $Id: G4UniformMagField.hh 110759 2018-06-13 06:23:20Z gcosmo $
//
//
// class G4UniformMagField
@@ -57,21 +57,21 @@ class G4UniformMagField : public G4MagneticField
G4double vTheta,
G4double vPhi ) ;
virtual ~G4UniformMagField() ;
virtual ~G4UniformMagField() override;
G4UniformMagField(const G4UniformMagField &p);
G4UniformMagField& operator = (const G4UniformMagField &p);
// Copy constructor and assignment operator.
virtual void GetFieldValue(const G4double yTrack[4],
G4double *MagField) const ;
void GetFieldValue(const G4double yTrack[4],
G4double *MagField) const override final;
void SetFieldValue(const G4ThreeVector& newFieldValue);
G4ThreeVector GetConstantFieldValue() const;
// Return the field value
virtual G4Field* Clone() const;
G4Field* Clone() const override final;
private:
@@ -53,7 +53,8 @@
class G4VIntegrationDriver {
public:
G4VIntegrationDriver() = default;
G4VIntegrationDriver()
: max_stepping_increase(5), max_stepping_decrease(0.1) {};
virtual ~G4VIntegrationDriver() = default;
G4VIntegrationDriver(const G4VIntegrationDriver&) = delete;
@@ -80,6 +81,9 @@ public:
virtual const G4MagIntegratorStepper* GetStepper() const = 0;
virtual G4MagIntegratorStepper* GetStepper() = 0;
// Method for compatibility -- relevant only for G4MagIntegratorDriver
virtual void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper);
// Taking the last step's normalised error, calculate
// a step size for the next step.
// Do not limit the next step's size within a factor of the
@@ -89,6 +93,12 @@ public:
virtual void SetVerboseLevel(G4int level) = 0;
virtual G4int GetVerboseLevel() const = 0;
protected:
G4double max_stepping_increase;
G4double max_stepping_decrease;
};
#endif