Virtual Testbed
Ship dynamics simulator for extreme conditions
plain_wave_generator.hh
1 #ifndef VTESTBED_CORE_PLAIN_WAVE_GENERATOR_HH
2 #define VTESTBED_CORE_PLAIN_WAVE_GENERATOR_HH
3 
4 #include <any>
5 #include <cmath>
6 #include <memory>
7 #include <stdexcept>
8 #include <vector>
9 
10 #include <vtestbed/base/blitz.hh>
11 #include <vtestbed/base/for_loop.hh>
12 #include <vtestbed/core/grid.hh>
13 #include <vtestbed/core/policy.hh>
14 #include <vtestbed/core/types.hh>
15 #include <vtestbed/core/wavy_surface_generator.hh>
16 
17 namespace vtb {
18 
19  namespace core {
20 
31  template <class T, int N, class Wave>
32  inline void
33  generate_wave(const Grid<T,N>& grid, Array<T,N>& result, Wave wave) {
34  #if defined(VTB_DEBUG)
35  if (!blitz::all(result.shape() == grid.shape())) {
36  throw std::invalid_argument("vtb::core::generate_wave: bad result shape");
37  }
38  #endif
39  const auto delta{grid.delta()};
40  parallel_for_loop<N>(
41  grid.begin(),
42  grid.end(),
43  [&result,&grid,&wave,&delta](const blitz::TinyVector<int,N>& idx) {
44  blitz::TinyVector<T,N> v{grid(idx, delta)};
45  blitz::TinyVector<T,N-1> x;
46  for (int i=1; i<N; ++i) { x(i-1) = v(i); }
47  result(idx) = wave(x, v(0));
48  }
49  );
50  }
51 
52  template <class T, int N, class Wave>
53  inline Array<T,N>
54  generate_wave(const Grid<T,N>& grid, Wave wave) {
55  Array<T,N> result(grid.shape());
56  generate_wave<T,N,Wave>(grid, result, wave);
57  return result;
58  }
59 
68  template <class T, int N, class Wave, Policy P=Policy::OpenMP>
70 
71  private:
73 
74  public:
75  using typename base_type::grid_type;
76  using typename base_type::array_type;
77  using wave_type = Wave;
78 
79  private:
80  Wave _wave;
81 
82  public:
83 
84  Plain_wave_generator() = default;
87  operator=(const Plain_wave_generator&) = default;
88  inline explicit Plain_wave_generator(const Wave& wave): _wave(wave) {}
89 
90  virtual void
91  generate(const grid_type& grid, array_type& result) = 0;
92 
93  inline const Wave& wave() const { return this->_wave; }
94 
95  inline grid_type acf_grid() const override { return this->_wave.acf_grid(); }
96 
97  };
98 
99  template <class T, int N, class Wave, Policy P>
101  make_plain_wave_generator(const Wave& wave);
102 
103  template <class T, int N, class Wave, Policy P>
105  make_plain_wave_generator();
106 
107  template <class T, int N>
109  make_plain_wave_generator(std::any wave, Policy policy);
110 
121  template <class T, int N>
123  public Wavy_surface_generator<T,N> {
124 
125  private:
127  using typename base_type::grid_type;
128  using typename base_type::array_type;
129 
130  public:
134 
135  private:
136  container_type _generators;
137 
138  public:
139 
143  operator=(const Irregular_wave_surface_generator&) = default;
144 
145  inline explicit
147  _generators(std::move(generators)) {}
148 
149  inline void
150  generate(const grid_type& grid, array_type& result) override {
151  result = T(0);
152  for (auto& gen : this->_generators) {
153  result += gen->generate(grid);
154  }
155  };
156 
157  };
158 
159  }
160 
161 }
162 
163 #endif // vim:filetype=cpp
Wavy surface generator that produces elevation grid for multiple waves.
const int_n & end() const noexcept
End indices (exclusive).
Definition: core/grid.hh:144
const int_n shape() const noexcept
The number of points for all dimensions.
Definition: core/grid.hh:108
const T delta(int i) const
The size of the patch (interval) for dimension i.
Definition: core/grid.hh:239
A region defined by start and end index and lower and upper bound for each dimension.
Definition: core/grid.hh:25
Wavy surface generator that produces elevation grid for individual wave.
const int_n & begin() const noexcept
Start indices (inclusive).
Definition: core/grid.hh:120
Main namespace.
Definition: convert.hh:9
void generate_wave(const Grid< T, N > &grid, Array< T, N > &result, Wave wave)
Generate wavy surface for specified wave and spatio-temporal grid.
Base class for wavy surface generators.
Definition: core/types.hh:50