Virtual Testbed
Ship dynamics simulator for extreme conditions
anlt_wind_solver_opencl.cc
1 #include <vtestbed/config/openmp.hh>
2 #include <vtestbed/config/opencl.hh>
3 #include <vtestbed/config/real_type.hh>
4 #include <vtestbed/core/anlt_wind_solver.hh>
5 #include <vtestbed/linalg/linear_algebra.hh>
6 #include <vtestbed/core/ship_hull_panel.hh>
7 #include <vtestbed/core/policy.hh>
8 #include <vtestbed/opencl/opencl.hh>
9 #include <vtestbed/opencl/vector.hh>
10 
11 using namespace vtb::opencl;
12 
13 namespace vtb {
14 
15  namespace core {
16 
17  template <class T>
19  public ANLT_wind_solver<T>,
20  public Context_base {
21 
22  private:
24  using typename base_type::array_type;
25  using typename base_type::wind_field_type;
26  using typename base_type::grid_type;
27  using typename base_type::panel_type;
28  using typename base_type::panel_array;
29  using typename base_type::ray_type;
30  using typename base_type::ray_array;
31  using vec3 = blitz::TinyVector<T,3>;
32 
33  private:
34  clx::kernel _kernel_near_the_boundary, _kernel_on_the_boundary;
35  Buffer<vec3> _d_wind_field;
36 
37  public:
38 
39  using Context_base::context;
40 
41  void context(Context* rhs) override {
42  Context_base::context(rhs);
43  auto prog = context()->compiler().compile("anlt_wind.cl");
44  this->_kernel_near_the_boundary = prog.kernel("wind_near_the_boundary");
45  this->_kernel_on_the_boundary = prog.kernel("wind_on_the_boundary");
46  }
47 
48  void step(const grid_type& grid, panel_array& panels) override;
49 
50  };
51  }
52 }
53 
54 template <class T>
56  const grid_type& grid,
57  panel_array& panels
58 ) {
59  const int npanels = panels.size();
60  auto& wind_field = this->_wind_field;
61  if (npanels == 0) {
62  if (this->near_the_boundary()) {
63  wind_field.resize(grid.shape());
64  wind_field = T{};
65  }
66  return;
67  }
68  auto& ppl = this->context()->pipeline();
69  vec3 u(5,0,0);
70  Buffer<panel_type> d_panels;
71  ppl.copy(panels, d_panels);
72  if (this->near_the_boundary()) {
73  auto& d_wind_field = this->_d_wind_field;
74  wind_field.resize(grid.shape());
75  ppl.allocate(wind_field, d_wind_field);
76  auto& kernel = this->_kernel_near_the_boundary;
77  kernel.argument(0, npanels);
78  kernel.argument(1, d_panels);
79  kernel.argument(2, d_wind_field);
80  kernel.argument(3, make_vector(grid.lbound()));
81  kernel.argument(4, make_vector(grid.ubound()));
82  kernel.argument(5, make_vector(grid.shape()));
83  kernel.argument(6, make_vector(u));
84  ppl.step();
85  ppl.kernel(kernel, clx::range(wind_field.size()));
86  ppl.step();
87  ppl.copy(d_wind_field, wind_field);
88  }
89  if (this->on_the_boundary()) {
90  auto& kernel = this->_kernel_on_the_boundary;
91  kernel.argument(0, npanels);
92  kernel.argument(1, d_panels);
93  kernel.argument(2, make_vector(u));
94  ppl.step();
95  ppl.kernel(kernel, clx::range(npanels));
96  ppl.step();
97  ppl.copy(d_panels, panels);
98  }
99  if (this->on_the_boundary() || this->near_the_boundary()) {
100  ppl.wait();
101  }
102 }
103 
104 template <>
105 auto
106 vtb::core::make_anlt_wind_solver<VTB_REAL_TYPE,vtb::core::Policy::OpenCL>() ->
107 std::unique_ptr<ANLT_wind_solver<VTB_REAL_TYPE>> {
109  new ANLT_wind_solver_opencl<VTB_REAL_TYPE>
110  );
111 }
112 
Triangular ship hull panel (face).
Main namespace.
Definition: convert.hh:9
OpenCL glue code.