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.