Virtual Testbed
Ship dynamics simulator for extreme conditions
guile/gerstner.cc
1 #include <vtestbed/config/real_type.hh>
2 #include <vtestbed/core/gerstner.hh>
3 #include <vtestbed/guile/macros.hh>
4 #include <vtestbed/guile/traits.hh>
5 
9 
10 namespace {
11  SCM type;
12  SCM kw_policy, kw_diffraction, kw_radiation, kw_waterline_only, kw_waves;
13  SCM sym_opencl, sym_openmp;
14 }
15 
16 
17 namespace vtb {
18 
19  namespace guile {
20 
21  template <> SCM traits_type::type() { return ::type; }
22 
30  inline SCM make_gerstner_solver(SCM rest) {
31  using namespace vtb::core;
32  using vtb::core::make_gerstner_solver;
33  using T = VTB_REAL_TYPE;
34  SCM s_policy = sym_opencl, diffraction = SCM_UNDEFINED, radiation = SCM_UNDEFINED,
35  waterline_only = SCM_UNDEFINED, waves = SCM_UNDEFINED;
36  scm_c_bind_keyword_arguments("make-gerstner-solver", rest,
37  scm_t_keyword_arguments_flags{},
38  kw_policy, &s_policy,
39  kw_diffraction, &diffraction,
40  kw_radiation, &radiation,
41  kw_waterline_only, &waterline_only,
42  kw_waves, &waves,
43  SCM_UNDEFINED);
44  Policy policy = Policy::OpenCL;
45  if (symbol_equal(s_policy, sym_opencl)) { policy = Policy::OpenCL; }
46  else if (symbol_equal(s_policy, sym_openmp)) { policy = Policy::OpenMP; }
47  else { throw_error("bad policy"); return SCM_UNSPECIFIED; }
48  auto&& solver = make_gerstner_solver<T,3>(policy);
49  if (is_bound(diffraction)) { solver->diffraction(from_scm<bool>(diffraction)); }
50  if (is_bound(radiation)) { solver->radiation(from_scm<bool>(radiation)); }
51  if (is_bound(waterline_only)) {
52  solver->waterline_only(from_scm<bool>(waterline_only));
53  }
54  if (is_bound(waves)) {
55  if (!is_list(waves)) {
56  throw_error("bad waves type");
57  return SCM_UNSPECIFIED;
58  }
59  using wave_array = typename Gerstner_solver<T,3>::wave_array;
60  using wave_type = typename wave_array::value_type;
61  wave_array new_waves;
62  while (waves != SCM_EOL) {
63  auto* wrapper = get_wrapper<wave_type>(scm_car(waves));
64  new_waves.emplace_back(*wrapper->get());
65  waves = scm_cdr(waves);
66  }
67  solver->waves(std::move(new_waves));
68  }
69  return traits_type::make(std::move(solver));
70  }
71 
72  template <> void
73  traits_type::define() {
74  ::type = define_type<object_type>("<gerstner-solver>");
75  kw_policy = scm_from_utf8_keyword("policy");
76  kw_diffraction = scm_from_utf8_keyword("diffraction");
77  kw_radiation = scm_from_utf8_keyword("radiation");
78  kw_waterline_only = scm_from_utf8_keyword("waterline-only");
79  kw_waves = scm_from_utf8_keyword("waves");
80  sym_opencl = scm_from_utf8_symbol("opencl");
81  sym_openmp = scm_from_utf8_symbol("openmp");
82  define_procedure("make-gerstner-solver", 0, 0, 1,
83  VTB_GUILE_1(make_gerstner_solver));
84  }
85 
86  }
87 
88 }
Trochoidal irrotational waves solves named after Gerstner.
Definition: gerstner.hh:31
Core components.
Definition: bstream.hh:181
OBJ importer/exporter.
Definition: object.hh:28
Main namespace.
Definition: convert.hh:9
SCM make_gerstner_solver(SCM rest)
Construct Gerstner solver.