FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
GaussPointDrag.h
1#pragma once
2
23#include "WetCylinderWater.h"
24
25#include <fhsim_environment/ElementFlowInteraction.h>
26#include <fhsim_environment/hydrodynamics/WetCylinderLaw.h>
27
28#include <Eigen/Eigen>
29
30#include <algorithm>
31#include <array>
32#include <cmath>
33#include <vector>
34
35namespace wet_cylinder_water
36{
37using environment::wet_cylinder::EndWater;
38
41{
42 Eigen::Vector3d force = Eigen::Vector3d::Zero();
43 Eigen::Vector3d moment = Eigen::Vector3d::Zero();
44};
45
58{
59public:
65 void Begin(double length, bool closed = false)
66 {
67 m_length = length;
68 m_closed = closed;
69 m_centres.clear();
70 m_axes.clear();
71 }
72
78 void Add(const Eigen::Vector3d& centre, const Eigen::Vector3d& axis)
79 {
80 m_centres.push_back(centre);
81 m_axes.push_back(axis);
82 }
83
85 void Build()
86 {
87 const int numElements = NumElements();
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());
91 if (numElements == 0)
92 return;
93 if (m_closed) {
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)
100 position *= 0.5; // two ends meet at every joint: their midpoint
101 return;
102 }
103 if (numElements == 1) {
104 m_ends[0] = {0, 1};
105 } else {
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);
110 }
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; // two ends meet: their midpoint
116 }
117
119 int NumElements() const { return static_cast<int>(m_centres.size()); }
120
122 int NumJoints() const { return static_cast<int>(m_positions.size()); }
123
125 const Eigen::Vector3d& JointPosition(int joint) const { return m_positions[joint]; }
126
132 int JointOfEnd(int element, int end) const { return m_ends[element][end]; }
133
138 void AppendJointPositions(std::vector<double>& points) const
139 {
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);
143 }
144
151 void QueryWater(const environment::wake::ElementFlowInteraction& flow, double T, int firstPoint)
152 {
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());
157 }
158 }
159
161 EndWater WaterOf(int element) const
162 {
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)}};
166 }
167
168private:
169 Eigen::Vector3d EndPosition(int element, int end) const { return m_centres[element] + (end == 1 ? 0.5 : -0.5) * m_length * m_axes[element]; }
170
172 int NearerEnd(int element, const Eigen::Vector3d& target) const
173 {
174 return (EndPosition(element, 1) - target).squaredNorm() < (EndPosition(element, 0) - target).squaredNorm() ? 1 : 0;
175 }
176
177 void AssignEnds(int element, int touchingEnd, int touchingJoint, int otherJoint)
178 {
179 m_ends[element][touchingEnd] = touchingJoint;
180 m_ends[element][1 - touchingEnd] = otherJoint;
181 }
182
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;
190};
191
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 {})
206{
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())};
209}
210} // namespace wet_cylinder_water
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 &centre, 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