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