6 #include <vtestbed/config/opencl.hh>     7 #include <vtestbed/config/openmp.hh>     8 #include <vtestbed/config/real_type.hh>     9 #include <vtestbed/core/anlt_wind_solver.hh>    10 #include <vtestbed/core/arma_wind_solver.hh>    11 #include <vtestbed/core/cosine_wave.hh>    12 #include <vtestbed/core/propulsor.hh>    13 #include <vtestbed/core/ship_motion_solver.hh>    14 #include <vtestbed/core/stokes_wave.hh>    15 #include <vtestbed/core/testbed.hh>    16 #include <vtestbed/core/wetted_surface_solver.hh>    17 #include <vtestbed/geometry/basis.hh>    18 #include <vtestbed/profile/profile.hh>    20 #if defined(VTB_WITH_OPENCL)    21 #include <vtestbed/opencl/opencl.hh>    26     sizeof(vtb::core::Vector3<VTB_REAL_TYPE>)*4,
    30 template <
class T, 
int N>
    33     {T{-1}, T(-100), T(-100), T{-100}},
    34     {T{0}, T(100), T(100), T{2}},
    42     this->_wpdomain_xyz.lbound() = 0;
    43     this->_wpdomain_xyz.ubound() = 0;
    44     grid3 wsgrid{this->wavy_surface_grid()};
    45     this->_wavysurface.resize(wsgrid.shape());
    46     this->_wavysurface = 0;
    47     this->_irregular_wavysurface.resize(wsgrid.shape());
    50         [&] (
const blitz::TinyVector<int,N>& idx) {
    51             auto txy = wsgrid(idx);
    52             this->_irregular_wavysurface(idx) = {txy(1), txy(2), 0};
    55     grid4 vpgrid{this->_grid_txyz.select(0,3,1,2)};
    56     this->_vpotential.resize(vpgrid.shape());
    57     this->_statistics_log.open(
"statistics.log");
    58     this->_statistics.write_header(this->_statistics_log);
    61     this->_ship_motion_solver.reset(
new ship_motion_solver_type);
    64 template <
class T, 
int N>
    67     VTB_PROFILE_BLOCK(
"step");
    68     const T t0 = this->_grid_txyz.ubound(0);
    69     this->_grid_txyz.lbound(0) = t0;
    70     this->_grid_txyz.ubound(0) = t0 + dt;
    71     switch (this->get_solver_type()) {
    72         case Solver_type::regular_solver: this->step_regular(); 
break;
    73         case Solver_type::gerstner_solver: this->step_irregular(); 
break;
    84     this->record_statistics(this->_statistics);
    87 template <
class T, 
int N>
    90     this->generate_waves();
    91     this->compute_wetted_panels_regular();
    92     if (has_wetted_panels()) {
    93         this->clamp_grid_to_wetted_panels();
    94         if (has_wave_pressure_domain()) {
    95             this->compute_wave_numbers();
    96             this->compute_velocity_potential();
    97             this->compute_wave_pressure();
   102 template <
class T, 
int N>
   106         VTB_PROFILE_BLOCK(
"fluid_motion");
   107         this->_gerstner_solver->compute_positions(this->_ship, this->_wssolver->all_panels(),
   108             this->_grid_txyz.select(0,1,2), this->_irregular_wavysurface);
   110     this->compute_wetted_panels_irregular();
   111     if (has_wetted_panels()) {
   112         this->clamp_grid_to_wetted_panels();
   113         if (has_wave_pressure_domain()) {
   114             VTB_PROFILE_BLOCK(
"compute_forces");
   117             this->_gerstner_solver->compute_forces(
   119                 this->_grid_txyz.select(0,3,1,2),
   120                 this->_wssolver->wetted_panels());
   121             this->_water_velocity.reference(this->_gerstner_solver->velocity());
   126 template <
class T, 
int N>
   129     this->_grid_txyz.lbound(0) = -1;
   130     this->_grid_txyz.ubound(0) = 0;
   132     this->_statistics.clear();
   133     this->_statistics_log.close();
   134     this->_statistics_log.open(
"statistics.log");
   135     this->_wavysurface = 0;
   136     this->_vpotential = 0;
   137     this->_wind_field = T{};
   138     this->_irregular_wavysurface = T{};
   141 template <
class T, 
int N>
   144     VTB_PROFILE_BLOCK(
"waves");
   145     grid3 wsgrid{this->wavy_surface_grid()};
   146     this->_wavysurface.reference(this->_wsgenerator->generate(wsgrid));
   149 template <
class T, 
int N>
   152     VTB_PROFILE_BLOCK(
"wind");
   153     this->_anlt_wind_solver->step(this->_wind_grid, this->_wssolver->dry_panels());
   154     this->_wind_field.reference(this->_anlt_wind_solver->wind_field());
   157 template <
class T, 
int N>
   160     VTB_PROFILE_BLOCK(
"wetted_panels");
   161     this->_wssolver->solve(ship(), grid_txyz(), this->wavy_surface());
   164 template <
class T, 
int N>
   167     VTB_PROFILE_BLOCK(
"wetted_panels");
   168     this->_wssolver->solve(ship(), grid_txyz(), this->irregular_wavy_surface());
   171 template <
class T, 
int N>
   175     const auto& wetted_panels = this->_wssolver->wetted_panels();
   177     for (
const auto& panel : wetted_panels) {
   178         const auto& centre = panel.centre();
   179         mm[0].update(centre(0));
   180         mm[1].update(centre(1));
   181         mm[2].update(centre(2));
   183     vec3 x_min{mm[0].min(),mm[1].min(),mm[2].min()};
   184     vec3 x_max{mm[0].max(),mm[1].max(),mm[2].max()};
   186     if (!wetted_panels.empty()) {
   187         T z_max = std::min(x_max(2), blitz::max(this->_wavysurface)) + 1;
   189         this->_grid_txyz.ubound(3) = z_max;
   190         this->_grid_txyz.lbound(3) = std::min(x_min(2)-1, z_max);
   192     grid3 grid_xyz{this->_grid_txyz.select(1,2,3)};
   193     x_min = clamp(x_min, grid_xyz);
   194     x_max = clamp(x_max, grid_xyz);
   195     int3 idx_min = int3{blitz::floor(grid_xyz.index(x_min))};
   196     int3 idx_max = int3{blitz::ceil(grid_xyz.index(x_max))};
   197     idx_min = blitz::max(0, idx_min);
   198     idx_max = blitz::min(grid_xyz.shape()-1, idx_max);
   200     int3 extent = idx_max - idx_min + 1;
   201     if (blitz::all(extent > 0)) {
   202         for (
int i=0; i<2; ++i) {
   204             if (!blitz::is_power_of_two(e)) {
   205                 extent(i) = blitz::next_power_of_two(e);
   208         idx_max = idx_min + extent - 1;
   209         for (
int i=0; i<2; ++i) {
   210             int diff = idx_max(i) - (grid_xyz.extent(i) - 1);
   216         if (blitz::any(idx_min < 0)) {
   218                 << 
"Please, increase wavy surface size to speed-up Fourier transforms"   221         extent = idx_max - idx_min + 1;
   223     domain3 d{idx_min, idx_max};
   224     this->_wpdomain_xyz = d;
   227 template <
class T, 
int N>
   230     const auto& _ = blitz::Range::all();
   231     const auto& grid_xy = this->_grid_txyz.select(1,2);
   232     const auto& zeta = this->_wavysurface;
   233     const int slice_t = zeta.extent(0)-1;
   234     const auto& w = wave_statistics(zeta(slice_t,_,_), grid_xy);
   235     auto& waves = this->_statistics.waves();
   240 template <
class T, 
int N>
   243     return wave_number_grid(this->_statistics.waves()).select(1,2);
   246 template <
class T, 
int N>
   249     VTB_PROFILE_BLOCK(
"wave_velocity");
   250     const auto _ = blitz::Range::all();
   251     _vpgrid_tzxy = _grid_txyz.select(0,3,1,2);
   252     _vpgrid_tzxy = _vpgrid_tzxy(_,_wpdomain_xyz[2],_wpdomain_xyz[0],_wpdomain_xyz[1]);
   253     _vpotential.resize(_vpgrid_tzxy.shape());
   254     _vpsolver->wave_number_grid(this->wave_number_grid_2d());
   257         _wavysurface(_,_wpdomain_xyz[0],_wpdomain_xyz[1]),
   262 template <
class T, 
int N>
   265     VTB_PROFILE_BLOCK(
"wave_pressure");
   266     grid3 wsgrid{_vpgrid_tzxy.select(0,2,3)};
   267     this->_wpsolver->solve(
   272         this->_wssolver->wetted_panels()
   276 template <
class T, 
int N>
   279     VTB_PROFILE_BLOCK(
"ship_motions");
   280     const T t0 = this->_grid_txyz.lbound(0);
   281     const T t1 = this->_grid_txyz.ubound(0);
   282     this->_ship_motion_solver->solve(
   284         this->wetted_panels(),
   292 template <
class T, 
int N>
   295     using Record = 
typename statistics_type::Record;
   296     VTB_PROFILE_BLOCK(
"statistics");
   297     T t = this->_grid_txyz.ubound(0);
   298     const auto& ship = this->_ship;
   299     stats.record(Record::Time, t);
   300     stats.record(Record::Euler_angles, ship.euler_angles());
   301     stats.record(Record::Position, ship.position());
   302     stats.record(Record::Velocity, ship.velocity());
   303     stats.record(Record::Angular_velocity, vector_to(ship.rotation_matrix(), ship.angular_velocity()));
   304     stats.record(Record::Acceleration, vector_to(ship.rotation_matrix(), ship.acceleration()));
   305     stats.record(Record::Angular_acceleration, ship.angular_acceleration());
   306     stats.record(Record::Underwater_volume,
   307                  this->_ship_motion_solver->equation().displacement());
   308     stats.record(Record::Angular_momentum, ship.angular_momentum());
   309     const auto& zeta = this->_wavysurface;
   310     const auto nx = zeta.extent(1);
   311     const auto ny = zeta.extent(2);
   312     stats.record(Record::Wavy_surface, zeta(zeta.extent(0)-1,nx/2,ny/2));
   313     stats.record_waves();
   314     stats.write_back(this->_statistics_log);
   315     this->_statistics_log.flush();
   318 template <
class T, 
int N>
   321     #if defined(VTB_WITH_OPENMP)   322     auto solver_t = get_solver_type();
   323     this->velocity_potential_solver(make_velocity_potential_solver<T,3,Policy::OpenMP>());
   324     this->wave_pressure_solver(make_wave_pressure_solver<T,Policy::OpenMP>());
   325     this->wetted_surface_solver(make_wetted_surface_solver<T,3,Policy::OpenMP>());
   326     this->anlt_wind_solver(make_anlt_wind_solver<T,Policy::OpenMP>());
   327     using default_wave = Propagating_stokes_wave<T,3>;
   328     this->wavy_surface_generator(
   329         make_plain_wave_generator<T,3,default_wave,Policy::OpenMP>()
   331     this->gerstner_solver(make_gerstner_solver<T,3,Policy::OpenMP>());
   332     set_solver_type(solver_t);
   336 template <
class T, 
int N>
   339     #if defined(VTB_WITH_OPENCL)   340     auto solver_t = get_solver_type();
   341     this->velocity_potential_solver(make_velocity_potential_solver<T,3,Policy::OpenCL>());
   342     this->wave_pressure_solver(make_wave_pressure_solver<T,Policy::OpenCL>());
   343     this->wetted_surface_solver(make_wetted_surface_solver<T,3,Policy::OpenCL>());
   344     this->anlt_wind_solver(make_anlt_wind_solver<T,Policy::OpenCL>());
   345     using default_wave = Propagating_stokes_wave<T,3>;
   346     this->wavy_surface_generator(
   347         make_plain_wave_generator<T,3,default_wave,Policy::OpenCL>()
   349     this->gerstner_solver(make_gerstner_solver<T,3,Policy::OpenCL>());
   350     set_solver_type(solver_t);
   354 template <
class T, 
int N>
   357     #if defined(VTB_WITH_OPENCL)   359     auto context = reinterpret_cast<Context*>(ptr);
   360     if (
auto vpsolver = dynamic_cast<Context_base*>(this->_vpsolver.get())) {
   361         vpsolver->context(context);
   363     if (
auto wpsolver = dynamic_cast<Context_base*>(this->_wpsolver.get())) {
   364         wpsolver->context(context);
   366     if (
auto wssolver = dynamic_cast<Context_base*>(this->_wssolver.get())) {
   367         wssolver->context(context);
   369     if (
auto wsgenerator = dynamic_cast<Context_base*>(this->_wsgenerator.get())) {
   370         wsgenerator->context(context);
   372     if (
auto gerstner_solver = dynamic_cast<Context_base*>(this->_gerstner_solver.get())) {
   373         gerstner_solver->context(context);
   375     if (
auto wind_solver = dynamic_cast<Context_base*>(this->_anlt_wind_solver.get())) {
   376         wind_solver->context(context);
 
Triangular ship hull panel (face).
 
Main class for interacting with virtual testbed.
 
void reset()
Reset simulation to the initial state and retain solver configuration.