FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
CableRMWaterLoad.h
1#pragma once
2
9#include "Cable.h"
10#include "cable/subroutines/CableSurface.h"
11
12#include <sfh/constants.h>
13
14#include <Eigen/Eigen>
15
16#include <cmath>
17#include <fhsim_environment/EnvironmentProvider.h>
18
19namespace RbCable
20{
23{
24 double length;
25 double radius;
26 bool kelp;
27 double kelpWeight;
28};
29
30const double kWaterDensity = 1025.0;
31const double kAirDensity = 1.025;
32const double kWaterViscosity = 1.005E-6;
33
47inline void AddAboveSeabedLoad(environment::EnvironmentProvider& environment, double T, const Eigen::Vector3d& P, const Eigen::Vector3d& V,
48 const Eigen::Vector3d& W, const Eigen::Vector3d& axis, const ElementProperties& element, Eigen::Matrix<double, 6, 1>& load)
49{
50 using vec3 = Eigen::Vector3d;
51 // The wet fraction of the element's cylinder against the wave surface over its ends (owner
52 // ruling R104, extending R66): the water part of the load takes f, the air part 1 - f. It was
53 // all water or all air by the centre's side of the surface.
54 const vec3 endA = P - 0.5 * element.length * axis;
55 const vec3 endB = P + 0.5 * element.length * axis;
56 const double f = cable_surface::CylinderWetFraction(environment, environment.MaxWaveElevation(), T, endA.data(), endB.data(), element.radius);
57 if (f > 0.0) {
58 const double rho = kWaterDensity;
59 load(2) -= element.length * element.radius * element.radius * sfh::pi * rho * 9.81 * f;
60
61 double currentVelocity[3];
62 environment.GetParticleVelocity(T, P.data(), currentVelocity);
63 vec3 v = V - vec3(currentVelocity);
64
65 double v_abs2 = v.squaredNorm();
66 if (v_abs2 > 0) {
67 vec3 vz = v.dot(axis) * axis;
68 vec3 vxy = v - vz;
69
70 vec3 wz = W.dot(axis) * axis;
71
72 double v_abs = v.norm(); /*Kelp application v2*/
73 double vz_abs = vz.norm();
74 double vxy_abs = vxy.norm();
75
76 // v . v_xy = |v_xy|^2, so cos(theta) = |v_xy| / |v|, which tends to 0 as v_xy does:
77 // 0 for flow along the axis, where the quotient below is 0/0 (MARE-0221).
78 double cosTheta = vxy_abs > 0 ? v.dot(vxy) / (v_abs * vxy_abs) : 0.0; /*Kelp application v2*/
79
80 const double reynolds = cable_hydrodynamics::ReynoldsNumber(v_abs2, vxy_abs, 2.0 * element.radius, kWaterViscosity);
81 const DragCoefficients coefficients = ElementDragCoefficients(reynolds, vxy_abs / sqrt(v_abs2));
82 const double Cd = coefficients.normal;
83 const double CtTorsion = coefficients.torsional;
84 // Sugar kelp rope application - start
85 if (element.kelp) {
86 load.segment<3>(0) += -0.2 * (1 + 4 * cosTheta) * element.kelpWeight * element.length * (1.0731 * v_abs * v + 1.0509 * v) * f; /*Kelp application v2*/
87 }
88 const double Ct_xyz = coefficients.tangential; // skin friction along the axis (R68)
89 // Sugar kelp rope application - end
90 load.segment<3>(0) += -rho * element.radius * element.length * (Cd * vxy_abs * vxy + Ct_xyz * vz_abs * vz) * f;
91 load.segment<3>(3) += -rho * 2 * sfh::pi * element.radius * element.length * element.radius * (CtTorsion * wz.norm() * wz) / 1000 * f;
92 }
93 // The Froude-Krylov force rho f V a_n normal to the axis (owner ruling R104, extending R67);
94 // no added-mass term, as the element's inertia has none (MARE-0314).
95 const auto waves = environment.GetWaves();
96 if (waves) {
97 double mean[3];
98 cable_surface::MeanWaveAcceleration(waves.get(), T, endA.data(), endB.data(), mean);
99 const vec3 a(mean);
100 double inertiaForce[3];
101 cable_hydrodynamics::MorisonInertiaForce(
102 cable_hydrodynamics::InertiaForceFactor(rho, sfh::pi * element.radius * element.radius * element.length, f, 0.0), a.data(), axis.data(), inertiaForce);
103 load.segment<3>(0) += vec3(inertiaForce);
104 }
105 }
106 if (f < 1.0) {
107 const double rho = kAirDensity;
108 vec3 vz = V.dot(axis) * axis;
109 vec3 vxy = V - vz;
110 double vz_abs = vz.norm();
111 double vxy_abs = vxy.norm();
112
113 double Cd = 1;
114 double Ct = 1;
115
116 load(2) -= element.length * element.radius * element.radius * sfh::pi * rho * 9.81 * (1.0 - f);
117 load.segment<3>(0) -= rho * element.radius * element.length * (Cd * vxy_abs * vxy + Ct * vz_abs * vz) * (1.0 - f);
118 }
119}
120
121} // namespace RbCable
The drag coefficients of a CableRM element.
Definition Cable.h:165
double normal
Cd, on the flow normal to the axis.
Definition Cable.h:166
double torsional
The coefficient of the torsional drag on the spin about the axis.
Definition Cable.h:168
double tangential
Ct, the skin friction on the flow along the axis (owner ruling R68).
Definition Cable.h:167
The properties of a CableRM element.
Definition CableRMWaterLoad.h:23
bool kelp
True for a kelp rope.
Definition CableRMWaterLoad.h:26
double length
The element length [m].
Definition CableRMWaterLoad.h:24
double kelpWeight
The kelp biomass per metre [N/m].
Definition CableRMWaterLoad.h:27
double radius
The element radius [m].
Definition CableRMWaterLoad.h:25