RK4ODEIntegrator.h
Go to the documentation of this file.
1 #ifndef _utl_RK4ODEIntegrator_h_
2 #define _utl_RK4ODEIntegrator_h_
3 
4 
5 namespace utl {
6 
19  template<class DerivativeFunctor, class VectorType>
20  class RK4Iterator {
21  public:
22  RK4Iterator(const double x, const VectorType& y,
23  DerivativeFunctor& d)
24  : fX(x), fDerivativeFunctor(d), fStatus(true)
25  { Copy(d, y, fY); }
26 
27  double GetX() const { return fX; }
28 
29  VectorType& GetY() { return fY; }
30 
31  const VectorType& GetY() const { return fY; }
32 
33  bool
34  Advance(const double dx, const VectorType& dYdX)
35  {
36  const unsigned int n = fDerivativeFunctor;
37  // first step: x -> x + dx/2
38  const double dx2 = 0.5 * dx;
39  VectorType y1;
40  for (unsigned int i = 0; i < n; ++i)
41  y1[i] = fY[i] + dx2 * dYdX[i];
42  // second step
43  const double x1 = fX + dx2;
44  VectorType dYdX1;
45  if (!fDerivativeFunctor(x1, y1, dYdX1))
46  return fStatus = false;
47  for (unsigned int i = 0; i < n; ++i)
48  y1[i] = fY[i] + dx2 * dYdX1[i];
49  // third step
50  VectorType dYdX2;
51  if (!fDerivativeFunctor(x1, y1, dYdX2))
52  return fStatus = false;
53  for (unsigned int i = 0; i < n; ++i) {
54  y1[i] = fY[i] + dx * dYdX2[i];
55  dYdX2[i] += dYdX1[i];
56  }
57  // fourth step
58  fX += dx;
59  if (!fDerivativeFunctor(fX, y1, dYdX1))
60  return fStatus = false;
61  const double dx6 = (1./6) * dx;
62  for (unsigned int i = 0; i < n; ++i)
63  fY[i] += dx6 * (dYdX[i] + dYdX1[i] + 2.*dYdX2[i]);
64  return fStatus = true;
65  }
66 
67  bool
68  Advance(const double dx)
69  {
70  VectorType dYdX;
71  fDerivativeFunctor(fX, fY, dYdX);
72  return Advance(dx, dYdX);
73  }
74 
76  operator+=(const double dx)
77  { Advance(dx); return *this; }
78 
80  operator-=(const double dx)
81  { Advance(-dx); return *this; }
82 
83  explicit operator bool() const { return fStatus; }
84 
85  private:
86  static
87  void
88  Copy(const unsigned int n, const VectorType& a, VectorType& b)
89  {
90  for (unsigned int i = 0; i < n; ++i)
91  b[i] = a[i];
92  }
93 
94  double fX;
95  VectorType fY;
96  DerivativeFunctor& fDerivativeFunctor;
97  bool fStatus;
98  };
99 
100 
160  template<class DerivativeFunctor>
162  public:
163  RK4ODEIntegrator(DerivativeFunctor& d)
164  : fDerivativeFunctor(d) { }
165 
166  template<class VectorType>
168  Begin(const double x, const VectorType& y)
169  {
170  return
172  }
173 
174  DerivativeFunctor& GetDerivativeFunctor()
175  { return fDerivativeFunctor; }
176 
177  private:
178  DerivativeFunctor& fDerivativeFunctor;
179  };
180 
181 }
182 
183 
184 #endif
DerivativeFunctor & fDerivativeFunctor
RK4Iterator(const double x, const VectorType &y, DerivativeFunctor &d)
RK4Iterator< DerivativeFunctor, VectorType > Begin(const double x, const VectorType &y)
DerivativeFunctor & GetDerivativeFunctor()
double GetX() const
bool Advance(const double dx, const VectorType &dYdX)
VectorType & GetY()
const VectorType & GetY() const
RK4Iterator & operator+=(const double dx)
static void Copy(const unsigned int n, const VectorType &a, VectorType &b)
bool Advance(const double dx)
RK4Iterator & operator-=(const double dx)
RK4ODEIntegrator(DerivativeFunctor &d)
DerivativeFunctor & fDerivativeFunctor

, generated on Tue Sep 26 2023.