File indexing completed on 2026-09-13 09:10:51
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
0030
0031
0032
0033
0034
0035
0036 #ifndef G4TMAG_ERROR_STEPPER_HH
0037 #define G4TMAG_ERROR_STEPPER_HH
0038
0039 #include "G4Types.hh"
0040 #include "G4MagIntegratorStepper.hh"
0041 #include "G4ThreeVector.hh"
0042 #include "G4LineSection.hh"
0043
0044
0045
0046
0047
0048 template <class T_Stepper, class T_Equation, unsigned int N>
0049 class G4TMagErrorStepper : public G4MagIntegratorStepper
0050 {
0051 public:
0052
0053 G4TMagErrorStepper(T_Equation* EqRhs, G4int numberOfVariables,
0054 G4int numStateVariables = 12)
0055 : G4MagIntegratorStepper(EqRhs, numberOfVariables, numStateVariables)
0056 , fEquation_Rhs(EqRhs) { ; }
0057
0058 virtual ~G4TMagErrorStepper() = default;
0059
0060 G4TMagErrorStepper(const G4TMagErrorStepper&) = delete;
0061 G4TMagErrorStepper& operator=(const G4TMagErrorStepper&) = delete;
0062
0063 inline void RightHandSide(G4double y[], G4double dydx[])
0064 {
0065 fEquation_Rhs->T_Equation::RightHandSide(y, dydx);
0066 }
0067
0068 inline void Stepper(const G4double yInput[], const G4double dydx[],
0069 G4double hstep, G4double yOutput[], G4double yError[]) override final;
0070
0071 inline G4double DistChord() const override final;
0072 G4StepperType StepperType() const override { return kTMagErrorStepper; }
0073
0074 private:
0075
0076
0077 G4ThreeVector fInitialPoint, fMidPoint, fFinalPoint;
0078
0079
0080
0081 G4double yInitial[N < 8 ? 8 : N];
0082 G4double yMiddle[N < 8 ? 8 : N];
0083 G4double dydxMid[N < 8 ? 8 : N];
0084 G4double yOneStep[N < 8 ? 8 : N];
0085
0086
0087
0088
0089 T_Equation* fEquation_Rhs;
0090 };
0091
0092
0093
0094 template <class T_Stepper, class T_Equation, unsigned int N >
0095 void G4TMagErrorStepper<T_Stepper,T_Equation,N>::
0096 Stepper(const G4double yInput[],
0097 const G4double dydx[],
0098 G4double hstep,
0099 G4double yOutput[],
0100 G4double yError[])
0101
0102
0103
0104
0105 {
0106 const unsigned int maxvar = GetNumberOfStateVariables();
0107
0108
0109 for(unsigned int i = 0; i < N; ++i)
0110 yInitial[i] = yInput[i];
0111 yInitial[7] =
0112 yInput[7];
0113 yMiddle[7] = yInput[7];
0114 yOneStep[7] = yInput[7];
0115
0116 for(unsigned int i = N; i < maxvar; ++i)
0117 yOutput[i] = yInput[i];
0118
0119 G4double halfStep = hstep * 0.5;
0120
0121
0122
0123 static_cast<T_Stepper*>(this)->DumbStepper(yInitial, dydx, halfStep,
0124 yMiddle);
0125 this->RightHandSide(yMiddle, dydxMid);
0126 static_cast<T_Stepper*>(this)->DumbStepper(yMiddle, dydxMid, halfStep,
0127 yOutput);
0128
0129
0130
0131 fMidPoint = G4ThreeVector(yMiddle[0], yMiddle[1], yMiddle[2]);
0132
0133
0134 static_cast<T_Stepper*>(this)->DumbStepper(yInitial, dydx, hstep, yOneStep);
0135 for(unsigned int i = 0; i < N; ++i)
0136 {
0137 yError[i] = yOutput[i] - yOneStep[i];
0138 yOutput[i] +=
0139 yError[i] *
0140 T_Stepper::IntegratorCorrection;
0141
0142
0143 }
0144
0145 fInitialPoint = G4ThreeVector(yInitial[0], yInitial[1], yInitial[2]);
0146 fFinalPoint = G4ThreeVector(yOutput[0], yOutput[1], yOutput[2]);
0147
0148 return;
0149 }
0150
0151
0152 template <class T_Stepper, class T_Equation, unsigned int N >
0153 inline G4double
0154 G4TMagErrorStepper<T_Stepper,T_Equation,N>::DistChord() const
0155 {
0156
0157
0158
0159
0160
0161
0162
0163
0164 G4double distLine, distChord;
0165
0166 if(fInitialPoint != fFinalPoint)
0167 {
0168 distLine = G4LineSection::Distline(fMidPoint, fInitialPoint, fFinalPoint);
0169
0170
0171
0172 distChord = distLine;
0173 }
0174 else
0175 {
0176 distChord = (fMidPoint - fInitialPoint).mag();
0177 }
0178
0179 return distChord;
0180 }
0181
0182 #endif