File indexing completed on 2025-10-25 08:45:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 template <class T>
0030 G4QSSDriver<T>::G4QSSDriver(T* pStepper) : G4InterpolationDriver<T, true>(0, pStepper)
0031 {
0032
0033 this->fSteppers.resize(1);
0034 }
0035
0036 template <class T>
0037 void G4QSSDriver<T>::OnStartTracking()
0038 {
0039 Base::OnStartTracking();
0040 if (! initializedOnFirstRun) {
0041
0042
0043 G4double dqRel = G4QSSMessenger::instance()->dQRel;
0044 G4double dQMin = G4QSSMessenger::instance()->dQMin;
0045 if (dqRel == 0) {
0046 dqRel = 0.001;
0047 }
0048 if (dQMin == 0) {
0049 dQMin = 0.0001;
0050 }
0051 this->SetPrecision(dqRel, dQMin);
0052
0053 initializedOnFirstRun = true;
0054 }
0055 }
0056
0057 template <class T>
0058 void G4QSSDriver<T>::SetPrecision(G4double dq_rel, G4double dq_min)
0059 {
0060 G4cout << "Setting QSS precision parameters: "
0061 << "dQRel = " << dq_rel << " - "
0062 << "dQMin = " << dq_min << G4endl;
0063
0064 for (const auto& item : this->fSteppers) {
0065 item.stepper->SetPrecision(dq_rel, dq_min);
0066 }
0067 }
0068
0069 template <class T>
0070 G4double G4QSSDriver<T>::AdvanceChordLimited(
0071 G4FieldTrack& track, G4double hstep, G4double epsStep, G4double chordDistance)
0072 {
0073
0074
0075 ++this->fTotalStepsForTrack;
0076 this->fLastStepper = this->fSteppers.begin();
0077
0078 const G4double preCurveLength = track.GetCurveLength();
0079 G4double postCurveLength = preCurveLength;
0080 auto it = this->fSteppers.begin();
0081
0082 it->stepper->reset(const_cast<const G4FieldTrack*>(&track));
0083
0084 field_utils::State yBegin, y;
0085 track.DumpToArray(yBegin);
0086 track.DumpToArray(y);
0087
0088 G4double hdid = OneGoodStep(it, y, this->fdydx, hstep, epsStep, preCurveLength, &track);
0089 postCurveLength += hdid;
0090
0091 G4double dChordStep = this->DistChord(yBegin, preCurveLength, y, postCurveLength);
0092
0093
0094 hdid = this->FindNextChord(
0095 yBegin, preCurveLength, y, postCurveLength, dChordStep, chordDistance);
0096
0097 track.LoadFromArray(y, this->fSteppers[0].stepper->GetNumberOfVariables());
0098 track.SetCurveLength(preCurveLength + hdid);
0099
0100 return hdid;
0101 }
0102
0103 template <class T>
0104 G4double G4QSSDriver<T>::OneGoodStep(typename G4InterpolationDriver<T, true>::StepperIterator it,
0105 field_utils::State& y, field_utils::State& dydx, G4double& hstep, G4double ,
0106 G4double curveLength, G4FieldTrack* )
0107 {
0108 G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
0109 it->stepper->Stepper(y, dydx, hstep, ytemp, yerr);
0110 G4double h = it->stepper->GetLastStepLength();
0111
0112
0113 it->begin = curveLength;
0114 it->end = curveLength + h;
0115 it->inverseLength = 1. / h;
0116
0117 field_utils::copy(y, ytemp);
0118
0119 return h;
0120 }