Virtual Testbed
Ship dynamics simulator for extreme conditions
ship_motion_solver.hh
1 #ifndef VTESTBED_CORE_SHIP_MOTION_SOLVER_HH
2 #define VTESTBED_CORE_SHIP_MOTION_SOLVER_HH
3 
4 #include <vtestbed/core/euler.hh>
5 #include <vtestbed/core/math.hh>
6 #include <vtestbed/core/rkf45.hh>
7 #include <vtestbed/core/ship.hh>
8 #include <vtestbed/core/ship_hull_panel.hh>
9 #include <vtestbed/geometry/polyline.hh>
10 
11 namespace vtb {
12 
13  namespace core {
14 
58  template <class T>
60 
61  public:
62  using value_type = T;
63  using vec2 = blitz::TinyVector<T,2>;
64  using vec3 = blitz::TinyVector<T,3>;
65  using ship_type = Ship<T>;
68  using state_vector_type = typename ship_type::state_vector_type;
69  using variables_type = typename ship_type::variables_type;
70  using basis_type = typename ship_type::basis_type;
71  using rotation_matrix_type = typename ship_type::rotation_matrix_type;
72  using quaternion_type = typename ship_type::quaternion_type;
74 
75  private:
76  rotation_matrix_type _inertia_matrix;
77  vec3 _gravity_force{T{}}, _forces{T{}}, _torques{T{}};
78  T _displacement{T{}};
79  vec3 _damping{T{0.50},T{0.90},T{0.50}};
80  vec3 _centre_of_gravity{T{}};
81  vec3 _centre_of_buoyancy{T{}};
82  vec3 _centre_of_floatation{T{}};
83  vec3 _centre_of_wind{T{}};
84 
85  public:
86 
87  Ship_motion_equation() = default;
88 
89  inline explicit
90  Ship_motion_equation(const rotation_matrix_type& inertia_matrix):
91  _inertia_matrix(inertia_matrix) {}
92 
93  inline void
94  solve(T t, const state_vector_type& v, state_vector_type& dv) {
95  quaternion_type q = unit(v.quaternion);
96  const auto& R = rotation_matrix(q);
97  const auto& R_inv = inverse(R);
98  const auto& I_body = inertia_matrix();
99  const auto& I_body_inv = inverse(I_body);
100  auto angvelocity = R*(I_body_inv*(R_inv*v.angmomentum));
101  dv.position = v.velocity;
102  dv.velocity = total_force() - damping()*v.velocity;
103  dv.quaternion = T{0.5}*(quaternion_type(0,angvelocity)*q);
104  dv.angmomentum = total_torque() - damping()*v.angmomentum;
105  };
106 
107  inline variables_type
108  operator()(T t, const variables_type& vars) {
109  state_vector_type result;
110  this->solve(t, reinterpret_cast<const state_vector_type&>(vars), result);
111  return static_cast<const variables_type&>(result);
112  }
113 
114  inline state_vector_type
115  operator()(T t, const state_vector_type& vars) {
116  state_vector_type result;
117  solve(t, vars, result);
118  return result;
119  }
120 
121  inline const rotation_matrix_type&
122  inertia_matrix() const { return this->_inertia_matrix; }
123  inline void
124  inertia_matrix(const rotation_matrix_type& rhs) { this->_inertia_matrix = rhs; }
125  inline void gravity_force(const vec3& rhs) { this->_gravity_force = rhs; }
126  inline void total_force(const vec3& rhs) { this->_forces = rhs; }
127  inline void total_torque(const vec3& rhs) { this->_torques = rhs; }
128  inline void damping(const vec3& rhs) { this->_damping = rhs; }
129  inline const vec3& damping() const { return this->_damping; }
130  inline T displacement() const { return this->_displacement; }
131  inline const vec3& total_force() const { return this->_forces; }
132  inline const vec3& total_torque() const { return this->_torques; }
133  inline const vec3& centre_of_gravity() const { return this->_centre_of_gravity; }
134  inline const vec3& centre_of_buoyancy() const { return this->_centre_of_buoyancy; }
135  inline const vec3& centre_of_floatation() const { return this->_centre_of_floatation; }
136  inline const vec3& centre_of_wind() const { return this->_centre_of_wind; }
137 
138  void calc_forces_and_torques(
139  const ship_type& ship,
140  const panel_array& wetted_panels,
141  const panel_array& dry_panels,
142  const waterline_type& waterline
143  );
144  void clear();
145 
146  private:
147  void calc_froude_krylov_and_wind(
148  const ship_type& ship,
149  T mass,
150  const panel_array& wetted_panels,
151  const panel_array& dry_panels,
152  const waterline_type& waterline
153  );
154  void calc_flooding(const ship_type& ship, T mass);
155  void calc_propulsor(const ship_type& ship, T mass);
156 
157  static vec3 centre_of_floatation(const waterline_type& waterline);
158  static void integrate(const panel_array& panels,
159  vec3& centre,
160  vec3& force,
161  T& volume);
162  };
163 
164  template <class T>
166 
167  public:
168  using rkf45_type = RKF45<T>;
169  //using rkf45_type = Euler_solver<T>;
171  using ship_type = typename equation_type::ship_type;
172  using panel_type = typename equation_type::panel_type;
173  using panel_array = typename equation_type::panel_array;
174  using waterline_type = typename equation_type::waterline_type;
175 
176  private:
177  rkf45_type _eqsolver;
178  equation_type _eq;
179 
180  public:
181 
182  Ship_motion_solver() = default;
183  virtual ~Ship_motion_solver() = default;
184 
185  inline const equation_type& equation() const { return this->_eq; }
186  inline equation_type& equation() { return this->_eq; }
187 
188  virtual void solve(
189  ship_type& ship,
190  const panel_array& wetted_panels,
191  const panel_array& dry_panels,
192  const waterline_type& waterline,
193  T t0, T t1
194  );
195 
196  };
197 
198  }
199 
200 }
201 
202 #endif // vim:filetype=cpp
Rigid ship with a mass and translational and angular velocity.
Definition: core/ship.hh:186
Runge—Khutta—Fehlberg initial value problem solver.
Definition: rkf45.hh:24
System of ordinary differential equations of translational and angular ship motion.
Triangular ship hull panel (face).
Main namespace.
Definition: convert.hh:9