23#include "WetCylinderWater.h"
25#include <fhsim_environment/ElementFlowInteraction.h>
26#include <fhsim_environment/hydrodynamics/WetCylinderLaw.h>
35namespace wet_cylinder_water
37using environment::wet_cylinder::EndWater;
42 Eigen::Vector3d
force = Eigen::Vector3d::Zero();
43 Eigen::Vector3d
moment = Eigen::Vector3d::Zero();
65 void Begin(
double length,
bool closed =
false)
78 void Add(
const Eigen::Vector3d& centre,
const Eigen::Vector3d& axis)
80 m_centres.push_back(centre);
81 m_axes.push_back(axis);
88 m_ends.resize(numElements);
89 const int numJoints = m_closed ? numElements : numElements + 1;
90 m_positions.assign(numElements > 0 ? numJoints : 0, Eigen::Vector3d::Zero());
94 for (
int i = 0; i < numElements; i++)
95 AssignEnds(i, NearerEnd(i, m_centres[(i + 1) % numElements]), i, (i + numElements - 1) % numElements);
96 for (
int i = 0; i < numElements; i++)
97 for (
int end = 0; end < 2; end++)
98 m_positions[m_ends[i][end]] += EndPosition(i, end);
99 for (Eigen::Vector3d& position : m_positions)
103 if (numElements == 1) {
106 for (
int i = 0; i < numElements - 1; i++)
107 AssignEnds(i, NearerEnd(i, m_centres[i + 1]), i + 1, i);
108 const int last = numElements - 1;
109 AssignEnds(last, NearerEnd(last, m_centres[last - 1]), last, numElements);
111 for (
int i = 0; i < numElements; i++)
112 for (
int end = 0; end < 2; end++)
113 m_positions[m_ends[i][end]] += EndPosition(i, end);
114 for (
int joint = 1; joint < numElements; joint++)
115 m_positions[joint] *= 0.5;
119 int NumElements()
const {
return static_cast<int>(m_centres.size()); }
122 int NumJoints()
const {
return static_cast<int>(m_positions.size()); }
125 const Eigen::Vector3d&
JointPosition(
int joint)
const {
return m_positions[joint]; }
132 int JointOfEnd(
int element,
int end)
const {
return m_ends[element][end]; }
140 points.reserve(points.size() + 3 * m_positions.size());
141 for (
const Eigen::Vector3d& position : m_positions)
142 points.insert(points.end(), position.data(), position.data() + 3);
151 void QueryWater(
const environment::wake::ElementFlowInteraction& flow,
double T,
int firstPoint)
153 m_water.resize(m_positions.size());
154 for (
int joint = 0; joint <
NumJoints(); joint++) {
155 m_water[joint].setZero();
156 flow.WaterVelocity(T, firstPoint + joint, m_positions[joint].data(), m_water[joint].data());
163 const Eigen::Vector3d& minus = m_water[m_ends[element][0]];
164 const Eigen::Vector3d& plus = m_water[m_ends[element][1]];
165 return {{minus(0), minus(1), minus(2)}, {plus(0), plus(1), plus(2)}};
169 Eigen::Vector3d EndPosition(
int element,
int end)
const {
return m_centres[element] + (end == 1 ? 0.5 : -0.5) * m_length * m_axes[element]; }
172 int NearerEnd(
int element,
const Eigen::Vector3d& target)
const
174 return (EndPosition(element, 1) - target).squaredNorm() < (EndPosition(element, 0) - target).squaredNorm() ? 1 : 0;
177 void AssignEnds(
int element,
int touchingEnd,
int touchingJoint,
int otherJoint)
179 m_ends[element][touchingEnd] = touchingJoint;
180 m_ends[element][1 - touchingEnd] = otherJoint;
183 double m_length = 0.0;
184 bool m_closed =
false;
185 std::vector<Eigen::Vector3d> m_centres;
186 std::vector<Eigen::Vector3d> m_axes;
187 std::vector<std::array<int, 2>> m_ends;
188 std::vector<Eigen::Vector3d> m_positions;
189 std::vector<Eigen::Vector3d> m_water;
203template<
class DragModel = environment::wet_cylinder::ReynoldsDrag>
204inline GaussDragLoad GaussPointDragLoad(
const environment::wet_cylinder::WetCylinder& cylinder,
double f,
const Eigen::Vector3d& V,
const Eigen::Vector3d& W,
205 const Eigen::Vector3d& axis,
const EndWater& water,
const DragModel& model = DragModel {})
207 const auto parts = environment::wet_cylinder::GaussPointDragLoad(cylinder, model, f, {V(0), V(1), V(2)}, {W(0), W(1), W(2)}, {axis(0), axis(1), axis(2)}, water);
208 return {Eigen::Vector3d(parts.force.data()), Eigen::Vector3d(parts.moment.data())};
Definition GaussPointDrag.h:58
int JointOfEnd(int element, int end) const
Definition GaussPointDrag.h:132
void Build()
Finds the joints and their positions from the elements added.
Definition GaussPointDrag.h:85
int NumElements() const
The number of elements in the chain.
Definition GaussPointDrag.h:119
void QueryWater(const environment::wake::ElementFlowInteraction &flow, double T, int firstPoint)
Definition GaussPointDrag.h:151
void Begin(double length, bool closed=false)
Definition GaussPointDrag.h:65
void Add(const Eigen::Vector3d ¢re, const Eigen::Vector3d &axis)
Definition GaussPointDrag.h:78
void AppendJointPositions(std::vector< double > &points) const
Definition GaussPointDrag.h:138
const Eigen::Vector3d & JointPosition(int joint) const
The position of joint joint [m], NED.
Definition GaussPointDrag.h:125
int NumJoints() const
The number of joints: one more than the number of elements in an open chain, as many in a closed loop...
Definition GaussPointDrag.h:122
EndWater WaterOf(int element) const
The water at the ends of element element, after QueryWater.
Definition GaussPointDrag.h:161
< The water velocity at the two ends of an element, from fhsim_environment.
Definition GaussPointDrag.h:41
Eigen::Vector3d moment
The sum of (s N) × F over the two points.
Definition GaussPointDrag.h:43
Eigen::Vector3d force
The sum of the drag at the two points.
Definition GaussPointDrag.h:42