Import Geant4 10.5.0.beta source tree
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user