Geant4-11
G4DormandPrinceRK78.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4DormandPrinceRK78 implementation
27//
28// Dormand-Prince 8(7)13M non-FSAL, based on RK scheme from:
29// P.J. Prince, J.R. Dormand, "High order embedded Runge-Kutta formulae",
30// Journal of Computational and Applied Mathematics, Volume 7, Issue 1, 1981,
31// Pages 67-75, ISSN 0377-0427, DOI: 10.1016/0771-050X(81)90010-3
32//
33// Created: Somnath Banerjee, Google Summer of Code 2015, 28 June 2015
34// Supervision: John Apostolakis, CERN
35// --------------------------------------------------------------------
36
38#include "G4LineSection.hh"
39
40// Constructor
41//
43 G4int noIntegrationVariables,
44 G4bool primary)
45 : G4MagIntegratorStepper(EqRhs, noIntegrationVariables)
46{
47 const G4int numberOfVariables = noIntegrationVariables;
48
49 // New Chunk of memory being created for use by the stepper
50
51 // aki - for storing intermediate RHS
52 //
53 ak2 = new G4double[numberOfVariables];
54 ak3 = new G4double[numberOfVariables];
55 ak4 = new G4double[numberOfVariables];
56 ak5 = new G4double[numberOfVariables];
57 ak6 = new G4double[numberOfVariables];
58 ak7 = new G4double[numberOfVariables];
59 ak8 = new G4double[numberOfVariables];
60 ak9 = new G4double[numberOfVariables];
61 ak10 = new G4double[numberOfVariables];
62 ak11 = new G4double[numberOfVariables];
63 ak12 = new G4double[numberOfVariables];
64 ak13 = new G4double[numberOfVariables];
65
66 const G4int numStateVars = std::max(noIntegrationVariables, 8);
67 yTemp = new G4double[numStateVars];
68 yIn = new G4double[numStateVars] ;
69
70 fLastInitialVector = new G4double[numStateVars] ;
71 fLastFinalVector = new G4double[numStateVars] ;
72
73 fLastDyDx = new G4double[numStateVars];
74
75 fMidVector = new G4double[numStateVars];
76 fMidError = new G4double[numStateVars];
77
78 if( primary )
79 {
80 fAuxStepper = new G4DormandPrinceRK78(EqRhs, numberOfVariables, !primary);
81 }
82}
83
84// Destructor
85//
87{
88 // Clear all previously allocated memory for stepper and DistChord
89
90 delete [] ak2;
91 delete [] ak3;
92 delete [] ak4;
93 delete [] ak5;
94 delete [] ak6;
95 delete [] ak7;
96 delete [] ak8;
97 delete [] ak9;
98 delete [] ak10;
99 delete [] ak11;
100 delete [] ak12;
101 delete [] ak13;
102 delete [] yTemp;
103 delete [] yIn;
104
105 delete [] fLastInitialVector;
106 delete [] fLastFinalVector;
107 delete [] fLastDyDx;
108 delete [] fMidVector;
109 delete [] fMidError;
110
111 delete fAuxStepper;
112}
113
114
115// The following scheme and the set of coefficients have been obtained from
116// Table2. RK8(7)13M (Rational approximations) from:
117// P. J. Prince and J. R. Dormand, "High order embedded Runge-Kutta formulae"
118// Journal of Computational and Applied Math., vol.7, no.1, pp.67-75, 1980.
119//
120// Stepper :
121//
122// Passing in the value of yInput[],the first time dydx[] and Step length
123// Giving back yOut and yErr arrays for output and error respectively
124//
126 const G4double dydx[],
127 G4double Step,
128 G4double yOut[],
129 G4double yErr[])
130{
131 G4int i;
132
133 // The various constants defined on the basis of butcher tableu
134 //
135 const G4double b21 = 1.0/18,
136 b31 = 1.0/48.0 ,
137 b32 = 1.0/16.0 ,
138
139 b41 = 1.0/32.0 ,
140 b42 = 0.0 ,
141 b43 = 3.0/32.0 ,
142
143 b51 = 5.0/16.0 ,
144 b52 = 0.0 ,
145 b53 = -75.0/64.0 ,
146 b54 = 75.0/64.0 ,
147
148 b61 = 3.0/80.0 ,
149 b62 = 0.0 ,
150 b63 = 0.0 ,
151 b64 = 3.0/16.0 ,
152 b65 = 3.0/20.0 ,
153
154 b71 = 29443841.0/614563906.0 ,
155 b72 = 0.0 ,
156 b73 = 0.0 ,
157 b74 = 77736538.0/692538347.0 ,
158 b75 = -28693883.0/1125000000.0 ,
159 b76 = 23124283.0/1800000000.0 ,
160
161 b81 = 16016141.0/946692911.0 ,
162 b82 = 0.0 ,
163 b83 = 0.0 ,
164 b84 = 61564180.0/158732637.0 ,
165 b85 = 22789713.0/633445777.0 ,
166 b86 = 545815736.0/2771057229.0 ,
167 b87 = -180193667.0/1043307555.0 ,
168
169 b91 = 39632708.0/573591083.0 ,
170 b92 = 0.0 ,
171 b93 = 0.0 ,
172 b94 = -433636366.0/683701615.0 ,
173 b95 = -421739975.0/2616292301.0 ,
174 b96 = 100302831.0/723423059.0 ,
175 b97 = 790204164.0/839813087.0 ,
176 b98 = 800635310.0/3783071287.0 ,
177
178 b101 = 246121993.0/1340847787.0 ,
179 b102 = 0.0 ,
180 b103 = 0.0 ,
181 b104 = -37695042795.0/15268766246.0 ,
182 b105 = -309121744.0/1061227803.0 ,
183 b106 = -12992083.0/490766935.0 ,
184 b107 = 6005943493.0/2108947869.0 ,
185 b108 = 393006217.0/1396673457.0 ,
186 b109 = 123872331.0/1001029789.0 ,
187
188 b111 = -1028468189.0/846180014.0 ,
189 b112 = 0.0 ,
190 b113 = 0.0 ,
191 b114 = 8478235783.0/508512852.0 ,
192 b115 = 1311729495.0/1432422823.0 ,
193 b116 = -10304129995.0/1701304382.0 ,
194 b117 = -48777925059.0/3047939560.0 ,
195 b118 = 15336726248.0/1032824649.0 ,
196 b119 = -45442868181.0/3398467696.0 ,
197 b1110 = 3065993473.0/597172653.0 ,
198
199 b121 = 185892177.0/718116043.0 ,
200 b122 = 0.0 ,
201 b123 = 0.0 ,
202 b124 = -3185094517.0/667107341.0 ,
203 b125 = -477755414.0/1098053517.0 ,
204 b126 = -703635378.0/230739211.0 ,
205 b127 = 5731566787.0/1027545527.0 ,
206 b128 = 5232866602.0/850066563.0 ,
207 b129 = -4093664535.0/808688257.0 ,
208 b1210 = 3962137247.0/1805957418.0 ,
209 b1211 = 65686358.0/487910083.0 ,
210
211 b131 = 403863854.0/491063109.0 ,
212 b132 = 0.0 ,
213 b133 = 0.0 ,
214 b134 = -5068492393.0/434740067.0 ,
215 b135 = -411421997.0/543043805.0 ,
216 b136 = 652783627.0/914296604.0 ,
217 b137 = 11173962825.0/925320556.0 ,
218 b138 = -13158990841.0/6184727034.0 ,
219 b139 = 3936647629.0/1978049680.0 ,
220 b1310 = -160528059.0/685178525.0 ,
221 b1311 = 248638103.0/1413531060.0 ,
222 b1312 = 0.0 ,
223
224 c1 = 14005451.0/335480064.0 ,
225 // c2 = 0.0 ,
226 // c3 = 0.0 ,
227 // c4 = 0.0 ,
228 // c5 = 0.0 ,
229 c6 = -59238493.0/1068277825.0 ,
230 c7 = 181606767.0/758867731.0 ,
231 c8 = 561292985.0/797845732.0 ,
232 c9 = -1041891430.0/1371343529.0 ,
233 c10 = 760417239.0/1151165299.0 ,
234 c11 = 118820643.0/751138087.0 ,
235 c12 = - 528747749.0/2220607170.0 ,
236 c13 = 1.0/4.0 ,
237
238 c_1 = 13451932.0/455176623.0 ,
239 // c_2 = 0.0 ,
240 // c_3 = 0.0 ,
241 // c_4 = 0.0 ,
242 // c_5 = 0.0 ,
243 c_6 = -808719846.0/976000145.0 ,
244 c_7 = 1757004468.0/5645159321.0 ,
245 c_8 = 656045339.0/265891186.0 ,
246 c_9 = -3867574721.0/1518517206.0 ,
247 c_10 = 465885868.0/322736535.0 ,
248 c_11 = 53011238.0/667516719.0 ,
249 c_12 = 2.0/45.0 ,
250 c_13 = 0.0 ,
251
252 dc1 = c_1 - c1 ,
253 // dc2 = c_2 - c2 ,
254 // dc3 = c_3 - c3 ,
255 // dc4 = c_4 - c4 ,
256 // dc5 = c_5 - c5 ,
257 dc6 = c_6 - c6 ,
258 dc7 = c_7 - c7 ,
259 dc8 = c_8 - c8 ,
260 dc9 = c_9 - c9 ,
261 dc10 = c_10 - c10 ,
262 dc11 = c_11 - c11 ,
263 dc12 = c_12 - c12 ,
264 dc13 = c_13 - c13 ;
265 //
266 // end of declaration !
267
268 const G4int numberOfVariables = GetNumberOfVariables();
269
270 // The number of variables to be integrated over
271 //
272 yOut[7] = yTemp[7] = yIn[7] = yInput[7];
273
274 // Saving yInput because yInput and yOut can be aliases for same array
275 //
276 for(i=0; i<numberOfVariables; ++i)
277 {
278 yIn[i]=yInput[i];
279 }
280 // RightHandSide(yIn, dydx) ; // 1st Stage - Not doing, getting passed
281
282 for(i=0; i<numberOfVariables; ++i)
283 {
284 yTemp[i] = yIn[i] + b21*Step*dydx[i] ;
285 }
286 RightHandSide(yTemp, ak2) ; // 2nd Stage
287
288 for(i=0; i<numberOfVariables; ++i)
289 {
290 yTemp[i] = yIn[i] + Step*(b31*dydx[i] + b32*ak2[i]) ;
291 }
292 RightHandSide(yTemp, ak3) ; // 3rd Stage
293
294 for(i=0; i<numberOfVariables; ++i)
295 {
296 yTemp[i] = yIn[i] + Step*(b41*dydx[i] + b42*ak2[i] + b43*ak3[i]) ;
297 }
298 RightHandSide(yTemp, ak4) ; // 4th Stage
299
300 for(i=0; i<numberOfVariables; ++i)
301 {
302 yTemp[i] = yIn[i] + Step*(b51*dydx[i] + b52*ak2[i] + b53*ak3[i] +
303 b54*ak4[i]) ;
304 }
305 RightHandSide(yTemp, ak5) ; // 5th Stage
306
307 for(i=0; i<numberOfVariables; ++i)
308 {
309 yTemp[i] = yIn[i] + Step*(b61*dydx[i] + b62*ak2[i] + b63*ak3[i] +
310 b64*ak4[i] + b65*ak5[i]) ;
311 }
312 RightHandSide(yTemp, ak6) ; // 6th Stage
313
314 for(i=0; i<numberOfVariables; ++i)
315 {
316 yTemp[i] = yIn[i] + Step*(b71*dydx[i] + b72*ak2[i] + b73*ak3[i] +
317 b74*ak4[i] + b75*ak5[i] + b76*ak6[i]);
318 }
319 RightHandSide(yTemp, ak7); // 7th Stage
320
321 for(i=0; i<numberOfVariables; ++i)
322 {
323 yTemp[i] = yIn[i] + Step*(b81*dydx[i] + b82*ak2[i] + b83*ak3[i] +
324 b84*ak4[i] + b85*ak5[i] + b86*ak6[i] +
325 b87*ak7[i]);
326 }
327 RightHandSide(yTemp, ak8); // 8th Stage
328
329 for(i=0; i<numberOfVariables; ++i)
330 {
331 yTemp[i] = yIn[i] + Step*(b91*dydx[i] + b92*ak2[i] + b93*ak3[i] +
332 b94*ak4[i] + b95*ak5[i] + b96*ak6[i] +
333 b97*ak7[i] + b98*ak8[i] );
334 }
335 RightHandSide(yTemp, ak9); // 9th Stage
336
337 for(i=0; i<numberOfVariables; ++i)
338 {
339 yTemp[i] = yIn[i] + Step*(b101*dydx[i] + b102*ak2[i] + b103*ak3[i] +
340 b104*ak4[i] + b105*ak5[i] + b106*ak6[i] +
341 b107*ak7[i] + b108*ak8[i] + b109*ak9[i]);
342 }
343 RightHandSide(yTemp, ak10); // 10th Stage
344
345 for(i=0; i<numberOfVariables; ++i)
346 {
347 yTemp[i] = yIn[i] + Step*(b111*dydx[i] + b112*ak2[i] + b113*ak3[i] +
348 b114*ak4[i] + b115*ak5[i] + b116*ak6[i] +
349 b117*ak7[i] + b118*ak8[i] + b119*ak9[i] +
350 b1110*ak10[i]);
351 }
352 RightHandSide(yTemp, ak11); // 11th Stage
353
354 for(i=0; i<numberOfVariables; ++i)
355 {
356 yTemp[i] = yIn[i] + Step*(b121*dydx[i] + b122*ak2[i] + b123*ak3[i] +
357 b124*ak4[i] + b125*ak5[i] + b126*ak6[i] +
358 b127*ak7[i] + b128*ak8[i] + b129*ak9[i] +
359 b1210*ak10[i] + b1211*ak11[i]);
360 }
361 RightHandSide(yTemp, ak12); // 12th Stage
362
363 for(i=0; i<numberOfVariables; ++i)
364 {
365 yTemp[i] = yIn[i]+Step*(b131*dydx[i] + b132*ak2[i] + b133*ak3[i] +
366 b134*ak4[i] + b135*ak5[i] + b136*ak6[i] +
367 b137*ak7[i] + b138*ak8[i] + b139*ak9[i] +
368 b1310*ak10[i] + b1311*ak11[i] + b1312*ak12[i]);
369 }
370 RightHandSide(yTemp, ak13); // 13th and final Stage
371
372 for(i=0; i<numberOfVariables; ++i)
373 {
374 // Accumulate increments with proper weights
375
376 yOut[i] = yIn[i] + Step*(c1*dydx[i] + // c2 * ak2[i] + c3 * ak3[i]
377 // + c4 * ak4[i] + c5 * ak5[i]
378 + c6*ak6[i] +
379 c7*ak7[i] + c8*ak8[i] +c9*ak9[i] + c10*ak10[i]
380 + c11*ak11[i] + c12*ak12[i] + c13*ak13[i]) ;
381
382 // Estimate error as difference between 7th and 8th order methods
383 //
384 yErr[i] = Step*(dc1*dydx[i] + // dc2*ak2[i] + dc3*ak3[i] + dc4*ak4[i]
385 // + dc5*ak5[i]
386 + dc6*ak6[i] + dc7*ak7[i] + dc8*ak8[i]
387 + dc9*ak9[i] + dc10*ak10[i] + dc11*ak11[i] + dc12*ak12[i]
388 + dc13*ak13[i] ) ;
389
390 // Store Input and Final values, for possible use in calculating chord
391 //
392 fLastInitialVector[i] = yIn[i] ;
393 fLastFinalVector[i] = yOut[i];
394 fLastDyDx[i] = dydx[i];
395 }
396 fLastStepLength = Step;
397
398 return ;
399}
400
401// DistChord
402//
404{
405 G4double distLine, distChord;
406 G4ThreeVector initialPoint, finalPoint, midPoint;
407
408 // Store last initial and final points
409 // (they will be overwritten in self-Stepper call!)
410 //
411 initialPoint = G4ThreeVector( fLastInitialVector[0],
413 finalPoint = G4ThreeVector( fLastFinalVector[0],
415
416 // Do half a step using StepNoErr
417
420
421 midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]);
422
423 // Use stored values of Initial and Endpoint + new Midpoint to evaluate
424 // distance of Chord
425 //
426 if (initialPoint != finalPoint)
427 {
428 distLine = G4LineSection::Distline(midPoint, initialPoint, finalPoint);
429 distChord = distLine;
430 }
431 else
432 {
433 distChord = (midPoint-initialPoint).mag();
434 }
435 return distChord;
436}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4DormandPrinceRK78(G4EquationOfMotion *EqRhs, G4int numberOfVariables=6, G4bool primary=true)
void Stepper(const G4double y[], const G4double dydx[], G4double h, G4double yout[], G4double yerr[])
G4DormandPrinceRK78 * fAuxStepper
G4double DistChord() const
static G4double Distline(const G4ThreeVector &OtherPnt, const G4ThreeVector &LinePntA, const G4ThreeVector &LinePntB)
G4int GetNumberOfVariables() const
void RightHandSide(const G4double y[], G4double dydx[]) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments