40#ifndef G4TDORMAND_PRINCE_45_HH
41#define G4TDORMAND_PRINCE_45_HH
47template <
class T_Equation,
unsigned int N = 6 >
99 fEquation_Rhs->T_Equation::RightHandSide(y, dydx);
108 yOutput, yError, dydxOutput);
113 static constexpr int N8=
N > 8 ?
N : 8;
126 T_Equation* fEquation_Rhs;
165template <
class T_Equation,
unsigned int N>
168 , fEquation_Rhs(equation)
173 G4Exception(
"G4TDormandPrince745: constructor",
"GeomField0001",
189template <
class T_Equation,
unsigned int N>
195 msg <<
"Equation has an incompatible number of variables." ;
196 msg <<
" template N = " <<
N
197 <<
" argument numVar = " << numVar ;
199 G4Exception(
"G4TCashKarpRKF45: constructor",
"GeomField0001",
202 assert( numVar ==
N );
205template <
class T_Equation,
unsigned int N>
214 StepWithError(yInput, dydx, hstep, yOutput, yError);
224template <
class T_Equation,
unsigned int N>
235 b31 = 3.0 / 40.0, b32 = 9.0 / 40.0,
236 b41 = 44.0 / 45.0, b42 = -56.0 / 15.0, b43 = 32.0/9.0,
238 b51 = 19372.0 / 6561.0, b52 = -25360.0 / 2187.0, b53 = 64448.0 / 6561.0,
239 b54 = -212.0 / 729.0,
241 b61 = 9017.0 / 3168.0 , b62 = -355.0 / 33.0,
242 b63 = 46732.0 / 5247.0, b64 = 49.0 / 176.0,
243 b65 = -5103.0 / 18656.0,
245 b71 = 35.0 / 384.0, b72 = 0.,
246 b73 = 500.0 / 1113.0, b74 = 125.0 / 192.0,
247 b75 = -2187.0 / 6784.0, b76 = 11.0 / 84.0,
261 dc1 = -(b71 - 5179.0 / 57600.0),
263 dc3 = -(b73 - 7571.0 / 16695.0),
264 dc4 = -(b74 - 393.0 / 640.0),
265 dc5 = -(b75 + 92097.0 / 339200.0),
266 dc6 = -(b76 - 187.0 / 2100.0),
267 dc7 = -(- 1.0 / 40.0);
273 yOut[7] = yTemp[7] = fyIn[7] = yInput[7];
277 for(
unsigned int i = 0; i <
N; ++i)
280 yTemp[i] = yInput[i] + b21 * hstep * dydx[i];
282 RightHandSideInl(yTemp, ak2);
284 for(
unsigned int i = 0; i <
N; ++i)
286 yTemp[i] = fyIn[i] + hstep * (b31 * dydx[i] + b32 * ak2[i]);
288 RightHandSideInl(yTemp, ak3);
290 for(
unsigned int i = 0; i <
N; ++i)
292 yTemp[i] = fyIn[i] + hstep * (
293 b41 * dydx[i] + b42 * ak2[i] + b43 * ak3[i]);
295 RightHandSideInl(yTemp, ak4);
297 for(
unsigned int i = 0; i <
N; ++i)
299 yTemp[i] = fyIn[i] + hstep * (
300 b51 * dydx[i] + b52 * ak2[i] + b53 * ak3[i] + b54 * ak4[i]);
302 RightHandSideInl(yTemp, ak5);
304 for(
unsigned int i = 0; i <
N; ++i)
306 yTemp[i] = fyIn[i] + hstep * (
307 b61 * dydx[i] + b62 * ak2[i] +
308 b63 * ak3[i] + b64 * ak4[i] + b65 * ak5[i]);
310 RightHandSideInl(yTemp, ak6);
312 for(
unsigned int i = 0; i <
N; ++i)
314 yOut[i] = fyIn[i] + hstep * (
315 b71 * dydx[i] + b72 * ak2[i] + b73 * ak3[i] +
316 b74 * ak4[i] + b75 * ak5[i] + b76 * ak6[i]);
318 RightHandSideInl(yOut, ak7);
320 for(
unsigned int i = 0; i <
N; ++i)
323 dc1 * dydx[i] + dc2 * ak2[i] +
324 dc3 * ak3[i] + dc4 * ak4[i] +
325 dc5 * ak5[i] + dc6 * ak6[i] + dc7 * ak7[i]
331 fdydxIn[i] = dydx[i];
334 fLastStepLength = hstep;
338template <
class T_Equation,
unsigned int N >
346 assert( yOutput != yInput );
347 assert( yError != yInput );
349 StepWithError( yInput, dydx, Step, yOutput, yError);
352template <
class T_Equation,
unsigned int N>
359 const G4double hf1 = 6025192743.0 / 30085553152.0,
360 hf3 = 51252292925.0 / 65400821598.0,
361 hf4 = - 2691868925.0 / 45128329728.0,
362 hf5 = 187940372067.0 / 1594534317056.0,
363 hf6 = - 1776094331.0 / 19743644256.0,
364 hf7 = 11237099.0 / 235043384.0;
368 for(
unsigned int i = 0; i < 3; ++i)
370 mid[i] = fyIn[i] + 0.5 * fLastStepLength * (
371 hf1 * fdydxIn[i] + hf3 * ak3[i] +
372 hf4 * ak4[i] + hf5 * ak5[i] + hf6 * ak6[i] + hf7 * ak7[i]);
386template <
class T_Equation,
unsigned int N>
397 const G4double bf1 = 1.0 / 11282082432.0 * (
398 157015080.0 * tau4 - 13107642775.0 * tau3 + 34969693132.0 * tau2 -
399 32272833064.0 * tau + 11282082432.0);
401 const G4double bf3 = - 100.0 / 32700410799.0 * tau * (
402 15701508.0 * tau3 - 914128567.0 * tau2 + 2074956840.0 * tau -
405 const G4double bf4 = 25.0 / 5641041216.0 * tau * (
406 94209048.0 * tau3 - 1518414297.0 * tau2 + 2460397220.0 * tau -
409 const G4double bf5 = - 2187.0 / 199316789632.0 * tau * (
410 52338360.0 * tau3 - 451824525.0 * tau2 + 687873124.0 * tau -
413 const G4double bf6 = 11.0 / 2467955532.0 * tau * (
414 106151040.0 * tau3 - 661884105.0 * tau2 +
415 946554244.0 * tau - 361440756.0);
417 const G4double bf7 = 1.0 / 29380423.0 * tau * (1.0 - tau) * (
418 8293050.0 * tau2 - 82437520.0 * tau + 44764047.0);
420 for(
unsigned int i = 0; i <
N; ++i)
422 yOut[i] = fyIn[i] + fLastStepLength * tau * (
423 bf1 * fdydxIn[i] + bf3 * ak3[i] + bf4 * ak4[i] +
424 bf5 * ak5[i] + bf6 * ak6[i] + bf7 * ak7[i]);
435template <
class T_Equation,
unsigned int N>
440 const G4double b81 = 6245.0 / 62208.0,
442 b83 = 8875.0 / 103032.0,
443 b84 = -125.0 / 1728.0,
444 b85 = 801.0 / 13568.0,
445 b86 = -13519.0 / 368064.0,
446 b87 = 11105.0 / 368064.0,
448 b91 = 632855.0 / 4478976.0,
450 b93 = 4146875.0 / 6491016.0,
451 b94 = 5490625.0 /14183424.0,
452 b95 = -15975.0 / 108544.0,
453 b96 = 8295925.0 / 220286304.0,
454 b97 = -1779595.0 / 62938944.0,
455 b98 = -805.0 / 4104.0;
462 for(
unsigned int i = 0; i <
N; ++i)
464 yTemp[i] = fyIn[i] + fLastStepLength * (
465 b81 * fdydxIn[i] + b82 * ak2[i] + b83 * ak3[i] +
466 b84 * ak4[i] + b85 * ak5[i] + b86 * ak6[i] +
470 RightHandSideInl(yTemp, ak8);
472 for(
unsigned int i = 0; i <
N; ++i)
474 yTemp[i] = fyIn[i] + fLastStepLength * (
475 b91 * fdydxIn[i] + b92 * ak2[i] + b93 * ak3[i] +
476 b94 * ak4[i] + b95 * ak5[i] + b96 * ak6[i] +
477 b97 * ak7[i] + b98 * ak8[i]
480 RightHandSideInl(yTemp, ak9);
485template <
class T_Equation,
unsigned int N>
495 bi[1][1] = -38039.0 / 7040.0,
496 bi[1][2] = 125923.0 / 10560.0,
497 bi[1][3] = -19683.0 / 1760.0,
498 bi[1][4] = 3303.0 / 880.0,
511 bi[3][1] = -12500.0 / 4081.0,
512 bi[3][2] = 205000.0 / 12243.0,
513 bi[3][3] = -90000.0 / 4081.0,
514 bi[3][4] = 36000.0 / 4081.0,
519 bi[4][1] = -3125.0 / 704.0,
520 bi[4][2] = 25625.0 / 1056.0,
521 bi[4][3] = -5625.0 / 176.0,
522 bi[4][4] = 1125.0 / 88.0,
527 bi[5][1] = 164025.0 / 74624.0,
528 bi[5][2] = -448335.0 / 37312.0,
529 bi[5][3] = 295245.0 / 18656.0,
530 bi[5][4] = -59049.0 / 9328.0,
535 bi[6][1] = -25.0 / 28.0,
536 bi[6][2] = 205.0 / 42.0,
537 bi[6][3] = -45.0 / 7.0,
538 bi[6][4] = 18.0 / 7.0,
543 bi[7][1] = -2.0 / 11.0,
544 bi[7][2] = 73.0 / 55.0,
545 bi[7][3] = -171.0 / 55.0,
546 bi[7][4] = 108.0 / 55.0,
551 bi[8][1] = 189.0 / 22.0,
552 bi[8][2] = -1593.0 / 55.0,
553 bi[8][3] = 3537.0 / 110.0,
554 bi[8][4] = -648.0 / 55.0,
559 bi[9][1] = 351.0 / 110.0,
560 bi[9][2] = -999.0 / 55.0,
561 bi[9][3] = 2943.0 / 110.0,
562 bi[9][4] = -648.0 / 55.0;
568 std::memset(b, 0.0,
sizeof(b));
571 for(
G4int j = 0; j <= 4; ++j)
573 for(
G4int iStage = 1; iStage <= 9; ++iStage)
575 b[iStage] += bi[iStage][j] * tauPower;
581 const G4double stepLen = fLastStepLength * tau;
582 for(
G4int i = 0; i <
N; ++i)
584 yOut[i] = fyIn[i] + stepLen * (
585 b[1] * fdydxIn[i] + b[2] * ak2[i] + b[3] * ak3[i] +
586 b[4] * ak4[i] + b[5] * ak5[i] + b[6] * ak6[i] +
587 b[7] * ak7[i] + b[8] * ak8[i] + b[9] * ak9[i]
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
static G4double Distline(const G4ThreeVector &OtherPnt, const G4ThreeVector &LinePntA, const G4ThreeVector &LinePntB)
void RightHandSideInl(const G4double y[], G4double dydx[])
G4TDormandPrince45(T_Equation *equation)
T_Equation * GetSpecificEquation()
void Interpolate(G4double tau, G4double yOut[]) const
virtual G4int IntegratorOrder() const override
void Interpolate4thOrder(G4double yOut[], G4double tau) const
void SetupInterpolation()
void StepWithFinalDerivate(const G4double yInput[], const G4double dydx[], G4double hstep, G4double yOutput[], G4double yError[], G4double dydxOutput[])
void Stepper(const G4double yInput[], const G4double dydx[], G4double hstep, G4double yOutput[], G4double yError[], G4double dydxOutput[])
const field_utils::ShortState< N > & GetYOut() const
virtual G4double DistChord() const override final
void SetupInterpolation5thOrder()
virtual void Stepper(const G4double yInput[], const G4double dydx[], G4double hstep, G4double yOutput[], G4double yError[]) override final
void Interpolate5thOrder(G4double yOut[], G4double tau) const
void StepWithError(const G4double yInput[], const G4double dydx[], G4double hstep, G4double yOutput[], G4double yError[])
void copy(G4double dst[], const G4double src[], std::size_t size=G4FieldTrack::ncompSVEC)