Virtual Testbed
Ship dynamics simulator for extreme conditions
testbed.hh
1 #ifndef VTESTBED_CORE_TESTBED_HH
2 #define VTESTBED_CORE_TESTBED_HH
3 
4 #include <iosfwd>
5 #include <memory>
6 
7 #include <vtestbed/base/blitz.hh>
8 #include <vtestbed/core/gerstner.hh>
9 #include <vtestbed/core/ship_motion_solver.hh>
10 #include <vtestbed/core/ship.hh>
11 #include <vtestbed/core/statistics.hh>
12 #include <vtestbed/core/types.hh>
13 #include <vtestbed/core/velocity_potential.hh>
14 #include <vtestbed/core/wave_numbers.hh>
15 #include <vtestbed/core/wave_pressure.hh>
16 #include <vtestbed/core/plain_wave_generator.hh>
17 #include <vtestbed/core/wetted_surface_solver.hh>
18 #include <vtestbed/core/arma_wind_solver.hh>
19 #include <vtestbed/core/anlt_wind_solver.hh>
20 
21 namespace vtb {
22 
23  namespace core {
24 
25  enum Solver_type {regular_solver, gerstner_solver};
26 
32  template <class T, int N>
33  class Testbed {
34 
35  public:
36  using value_type = T;
37  using ship_type = Ship<T>;
45  using vertex_field_3d = blitz::Array<blitz::TinyVector<T,3>,3>;
51  using grid2 = Grid<T,N-1>;
52  using grid3 = Grid<T,N>;
53  using grid4 = Grid<T,N+1>;
54  using array_type = Array<T,N>;
55  using phi_array_type = Array<T,N+1>;
56  using domain3 = blitz::RectDomain<N>;
57  using domain4 = blitz::RectDomain<N+1>;
59  using array2 = Array<T,2>;
60  using array3 = Array<T,3>;
61  using vec3 = Vector3<T>;
68  using panel_type = typename wetted_surface_solver_type::panel_type;
69  using panel_array = typename wetted_surface_solver_type::panel_array;
70  using waterline_type = typename wetted_surface_solver_type::waterline_type;
71  using irregular_surface_type = Array<vec3, 3>;
72  using irregular_surface_type_2d = Array<vec3, 2>;
73 
74  private:
75  ship_type _ship;
76  ship_motion_solver_ptr _ship_motion_solver;
77  wavy_surface_generator_ptr _wsgenerator;
79  wave_pressure_solver_ptr _wpsolver;
80  wetted_surface_solver_ptr _wssolver;
81  arma_wind_solver_ptr _arma_wind_solver;
82  anlt_wind_solver_ptr _anlt_wind_solver;
83  vertex_field_3d _wind_field;
84  grid4 _grid_txyz;
85  grid3 _wind_grid;
86  grid4 _vpgrid_tzxy;
87  domain3 _wpdomain_xyz;
88  array_type _wavysurface;
90  phi_array_type _vpotential;
91  statistics_type _statistics{1024};
92  std::ofstream _statistics_log;
93  gerstner_solver_ptr _gerstner_solver;
94  irregular_surface_type _irregular_wavysurface;
95  vertex_field_3d _water_velocity;
96  Solver_type _solver_type = Solver_type::gerstner_solver;
97 
98  public:
99 
100  Testbed();
101  ~Testbed() = default;
102  Testbed(Testbed&&) = default;
103  Testbed& operator=(Testbed&&) = default;
104  Testbed(const Testbed&) = delete;
105  Testbed& operator=(const Testbed&) = delete;
106 
107  inline void set_solver_type(Solver_type type) { this->_solver_type = type; }
108  inline Solver_type get_solver_type() const { return this->_solver_type; }
109 
110  inline const ship_type& ship() const { return this->_ship; }
111  inline ship_type& ship() { return this->_ship; }
112  inline void ship(ship_type&& rhs) { this->_ship = std::move(rhs); }
113  inline void ship(const ship_type& rhs) { this->_ship = rhs; }
114 
115  inline void
116  gerstner_solver(gerstner_solver_ptr&& rhs) {
117  this->_gerstner_solver = std::move(rhs);
118  set_solver_type(Solver_type::gerstner_solver);
119  }
120 
121  inline gerstner_solver_type*
122  gerstner_solver() {
123  return this->_gerstner_solver.get();
124  }
125 
126  inline const gerstner_solver_type*
127  gerstner_solver() const {
128  return this->_gerstner_solver.get();
129  }
130 
131  inline void
132  wavy_surface_generator(wavy_surface_generator_ptr&& rhs) {
133  this->_wsgenerator = std::move(rhs);
134  set_solver_type(Solver_type::regular_solver);
135  }
136 
137  inline const wavy_surface_generator_type*
138  wavy_surface_generator() const noexcept {
139  return this->_wsgenerator.get();
140  }
141 
143  wavy_surface_generator() noexcept {
144  return this->_wsgenerator.get();
145  }
146 
147  inline void
148  velocity_potential_solver(velocity_potential_solver_ptr&& rhs) {
149  this->_vpsolver = std::move(rhs);
150  }
151 
152  inline const velocity_potential_solver_type*
153  velocity_potential_solver() const noexcept {
154  return this->_vpsolver.get();
155  }
156 
158  velocity_potential_solver() noexcept {
159  return this->_vpsolver.get();
160  }
161 
162  inline void
163  wave_pressure_solver(wave_pressure_solver_ptr&& rhs) {
164  this->_wpsolver = std::move(rhs);
165  }
166 
167  inline const wave_pressure_solver_type*
168  wave_pressure_solver() const noexcept {
169  return this->_wpsolver.get();
170  }
171 
173  wave_pressure_solver() noexcept {
174  return this->_wpsolver.get();
175  }
176 
177  inline void
178  wetted_surface_solver(wetted_surface_solver_ptr&& rhs) {
179  this->_wssolver = std::move(rhs);
180  }
181 
183  wetted_surface_solver() {
184  return this->_wssolver.get();
185  }
186 
187  inline const wetted_surface_solver_type*
188  wetted_surface_solver() const {
189  return this->_wssolver.get();
190  }
191 
196  inline const array_type&
197  wavy_surface() const noexcept {
198  return this->_wavysurface;
199  }
200 
201  inline const grid4 grid() const { return this->_grid_txyz; }
202 
203  inline array2
204  wavy_surface_2d() const noexcept {
205  int t_idx = this->_grid_txyz.extent(0)-1;
206  const auto& _ = blitz::Range::all();
207  return this->_wavysurface(t_idx,_,_);
208  }
209 
210  inline irregular_surface_type
211  irregular_wavy_surface() {
212  return this->_irregular_wavysurface;
213  }
214 
215  inline irregular_surface_type_2d
216  irregular_wavy_surface_2d() const {
217  int t_idx = this->_grid_txyz.extent(0)-1;
218  const auto& _ = blitz::Range::all();
219  return this->_irregular_wavysurface(t_idx,_,_).copy();
220  }
221 
226  inline const phi_array_type&
227  velocity_potential() const noexcept {
228  return this->_vpotential;
229  }
230 
231  inline array3
232  velocity_potential_3d() const noexcept {
233  int t_idx = std::max(0, this->_vpgrid_tzxy.extent(0)-1);
234  const auto& _ = blitz::Range::all();
235  return this->_vpotential(t_idx,_,_,_);
236  }
237 
238  void step(T dt);
239 
248  void reset();
249 
250  inline ship_motion_solver_type*
251  ship_motion_solver() {
252  return this->_ship_motion_solver.get();
253  }
254 
255  inline const ship_motion_solver_type*
256  ship_motion_solver() const {
257  return this->_ship_motion_solver.get();
258  }
259 
263  inline void
264  wavy_surface_grid(const grid2& rhs) noexcept {
265  this->_grid_txyz.lbound(1) = rhs.lbound(0);
266  this->_grid_txyz.lbound(2) = rhs.lbound(1);
267  this->_grid_txyz.ubound(1) = rhs.ubound(0);
268  this->_grid_txyz.ubound(2) = rhs.ubound(1);
269  this->_grid_txyz.begin(1) = rhs.begin(0);
270  this->_grid_txyz.begin(2) = rhs.begin(1);
271  this->_grid_txyz.end(1) = rhs.end(0);
272  this->_grid_txyz.end(2) = rhs.end(1);
273  }
274 
279  inline grid3
280  wavy_surface_grid() const noexcept {
281  return this->_grid_txyz.select(0,1,2);
282  }
283 
287  inline grid2
288  wavy_surface_grid_2d() const noexcept {
289  return this->_grid_txyz.select(1,2);
290  }
291 
296  inline grid4
297  velocity_potential_grid() const noexcept {
298  return this->_vpgrid_tzxy;
299  }
300 
301  inline grid3
302  velocity_potential_grid_3d() const noexcept {
303  return this->_vpgrid_tzxy.select(1,2,3);
304  }
305 
307  inline T time_instant() const noexcept { return this->_grid_txyz.lbound(0); }
308 
309  inline const grid4& grid_txyz() const { return this->_grid_txyz; }
310 
312  inline const panel_array&
313  wetted_panels() const noexcept {
314  return this->_wssolver->wetted_panels();
315  }
316 
317  inline const panel_array&
318  dry_panels() const noexcept {
319  return this->_wssolver->dry_panels();
320  }
321 
322  inline bool
323  has_wetted_panels() const noexcept {
324  return !this->wetted_panels().empty();
325  }
326 
327  inline bool
328  has_wave_pressure_domain() const noexcept {
329  return !blitz::empty(this->_wpdomain_xyz);
330  }
331 
332  void record_statistics(statistics_type& stats);
333  inline const statistics_type& statistics() const { return this->_statistics; }
334  inline statistics_type& statistics() { return this->_statistics; }
335 
336  inline const vertex_field_3d& wind_field() const { return this->_wind_field; }
337  inline const grid3& wind_grid() const { return this->_wind_grid; }
338 
339  inline const vertex_field_3d&
340  water_velocity_field() const {
341  return this->_water_velocity;
342  }
343 
344  inline void
345  arma_wind_solver(arma_wind_solver_ptr&& rhs) {
346  this->_arma_wind_solver = std::move(rhs);
347  }
348 
349  inline void
350  anlt_wind_solver(anlt_wind_solver_ptr&& rhs) {
351  this->_anlt_wind_solver = std::move(rhs);
352  }
353 
354  inline const anlt_wind_solver_type*
355  wind_solver() const {
356  return this->_anlt_wind_solver.get();
357  }
358 
359  inline const waterline_type&
360  waterline() const {
361  return this->_wssolver->waterline();
362  }
363 
364  void openmp_solvers();
365  void opencl_solvers();
366  void opencl_context(void* ptr);
367 
368  private:
369 
370  void step_regular();
371  void step_irregular();
372  auto wave_number_grid_2d() const -> grid2;
373  void clamp_grid_to_wetted_panels();
374  void compute_velocity_potential();
375  void compute_wave_numbers();
376  void compute_wave_pressure();
377  void compute_wetted_panels_regular();
378  void compute_wetted_panels_irregular();
379  void compute_wind();
380  void generate_waves();
381  void move_ship();
382 
383  inline friend bstream&
384  operator<<(bstream& out, const Testbed& rhs) {
385  out << rhs._ship;
386  out << rhs._grid_txyz;
387  out << rhs._wavysurface;
388  out << rhs._vpotential;
389  return out;
390  }
391 
392  inline friend bstream&
393  operator>>(bstream& in, Testbed& rhs) {
394  in >> rhs._ship;
395  in >> rhs._grid_txyz;
396  in >> rhs._wavysurface;
397  in >> rhs._vpotential;
398  return in;
399  }
400 
401  };
402 
403  }
404 
405 }
406 
407 #endif // vim:filetype=cpp
Rigid ship with a mass and translational and angular velocity.
Definition: core/ship.hh:186
int extent(int i) const noexcept
The number of points for dimension i.
Definition: core/grid.hh:114
const panel_array & wetted_panels() const noexcept
Wetted ship hull faces that comprise underwater part of the hull.
Definition: testbed.hh:313
const int_n & end() const noexcept
End indices (exclusive).
Definition: core/grid.hh:144
Base class for all wave pressure solvers.
grid4 velocity_potential_grid() const noexcept
Definition: testbed.hh:297
const vec & lbound() const noexcept
Lower bound of the region.
Definition: core/grid.hh:168
grid2 wavy_surface_grid_2d() const noexcept
Definition: testbed.hh:288
void wavy_surface_grid(const grid2 &rhs) noexcept
Definition: testbed.hh:264
const array_type & wavy_surface() const noexcept
Definition: testbed.hh:197
A region defined by start and end index and lower and upper bound for each dimension.
Definition: core/grid.hh:25
Triangular ship hull panel (face).
const int_n & begin() const noexcept
Start indices (inclusive).
Definition: core/grid.hh:120
Main namespace.
Definition: convert.hh:9
Base class for all velocity potential solvers.
Main class for interacting with virtual testbed.
Definition: testbed.hh:33
T time_instant() const noexcept
Current time instant in seconds.
Definition: testbed.hh:307
const phi_array_type & velocity_potential() const noexcept
Definition: testbed.hh:227
grid3 wavy_surface_grid() const noexcept
Definition: testbed.hh:280
const vec & ubound() const noexcept
Upper bound of the region.
Definition: core/grid.hh:190
Base class for wavy surface generators.
Definition: core/types.hh:50
void reset()
Reset simulation to the initial state and retain solver configuration.