Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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],
412 fLastInitialVector[1], fLastInitialVector[2]);
413 finalPoint = G4ThreeVector( fLastFinalVector[0],
414 fLastFinalVector[1], fLastFinalVector[2]);
415
416 // Do half a step using StepNoErr
417
418 fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength,
419 fMidVector, fMidError );
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[]) override
G4double DistChord() const override
static G4double Distline(const G4ThreeVector &OtherPnt, const G4ThreeVector &LinePntA, const G4ThreeVector &LinePntB)
G4MagIntegratorStepper(G4EquationOfMotion *Equation, G4int numIntegrationVariables, G4int numStateVariables=12, G4bool isFSAL=false)
G4int GetNumberOfVariables() const
void RightHandSide(const G4double y[], G4double dydx[]) const