00001 #include "BDSRK4Stepper.hh"
00002 #include "G4ThreeVector.hh"
00003
00005
00006
00007
00008 extern G4double BDSLocalRadiusOfCurvature;
00009
00010 BDSRK4Stepper::BDSRK4Stepper(G4EquationOfMotion* EqRhs, G4int nvar) :
00011 G4MagIntegratorStepper(EqRhs,nvar)
00012 {
00013 itsEqRhs = EqRhs;
00014
00015 unsigned int noVariables= std::max(nvar,8);
00016
00017 dydxm = new G4double[noVariables];
00018 dydxt = new G4double[noVariables];
00019 yt = new G4double[noVariables];
00020
00021 yTemp = new G4double[noVariables];
00022 yIn = new G4double[noVariables];
00023 }
00024
00026
00027
00028
00029 BDSRK4Stepper::~BDSRK4Stepper()
00030 {
00031 delete[] dydxm;
00032 delete[] dydxt;
00033 delete[] yt;
00034
00035 delete[] yTemp;
00036 delete[] yIn;
00037 }
00038
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 void
00050 BDSRK4Stepper::AdvanceHelix( const G4double yIn[],
00051 const G4double dydx[],
00052 const G4double h,
00053 G4double yOut[])
00054 {
00055
00056 #ifdef DEBUG
00057 G4cout<<"stepping by "<<h<<G4endl;
00058 #endif
00059
00060 const G4int nvar = this->GetNumberOfVariables();
00061
00062 #ifdef DEBUG
00063 G4cout<<"nvar="<<nvar<<G4endl;
00064 #endif
00065
00066 G4int i;
00067 G4double hh = h*0.5 , h6 = h/6.0 ;
00068
00069
00070
00071
00072 yt[7] = yIn[7];
00073 yOut[7] = yIn[7];
00074
00075
00076
00077 const G4double *pIn = yIn+3;
00078 G4double itsMomentum = sqrt(pIn[0]*pIn[0]+pIn[1]*pIn[1]+pIn[2]*pIn[2]);
00079
00080 G4double BField[6];
00081 G4double Pos[4];
00082 Pos[0] = yIn[0];
00083 Pos[1] = yIn[1];
00084 Pos[2] = yIn[2];
00085 Pos[3] = 0.;
00086 itsEqRhs->GetFieldObj()->GetFieldValue(Pos,BField);
00087
00088 G4ThreeVector BVec = G4ThreeVector(BField[0],
00089 BField[1],
00090 BField[2]);
00091 G4ThreeVector pVec = G4ThreeVector(pIn[0],
00092 pIn[1],
00093 pIn[2]);
00094
00095 G4double Bmag = (BVec.cross(pVec.unit())).mag();
00096
00097 BDSLocalRadiusOfCurvature = (itsMomentum/GeV) / (0.299792458*Bmag/tesla)*m;
00098
00099 #ifdef DEBUG
00100 G4cout<<" Pos = ("<<Pos[0]/mm<<" "<<Pos[1]/mm<<" " <<Pos[2]/mm<<") mm"<<G4endl;
00101 G4cout<<" Mtm = ("<<pIn[0]/GeV<<" "<<pIn[1]/GeV<<" " <<pIn[2]/GeV<<") GeV"<<G4endl;
00102 G4cout<<" BField = ("<<BField[0]/tesla<<" "<<BField[1]/tesla<<" "<<BField[2]/tesla<<") T"<<G4endl;
00103 G4cout<<" Local curvature radius = "<<BDSLocalRadiusOfCurvature/m<<" m"<<G4endl;
00104 #endif
00105
00106
00107
00108
00109
00110 #ifdef DEBUG
00111 G4cout<<"===>RK Steps 1-2, before, dydx : ";
00112 for(i=0;i<nvar;i++) {
00113 G4cout<<dydx[i]<<" ";
00114 }
00115 G4cout<<G4endl;
00116
00117 G4cout<<"yIn: ";
00118 for(i=0;i<nvar;i++) {
00119 G4cout<<yIn[i]<<" ";
00120 }
00121 G4cout<<G4endl;
00122 #endif
00123
00124 for(i=0;i<nvar;i++)
00125 {
00126 yt[i] = yIn[i] + hh*dydx[i] ;
00127 }
00128 RightHandSide(yt,dydxt) ;
00129
00130 #ifdef DEBUG
00131 G4cout<<"after, dydx: ";
00132 for(i=0;i<nvar;i++) {
00133 G4cout<<dydxt[i]<<" ";
00134 }
00135 G4cout<<G4endl;
00136
00137 G4cout<<"after, yt: ";
00138 for(i=0;i<nvar;i++) {
00139 G4cout<<yt[i]<<" ";
00140 }
00141 G4cout<<G4endl;
00142 #endif
00143
00144 #ifdef DEBUG
00145 G4cout<<"===>RK Steps 3-4"<<G4endl;
00146 #endif
00147
00148 for(i=0;i<nvar;i++)
00149 {
00150 yt[i] = yIn[i] + hh*dydxt[i] ;
00151 }
00152 RightHandSide(yt,dydxm) ;
00153
00154 for(i=0;i<nvar;i++)
00155 {
00156 yt[i] = yIn[i] + h*dydxm[i] ;
00157 dydxm[i] += dydxt[i] ;
00158 }
00159 RightHandSide(yt,dydxt) ;
00160
00161 for(i=0;i<nvar;i++)
00162 {
00163 yOut[i] = yIn[i]+h6*(dydx[i]+dydxt[i]+2.0*dydxm[i]);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 return;
00179
00180 }
00181
00182
00183 void BDSRK4Stepper::Stepper( const G4double yInput[],
00184 const G4double dydx[],
00185 const G4double hstep,
00186 G4double yOut[],
00187 G4double yErr[] )
00188 {
00189 const G4int nvar = 6 ;
00190 G4int i;
00191 const G4double *pIn = yInput+3;
00192 G4ThreeVector v0= G4ThreeVector( pIn[0], pIn[1], pIn[2]);
00193
00194
00195
00196
00197 for(i=0;i<nvar;i++) yIn[i]=yInput[i];
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 G4double h = hstep;
00216
00217
00218
00219 AdvanceHelix(yIn, dydx, h, yOut);
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 for(i=0;i<nvar;i++) {
00232 yErr[i] = h*h*h*(yOut[i] - yIn[i]) ;
00233
00234 }
00235
00236
00237
00238 }
00239
00240 G4double BDSRK4Stepper::DistChord() const
00241 {
00242
00243 return 0.0;
00244 }