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