Virtual Testbed
Ship dynamics simulator for extreme conditions
euler.hh
1 #ifndef VTESTBED_CORE_EULER_HH
2 #define VTESTBED_CORE_EULER_HH
3 
4 #include <algorithm>
5 
6 #include <vtestbed/base/blitz.hh>
7 
8 namespace vtb {
9 
10  namespace core {
11 
20  template <class T>
21  class Euler_solver {
22 
23  public:
24  using value_type = T;
25 
26  private:
27  T _minstep = T(1e-3);
28  T _step{1e-3};
29  bool _verbose = false;
30 
31  public:
32 
33  Euler_solver() = default;
34  Euler_solver(const Euler_solver&) = default;
35  Euler_solver& operator=(const Euler_solver&) = default;
36  Euler_solver(Euler_solver&&) = default;
37  Euler_solver& operator=(Euler_solver&&) = default;
38  ~Euler_solver() = default;
39 
40  template <class Function, int N>
41  inline blitz::TinyVector<T,N>
42  solve(Function f, T t0, T t1, const blitz::TinyVector<T,N>& x0) {
43  using vec = blitz::TinyVector<T,N>;
44  using std::min;
45  bool finished = false;
46  const T h_min = this->_minstep;
47  T h = this->_step;
48  T t_n = t0;
49  vec x_n = x0;
50  while (!finished) {
51  if (this->_verbose) {
52  std::clog
53  << std::setw(8) << "euler"
54  << std::setw(12) << t_n
55  << std::setw(12) << h
56  << std::setw(10) << x_n
57  << std::endl;
58  }
59  if (t_n+h+h_min > t1) {
60  h = t1-t_n;
61  finished = true;
62  }
63  x_n += h*f(t_n, x_n);
64  t_n += h;
65  }
66  if (this->_verbose) {
67  std::clog
68  << std::setw(8) << "euler"
69  << std::setw(12) << t_n
70  << std::setw(12) << h
71  << std::setw(10) << x_n
72  << std::endl;
73  }
74  return x_n;
75  }
76 
78  template <class Function, int N>
79  inline blitz::TinyVector<T,N>
80  operator()(Function f, T t0, T t1, const blitz::TinyVector<T,N>& x0) {
81  return this->solve<Function,N>(f, t0, t1, x0);
82  }
83 
84  inline void
85  step(T rhs) {
86  if (!(rhs > T(0))) {
87  throw std::invalid_argument("Euler_solver::step <= 0");
88  }
89  this->_step = rhs;
90  }
91 
92  inline void
93  min_step(T rhs) {
94  if (!(rhs > T(0))) {
95  throw std::invalid_argument("Euler_solver::min_step <= 0");
96  }
97  this->_minstep = rhs;
98  }
99 
100  inline T min_step() const { return this->_minstep; }
101  inline T step() const { return this->_step; }
102  inline void verbose(bool rhs) { this->_verbose = rhs; }
103  inline bool verbose() const { return this->_verbose; }
104 
105  };
106 
107 
108  }
109 
110 }
111 
112 #endif // vim:filetype=cpp
blitz::TinyVector< T, N > operator()(Function f, T t0, T t1, const blitz::TinyVector< T, N > &x0)
Definition: euler.hh:80
Main namespace.
Definition: convert.hh:9
Euler initial value problem solver.
Definition: euler.hh:21