Virtual Testbed
Ship dynamics simulator for extreme conditions
core/wave.hh
1 #ifndef VTESTBED_CORE_WAVE_HH
2 #define VTESTBED_CORE_WAVE_HH
3 
4 #include <cmath>
5 
6 #include <vtestbed/base/blitz.hh>
7 #include <vtestbed/core/grid.hh>
8 #include <vtestbed/core/units.hh>
9 
10 namespace vtb {
11 
12  namespace core {
13 
14  namespace bits {
15 
16  template <class T, int N>
17  struct Wave_number;
18 
19  template <class T>
20  struct Wave_number<T,1> {
21  static inline blitz::TinyVector<T,1>
22  wave_number(Length<T> length, Direction<T> angle) {
23  return 2*T{M_PI}/length;
24  }
25  };
26 
27  template <class T>
28  struct Wave_number<T,2> {
29  static inline blitz::TinyVector<T,2>
30  wave_number(Length<T> length, Direction<T> angle) {
31  const T a = 2*T{M_PI}/length;
32  return {a*std::cos(angle), a*std::sin(angle)};
33  }
34  };
35 
36  }
37 
38  template <class T, int N>
39  inline blitz::TinyVector<T,N>
40  wave_number(Length<T> length, Direction<T> angle) {
41  return bits::Wave_number<T,N>::wave_number(length, angle);
42  }
43 
53  template <class T, int N>
54  class alignas(16) Wave_base {
55 
56  public:
57  typedef T value_type;
58  typedef blitz::TinyVector<T,N-1> vec;
59 
60  protected:
61  T _amplitude{1};
62  vec _k{T{0.05}};
63  T _angfrequency{1};
64 
65  public:
66 
67  Wave_base() = default;
68  Wave_base(const Wave_base&) = default;
69  Wave_base& operator=(const Wave_base&) = default;
70 
71  inline explicit
72  Wave_base(Amplitude<T> amplitude, const vec& k, Frequency<T> freq):
73  _amplitude{amplitude},
74  _k{k},
75  _angfrequency{freq} {}
76 
77  inline explicit
78  Wave_base(
79  Amplitude<T> amplitude,
80  Length<T> length,
81  Direction<T> direction,
82  Frequency<T> velocity
83  ):
84  _amplitude{amplitude},
85  _k{::vtb::core::wave_number<T,N-1>(length, direction)},
86  _angfrequency{velocity} {}
87 
89  inline T
90  amplitude() const noexcept {
91  return this->_amplitude;
92  }
93 
95  inline const vec&
96  wave_number() const noexcept {
97  return this->_k;
98  }
99 
101  inline T
102  angular_frequency() const noexcept {
103  return this->_angfrequency;
104  }
105 
107  inline vec
108  length() const noexcept {
109  return T{2}*T{M_PI} / this->wave_number();
110  }
111 
113  inline T
114  scalar_length() const noexcept {
115  return T{2}*T{M_PI} / blitz::length(this->wave_number());
116  }
117 
119  inline T
120  direction() const noexcept {
121  return std::atan2(this->_k(1), this->_k(0));
122  }
123 
125  inline T
126  period() const noexcept {
127  return T{2}*T{M_PI} / this->angular_frequency();
128  }
129 
131  inline vec
132  phase_velocity() const noexcept {
133  return this->angular_frequency() / this->wave_number();
134  }
135 
136  inline constexpr static int
137  dimensions() noexcept {
138  return N;
139  }
140 
141  };
142 
149  template <class T, int N>
150  class No_wave: public Wave_base<T,N> {
151 
152  public:
153  using typename Wave_base<T,N>::vec;
154 
155  public:
156 
157  No_wave() = default;
158  No_wave(const No_wave&) = default;
159  No_wave& operator=(const No_wave&) = default;
160 
162  inline T
163  operator()(const vec&, T) const noexcept {
164  return T{0};
165  }
166 
167  };
168 
169  template <class T, int N, class Wave>
170  inline T
171  courant_number_sum(const Wave& wave, const Grid<T,N>& grid) {
172  static_assert(N == 3, "bad N");
173  const auto& dx = grid.select(1,2).delta();
174  return sum(wave.max_velocity() / dx);
175  }
176 
177  template <class T, int N, class Wave>
178  inline T
179  courant_number(const Wave& wave, const Grid<T,N>& grid) {
180  static_assert(N == 3, "bad N");
181  const T& dt = grid.delta(0);
182  return dt * courant_number_sum<T,N,Wave>(wave, grid);
183  }
184 
185  }
186 
187 }
188 
189 #endif // vim:filetype=cpp
T operator()(const vec &, T) const noexcept
Returns wavy surface elevation at point x.
Definition: core/wave.hh:163
T angular_frequency() const noexcept
Get wave angular frequency.
Definition: core/wave.hh:102
const vec & wave_number() const noexcept
Get wave numbers for each dimension.
Definition: core/wave.hh:96
vec phase_velocity() const noexcept
Get phase velocity.
Definition: core/wave.hh:132
vec length() const noexcept
Get wave length.
Definition: core/wave.hh:108
T direction() const noexcept
Get wave direction in radians.
Definition: core/wave.hh:120
T scalar_length() const noexcept
Get wave length.
Definition: core/wave.hh:114
T length(const blitz::TinyVector< T, N > &x)
Computes vector length without overflow.
Definition: blitz.hh:471
T amplitude() const noexcept
Get wave amplitude.
Definition: core/wave.hh:90
Main namespace.
Definition: convert.hh:9
T period() const noexcept
Get wave period.
Definition: core/wave.hh:126