Virtual Testbed
Ship dynamics simulator for extreme conditions
wave_pressure_openmp.cc
1 #include <vtestbed/base/constants.hh>
2 #include <vtestbed/config/openmp.hh>
3 #include <vtestbed/config/real_type.hh>
4 #include <vtestbed/core/derivative.hh>
5 #include <vtestbed/core/grid_interpolation.hh>
6 #include <vtestbed/core/wave_pressure.hh>
7 
8 using vtb::core::Policy;
9 
10 namespace vtb {
11 
12  namespace core {
13 
14  template <class T>
16 
17  private:
19 
20  public:
21  using typename base_type::panel_type;
22  using typename base_type::panel_array;
23  using typename base_type::grid3;
24  using typename base_type::grid4;
25  using typename base_type::array3;
26  using typename base_type::array4;
27  using typename base_type::vec3;
28 
29  protected:
30 
31  void solve(const grid3& wavy_surface_grid,
32  array3 wavy_surface,
33  const grid4& phi_grid,
34  array4 velocity_potential,
35  panel_array& panels) override;
36 
37  void
38  calculate_pressure(
39  const grid4& phi_grid,
40  const array4& velocity_potential,
41  const array3& wavy_surface,
42  array4& pressure);
43 
44  void
45  calculate_pressure_force(
46  const grid4& pressure_grid,
47  array4& pressure,
48  panel_array& panels);
49 
50  };
51 
52  }
53 
54 }
55 
56 template <class T>
57 void
59  const grid3& wavy_surface_grid,
60  array3 wavy_surface,
61  const grid4& phi_grid,
62  array4 velocity_potential,
63  panel_array& panels
64 ) {
65  using blitz::Range;
66  using blitz::RectDomain;
67  grid3 grid_xyz = phi_grid.select(2,3,1);
68  if (this->clip()) {
69  grid_xyz = clamp(grid_xyz, panels);
70  if (grid_xyz.empty()) { return; }
71  grid_xyz.compact();
72  }
73  RectDomain<3> rect{grid_xyz.begin(), grid_xyz.end()-1};
74  const auto _ = Range::all();
75  const grid4& smaller_grid = phi_grid(_,rect[2],rect[0],rect[1]);
76  array4 phi(velocity_potential(_,rect[2],rect[0],rect[1]));
77  array4 pressure(smaller_grid.shape());
78  this->calculate_pressure(smaller_grid, phi, wavy_surface, pressure);
79  this->calculate_pressure_force(smaller_grid, pressure, panels);
80 }
81 
82 template <class T>
83 void
86  const grid4& grid,
87  const array4& phi,
88  const array3& zeta,
89  array4& pressure
90 ) {
91  using blitz::pow2;
92  using namespace vtb::core;
94  const auto& delta = grid.delta();
95  const auto g = this->g();
96  constexpr auto p0 = constants<T>::atmospheric_pressure();
97  parallel_for_loop<4>(
98  grid.shape(),
99  [&](const int4& idx) {
100  const T z = grid(idx(1),1);
101  const auto& grad = gradient(idx, delta, phi);
102  pressure(idx) = p0-this->density() * (
103  grad(0) + T(0.5)*(pow2(grad(1)) + pow2(grad(2)) + pow2(grad(3))) +
104  g*z
105  );
106  }
107  );
108 }
109 
110 template <class T>
111 void
114  const grid4& pressure_grid,
115  array4& pressure,
116  panel_array& panels
117 ) {
118  using blitz::Range;
119  const auto _ = Range::all();
120  const auto& new_pressure_grid = pressure_grid.select(1,2,3);
121  Array<T,3> new_pressure(pressure(pressure_grid.num_patches(0),_,_,_));
122  Linear_interpolation<T,3> interpolate{new_pressure, new_pressure_grid};
123  const int npanels = panels.size();
124  #if defined(VTB_WITH_OPENMP)
125  #pragma omp parallel for
126  #endif
127  for (int i=0; i<npanels; ++i) {
128  panel_type& panel = panels[i];
129  const auto& centre = panel.centre();
130  vec3 x{centre(2), centre(0), centre(1)};
131  panel.force() = interpolate(x) * (-panel.normal()) * panel.area();
132  }
133 }
134 
135 template <>
136 auto
137 vtb::core::make_wave_pressure_solver<VTB_REAL_TYPE,Policy::OpenMP>()
141  );
142 }
Base class for all wave pressure solvers.
Core components.
Definition: bstream.hh:181
Triangular ship hull panel (face).
Main namespace.
Definition: convert.hh:9