Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4DormandPrince745 implementation << 27 // 26 // 28 // DormandPrince7 - 5(4) non-FSAL << 27 // Class description: 29 // definition of the stepper() method that eva << 30 // field propagation. << 31 // The coefficients and the algorithm have bee << 32 // 28 // 33 // J. R. Dormand and P. J. Prince, "A family o << 29 // DormandPrince7 - 5(4) non-FSAL 34 // Journal of computational and applied Math., << 35 // 30 // 36 // The Butcher table of the Dormand-Prince-7-4 << 31 // This is the source file of G4DormandPrince745 class containing the >> 32 // definition of the stepper() method that evaluates one step in >> 33 // field propagation. >> 34 // The coefficients and the algorithm have been adapted from >> 35 // >> 36 // Table 2 : Coefficients of RK5(4)7M >> 37 // ---Ref--- >> 38 // J. R. Dormand and P. J. Prince, “A family of embedded Runge-Kutta formulae,” >> 39 // Journal of computational and applied …, vol. 6, no. 1, pp. 19–26, 1980. >> 40 // ------------------ >> 41 // >> 42 // The Butcher table of the Dormand-Prince-7-4-5 method is as follows : 37 // 43 // 38 // 0 | 44 // 0 | 39 // 1/5 | 1/5 45 // 1/5 | 1/5 40 // 3/10| 3/40 9/40 << 46 // 3/10| 3/40 9/40 41 // 4/5 | 44/45 56/15 32/9 << 47 // 4/5 | 44/45 −56/15 32/9 42 // 8/9 | 19372/6561 25360/2187 64448/6561 << 48 // 8/9 | 19372/6561 −25360/2187 64448/6561 −212/729 43 // 1 | 9017/3168 355/33 46732/5247 << 49 // 1 | 9017/3168 −355/33 46732/5247 49/176 −5103/18656 44 // 1 | 35/384 0 500/1113 << 50 // 1 | 35/384 0 500/1113 125/192 −2187/6784 11/84 45 // ---------------------------------------- 51 // ------------------------------------------------------------------------ 46 // 35/384 0 500/1113 << 52 // 35/384 0 500/1113 125/192 −2187/6784 11/84 0 47 // 5179/57600 0 7571/16695 << 53 // 5179/57600 0 7571/16695 393/640 −92097/339200 187/2100 1/40 >> 54 // >> 55 // >> 56 // Implementation by Somnath Banerjee - GSoC 2015 >> 57 // Work supported by Google as part of Google Summer of Code 2015. >> 58 // Supervision / code review: John Apostolakis >> 59 // >> 60 // First version: 25 May 2015 - Somnath Banerjee >> 61 // >> 62 // Note: Current version includes 3 versions of 'DistChord' method. >> 63 // Default is hard-coded interpolation. 48 // 64 // 49 // Created: Somnath Banerjee, Google Summer of << 50 // Supervision: John Apostolakis, CERN << 51 // ------------------------------------------- << 52 << 53 #include "G4DormandPrince745.hh" 65 #include "G4DormandPrince745.hh" 54 #include "G4LineSection.hh" 66 #include "G4LineSection.hh" >> 67 #include <cmath> 55 68 56 #include <cstring> << 69 //Constructor 57 << 70 G4DormandPrince745::G4DormandPrince745(G4EquationOfMotion *EqRhs, 58 using namespace field_utils; << 71 G4int noIntegrationVariables, 59 << 72 G4bool primary) 60 // Name of this steppers << 73 : G4MagIntegratorStepper(EqRhs, noIntegrationVariables), 61 const G4String& G4DormandPrince745::StepperTyp << 74 fAuxStepper(0) 62 { 75 { 63 static G4String _stepperType("G4DormandPrinc << 76 const G4int numberOfVariables = // noIntegrationVariables; 64 return _stepperType; << 77 std::max( noIntegrationVariables, >> 78 ( ( (noIntegrationVariables-1)/4 + 1 ) * 4 ) ); >> 79 // For better alignment with cache-line >> 80 >> 81 //New Chunk of memory being created for use by the stepper >> 82 >> 83 //ak_i - for storing intermediate RHS >> 84 ak2 = new G4double[numberOfVariables]; >> 85 ak3 = new G4double[numberOfVariables]; >> 86 ak4 = new G4double[numberOfVariables]; >> 87 ak5 = new G4double[numberOfVariables]; >> 88 ak6 = new G4double[numberOfVariables]; >> 89 ak7 = new G4double[numberOfVariables]; >> 90 // Also always allocate arrays for interpolation stages >> 91 ak8 = new G4double[numberOfVariables]; >> 92 ak9 = new G4double[numberOfVariables]; >> 93 >> 94 // Must ensure space for extra 'state' variables exists - i.e. yIn[7] >> 95 const G4int numStateVars = >> 96 std::max(noIntegrationVariables, >> 97 std::max( GetNumberOfStateVariables(), 8) >> 98 ); >> 99 yTemp = new G4double[numStateVars]; >> 100 yIn = new G4double[numStateVars]; >> 101 >> 102 fLastInitialVector = new G4double[numStateVars] ; >> 103 fLastFinalVector = new G4double[numStateVars] ; >> 104 >> 105 // fLastDyDx = new G4double[numberOfVariables]; >> 106 >> 107 fMidVector = new G4double[numStateVars]; >> 108 fMidError = new G4double[numStateVars]; >> 109 >> 110 yTemp = new G4double[numberOfVariables] ; >> 111 yIn = new G4double[numberOfVariables] ; >> 112 >> 113 fLastInitialVector = new G4double[numberOfVariables] ; >> 114 fLastFinalVector = new G4double[numberOfVariables] ; >> 115 fInitialDyDx = new G4double[numberOfVariables]; >> 116 >> 117 fMidVector = new G4double[numberOfVariables]; >> 118 fMidError = new G4double[numberOfVariables]; >> 119 fAuxStepper = nullptr; >> 120 if( primary ) >> 121 { >> 122 fAuxStepper = new G4DormandPrince745(EqRhs, numberOfVariables, >> 123 !primary); >> 124 } >> 125 fLastStepLength = -1.0; 65 } 126 } 66 127 67 // Description of this steppers - plus details << 128 //Destructor 68 const G4String& G4DormandPrince745::StepperDes << 129 G4DormandPrince745::~G4DormandPrince745() 69 { 130 { 70 static G4String _stepperDescription( << 131 //clear all previously allocated memory for stepper and DistChord 71 "Embedeed 5th order Runge-Kutta stepper - << 132 delete[] ak2; 72 return _stepperDescription; << 133 delete[] ak3; >> 134 delete[] ak4; >> 135 delete[] ak5; >> 136 delete[] ak6; >> 137 delete[] ak7; >> 138 // Used only for interpolation >> 139 delete[] ak8; >> 140 delete[] ak9; >> 141 >> 142 delete[] yTemp; >> 143 delete[] yIn; >> 144 >> 145 delete[] fLastInitialVector; >> 146 delete[] fLastFinalVector; >> 147 delete[] fInitialDyDx; >> 148 delete[] fMidVector; >> 149 delete[] fMidError; >> 150 >> 151 delete fAuxStepper; 73 } 152 } 74 153 75 G4DormandPrince745::G4DormandPrince745(G4Equat << 76 G4int n << 77 : G4MagIntegratorStepper(equation, noInteg << 78 { << 79 } << 80 154 81 void G4DormandPrince745::Stepper(const G4doubl << 155 // The coefficients and the algorithm have been adapted from 82 const G4doubl << 156 // Table 2 : Coefficients of RK5(4)7M 83 G4doubl << 157 // ---Ref--- 84 G4doubl << 158 // J. R. Dormand and P. J. Prince, “A family of embedded Runge-Kutta formulae,” 85 G4doubl << 159 // Journal of computational and applied …, vol. 6, no. 1, pp. 19–26, 1980. 86 G4doubl << 160 // ------------------ 87 { << 88 Stepper(yInput, dydx, hstep, yOutput, yError << 89 field_utils::copy(dydxOutput, ak7); << 90 } << 91 161 92 // Stepper << 162 // The Butcher table of the Dormand-Prince-7-4-5 method is as follows : 93 // 163 // >> 164 // 0 | >> 165 // 1/5 | 1/5 >> 166 // 3/10| 3/40 9/40 >> 167 // 4/5 | 44/45 −56/15 32/9 >> 168 // 8/9 | 19372/6561 −25360/2187 64448/6561 −212/729 >> 169 // 1 | 9017/3168 −355/33 46732/5247 49/176 −5103/18656 >> 170 // 1 | 35/384 0 500/1113 125/192 −2187/6784 11/84 >> 171 // ------------------------------------------------------------------------ >> 172 // 35/384 0 500/1113 125/192 −2187/6784 11/84 0 >> 173 // 5179/57600 0 7571/16695 393/640 −92097/339200 187/2100 1/40 >> 174 >> 175 >> 176 //Stepper : >> 177 94 // Passing in the value of yInput[],the first 178 // Passing in the value of yInput[],the first time dydx[] and Step length 95 // Giving back yOut and yErr arrays for output 179 // Giving back yOut and yErr arrays for output and error respectively 96 // << 180 97 void G4DormandPrince745::Stepper(const G4doubl 181 void G4DormandPrince745::Stepper(const G4double yInput[], 98 const G4doubl << 182 const G4double DyDx[], 99 G4doubl << 183 G4double Step, 100 G4doubl << 184 G4double yOut[], 101 G4doubl << 185 G4double yErr[] ) 102 { 186 { 103 // The various constants defined on the ba << 187 G4int i; 104 // << 188 105 const G4double b21 = 0.2, << 189 //The various constants defined on the basis of butcher tableu 106 b31 = 3.0 / 40.0, b32 = 9.0 << 190 const G4double //G4double - only once 107 b41 = 44.0 / 45.0, b42 = -5 << 191 b21 = 0.2 , 108 << 192 109 b51 = 19372.0 / 6561.0, b52 = -25360.0 << 193 b31 = 3.0/40.0, b32 = 9.0/40.0 , 110 b54 = -212.0 / 729.0, << 194 111 << 195 b41 = 44.0/45.0, b42 = -56.0/15.0, b43 = 32.0/9.0, 112 b61 = 9017.0 / 3168.0 , b62 = -355.0 << 196 113 b63 = 46732.0 / 5247.0, b64 = 49.0 / 1 << 197 b51 = 19372.0/6561.0, b52 = -25360.0/2187.0, b53 = 64448.0/6561.0, 114 b65 = -5103.0 / 18656.0, << 198 b54 = -212.0/729.0 , 115 << 199 116 b71 = 35.0 / 384.0, b72 = 0., << 200 b61 = 9017.0/3168.0 , b62 = -355.0/33.0, 117 b73 = 500.0 / 1113.0, b74 = 125.0 / 19 << 201 b63 = 46732.0/5247.0 , b64 = 49.0/176.0 , 118 b75 = -2187.0 / 6784.0, b76 = 11.0 / 8 << 202 b65 = -5103.0/18656.0 , >> 203 >> 204 b71 = 35.0/384.0, b72 = 0., >> 205 b73 = 500.0/1113.0, b74 = 125.0/192.0, >> 206 b75 = -2187.0/6784.0, b76 = 11.0/84.0, 119 207 120 //Sum of columns, sum(bij) = ei 208 //Sum of columns, sum(bij) = ei 121 // e1 = 0. , << 209 // e1 = 0. , 122 // e2 = 1.0/5.0 , << 210 // e2 = 1.0/5.0 , 123 // e3 = 3.0/10.0 , << 211 // e3 = 3.0/10.0 , 124 // e4 = 4.0/5.0 , << 212 // e4 = 4.0/5.0 , 125 // e5 = 8.0/9.0 , << 213 // e5 = 8.0/9.0 , 126 // e6 = 1.0 , << 214 // e6 = 1.0 , 127 // e7 = 1.0 , << 215 // e7 = 1.0 , 128 216 129 // Difference between the higher and the l << 217 // Difference between the higher and the lower order method coeff. : 130 // b7j are the coefficients of higher orde 218 // b7j are the coefficients of higher order 131 219 132 dc1 = -(b71 - 5179.0 / 57600.0), << 220 dc1 = -( b71 - 5179.0/57600.0), 133 dc2 = -(b72 - .0), << 221 dc2 = -( b72 - .0), 134 dc3 = -(b73 - 7571.0 / 16695.0), << 222 dc3 = -( b73 - 7571.0/16695.0), 135 dc4 = -(b74 - 393.0 / 640.0), << 223 dc4 = -( b74 - 393.0/640.0), 136 dc5 = -(b75 + 92097.0 / 339200.0), << 224 dc5 = -( b75 + 92097.0/339200.0), 137 dc6 = -(b76 - 187.0 / 2100.0), << 225 dc6 = -( b76 - 187.0/2100.0), 138 dc7 = -(- 1.0 / 40.0); << 226 dc7 = -( - 1.0/40.0 ); //end of declaration 139 227 140 const G4int numberOfVariables = GetNumberO << 228 const G4int numberOfVariables= this->GetNumberOfVariables(); 141 State yTemp = {0., 0., 0., 0., 0., 0., 0., << 142 229 143 // The number of variables to be integrate 230 // The number of variables to be integrated over 144 // << 145 yOut[7] = yTemp[7] = yInput[7]; 231 yOut[7] = yTemp[7] = yInput[7]; 146 << 147 // Saving yInput because yInput and yOut 232 // Saving yInput because yInput and yOut can be aliases for same array 148 // << 233 149 for(G4int i = 0; i < numberOfVariables; ++ << 234 for(i=0;i<numberOfVariables;i++) 150 { 235 { 151 fyIn[i] = yInput[i]; << 236 yIn[i]=yInput[i]; 152 } 237 } 153 // RightHandSide(yIn, dydx); // Not don << 154 238 155 for(G4int i = 0; i < numberOfVariables; ++ << 239 // RightHandSide(yIn, DyDx) ; >> 240 // 1st Step - Not doing, getting passed >> 241 >> 242 for(i=0;i<numberOfVariables;i++) 156 { 243 { 157 yTemp[i] = fyIn[i] + b21 * hstep * dyd << 244 yTemp[i] = yIn[i] + b21*Step*DyDx[i] ; 158 } 245 } 159 RightHandSide(yTemp, ak2); // << 246 RightHandSide(yTemp, ak2) ; // 2nd stage 160 247 161 for(G4int i = 0; i < numberOfVariables; ++ << 248 for(i=0;i<numberOfVariables;i++) 162 { 249 { 163 yTemp[i] = fyIn[i] + hstep * (b31 * dy << 250 yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ; 164 } 251 } 165 RightHandSide(yTemp, ak3); // << 252 RightHandSide(yTemp, ak3) ; // 3rd stage 166 253 167 for(G4int i = 0; i < numberOfVariables; ++ << 254 for(i=0;i<numberOfVariables;i++) 168 { 255 { 169 yTemp[i] = fyIn[i] + hstep * ( << 256 yTemp[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ; 170 b41 * dydx[i] + b42 * ak2[i] + b43 << 171 } 257 } 172 RightHandSide(yTemp, ak4); // << 258 RightHandSide(yTemp, ak4) ; // 4th stage 173 259 174 for(G4int i = 0; i < numberOfVariables; ++ << 260 for(i=0;i<numberOfVariables;i++) 175 { 261 { 176 yTemp[i] = fyIn[i] + hstep * ( << 262 yTemp[i] = yIn[i] + Step*(b51*DyDx[i] + b52*ak2[i] + b53*ak3[i] + 177 b51 * dydx[i] + b52 * ak2[i] + b53 << 263 b54*ak4[i]) ; 178 } 264 } 179 RightHandSide(yTemp, ak5); // << 265 RightHandSide(yTemp, ak5) ; // 5th stage 180 266 181 for(G4int i = 0; i < numberOfVariables; ++ << 267 for(i=0;i<numberOfVariables;i++) 182 { 268 { 183 yTemp[i] = fyIn[i] + hstep * ( << 269 yTemp[i] = yIn[i] + Step*(b61*DyDx[i] + b62*ak2[i] + b63*ak3[i] + 184 b61 * dydx[i] + b62 * ak2[i] + << 270 b64*ak4[i] + b65*ak5[i]) ; 185 b63 * ak3[i] + b64 * ak4[i] + b65 << 186 } 271 } 187 RightHandSide(yTemp, ak6); // << 272 RightHandSide(yTemp, ak6) ; // 6th stage 188 273 189 for(G4int i = 0; i < numberOfVariables; ++ << 274 for(i=0;i<numberOfVariables;i++) 190 { 275 { 191 yOut[i] = fyIn[i] + hstep * ( << 276 yOut[i] = yIn[i] + Step*(b71*DyDx[i] + b72*ak2[i] + b73*ak3[i] + 192 b71 * dydx[i] + b72 * ak2[i] + b73 << 277 b74*ak4[i] + b75*ak5[i] + b76*ak6[i] ); 193 b74 * ak4[i] + b75 * ak5[i] + b76 << 194 } 278 } 195 RightHandSide(yOut, ak7); // << 279 RightHandSide(yOut, ak7); //7th and Final stage 196 280 197 for(G4int i = 0; i < numberOfVariables; ++ << 281 for(i=0;i<numberOfVariables;i++) 198 { 282 { 199 yErr[i] = hstep * ( << 283 yErr[i] = Step*(dc1*DyDx[i] + dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i] + 200 dc1 * dydx[i] + dc2 * ak2[i] + << 284 dc5*ak5[i] + dc6*ak6[i] + dc7*ak7[i] ) + 1.5e-18 ; 201 dc3 * ak3[i] + dc4 * ak4[i] + << 202 dc5 * ak5[i] + dc6 * ak6[i] + dc7 << 203 ) + 1.5e-18; << 204 285 205 // Store Input and Final values, for p 286 // Store Input and Final values, for possible use in calculating chord 206 // << 287 fLastInitialVector[i] = yIn[i] ; 207 fyOut[i] = yOut[i]; << 288 fLastFinalVector[i] = yOut[i]; 208 fdydxIn[i] = dydx[i]; << 289 fInitialDyDx[i] = DyDx[i]; 209 } 290 } 210 291 211 fLastStepLength = hstep; << 292 fLastStepLength = Step; >> 293 >> 294 return ; 212 } 295 } 213 296 214 G4double G4DormandPrince745::DistChord() const << 215 { << 216 // Coefficients were taken from Some Pract << 217 // by Lawrence F. Shampine, page 149, c* << 218 // << 219 const G4double hf1 = 6025192743.0 / 300855 << 220 hf3 = 51252292925.0 / 65400 << 221 hf4 = - 2691868925.0 / 4512 << 222 hf5 = 187940372067.0 / 1594 << 223 hf6 = - 1776094331.0 / 1974 << 224 hf7 = 11237099.0 / 23504338 << 225 297 226 G4ThreeVector mid; << 298 // Calculate DistChord given start, mid and end-point of step >> 299 G4double G4DormandPrince745::DistLine( G4double yStart[], G4double yMid[], G4double yEnd[] ) const >> 300 { >> 301 G4double distLine, distChord; >> 302 G4ThreeVector initialPoint, finalPoint, midPoint; >> 303 >> 304 initialPoint = G4ThreeVector( yStart[0], yStart[1], yStart[2]); >> 305 finalPoint = G4ThreeVector( yEnd[0], yEnd[1], yEnd[2]); >> 306 midPoint = G4ThreeVector( yMid[0], yMid[1], yMid[2]); 227 307 228 for(G4int i = 0; i < 3; ++i) << 308 // Use stored values of Initial and Endpoint + new Midpoint to evaluate >> 309 // distance of Chord >> 310 if (initialPoint != finalPoint) 229 { 311 { 230 mid[i] = fyIn[i] + 0.5 * fLastStepLeng << 312 distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint ); 231 hf1 * fdydxIn[i] + hf3 * ak3[i] + << 313 distChord = distLine; 232 hf4 * ak4[i] + hf5 * ak5[i] + hf6 << 314 } >> 315 else >> 316 { >> 317 distChord = (midPoint-initialPoint).mag(); 233 } 318 } >> 319 return distChord; >> 320 } >> 321 >> 322 // (New) DistChord function using interpolation >> 323 G4double G4DormandPrince745::DistChord2() const >> 324 { >> 325 // Copy the values of stages from this (original) into the Aux Stepper >> 326 *fAuxStepper = *this; 234 327 235 const G4ThreeVector begin = makeVector(fyI << 328 //Preparing for the interpolation 236 const G4ThreeVector end = makeVector(fyOut << 329 fAuxStepper->SetupInterpolation(); // (fLastInitialVector, fInitialDyDx, fLastStepLength); >> 330 //Interpolate to half step >> 331 fAuxStepper->Interpolate( /*fLastInitialVector, fInitialDyDx, fLastStepLength,*/ 0.5, fAuxStepper->fMidVector); 237 332 238 return G4LineSection::Distline(mid, begin, << 333 return DistLine( fLastInitialVector, fAuxStepper->fMidVector, fLastFinalVector); 239 } 334 } 240 335 241 // The lower (4th) order interpolant given by << 336 G4double G4DormandPrince745::DistChord() const 242 // J. R. Dormand and P. J. Prince, "Run << 243 // Computers & Mathematics with Applica << 244 // pp. 1007-1017, 1986. << 245 // << 246 void G4DormandPrince745:: << 247 Interpolate4thOrder(G4double yOut[], G4double << 248 { 337 { 249 const G4int numberOfVariables = GetNumberO << 338 // Coefficients were taken from Some Practical Runge-Kutta Formulas by Lawrence F. Shampine, page 149, c* 250 << 339 const G4double 251 const G4double tau2 = tau * tau, << 340 hf1 = 6025192743.0 / 30085553152.0, 252 tau3 = tau * tau2, << 341 hf2 = 0.0, 253 tau4 = tau2 * tau2; << 342 hf3 = 51252292925.0 / 65400821598.0, >> 343 hf4 = - 2691868925.0 / 45128329728.0, >> 344 hf5 = 187940372067.0 / 1594534317056.0, >> 345 hf6 = - 1776094331.0 / 19743644256.0, >> 346 hf7 = 11237099.0 / 235043384.0; >> 347 >> 348 for(G4int i = 0; i < 3; ++i) { >> 349 fMidVector[i] = fLastInitialVector[i] + 0.5 * fLastStepLength * >> 350 (hf1 * fInitialDyDx[i] + hf2 * ak2[i] + hf3 * ak3[i] + >> 351 hf4 * ak4[i] + hf5 * ak5[i] + hf6 * ak6[i] + hf7 * ak7[i]); >> 352 } >> 353 >> 354 // Use stored values of Initial and Endpoint + new Midpoint to evaluate >> 355 // distance of Chord >> 356 return DistLine( fLastInitialVector, fMidVector, fLastFinalVector); >> 357 } 254 358 255 const G4double bf1 = 1.0 / 11282082432.0 * << 359 //The original DistChord() function for the class 256 157015080.0 * tau4 - 13107642775.0 * t << 360 G4double G4DormandPrince745::DistChord3() const 257 32272833064.0 * tau + 11282082432.0); << 361 { >> 362 // Do half a step using StepNoErr >> 363 fAuxStepper->Stepper( fLastInitialVector, fInitialDyDx, 0.5 * fLastStepLength, >> 364 fAuxStepper->fMidVector, fAuxStepper->fMidError) ; >> 365 return DistLine( fLastInitialVector, fAuxStepper->fMidVector, fLastFinalVector); >> 366 } 258 367 259 const G4double bf3 = - 100.0 / 32700410799 << 368 // The lower (4th) order interpolant given by Dormand and prince 260 15701508.0 * tau3 - 914128567.0 * tau2 << 369 // "An RK 5(4) triple" 261 1323431896.0); << 370 //---Ref--- 262 << 371 // J. R. Dormand and P. J. Prince, “Runge-Kutta triples,” 263 const G4double bf4 = 25.0 / 5641041216.0 * << 372 // Computers & Mathematics with Applications, vol. 12, no. 9, 264 94209048.0 * tau3 - 1518414297.0 * tau << 373 // pp. 1007–1017, 1986. 265 889289856.0); << 374 //--------------------------- 266 << 267 const G4double bf5 = - 2187.0 / 1993167896 << 268 52338360.0 * tau3 - 451824525.0 * tau2 << 269 259006536.0); << 270 375 271 const G4double bf6 = 11.0 / 2467955532.0 * << 376 void G4DormandPrince745::SetupInterpolation_low() // const G4double *yInput, const G4double *dydx, const G4double Step) 272 106151040.0 * tau3 - 661884105.0 * tau << 377 { 273 946554244.0 * tau - 361440756.0); << 378 //Nothing to be done 274 << 379 } 275 const G4double bf7 = 1.0 / 29380423.0 * ta << 276 8293050.0 * tau2 - 82437520.0 * tau + << 277 380 278 for(G4int i = 0; i < numberOfVariables; ++ << 381 void G4DormandPrince745::Interpolate_low( /* const G4double yInput[], 279 { << 382 const G4double dydx[], 280 yOut[i] = fyIn[i] + fLastStepLength * << 383 const G4double Step, */ 281 bf1 * fdydxIn[i] + bf3 * ak3[i] + << 384 G4double yOut[], 282 bf5 * ak5[i] + bf6 * ak6[i] + bf7 << 385 G4double tau ) >> 386 { >> 387 G4double bf1, bf2, bf3, bf4, bf5, bf6, bf7; >> 388 // Coefficients for all the seven stages. >> 389 G4double Step = fLastStepLength; >> 390 const G4double *dydx= fInitialDyDx; >> 391 >> 392 const G4int numberOfVariables= this->GetNumberOfVariables(); >> 393 >> 394 // for(int i=0;i<numberOfVariables;i++) { yIn[i]=yInput[i]; } >> 395 >> 396 const G4double >> 397 tau_2 = tau * tau, >> 398 tau_3 = tau * tau_2, >> 399 tau_4 = tau_2 * tau_2; >> 400 >> 401 bf1 = (157015080.0*tau_4 - 13107642775.0*tau_3+ 34969693132.0*tau_2- 32272833064.0*tau >> 402 + 11282082432.0)/11282082432.0, >> 403 bf2 = 0.0 , >> 404 bf3 = - 100.0*tau*(15701508.0*tau_3 - 914128567.0*tau_2 + 2074956840.0*tau >> 405 - 1323431896.0)/32700410799.0, >> 406 bf4 = 25.0*tau*(94209048.0*tau_3- 1518414297.0*tau_2+ 2460397220.0*tau - 889289856.0)/5641041216.0 , >> 407 bf5 = -2187.0*tau*(52338360.0*tau_3 - 451824525.0*tau_2 + 687873124.0*tau - 259006536.0)/199316789632.0 , >> 408 bf6 = 11.0*tau*(106151040.0*tau_3- 661884105.0*tau_2 + 946554244.0*tau - 361440756.0)/2467955532.0 , >> 409 bf7 = tau*(1.0 - tau)*(8293050.0*tau_2 - 82437520.0*tau + 44764047.0)/ 29380423.0 ; >> 410 >> 411 //Putting together the coefficients calculated as the respective stage coefficients >> 412 for( int i=0; i<numberOfVariables; i++){ >> 413 yOut[i] = yIn[i] + Step*tau*(bf1*dydx[i] + bf2*ak2[i] + bf3*ak3[i] + bf4*ak4[i] >> 414 + bf5*ak5[i] + bf6*ak6[i] + bf7*ak7[i] ) ; 283 } 415 } 284 } 416 } 285 417 >> 418 286 // Following interpolant of order 5 was given 419 // Following interpolant of order 5 was given by Baker,Dormand,Gilmore, Prince : 287 // T. S. Baker, J. R. Dormand, J. P. Gi << 420 //---Ref--- 288 // "Continuous approximation with embed << 421 // T. S. Baker, J. R. Dormand, J. P. Gilmore, and P. J. Prince, 289 // Applied Numerical Mathematics, vol. << 422 // “Continuous approximation with embedded Runge-Kutta methods,” 290 // << 423 // Applied Numerical Mathematics, vol. 22, no. 1, pp. 51–62, 1996. 291 // Calculating the extra stages for the interp << 424 //--------------------- 292 // << 425 293 void G4DormandPrince745::SetupInterpolation5th << 426 // Calculating the extra stages for the interpolant : 294 { << 427 void G4DormandPrince745::SetupInterpolation_high( /* const G4double yInput[], 295 // Coefficients for the additional stages << 428 const G4double dydx[], 296 // << 429 const G4double Step */ ){ 297 const G4double b81 = 6245.0 / 62208.0, << 430 298 b82 = 0.0, << 431 //Coefficients for the additional stages : 299 b83 = 8875.0 / 103032.0, << 432 const G4double 300 b84 = -125.0 / 1728.0, << 433 b81 = 6245.0/62208.0 , 301 b85 = 801.0 / 13568.0, << 434 b82 = 0.0 , 302 b86 = -13519.0 / 368064.0, << 435 b83 = 8875.0/103032.0 , 303 b87 = 11105.0 / 368064.0, << 436 b84 = -125.0/1728.0 , 304 << 437 b85 = 801.0/13568.0 , 305 b91 = 632855.0 / 4478976.0, << 438 b86 = -13519.0/368064.0 , 306 b92 = 0.0, << 439 b87 = 11105.0/368064.0 , 307 b93 = 4146875.0 / 6491016.0 << 440 308 b94 = 5490625.0 /14183424.0 << 441 b91 = 632855.0/4478976.0 , 309 b95 = -15975.0 / 108544.0, << 442 b92 = 0.0 , 310 b96 = 8295925.0 / 220286304 << 443 b93 = 4146875.0/6491016.0 , 311 b97 = -1779595.0 / 62938944 << 444 b94 = 5490625.0/14183424.0 , 312 b98 = -805.0 / 4104.0; << 445 b95 = -15975.0/108544.0 , >> 446 b96 = 8295925.0/220286304.0 , >> 447 b97 = -1779595.0/62938944.0 , >> 448 b98 = -805.0/4104.0 ; >> 449 >> 450 const G4int numberOfVariables= this->GetNumberOfVariables(); >> 451 const G4double *dydx = fInitialDyDx; >> 452 const G4double Step = fLastStepLength; 313 453 314 const G4int numberOfVariables = GetNumberO << 454 // Saving yInput because yInput and yOut can be aliases for same array 315 State yTemp = {0., 0., 0., 0., 0., 0., 0., << 455 // for(int i=0;i<numberOfVariables;i++) { yIn[i]=yInput[i]; } >> 456 // yTemp[7] = yIn[7]; 316 457 317 // Evaluate the extra stages << 458 //Evaluate the extra stages : 318 // << 459 for(int i=0;i<numberOfVariables;i++) 319 for(G4int i = 0; i < numberOfVariables; ++ << 320 { 460 { 321 yTemp[i] = fyIn[i] + fLastStepLength * << 461 yTemp[i] = yIn[i] + Step*(b81*dydx[i] + b82*ak2[i] + b83*ak3[i] + 322 b81 * fdydxIn[i] + b82 * ak2[i] + << 462 b84*ak4[i] + b85*ak5[i] + b86*ak6[i] + 323 b84 * ak4[i] + b85 * ak5[i] + b86 << 463 b87*ak7[i]); 324 b87 * ak7[i] << 325 ); << 326 } 464 } 327 RightHandSide(yTemp, ak8); // 8th << 465 RightHandSide(yTemp, ak8); //8th Stage 328 466 329 for(G4int i = 0; i < numberOfVariables; ++ << 467 for(int i=0;i<numberOfVariables;i++) 330 { 468 { 331 yTemp[i] = fyIn[i] + fLastStepLength * << 469 yTemp[i] = yIn[i] + Step*(b91*dydx[i] + b92*ak2[i] + b93*ak3[i] + 332 b91 * fdydxIn[i] + b92 * ak2[i] + << 470 b94*ak4[i] + b95*ak5[i] + b96*ak6[i] + 333 b94 * ak4[i] + b95 * ak5[i] + b96 << 471 b97*ak7[i] + b98*ak8[i] ); 334 b97 * ak7[i] + b98 * ak8[i] << 335 ); << 336 } 472 } 337 RightHandSide(yTemp, ak9); // 9th << 473 RightHandSide(yTemp, ak9); //9th Stage 338 } 474 } 339 475 >> 476 340 // Calculating the interpolated result yOut wi 477 // Calculating the interpolated result yOut with the coefficients 341 // << 478 void G4DormandPrince745::Interpolate_high( /* const G4double yInput[], 342 void G4DormandPrince745:: << 479 const G4double dydx[], 343 Interpolate5thOrder(G4double yOut[], G4double << 480 const G4double Step, */ 344 { << 481 G4double yOut[], 345 // Define the coefficients for the polynom << 482 G4double tau ){ 346 // << 483 //Define the coefficients for the polynomials 347 G4double bi[10][5]; << 484 G4double bi[10][5], b[10]; >> 485 const G4int numberOfVariables = this->GetNumberOfVariables(); >> 486 const G4double *dydx = fInitialDyDx; >> 487 // const G4double fullStep = fLastStepLength; >> 488 >> 489 // If given requestedStep in argument: >> 490 // G4double tau = requestedStep / fLastStepLength; 348 491 349 // COEFFICIENTS OF bi[1] 492 // COEFFICIENTS OF bi[1] 350 bi[1][0] = 1.0, << 493 bi[1][0] = 1.0 , 351 bi[1][1] = -38039.0 / 7040.0, << 494 bi[1][1] = -38039.0/7040.0 , 352 bi[1][2] = 125923.0 / 10560.0, << 495 bi[1][2] = 125923.0/10560.0 , 353 bi[1][3] = -19683.0 / 1760.0, << 496 bi[1][3] = -19683.0/1760.0 , 354 bi[1][4] = 3303.0 / 880.0, << 497 bi[1][4] = 3303.0/880.0 , 355 // -------------------------------------- 498 // -------------------------------------------------------- 356 // 499 // 357 // COEFFICIENTS OF bi[2] 500 // COEFFICIENTS OF bi[2] 358 bi[2][0] = 0.0, << 501 bi[2][0] = 0.0 , 359 bi[2][1] = 0.0, << 502 bi[2][1] = 0.0 , 360 bi[2][2] = 0.0, << 503 bi[2][2] = 0.0 , 361 bi[2][3] = 0.0, << 504 bi[2][3] = 0.0 , 362 bi[2][4] = 0.0, << 505 bi[2][4] = 0.0 , 363 // -------------------------------------- 506 // -------------------------------------------------------- 364 // 507 // 365 // COEFFICIENTS OF bi[3] 508 // COEFFICIENTS OF bi[3] 366 bi[3][0] = 0.0, << 509 bi[3][0] = 0.0 , 367 bi[3][1] = -12500.0 / 4081.0, << 510 bi[3][1] = -12500.0/4081.0 , 368 bi[3][2] = 205000.0 / 12243.0, << 511 bi[3][2] = 205000.0/12243.0 , 369 bi[3][3] = -90000.0 / 4081.0, << 512 bi[3][3] = -90000.0/4081.0 , 370 bi[3][4] = 36000.0 / 4081.0, << 513 bi[3][4] = 36000.0/4081.0 , 371 // -------------------------------------- 514 // -------------------------------------------------------- 372 // 515 // 373 // COEFFICIENTS OF bi[4] 516 // COEFFICIENTS OF bi[4] 374 bi[4][0] = 0.0, << 517 bi[4][0] = 0.0 , 375 bi[4][1] = -3125.0 / 704.0, << 518 bi[4][1] = -3125.0/704.0 , 376 bi[4][2] = 25625.0 / 1056.0, << 519 bi[4][2] = 25625.0/1056.0 , 377 bi[4][3] = -5625.0 / 176.0, << 520 bi[4][3] = -5625.0/176.0 , 378 bi[4][4] = 1125.0 / 88.0, << 521 bi[4][4] = 1125.0/88.0 , 379 // -------------------------------------- 522 // -------------------------------------------------------- 380 // 523 // 381 // COEFFICIENTS OF bi[5] 524 // COEFFICIENTS OF bi[5] 382 bi[5][0] = 0.0, << 525 bi[5][0] = 0.0 , 383 bi[5][1] = 164025.0 / 74624.0, << 526 bi[5][1] = 164025.0/74624.0 , 384 bi[5][2] = -448335.0 / 37312.0, << 527 bi[5][2] = -448335.0/37312.0 , 385 bi[5][3] = 295245.0 / 18656.0, << 528 bi[5][3] = 295245.0/18656.0 , 386 bi[5][4] = -59049.0 / 9328.0, << 529 bi[5][4] = -59049.0/9328.0 , 387 // -------------------------------------- 530 // -------------------------------------------------------- 388 // 531 // 389 // COEFFICIENTS OF bi[6] 532 // COEFFICIENTS OF bi[6] 390 bi[6][0] = 0.0, << 533 bi[6][0] = 0.0 , 391 bi[6][1] = -25.0 / 28.0, << 534 bi[6][1] = -25.0/28.0 , 392 bi[6][2] = 205.0 / 42.0, << 535 bi[6][2] = 205.0/42.0 , 393 bi[6][3] = -45.0 / 7.0, << 536 bi[6][3] = -45.0/7.0 , 394 bi[6][4] = 18.0 / 7.0, << 537 bi[6][4] = 18.0/7.0 , 395 // -------------------------------------- 538 // -------------------------------------------------------- 396 // 539 // 397 // COEFFICIENTS OF bi[7] 540 // COEFFICIENTS OF bi[7] 398 bi[7][0] = 0.0, << 541 bi[7][0] = 0.0 , 399 bi[7][1] = -2.0 / 11.0, << 542 bi[7][1] = -2.0/11.0 , 400 bi[7][2] = 73.0 / 55.0, << 543 bi[7][2] = 73.0/55.0 , 401 bi[7][3] = -171.0 / 55.0, << 544 bi[7][3] = -171.0/55.0 , 402 bi[7][4] = 108.0 / 55.0, << 545 bi[7][4] = 108.0/55.0 , 403 // -------------------------------------- 546 // -------------------------------------------------------- 404 // 547 // 405 // COEFFICIENTS OF bi[8] 548 // COEFFICIENTS OF bi[8] 406 bi[8][0] = 0.0, << 549 bi[8][0] = 0.0 , 407 bi[8][1] = 189.0 / 22.0, << 550 bi[8][1] = 189.0/22.0 , 408 bi[8][2] = -1593.0 / 55.0, << 551 bi[8][2] = -1593.0/55.0 , 409 bi[8][3] = 3537.0 / 110.0, << 552 bi[8][3] = 3537.0/110.0 , 410 bi[8][4] = -648.0 / 55.0, << 553 bi[8][4] = -648.0/55.0 , 411 // -------------------------------------- 554 // -------------------------------------------------------- 412 // 555 // 413 // COEFFICIENTS OF bi[9] 556 // COEFFICIENTS OF bi[9] 414 bi[9][0] = 0.0, << 557 bi[9][0] = 0.0 , 415 bi[9][1] = 351.0 / 110.0, << 558 bi[9][1] = 351.0/110.0 , 416 bi[9][2] = -999.0 / 55.0, << 559 bi[9][2] = -999.0/55.0 , 417 bi[9][3] = 2943.0 / 110.0, << 560 bi[9][3] = 2943.0/110.0 , 418 bi[9][4] = -648.0 / 55.0; << 561 bi[9][4] = -648.0/55.0 ; 419 // -------------------------------------- 562 // -------------------------------------------------------- 420 << 563 421 // Calculating the polynomials << 564 // for(G4int i = 0; i< numberOfVariables; i++) { yIn[i] = yInput[i]; } 422 << 565 423 G4double b[10]; << 566 // Calculating the polynomials : 424 std::memset(b, 0.0, sizeof(b)); << 567 #if 1 425 << 568 for(int iStage=1; iStage<=9; iStage++){ 426 G4double tauPower = 1.0; << 569 b[iStage] = 0; 427 for(G4int j = 0; j <= 4; ++j) << 570 } 428 { << 571 429 for(G4int iStage = 1; iStage <= 9; ++iS << 572 for(int j=0; j<=4; j++){ 430 { << 573 G4double tauPower = 1.0; 431 b[iStage] += bi[iStage][j] * tauPowe << 574 for(int iStage=1; iStage<=9; iStage++){ >> 575 b[iStage] += bi[iStage][j]*tauPower; 432 } 576 } 433 tauPower *= tau; 577 tauPower *= tau; 434 } 578 } >> 579 #else >> 580 G4double tau0 = tau; 435 581 436 const G4int numberOfVariables = GetNumberO << 582 for(int i=1; i<=9; i++){ //Here i is NOT the coordinate no. , it's stage no. 437 const G4double stepLen = fLastStepLength * << 583 b[i] = 0; 438 for(G4int i = 0; i < numberOfVariables; ++ << 584 tau = 1.0; 439 { << 585 for(int j=0; j<=4; j++){ 440 yOut[i] = fyIn[i] + stepLen * ( << 586 b[i] += bi[i][j]*tau; 441 b[1] * fdydxIn[i] + b[2] * ak2[i] << 587 tau*=tau0; 442 b[4] * ak4[i] + b[5] * ak5[i] + b[ << 588 } 443 b[7] * ak7[i] + b[8] * ak8[i] + b[ << 589 } 444 ); << 590 #endif >> 591 >> 592 G4double stepLen = fLastStepLength * tau; >> 593 for(int i=0; i<numberOfVariables; i++){ //Here i IS the cooridnate no. >> 594 yOut[i] = yIn[i] + stepLen *(b[1]*dydx[i] + b[2]*ak2[i] + b[3]*ak3[i] + >> 595 b[4]*ak4[i] + b[5]*ak5[i] + b[6]*ak6[i] + >> 596 b[7]*ak7[i] + b[8]*ak8[i] + b[9]*ak9[i] ); 445 } 597 } >> 598 >> 599 } >> 600 >> 601 //G4DormandPrince745::G4DormandPrince745(G4DormandPrince745& DP_Obj){ >> 602 // >> 603 //} >> 604 >> 605 // Overloaded = operator >> 606 G4DormandPrince745& G4DormandPrince745::operator=(const G4DormandPrince745& right) >> 607 { >> 608 // this->G4DormandPrince745(right.GetEquationOfMotion(),right.GetNumberOfVariables(), false); >> 609 >> 610 int noVars = right.GetNumberOfVariables(); >> 611 for(int i =0; i< noVars; i++) >> 612 { >> 613 this->ak2[i] = right.ak2[i]; >> 614 this->ak3[i] = right.ak3[i]; >> 615 this->ak4[i] = right.ak4[i]; >> 616 this->ak5[i] = right.ak5[i]; >> 617 this->ak6[i] = right.ak6[i]; >> 618 this->ak7[i] = right.ak7[i]; >> 619 this->ak8[i] = right.ak8[i]; >> 620 this->ak9[i] = right.ak9[i]; >> 621 >> 622 this->fInitialDyDx[i] = right.fInitialDyDx[i]; >> 623 this->fLastInitialVector[i] = right.fLastInitialVector[i]; >> 624 this->fMidVector[i] = right.fMidVector[i]; >> 625 this->fMidError[i] = right.fMidError[i]; >> 626 } >> 627 >> 628 this->fLastStepLength = right.fLastStepLength; >> 629 >> 630 return *this; 446 } 631 } 447 632