00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "G4ConstRK4.hh"
00034 #include "G4ThreeVector.hh"
00035 #include "G4LineSection.hh"
00036
00038
00039
00040
00041
00042 G4ConstRK4::G4ConstRK4(G4Mag_EqRhs* EqRhs, G4int numStateVariables)
00043 : G4MagErrorStepper(EqRhs, 6, numStateVariables)
00044 {
00045
00046 if( numStateVariables < 8 )
00047 {
00048 std::ostringstream message;
00049 message << "The number of State variables at least 8 " << G4endl
00050 << "Instead it is - numStateVariables= " << numStateVariables;
00051 G4Exception("G4ConstRK4::G4ConstRK4()", "GeomField0002",
00052 FatalException, message, "Use another Stepper!");
00053 }
00054
00055 fEq = EqRhs;
00056 yMiddle = new G4double[8];
00057 dydxMid = new G4double[8];
00058 yInitial = new G4double[8];
00059 yOneStep = new G4double[8];
00060
00061 dydxm = new G4double[8];
00062 dydxt = new G4double[8];
00063 yt = new G4double[8];
00064 Field[0]=0.; Field[1]=0.; Field[2]=0.;
00065 }
00066
00068
00069
00070
00071 G4ConstRK4::~G4ConstRK4()
00072 {
00073 delete [] yMiddle;
00074 delete [] dydxMid;
00075 delete [] yInitial;
00076 delete [] yOneStep;
00077 delete [] dydxm;
00078 delete [] dydxt;
00079 delete [] yt;
00080 }
00081
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 void G4ConstRK4::DumbStepper( const G4double yIn[],
00093 const G4double dydx[],
00094 G4double h,
00095 G4double yOut[])
00096 {
00097 G4double hh = h*0.5 , h6 = h/6.0 ;
00098
00099
00100 yt[5] = yIn[5] + hh*dydx[5] ;
00101 yt[4] = yIn[4] + hh*dydx[4] ;
00102 yt[3] = yIn[3] + hh*dydx[3] ;
00103 yt[2] = yIn[2] + hh*dydx[2] ;
00104 yt[1] = yIn[1] + hh*dydx[1] ;
00105 yt[0] = yIn[0] + hh*dydx[0] ;
00106 RightHandSideConst(yt,dydxt) ;
00107
00108
00109 yt[5] = yIn[5] + hh*dydxt[5] ;
00110 yt[4] = yIn[4] + hh*dydxt[4] ;
00111 yt[3] = yIn[3] + hh*dydxt[3] ;
00112 yt[2] = yIn[2] + hh*dydxt[2] ;
00113 yt[1] = yIn[1] + hh*dydxt[1] ;
00114 yt[0] = yIn[0] + hh*dydxt[0] ;
00115 RightHandSideConst(yt,dydxm) ;
00116
00117
00118
00119 yt[5] = yIn[5] + h*dydxm[5] ;
00120 dydxm[5] += dydxt[5] ;
00121 yt[4] = yIn[4] + h*dydxm[4] ;
00122 dydxm[4] += dydxt[4] ;
00123 yt[3] = yIn[3] + h*dydxm[3] ;
00124 dydxm[3] += dydxt[3] ;
00125 yt[2] = yIn[2] + h*dydxm[2] ;
00126 dydxm[2] += dydxt[2] ;
00127 yt[1] = yIn[1] + h*dydxm[1] ;
00128 dydxm[1] += dydxt[1] ;
00129 yt[0] = yIn[0] + h*dydxm[0] ;
00130 dydxm[0] += dydxt[0] ;
00131 RightHandSideConst(yt,dydxt) ;
00132
00133
00134 yOut[5] = yIn[5]+h6*(dydx[5]+dydxt[5]+2.0*dydxm[5]);
00135 yOut[4] = yIn[4]+h6*(dydx[4]+dydxt[4]+2.0*dydxm[4]);
00136 yOut[3] = yIn[3]+h6*(dydx[3]+dydxt[3]+2.0*dydxm[3]);
00137 yOut[2] = yIn[2]+h6*(dydx[2]+dydxt[2]+2.0*dydxm[2]);
00138 yOut[1] = yIn[1]+h6*(dydx[1]+dydxt[1]+2.0*dydxm[1]);
00139 yOut[0] = yIn[0]+h6*(dydx[0]+dydxt[0]+2.0*dydxm[0]);
00140
00141 }
00142
00144
00145
00146
00147 void
00148 G4ConstRK4::Stepper( const G4double yInput[],
00149 const G4double dydx[],
00150 G4double hstep,
00151 G4double yOutput[],
00152 G4double yError [] )
00153 {
00154 const G4int nvar = 6;
00155 const G4int maxvar= GetNumberOfStateVariables();
00156
00157
00158 G4double correction = 1. / ( (1 << IntegratorOrder()) -1 );
00159
00160 G4int i;
00161
00162
00163 for (i=0; i<maxvar; i++) { yInitial[i]= yInput[i]; }
00164
00165
00166 for (i=nvar; i<maxvar; i++) { yOutput[i]= yInput[i]; }
00167
00168
00169 yMiddle[7] = yInput[7];
00170 yOneStep[7] = yInput[7];
00171
00172 yError[7] = 0.0;
00173
00174 G4double halfStep = hstep * 0.5;
00175
00176
00177
00178 GetConstField(yInitial,Field);
00179 DumbStepper (yInitial, dydx, halfStep, yMiddle);
00180 RightHandSideConst(yMiddle, dydxMid);
00181 DumbStepper (yMiddle, dydxMid, halfStep, yOutput);
00182
00183
00184
00185 fMidPoint = G4ThreeVector( yMiddle[0], yMiddle[1], yMiddle[2]);
00186
00187
00188
00189 DumbStepper(yInitial, dydx, hstep, yOneStep);
00190 for(i=0;i<nvar;i++)
00191 {
00192 yError [i] = yOutput[i] - yOneStep[i] ;
00193 yOutput[i] += yError[i]*correction ;
00194
00195
00196 }
00197
00198 fInitialPoint = G4ThreeVector( yInitial[0], yInitial[1], yInitial[2]);
00199 fFinalPoint = G4ThreeVector( yOutput[0], yOutput[1], yOutput[2]);
00200
00201 return;
00202 }
00203
00205
00206
00207
00208
00209
00210
00211
00212
00213 G4double G4ConstRK4::DistChord() const
00214 {
00215 G4double distLine, distChord;
00216
00217 if (fInitialPoint != fFinalPoint)
00218 {
00219 distLine= G4LineSection::Distline( fMidPoint, fInitialPoint, fFinalPoint );
00220
00221
00222 distChord = distLine;
00223 }
00224 else
00225 {
00226 distChord = (fMidPoint-fInitialPoint).mag();
00227 }
00228 return distChord;
00229 }