1 #ifndef _utl_RK5ODEIntegrator_h_
2 #define _utl_RK5ODEIntegrator_h_
11 template<
class VectorType>
14 const VectorType& y,
const VectorType& dYdX,
15 VectorType& errorScaling)
18 for (
unsigned int i = 0; i < n; ++i)
35 template<
class DerivativeFunctor,
class VectorType>
50 const VectorType&
GetY()
const {
return fY; }
55 Advance(
const double dx,
const VectorType& dYdX)
81 explicit operator bool()
const {
return fStatus; }
87 Step(
const double dx, VectorType& yNew,
const VectorType& dYdX)
92 for (
unsigned int k = 0; k < 5; ++k) {
93 for (
unsigned int i = 0; i < n; ++i) {
94 double dy =
fB[k][0] * dYdX[i];
95 for (
unsigned int j = 1; j <= k; ++j)
96 dy +=
fB[k][j] * dYdXt[j-1][i];
97 y1[i] =
fY[i] + dx * dy;
102 for (
unsigned int i = 0; i < n; ++i) {
103 double dy =
fC[0] * dYdX[i];
104 double de =
fD[0] * dYdX[i];
105 for (
unsigned int j = 1; j < 5; ++j) {
106 dy +=
fC[j] * dYdXt[j][i];
107 de +=
fD[j] * dYdXt[j][i];
109 yNew[i] =
fY[i] + dx * dy;
117 Copy(
const unsigned int n,
const VectorType&
a, VectorType&
b)
119 for (
unsigned int i = 0; i < n; ++i)
125 Clear(
const unsigned int n, VectorType&
b)
127 for (
unsigned int i = 0; i < n; ++i)
138 static const double fA[6];
139 static const double fB[5][5];
140 static const double fC[5];
141 static const double fD[5];
143 template<
class A,
class B,
class C>
147 template<
class DerivativeFunctor,
class VectorType>
149 0.2, 0.3, 0.6, 1, 0.875
152 template<
class DerivativeFunctor,
class VectorType>
153 const double RK5Iterator<DerivativeFunctor, VectorType>::fB[][5] = {
157 { -11./54, 2.5, -70./27, 35./27 },
158 { 1631./55296, 175./512, 575./13824, 44275./110592, 253./4096 }
161 template<
class DerivativeFunctor,
class VectorType>
162 const double RK5Iterator<DerivativeFunctor, VectorType>::fC[] = {
163 37./378, 250./621, 125./594, 0, 512./1771
166 template<
class DerivativeFunctor,
class VectorType>
167 const double RK5Iterator<DerivativeFunctor, VectorType>::fD[] = {
168 RK5Iterator<DerivativeFunctor, VectorType>::fC[0] - 2825./27648,
169 RK5Iterator<DerivativeFunctor, VectorType>::fC[1] - 18575./48384,
170 RK5Iterator<DerivativeFunctor, VectorType>::fC[2] - 13525./55296,
171 RK5Iterator<DerivativeFunctor, VectorType>::fC[3] - 277./14336,
172 RK5Iterator<DerivativeFunctor, VectorType>::fC[4] - 0.25
188 template<
class DerivativeFunctor,
190 class ErrorScalingPolicy = DefaultRK5ErrorScaling>
194 const VectorType& y0,
195 DerivativeFunctor& d,
196 const double accuracy = 1e-5,
197 const ErrorScalingPolicy& errorScaling =
207 const double accuracy = 1e-5,
208 const ErrorScalingPolicy& errorScaling =
230 const unsigned int n =
fIterator.GetDerivativeFunctor();
233 fIterator.GetDerivativeFunctor()(x, y, dYdX);
235 double dxAttempt = dx;
236 double x1 = x + dxAttempt;
241 double stepFactor = 0.1;
242 if (
fIterator.Step(dxAttempt, y1, dYdX)) {
248 dxAttempt *= stepFactor;
268 {
Advance(-dx);
return *
this; }
283 const VectorType& error,
const VectorType& scaling)
286 for (
unsigned int i = 1; i < n; ++i) {
287 const double se =
std::abs(error[i] / scaling[i]);
306 class DerivativeFunctor,
308 class ErrorScalingPolicy
316 class DerivativeFunctor,
318 class ErrorScalingPolicy
323 >::fPowerDown = -0.25;
326 class DerivativeFunctor,
328 class ErrorScalingPolicy
333 >::fSlightlyLess = 0.9;
336 class DerivativeFunctor,
338 class ErrorScalingPolicy
343 >::fPowerLawThreshold = 1.889568e-4;
406 template<
class DerivativeFunctor>
412 template<
class VectorType>
414 Begin(
const double x,
const VectorType& y)
421 template<
class VectorType>
424 const double accuracy = 1e-5)
432 template<
class VectorType,
433 class ErrorScalingPolicy>
436 const double accuracy, ErrorScalingPolicy& es)
AdaptiveRK5Iterator & operator+=(const double dx)
AdaptiveRK5Iterator< DerivativeFunctor, VectorType, ErrorScalingPolicy > AdaptiveBegin(const double x, const double dx, const VectorType &y, const double accuracy, ErrorScalingPolicy &es)
DerivativeFunctor & fDerivativeFunctor
const VectorType & GetY() const
static const double fPowerLawThreshold
bool Step(const double dx, VectorType &yNew, const VectorType &dYdX)
const ErrorScalingPolicy & fErrorScaling
AdaptiveRK5Iterator(const double x0, const double dx0, const VectorType &y0, DerivativeFunctor &d, const double accuracy=1e-5, const ErrorScalingPolicy &errorScaling=DefaultRK5ErrorScaling())
AdaptiveRK5Iterator & operator-=(const double dx)
static const double fB[5][5]
static const double fA[6]
RK5Iterator< DerivativeFunctor, VectorType > Begin(const double x, const VectorType &y)
RK5Iterator(const double x, const VectorType &y, DerivativeFunctor &d)
double pow(const double x, const unsigned int i)
static const double fPowerUp
RK5Iterator & operator-=(const double dx)
double abs(const SVector< n, T > &v)
AdaptiveRK5Iterator & operator++()
double GetNextStepSize() const
DerivativeFunctor & GetDerivativeFunctor()
DerivativeFunctor & fDerivativeFunctor
static double GetMaxScaledError(const unsigned int n, const VectorType &error, const VectorType &scaling)
static const double fPowerDown
const VectorType & GetYError() const
static const double fSlightlyLess
const VectorType & GetYError() const
AdaptiveRK5Iterator< DerivativeFunctor, VectorType > AdaptiveBegin(const double x, const double dx, const VectorType &y, const double accuracy=1e-5)
DerivativeFunctor & GetDerivativeFunctor()
void operator()(const unsigned int n, const double dx, const VectorType &y, const VectorType &dYdX, VectorType &errorScaling) const
static void Clear(const unsigned int n, VectorType &b)
RK5Iterator< DerivativeFunctor, VectorType > fIterator
bool Advance(const double dx, const VectorType &dYdX)
AdaptiveRK5Iterator(const double dx0, const RK5Iterator< DerivativeFunctor, VectorType > &rk5It, const double accuracy=1e-5, const ErrorScalingPolicy &errorScaling=DefaultRK5ErrorScaling())
static const double fC[5]
bool Advance(const double dx)
RK5Iterator & operator+=(const double dx)
static const double fD[5]
bool Advance(const double dx)
static void Copy(const unsigned int n, const VectorType &a, VectorType &b)
RK5ODEIntegrator(DerivativeFunctor &d)
const VectorType & GetY() const