UNIVERS  15.3
UNIVERS base processing software API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ode_runge4.hpp
1 /* ode_runge4.hpp */
2 /* $Id$ */
3 #ifndef __ode_runge4_hpp
4 #define __ode_runge4_hpp
5 
6 #include <mth/ode.hpp>
7 
9 namespace ode
10 {
12  template <typename T, typename X, typename F> class Runge4_1D : public Solver1D<T, X, F>
13  {
14  public:
15 
17  bool operator()(const T &t,
18  const T &dt,
19  F &f,
20  X &x,
21  X &dx
22  ) const
23  {return step(t, dt, f, x, dx);}
24 
26  bool operator()(const T &t,
27  const T &dt,
28  F &f,
29  X &x,
30  X &dx,
31  X &theta
32  ) const
33  {return step(t, dt, f, x, dx, theta);}
34 
35 
36 
37  protected:
38 
40  virtual bool step(const T &t,
41  const T &dt,
42  F &f,
43  X &x,
44  X &dx
45  ) const;
46 
48  bool step(const T &t,
49  const T &dt,
50  F &f,
51  X &x,
52  X &dx,
53  X &theta
54  ) const;
55  };
56 
58  template <typename T, typename X, typename F> class Runge4 : public Solver<T, X, F>
59  {
60  protected:
61 
63  virtual bool step(const T &t,
64  const T &dt,
65  const std::vector<F> &f,
66  std::vector<X> &x,
67  std::vector<X> &dx
68  ) const;
69  };
70 
71 
72  // ------------------------------------------------------------------------------------------------------------
73  // -- Inline implementation -----------------------------------------------------------------------------------
74  // ------------------------------------------------------------------------------------------------------------
75 
77  template <typename T, typename X, typename F>
78  bool Runge4_1D<T,X,F>::step(const T &t,
79  const T &dt,
80  F &f,
81  X &x,
82  X &dx
83  ) const
84  {
85  X k1 = f(t, x);
86 
87  dx = x + k1*dt*(T)0.5; // using dx as temporary variable
88  X k2 = f(t + dt*(T)0.5, dx);
89 
90  dx = x + k2*dt*(T)0.5;
91  X k3 = f(t + dt*(T)0.5, dx);
92 
93  dx = x + k3*dt;
94  X k4 = f(t + dt, dx);
95 
96  dx = (k1 + (T)2*k2 + (T)2*k3 + k4)*dt/(T)6.;
97 
98  return true;
99  }
100 
101 
103  template <typename T, typename X, typename F>
104  bool Runge4_1D<T,X,F>::step(const T &t,
105  const T &dt,
106  F &f,
107  X &x,
108  X &dx,
109  X &theta
110  ) const
111  {
112  X k1 = f(t, x);
113 
114  dx = x + k1*dt*(T)0.5; // using dx as temporary variable
115  X k2 = f(t + dt*(T)0.5, dx);
116 
117  dx = x + k2*dt*(T)0.5;
118  X k3 = f(t + dt*(T)0.5, dx);
119 
120  dx = x + k3*dt;
121  X k4 = f(t + dt, dx);
122 
123  theta = (k2 - k3)/(k1 - k2);
124 
125  dx = (k1 + (T)2*k2 + (T)2*k3 + k4)*dt/(T)6.;
126 
127  return true;
128  }
129 
130  /* Inline implementation for one equation solver. */
131  template <typename T, typename X, typename F>
132  bool Runge4<T,X,F>::step(const T &t,
133  const T &dt,
134  const std::vector<F> &f,
135  std::vector<X> &x,
136  std::vector<X> &dx
137  ) const
138  {
139  // check sizes
140  if (f.size() != x.size() || x.size() != dx.size())
141  {
142  printf ("ode::Runge4::solve: error, different sizes of f(%zu), x(%zu), dx(%zu)\n",
143  f.size(), x.size(), dx.size());
144  }
145 
146  // calc current right parts values
147  std::vector<X> k1(f.size(), 0.);
148  for (size_t i=0; i<f.size(); i++)
149  k1[i] = f[i](t, x);
150 
151  // shifted vector
152  std::vector<X> s(f.size(), 0.);
153  for (size_t i=0; i<f.size(); i++)
154  s[i] = x[i] + k1[i]*dt*(T)0.5;
155 
156  // second order koefficients
157  std::vector<X> k2(f.size(), 0.);
158  for (size_t i=0; i<f.size(); i++)
159  k2[i] = f[i](t + dt*(T)0.5, s);
160 
161  // shifted vector
162  for (size_t i=0; i<f.size(); i++)
163  s[i] = x[i] + k2[i]*dt*(T)0.5;
164 
165  // third order koefficients
166  std::vector<X> k3(f.size(), 0.);
167  for (size_t i=0; i<f.size(); i++)
168  k3[i] = f[i](t + dt*(T)0.5, s);
169 
170  // shifted vector
171  for (size_t i=0; i<f.size(); i++)
172  s[i] = x[i] + k3[i]*dt;
173 
174  // fourth order koefficients
175  std::vector<X> k4(f.size(), 0.);
176  for (size_t i=0; i<f.size(); i++)
177  k4[i] = f[i](t + dt, s);
178 
179  // resulted functions values
180  for (size_t i=0; i<f.size(); i++)
181  dx[i] = (k1[i] + (T)2*k2[i] + (T)2*k3[i] + k4[i])*dt/(T)6;
182 
183  return true;
184  }
185 };
186 
187 #endif /* ode_runge4.hpp */
bool operator()(const T &t, const T &dt, F &f, X &x, X &dx, X &theta) const
Definition: ode_runge4.hpp:26
virtual bool step(const T &t, const T &dt, const std::vector< F > &f, std::vector< X > &x, std::vector< X > &dx) const
Definition: ode_runge4.hpp:132
Definition: ode_runge4.hpp:12
bool operator()(const T &t, const T &dt, F &f, X &x, X &dx) const
Definition: ode_runge4.hpp:17
Definition: ode.hpp:41
Definition: ode_runge4.hpp:58
Definition: ode.hpp:13
virtual bool step(const T &t, const T &dt, F &f, X &x, X &dx) const
Definition: ode_runge4.hpp:78