FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
InternalCable.h
1
10
11#ifndef CInternalCable_H
12#define CInternalCable_H
13
14// Includes
15#include "cable/subroutines/CableElDynStiff.h"
16
17#include "sfh/constants.h"
18#include "sfh/linalg.h"
19#include "sfh/math/array.h"
20#include "sfh/math/math.h"
21#include "sfh/timers/StopWatch.h"
22
23#include <fhsim/simobject/SimObject.h>
24#include <fhsim_environment/EnvironmentProvider.h>
25#include <fhsim_environment/ElementFlowInteraction.h>
26#include <limits>
27#include <string>
28#include <vector>
29
30
31#define ATTACH_SPHERE
32
36{
37inline constexpr int kNumElements = 2;
38inline constexpr double kDensity = 1100;
39inline constexpr double kNumericalDamping = 1;
40inline constexpr double kDiameter = 0.01;
41inline constexpr double kYoungsModulus = 1e9;
42inline constexpr double kDampingRatio = 1;
43inline constexpr double kFluidRho = 1025;
44inline constexpr double kMaxStepLength = 1e-10;
45inline constexpr double kMaxTension = 1e10;
46inline constexpr double kStepSafetyFactor = 50;
47inline constexpr double kMeanTension = 0;
48inline constexpr double kAdaptationPeriod = 0;
49inline constexpr const char* kMaterialName = "Trawl/SteelWire";
50inline constexpr int kNumFaces = 5;
51inline constexpr int kBranchedNumFaces = 6;
52inline constexpr double kDrawScale = 1;
53inline constexpr double kMaxLengthChangeSpeed = 20;
54} // namespace cable_defaults
55
56
59{
60 int numElements;
61 double density;
62 double numericalDamping;
63 double diameter;
64 double dE;
65 double dampingRatio;
66 double fluidRho;
67 double maxStep;
68 double maxTension;
69 double stepSafetyFactor;
70 double dMeanTension0;
71 double eAdaptationPeriod;
72 std::string materialName;
73 int cableFaces;
74 std::string cableName;
75 double drawScale;
76
79 {
80 Reset();
81 }
83 void Reset()
84 {
85 numElements = cable_defaults::kNumElements;
87 numericalDamping = cable_defaults::kNumericalDamping;
90 dampingRatio = cable_defaults::kDampingRatio;
93 maxTension = cable_defaults::kMaxTension;
94 stepSafetyFactor = cable_defaults::kStepSafetyFactor;
95 dMeanTension0 = cable_defaults::kMeanTension;
96 eAdaptationPeriod = cable_defaults::kAdaptationPeriod;
97 materialName = cable_defaults::kMaterialName;
98 cableFaces = cable_defaults::kNumFaces;
99 cableName = "";
100 drawScale = cable_defaults::kDrawScale;
101 }
103 double CalcEA()
104 {
105 return sfh::pi * 0.25 * diameter * diameter * dE;
106 }
107};
108
111{
112 double deltaTheta;
113 double* adTheta;
114 double* adSinTheta;
115 double* adCosTheta;
116 double textureScale;
117 double* adCirclePos;
118 double* adFacePosNormal;
119 double* adTextureCoordU;
120 double* adTextureCoordV;
121 int numRenderEdges;
122 double drawDiam;
123 int* aiIndex;
124 int sizeIndexBuffer;
125
130 SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
131 {
132 drawDiam = drawDiameter;
133 numRenderEdges = numFaces + 1;
134 sizeIndexBuffer = numElements * numRenderEdges * 2;
135 textureScale = 5 * (sfh::pi * drawDiam);
136 aiIndex = new int[sizeIndexBuffer];
137 deltaTheta = 2 * sfh::pi / numFaces;
138 adTheta = new double[numRenderEdges];
139 adSinTheta = new double[numRenderEdges];
140 adCosTheta = new double[numRenderEdges];
141 adCirclePos = new double[(numElements + 1) * (numRenderEdges) * 3];
142 adFacePosNormal = new double[(numElements + 1) * (numRenderEdges) * 3];
143 adTextureCoordU = new double[numRenderEdges];
144 adTextureCoordV = new double[numElements + 1];
145 adTextureCoordV[0] = 0;
146 for (unsigned short i = 0; i < numRenderEdges; i++) {
147 adTheta[i] = i * deltaTheta;
148 adSinTheta[i] = sin(adTheta[i]);
149 adCosTheta[i] = cos(adTheta[i]);
150 adTextureCoordU[i] = adTheta[i] * (sfh::pi * drawDiam) / textureScale;
151 }
152 int i = 0;
153 for (int element = 0; element < numElements; element++) {
154 for (int edge = 0; edge < numRenderEdges; edge++) {
155 aiIndex[i++] = element * numRenderEdges + edge;
156 aiIndex[i++] = (element + 1) * numRenderEdges + edge;
157 }
158 }
159 }
160
163 {
164 delete[] adTheta;
165 delete[] adSinTheta;
166 delete[] adCosTheta;
167 delete[] adCirclePos;
168 delete[] adFacePosNormal;
169 delete[] adTextureCoordU;
170 delete[] adTextureCoordV;
171 }
172
179 void Update(int element, const double* adElPosA, const double* adElPosB, const double* adDirection, double dL0)
180 {
181 // Creating a vector not parallel to the direction of the element.
182 sfh::math::FindNotParallel(adDirection, 3, adNotParallel);
183
184 // Creating two vectors normal to each other and the direction of the element.
185 sfh::linalg::Cross(adDirection, adNotParallel, adNormal1);
186 sfh::linalg::Cross(adDirection, adNormal1, adNormal2);
187 sfh::math::Normalize3(adNormal1);
188 sfh::math::Normalize3(adNormal2);
189 sfh::math::ArrayMultiply(adNormal1, drawDiam / 2.0, 3);
190 sfh::math::ArrayMultiply(adNormal2, drawDiam / 2.0, 3);
191 adTextureCoordV[element + 1] = adTextureCoordV[element] + dL0 / textureScale * 3;
192
193 for (unsigned short face = 0; face < numRenderEdges; face++) {
194 for (unsigned short ind = 0; ind < 3; ind++) {
195 if (element == 0) {
196 adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
197 adCirclePos[element * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosA[ind] + adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind];
198 }
199 adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
200 adCirclePos[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosB[ind] + adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind];
201 }
202 }
203 }
204
205private:
206 // Varaiables to avoid excessive allocations
207 double adNotParallel[3];
208 double adNormal1[3];
209 double adNormal2[3];
210};
211
212// Class definition
214{
215public:
217 InternalCable(ISimObjectCreator* creator, const SCableSpec& CableSpec);
218
220 virtual ~InternalCable();
221
222 // Member functions
223 virtual void FinalSetup(const double dT, const double* const adX, ISimObjectCreator* const creator);
224
226 virtual void OdeFcn(const double* const adPosA,
227 const double* const adVelA,
228 const double* const adPosB,
229 const double* const adVelB,
230 const double* const adX,
231 double* const adXDot,
232 double dT) const;
233
236 bool HasForceOutsideJacobian() const { return m_forceOutsideJacobian; }
237
248 void EvaluateElementsAt(const double* adPosA, const double* adVelA, const double* adPosB, const double* adVelB, const double* adX, double dT) const;
249
252 double EndInertia(int end) const;
253
259 const double* posA, const double* velA,
260 const double* posB, const double* velB,
261 const double* X, double* J, int nStates, int stateOffset) const;
262
283 const double* posA, const double* velA,
284 const double* posB, const double* velB,
285 int globalPosIdxA, int globalVelIdxA,
286 int globalPosIdxB, int globalVelIdxB,
287 double endInertiaA, double endInertiaB,
288 const double* X, double* J, int nStates, int stateOffset) const;
289
291 virtual bool InitializeStates(const double* const adPosA,
292 const double* const adVelA,
293 const double* const adPosB,
294 const double* const adVelB,
295 double* const adX);
296
298 void UpdateCable(double newLength);
299
310 void AdvanceMeanTension(const double* adPosA, const double* adPosB, const double* adX, double T);
311
323 void TakeWakes(const double* adPosA, const double* adPosB, const double* adX, double T);
324
327 double* const adEndForceA,
328 double* const adEndForceB,
329 double* const pdEndInertiaA,
330 double* const pdEndInertiaB,
331 const double* const adPosA,
332 const double* const adVelA,
333 const double* const adPosB,
334 const double* const adVelB,
335 const double* const adX,
336 double dT);
337
339 double GetLength();
340
341#ifdef FH_VISUALIZATION
343 void RenderInit(Ogre::Root* ogreRoot);
344
346 void RenderUpdate(const double* const adX, const double* adPosA, const double* adPosB);
347#endif
348
349 unsigned long m_numElements;
350 unsigned long m_numNodes;
351protected:
352 // Deletes all node forces.
353 void ResetAllNodeForces() const;
354
355 // Adds the forces from each cable element to the array of node forces.
356 void AddAllElementForces(const double* const adPosA,
357 const double* const adVelA,
358 const double* const adPosB,
359 const double* const adVelB,
360 const double* const adX,
361 double dT) const;
362
363 // Calculates the derivatives of the states of the cable.
364 void CalcDerivatives(const double* const adX,
365 double* const adXDot) const;
366
367 // Adds the forces from one element to the array of node forces.
368 virtual void AddElementForce(int cableElement,
369 const double adPosA[3],
370 const double adVelA[3],
371 const double adPosB[3],
372 const double adVelB[3],
373 double adForceA[3],
374 double adForceB[3],
375 double dT) const;
376
382 virtual void AddNodeForce(const double /*pos*/[3], const double /*vel*/[3], double /*force*/[3]) const { }
383
386 void MarkForceOutsideJacobian() const { m_forceOutsideJacobian = true; }
387
393 void AddBareElementForce(int cableElement,
394 const double posA[3], const double velA[3], const double posB[3], const double velB[3],
395 const double waterVel[3], double forceA[3], double forceB[3]) const;
396
399 double NodeInertia(unsigned long node) const;
400
404 bool SegmentEndBlocks(unsigned long segment,
405 const double* posA, const double* velA,
406 const double* posB, const double* velB,
407 const double* X, double dFA_dposB[9], double dFA_dvelA[9]) const;
408
409 unsigned long* m_iStatePos;
410 unsigned long* m_iStateVel;
411
412 // Member variables
414 double m_eA;
415 double m_meanTensionTime = std::numeric_limits<double>::quiet_NaN();
416
418 double** m_aadForceA;
419 double** m_aadForceB;
420
421 environment::wake::ElementFlowInteraction m_flow;
422 environment::EnvironmentProvider* m_environment = nullptr;
423 double m_elVelWater[3];
424 double m_elMeanPos[3];
425 double m_elMeanVel[3];
426
427#ifdef FH_VISUALIZATION
428 SCableRenderSpec* m_renderSpec;
429 Ogre::Root* m_ogreRoot;
430 Ogre::SceneManager* m_sceneMgr;
431 Ogre::Entity* m_renderElement;
432 Ogre::SceneNode* m_renderNode;
433 Ogre::ManualObject* m_cableRenderObj;
434 double m_drawDiam;
435# ifdef ATTACH_SPHERE
436 Ogre::Entity* m_renderSphere[2];
437 Ogre::SceneNode* m_renderNodeSphere[2];
438# endif
439#endif
440
441private:
442 mutable bool m_forceOutsideJacobian = false;
443};
444
445
446#endif
Definition CableElDynStiff.h:31
Definition InternalCable.h:214
virtual ~InternalCable()
The destructor deletes dynamically allocated memory.
void ComputeStructuralJacobian(const double *posA, const double *velA, const double *posB, const double *velB, const double *X, double *J, int nStates, int stateOffset) const
double m_eA
The stiffness of the cable.
Definition InternalCable.h:414
double ** m_aadForceB
The force on the B nodes.
Definition InternalCable.h:419
void EvaluateElementsAt(const double *adPosA, const double *adVelA, const double *adPosB, const double *adVelB, const double *adX, double dT) const
virtual void AddNodeForce(const double[3], const double[3], double[3]) const
Definition InternalCable.h:382
double ** m_aadForceA
The force on the A nodes.
Definition InternalCable.h:418
bool HasForceOutsideJacobian() const
Definition InternalCable.h:236
void AddEndpointJacobianContributions(const double *posA, const double *velA, const double *posB, const double *velB, int globalPosIdxA, int globalVelIdxA, int globalPosIdxB, int globalVelIdxB, double endInertiaA, double endInertiaB, const double *X, double *J, int nStates, int stateOffset) const
void MarkForceOutsideJacobian() const
Definition InternalCable.h:386
void AddBareElementForce(int cableElement, const double posA[3], const double velA[3], const double posB[3], const double velB[3], const double waterVel[3], double forceA[3], double forceB[3]) const
unsigned long m_numNodes
The number of nodes of the cable.
Definition InternalCable.h:350
void TakeWakes(const double *adPosA, const double *adPosB, const double *adX, double T)
SCableSpec m_CableSpec
The cable specification.
Definition InternalCable.h:413
environment::wake::ElementFlowInteraction m_flow
The flow at the element midpoints, the other objects' wakes taken per step (MARE-0223); the Environme...
Definition InternalCable.h:421
double m_meanTensionTime
The time of the last AdvanceMeanTension.
Definition InternalCable.h:415
double NodeInertia(unsigned long node) const
double EndInertia(int end) const
unsigned long * m_iStatePos
An array of indices to the node position states.
Definition InternalCable.h:409
environment::EnvironmentProvider * m_environment
m_flow's Environment, from FinalSetup; null before it and without one (fhsim_fishery's tests set it b...
Definition InternalCable.h:422
CableElDynStiff ** m_cableElements
An array holding the cable elements.
Definition InternalCable.h:417
virtual void OdeFcn(const double *const adPosA, const double *const adVelA, const double *const adPosB, const double *const adVelB, const double *const adX, double *const adXDot, double dT) const
Calculates the state derivatives and the end forces.
bool SegmentEndBlocks(unsigned long segment, const double *posA, const double *velA, const double *posB, const double *velB, const double *X, double dFA_dposB[9], double dFA_dvelA[9]) const
virtual bool InitializeStates(const double *const adPosA, const double *const adVelA, const double *const adPosB, const double *const adVelB, double *const adX)
Method for setting initial conditions when the input is known, which may be implemented in the indivi...
unsigned long m_numElements
The number of elements to divide the cable into.
Definition InternalCable.h:349
double GetLength()
Calculates the length of the cable.
void UpdateCable(double newLength)
Sets the unstretched length of the cable, divided equally between its elements.
unsigned long * m_iStateVel
An array of indices to the node velocity states.
Definition InternalCable.h:410
void AddEndForcesAndInertia(double *const adEndForceA, double *const adEndForceB, double *const pdEndInertiaA, double *const pdEndInertiaB, const double *const adPosA, const double *const adVelA, const double *const adPosB, const double *const adVelB, const double *const adX, double dT)
Adds the end forces and inertia to the supplied data structures.
void AdvanceMeanTension(const double *adPosA, const double *adPosB, const double *adX, double T)
InternalCable(ISimObjectCreator *creator, const SCableSpec &CableSpec)
The constructor sets the pointer to the output object and the parser object.
Definition InternalCable.h:36
constexpr double kMaxLengthChangeSpeed
Cable/Branched: how fast the cables may change length [m/s].
Definition InternalCable.h:53
constexpr double kDrawScale
The visual scale of the cable.
Definition InternalCable.h:52
constexpr double kMaxTension
The maximum tension in the cable [N].
Definition InternalCable.h:45
constexpr int kNumFaces
The visual number of faces of Cable/LumpedMass.
Definition InternalCable.h:50
constexpr double kStepSafetyFactor
Read and checked, not used by the stiffness calculation.
Definition InternalCable.h:46
constexpr double kMeanTension
The mean tension of the cable [N].
Definition InternalCable.h:47
constexpr double kFluidRho
The density of the surrounding fluid [kg/m³].
Definition InternalCable.h:43
constexpr double kAdaptationPeriod
The time constant of the adaptation of the mean tension [s].
Definition InternalCable.h:48
constexpr double kYoungsModulus
The stiffness of the cable material [Pa].
Definition InternalCable.h:41
constexpr double kDampingRatio
The relative axial damping.
Definition InternalCable.h:42
constexpr int kBranchedNumFaces
The visual number of faces of Cable/Branched's General tag.
Definition InternalCable.h:51
constexpr double kDiameter
The diameter of the cable [m].
Definition InternalCable.h:40
constexpr double kDensity
The density of the cable material [kg/m³].
Definition InternalCable.h:38
constexpr double kNumericalDamping
Linear damping rate on each node's velocity (relative to the earth, not the water) [1/s].
Definition InternalCable.h:39
constexpr double kMaxStepLength
The step the reduced stiffness is chosen for [s]; this small keeps the full stiffness.
Definition InternalCable.h:44
Contains some specifications and methods used for rendering cables.
Definition InternalCable.h:111
SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
Definition InternalCable.h:130
~SCableRenderSpec()
The destructor frees allocated memory.
Definition InternalCable.h:162
void Update(int element, const double *adElPosA, const double *adElPosB, const double *adDirection, double dL0)
Definition InternalCable.h:179
Contains some specifications used for simulating cables.
Definition InternalCable.h:59
void Reset()
Resets the specification to the defaults.
Definition InternalCable.h:83
double CalcEA()
Calculates the stiffness of the cable.
Definition InternalCable.h:103
SCableSpec()
The constructor sets some default values.
Definition InternalCable.h:78