FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
CableSegmentDrag.h
1#ifndef CABLE_SEGMENT_DRAG_H
2#define CABLE_SEGMENT_DRAG_H
3
4#include <cmath>
5#include <fhsim_environment/hydrodynamics/CylinderHydro.h>
6
18{
20inline bool SegmentAxis(const double* pk, const double* pl, double& length, double axis[3])
21{
22 const double d[3] = {pl[0] - pk[0], pl[1] - pk[1], pl[2] - pk[2]};
23 length = std::sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
24 if (length < 1e-10)
25 return false;
26 for (int j = 0; j < 3; ++j)
27 axis[j] = d[j] / length;
28 return true;
29}
30
40inline void Force(const double* pk, const double* pl, const double* vk, const double* current, double rho, double D, double force[3])
41{
42 force[0] = force[1] = force[2] = 0.0;
43 double length, axis[3];
44 if (!SegmentAxis(pk, pl, length, axis))
45 return;
46 const double w[3] = {vk[0] - current[0], vk[1] - current[1], vk[2] - current[2]};
47 namespace cylinder_hydro = environment::cylinder_hydro;
48 cylinder_hydro::DragForce(rho, D, 0.5 * length, cylinder_hydro::kWaterKinematicViscosity, w, axis, cylinder_hydro::DragFormulation::Independence, force);
49}
50
58inline void AddJacobian(const double* pk, const double* pl, const double* vk, const double* current, double rho, double D,
59 double* dF_dpk, double* dF_dpl, double* dF_dvk)
60{
61 double length, axis[3];
62 if (!SegmentAxis(pk, pl, length, axis))
63 return;
64 const double w[3] = {vk[0] - current[0], vk[1] - current[1], vk[2] - current[2]};
65 namespace cylinder_hydro = environment::cylinder_hydro;
66 const double halfLength = 0.5 * length;
67 const double nu = cylinder_hydro::kWaterKinematicViscosity;
68 const auto formulation = cylinder_hydro::DragFormulation::Independence;
69 double force[3], dF_dw[9], dF_daxis[9];
70 cylinder_hydro::DragForce(rho, D, halfLength, nu, w, axis, formulation, force);
71 cylinder_hydro::DragForceJacobian(rho, D, halfLength, nu, w, axis, formulation, dF_dw, dF_daxis);
72
73 for (int j = 0; j < 3; ++j) {
74 for (int k = 0; k < 3; ++k) {
75 // F is linear in the length |d| / 2: dF/d|d| = F / |d|.
76 double dF_dd = force[j] * axis[k] / length;
77 for (int m = 0; m < 3; ++m)
78 dF_dd += dF_daxis[j * 3 + m] * (((m == k) ? 1.0 : 0.0) - axis[m] * axis[k]) / length;
79 dF_dvk[j * 3 + k] += dF_dw[j * 3 + k];
80 dF_dpl[j * 3 + k] += dF_dd;
81 dF_dpk[j * 3 + k] -= dF_dd;
82 }
83 }
84}
85} // namespace cable_segment_drag
86
87#endif
Definition CableSegmentDrag.h:18
void AddJacobian(const double *pk, const double *pl, const double *vk, const double *current, double rho, double D, double *dF_dpk, double *dF_dpl, double *dF_dvk)
Definition CableSegmentDrag.h:58
void Force(const double *pk, const double *pl, const double *vk, const double *current, double rho, double D, double force[3])
Definition CableSegmentDrag.h:40
bool SegmentAxis(const double *pk, const double *pl, double &length, double axis[3])
The segment's length |d| and unit direction Q; false for a degenerate segment.
Definition CableSegmentDrag.h:20