FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
CableSegmentStructuralJacobian.h
1#ifndef CABLE_SEGMENT_STRUCTURAL_JACOBIAN_H
2#define CABLE_SEGMENT_STRUCTURAL_JACOBIAN_H
3
4#include <cmath>
5
29inline void SetCableSegmentStructuralJacobian(const double* pk, const double* pl, const double* vk, const double* vl,
30 double restLength, double springCoef, double damperCoef, double* dF_dpk, double* dF_dpl, double* dF_dvk,
31 double* dF_dvl)
32{
33 const double d[3] = {pk[0] - pl[0], pk[1] - pl[1], pk[2] - pl[2]};
34 const double L2 = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
35
36 for (int i = 0; i < 9; ++i)
37 dF_dpk[i] = dF_dpl[i] = dF_dvk[i] = dF_dvl[i] = 0.0;
38 if (L2 < 1e-20)
39 return;
40
41 const double L = std::sqrt(L2);
42 const double Linv = 1.0 / L;
43 const double Q[3] = {d[0] * Linv, d[1] * Linv, d[2] * Linv};
44
45 const double dV[3] = {vk[0] - vl[0], vk[1] - vl[1], vk[2] - vl[2]};
46 const double QdotdV = Q[0] * dV[0] + Q[1] * dV[1] + Q[2] * dV[2];
47
48 const bool inTension = (L > restLength);
49 const double tension = inTension ? springCoef * (L - restLength) : 0.0;
50 const double TD = tension + damperCoef * QdotdV;
51
52 const double extension = inTension ? (L - restLength) / restLength : 0.0;
53 const double dT_dL = (extension > 1e-8) ? springCoef : 0.0;
54
55 // F[j] = -TD * Q[j]: dF[j]/dpk[k] = -dTD/dpk[k] * Q[j] - TD * dQ[j]/dpk[k]
56 for (int j = 0; j < 3; ++j) {
57 for (int k = 0; k < 3; ++k) {
58 const double dTD_dpk = dT_dL * Q[k] + damperCoef * (dV[k] - QdotdV * Q[k]) * Linv;
59 const double dQj_dpk = ((j == k ? 1.0 : 0.0) - Q[j] * Q[k]) * Linv;
60
61 dF_dpk[j * 3 + k] = -dTD_dpk * Q[j] - TD * dQj_dpk;
62 dF_dpl[j * 3 + k] = -dF_dpk[j * 3 + k]; // d = pk - pl
63 dF_dvk[j * 3 + k] = -damperCoef * Q[k] * Q[j];
64 dF_dvl[j * 3 + k] = damperCoef * Q[k] * Q[j];
65 }
66 }
67}
68
69#endif