38const G4double G4BorisDriver::fErrorConstraintShrink = std::pow(
39 fMaxSteppingDecrease / fSafetyFactor, 1. / fPowerShrink);
41const G4double G4BorisDriver::fErrorConstraintGrow = std::pow(
42 fMaxSteppingIncrease / fSafetyFactor, 1. / fPowerGrow);
49 : fMinimumStep(hminimum),
50 fVerbosity(verbosity),
54 assert(boris->GetNumberOfVariables() == numberOfComponents);
56 if(boris->GetNumberOfVariables() != numberOfComponents)
58 std::ostringstream msg;
59 msg <<
"Disagreement in number of variables = "
60 << boris->GetNumberOfVariables()
61 <<
" vs no of components = " << numberOfComponents;
82 std::ostringstream message;
83 message <<
"Proposed step is zero; hstep = " << hstep <<
" !";
90 std::ostringstream message;
91 message <<
"Invalid run condition." <<
G4endl
92 <<
"Proposed step is negative; hstep = " << hstep <<
G4endl
93 <<
"Requested step cannot be negative! Aborting event.";
99 if( hinitial == 0.0 ) { hinitial = hstep; }
100 if( hinitial < 0.0 ) { hinitial = std::fabs( hinitial ); }
113 const G4int nvar= GetNumberOfVariables();
117 std::memcpy(yOut + nvar,
122 const G4double endCurveLength = curveLength + hstep;
132 std::max(
epsilon * hstep, fSmallestFraction * curveLength);
136 for (
G4int nstp = 0; nstp < fMaxNoSteps; ++nstp)
146 CheckStep(EndPos, StartPos, hdid);
149 if (curveLength >= endCurveLength || htry < hThreshold)
154 htry = std::max(hnext, fMinimumStep);
155 if (curveLength + htry > endCurveLength)
157 htry = endCurveLength - curveLength;
184 const G4int max_trials = 100;
186 for (
G4int iter = 0; iter < max_trials; ++iter)
188 boris->StepWithErrorEstimate(y, restMass, charge, h, ytemp, yerr);
200 if(xnew == curveLength)
202 std::ostringstream message;
203 message <<
"Stepsize underflow in Stepper !" <<
G4endl
204 <<
"- Step's start x=" << curveLength
205 <<
" and end x= " << xnew
206 <<
" are equal !! " <<
G4endl
207 <<
" Due to step-size= " << h
208 <<
". Note that input step was " << htry;
216 curveLength += (hdid = h);
227 const auto nvar = boris->GetNumberOfVariables();
238 boris->StepWithMidAndErrorEstimate(yIn, restMass, charge, hstep,
256 std::memcpy(yOut + nvar, yIn + nvar,
293 if (error2 > fErrorConstraintShrink * fErrorConstraintShrink)
295 return fMaxSteppingDecrease * h;
297 return fSafetyFactor * h * std::pow(error2, 0.5 * fPowerShrink);
305 if (error2 < fErrorConstraintGrow * fErrorConstraintGrow)
307 return fMaxSteppingIncrease * h;
309 return fSafetyFactor * h * std::pow(error2, 0.5 * fPowerGrow);
317 "This method is not implemented. BorisDriver/Stepper should keep its equation");
325 os <<
"State of G4BorisDriver: " << std::endl;
326 os <<
" Method is implemented, but gives no information. " << std::endl;
G4double epsilon(G4double density, G4double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
void OneGoodStep(G4double yCurrentState[], G4double &curveLength, G4double htry, G4double epsilon_rel, G4double restMass, G4double charge, G4double &hdid, G4double &hnext)
G4EquationOfMotion * GetEquationOfMotion() override
void StreamInfo(std::ostream &os) const override
G4double ShrinkStepSize2(G4double h, G4double error2) const
void GetDerivatives(const G4FieldTrack &track, G4double dydx[]) const override
G4BorisDriver(G4double hminimum, G4BorisScheme *Boris, G4int numberOfComponents=6, G4bool verbosity=false)
void SetEquationOfMotion(G4EquationOfMotion *equation) override
G4bool AccurateAdvance(G4FieldTrack &track, G4double stepLen, G4double eps, G4double beginStep=0) override
G4bool QuickAdvance(G4FieldTrack &y_val, const G4double dydx[], G4double hstep, G4double &missDist, G4double &dyerr) override
G4double GrowStepSize2(G4double h, G4double error2) const
The G4BorisScheme class implements of the Boris algorithm for advancing charged particles in an elect...
G4EquationOfMotion is the abstract base class for the right hand size of the equation of motion of a ...
void EvaluateRhsReturnB(const G4double y[], G4double dydx[], G4double Field[]) const
G4FieldTrack defines a data structure bringing together a magnetic track's state (position,...
G4double GetCurveLength() const
G4double GetCharge() const
void SetCurveLength(G4double nCurve_s)
G4double GetRestMass() const
void DumpToArray(G4double valArr[ncompSVEC]) const
void LoadFromArray(const G4double valArr[ncompSVEC], G4int noVarsIntegrated)
static G4double Distline(const G4ThreeVector &OtherPnt, const G4ThreeVector &LinePntA, const G4ThreeVector &LinePntB)
G4double absoluteError(const G4double y[], const G4double yerr[], G4double hstep)
G4double relativeError2(const G4double y[], const G4double yerr[], G4double hstep, G4double errorTolerance)
G4ThreeVector makeVector(const ArrayType &array, Value3D value)
void copy(G4double dst[], const G4double src[], std::size_t size=G4FieldTrack::ncompSVEC)