1 #include <vtestbed/config/opencl.hh> 2 #include <vtestbed/config/real_type.hh> 3 #include <vtestbed/core/policy.hh> 4 #include <vtestbed/core/ship.hh> 5 #include <vtestbed/core/ship_hull_panel.hh> 6 #include <vtestbed/core/wetted_surface_solver.hh> 7 #include <vtestbed/geometry/face.hh> 8 #include <vtestbed/opencl/opencl.hh> 9 #include <vtestbed/opencl/vector.hh> 16 using vtb::opencl::make_vector;
22 template <
class T,
int N>
33 using typename base_type::vertex_type;
35 using line_segment_type =
typename waterline_type::value_type;
42 clx::kernel _kernel_regular, _kernel_irregular;
46 using Context_base::context;
48 void context(
Context* rhs)
override {
49 Context_base::context(rhs);
50 auto cc = context()->compiler();
51 auto options = cc.options();
52 cc.options(options +
" -DVTB_REGULAR");
53 this->_kernel_regular =
54 cc.compile(
"wetted_surface.cl").kernel(
"wetted_panels");
55 cc.options(options +
" -DVTB_IRREGULAR");
56 this->_kernel_irregular =
57 cc.compile(
"wetted_surface.cl").kernel(
"wetted_panels");
64 Array3<T> wavy_surface
71 Array3<vertex_type> wavy_surface
79 const void* wavy_surface,
80 size_t wavy_surface_size,
88 template <
class T,
int N>
92 const grid_type& grid_txyz,
93 const void* wavy_surface,
94 size_t wavy_surface_size,
97 const auto& vertices = ship.hull().vertices();
98 const auto& faces = ship.hull().faces();
99 const int nvertices = vertices.size();
100 const int nfaces = faces.size();
101 auto& waterline = this->_waterline;
102 auto& all_panels = this->_all_panels;
103 auto& mask = this->_wetted_vertices_mask;
104 mask.resize(nvertices);
105 mask.assign(nvertices,
false);
106 all_panels.resize(nfaces);
107 waterline.resize(nfaces);
108 Grid<T,2> grid_xy = grid_txyz.select(1,2);
109 #if defined(VTB_DEBUG_WETTED_PANELS_OPENCL) 110 std::clog <<
"wavy surface size: " << grid_xy << std::endl;
112 int offset = (grid_txyz.extent(0)-1)*product(grid_xy.shape());
114 clx::buffer d_wavy_surface;
115 auto& ppl = this->context()->pipeline();
116 ppl.allocate(all_panels, d_panels);
117 ppl.allocate(waterline, this->_d_waterline);
118 ppl.copy(vertices, this->_d_vertices);
119 ppl.copy(faces, this->_d_faces);
120 ppl.copy(wavy_surface, wavy_surface_size, d_wavy_surface);
121 kernel.argument(0, nfaces);
122 kernel.argument(1, this->_d_faces);
123 kernel.argument(2, this->_d_vertices);
124 kernel.argument(3, d_panels);
125 kernel.argument(4, make_vector(ship.
position()));
126 kernel.argument(5, make_vector(ship.rotation_matrix()));
127 kernel.argument(6, d_wavy_surface);
128 kernel.argument(7, offset);
129 kernel.argument(8, make_vector(grid_xy.lbound()));
130 kernel.argument(9, make_vector(grid_xy.ubound()));
131 kernel.argument(10, make_vector(grid_xy.shape()));
132 kernel.argument(11, this->_d_waterline);
134 ppl.kernel(kernel, clx::range(nfaces));
136 ppl.copy(d_panels, all_panels);
137 ppl.copy(this->_d_waterline, waterline);
139 auto& dry_panels = this->_dry_panels;
141 dry_panels.reserve(nfaces/2);
142 auto& wetted_panels = this->_wetted_panels;
143 wetted_panels.clear();
144 wetted_panels.reserve(nfaces/2);
145 for (
int i=0; i<nfaces; ++i) {
146 const auto& panel = all_panels[i];
147 if (panel.wetted()) {
148 wetted_panels.emplace_back(panel);
149 const auto& f = faces[i];
150 mask[f[0]] =
true, mask[f[1]] =
true, mask[f[2]] =
true;
152 dry_panels.emplace_back(panel);
155 int new_waterline_size = 0;
156 for (
int i=0; i<nfaces; ++i) {
157 const auto& segment = waterline[i];
158 if (all(segment.front() == 0 && segment.back() == 0)) {
159 new_waterline_size = i;
163 waterline.resize(new_waterline_size);
166 template <
class T,
int N>
171 Array3<vertex_type> wavy_surface
173 if (!wavy_surface.isStorageContiguous()) { wavy_surface.makeUnique(); }
174 do_solve(ship, grid_txyz, wavy_surface.data(), wavy_surface.
size()*
sizeof(vertex_type),
175 this->_kernel_irregular);
178 template <
class T,
int N>
183 Array3<T> wavy_surface
185 if (!wavy_surface.isStorageContiguous()) { wavy_surface.makeUnique(); }
186 do_solve(ship, grid_txyz, wavy_surface.data(), wavy_surface.
size()*
sizeof(T),
187 this->_kernel_regular);
192 vtb::core::make_wetted_surface_solver<VTB_REAL_TYPE,3,vtb::core::Policy::OpenCL>() ->
const vec3 & position(int i=0) const
Get position or its time derivatives in Earth-fixed coordinate system.
Rigid ship with a mass and translational and angular velocity.
const vec size() const noexcept
The size of the region.
Triangular ship hull panel (face).
void solve(const ship_type &ship, const grid_type &grid_txyz, Array3< T > wavy_surface) override
Determine underwater hull panels (faces) taking into account ship position and orientation.