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
33
36{
37 int numElements;
38 double density;
39 double numericalDamping;
40 double diameter;
41 double dE;
42 double dampingRatio;
43 double fluidRho;
44 double maxStep;
45 double maxTension;
46 double stepSafetyFactor;
47 double dMeanTension0;
48 double eAdaptationPeriod;
49 std::string materialName;
50 int cableFaces;
51 std::string cableName;
52 double drawScale;
53
56 {
57 Reset();
58 }
60 void Reset()
61 {
62 numElements = 2;
63 density = 1100;
64 numericalDamping = 1;
65 diameter = 0.01;
66 dE = 1e9;
67 dampingRatio = 1;
68 fluidRho = 1025;
69 maxStep = 1e-10;
70 maxTension = 1e10;
71 stepSafetyFactor = 50;
72 dMeanTension0 = 0;
73 eAdaptationPeriod = 0;
74 materialName = "Trawl/SteelWire";
75 cableFaces = 5;
76 cableName = "";
77 drawScale = 1;
78 }
80 double CalcEA()
81 {
82 return sfh::pi * 0.25 * diameter * diameter * dE;
83 }
84};
85
88{
89 double deltaTheta;
90 double* adTheta;
91 double* adSinTheta;
92 double* adCosTheta;
93 double textureScale;
94 double* adCirclePos;
95 double* adFacePosNormal;
96 double* adTextureCoordU;
97 double* adTextureCoordV;
98 int numRenderEdges;
99 double drawDiam;
100 int* aiIndex;
101 int sizeIndexBuffer;
102
107 SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
108 {
109 drawDiam = drawDiameter;
110 numRenderEdges = numFaces + 1;
111 sizeIndexBuffer = numElements * numRenderEdges * 2;
112 textureScale = 5 * (sfh::pi * drawDiam);
113 aiIndex = new int[sizeIndexBuffer];
114 deltaTheta = 2 * sfh::pi / numFaces;
115 adTheta = new double[numRenderEdges];
116 adSinTheta = new double[numRenderEdges];
117 adCosTheta = new double[numRenderEdges];
118 adCirclePos = new double[(numElements + 1) * (numRenderEdges) * 3];
119 adFacePosNormal = new double[(numElements + 1) * (numRenderEdges) * 3];
120 adTextureCoordU = new double[numRenderEdges];
121 adTextureCoordV = new double[numElements + 1];
122 adTextureCoordV[0] = 0;
123 for (unsigned short i = 0; i < numRenderEdges; i++) {
124 adTheta[i] = i * deltaTheta;
125 adSinTheta[i] = sin(adTheta[i]);
126 adCosTheta[i] = cos(adTheta[i]);
127 adTextureCoordU[i] = adTheta[i] * (sfh::pi * drawDiam) / textureScale;
128 }
129 int i = 0;
130 for (int element = 0; element < numElements; element++) {
131 for (int edge = 0; edge < numRenderEdges; edge++) {
132 aiIndex[i++] = element * numRenderEdges + edge;
133 aiIndex[i++] = (element + 1) * numRenderEdges + edge;
134 }
135 }
136 }
137
140 {
141 delete[] adTheta;
142 delete[] adSinTheta;
143 delete[] adCosTheta;
144 delete[] adCirclePos;
145 delete[] adFacePosNormal;
146 delete[] adTextureCoordU;
147 delete[] adTextureCoordV;
148 }
149
156 void Update(int element, const double* adElPosA, const double* adElPosB, const double* adDirection, double dL0)
157 {
158 // Creating a vector not parallel to the direction of the element.
159 sfh::math::FindNotParallel(adDirection, 3, adNotParallel);
160
161 // Creating two vectors normal to each other and the direction of the element.
162 sfh::linalg::Cross(adDirection, adNotParallel, adNormal1);
163 sfh::linalg::Cross(adDirection, adNormal1, adNormal2);
164 sfh::math::Normalize3(adNormal1);
165 sfh::math::Normalize3(adNormal2);
166 sfh::math::ArrayMultiply(adNormal1, drawDiam / 2.0, 3);
167 sfh::math::ArrayMultiply(adNormal2, drawDiam / 2.0, 3);
168 adTextureCoordV[element + 1] = adTextureCoordV[element] + dL0 / textureScale * 3;
169
170 for (unsigned short face = 0; face < numRenderEdges; face++) {
171 for (unsigned short ind = 0; ind < 3; ind++) {
172 if (element == 0) {
173 adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
174 adCirclePos[element * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosA[ind] + adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind];
175 }
176 adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
177 adCirclePos[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosB[ind] + adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind];
178 }
179 }
180 }
181
182private:
183 // Varaiables to avoid excessive allocations
184 double adNotParallel[3];
185 double adNormal1[3];
186 double adNormal2[3];
187};
188
189// Class definition
191{
192public:
194 InternalCable(ISimObjectCreator* creator, const SCableSpec& CableSpec);
195
197 virtual ~InternalCable();
198
199 // Member functions
200 virtual void FinalSetup(const double dT, const double* const adX, ISimObjectCreator* const creator);
201
203 virtual void OdeFcn(const double* const adPosA,
204 const double* const adVelA,
205 const double* const adPosB,
206 const double* const adVelB,
207 const double* const adX,
208 double* const adXDot,
209 double dT) const;
210
213 bool HasForceOutsideJacobian() const { return m_forceOutsideJacobian; }
214
225 void EvaluateElementsAt(const double* adPosA, const double* adVelA, const double* adPosB, const double* adVelB, const double* adX, double dT) const;
226
229 double EndInertia(int end) const;
230
236 const double* posA, const double* velA,
237 const double* posB, const double* velB,
238 const double* X, double* J, int nStates, int stateOffset) const;
239
260 const double* posA, const double* velA,
261 const double* posB, const double* velB,
262 int globalPosIdxA, int globalVelIdxA,
263 int globalPosIdxB, int globalVelIdxB,
264 double endInertiaA, double endInertiaB,
265 const double* X, double* J, int nStates, int stateOffset) const;
266
268 virtual bool InitializeStates(const double* const adPosA,
269 const double* const adVelA,
270 const double* const adPosB,
271 const double* const adVelB,
272 double* const adX);
273
275 void UpdateCable(double newLength);
276
287 void AdvanceMeanTension(const double* adPosA, const double* adPosB, const double* adX, double T);
288
300 void TakeWakes(const double* adPosA, const double* adPosB, const double* adX, double T);
301
304 double* const adEndForceA,
305 double* const adEndForceB,
306 double* const pdEndInertiaA,
307 double* const pdEndInertiaB,
308 const double* const adPosA,
309 const double* const adVelA,
310 const double* const adPosB,
311 const double* const adVelB,
312 const double* const adX,
313 double dT);
314
316 double GetLength();
317
318#ifdef FH_VISUALIZATION
320 void RenderInit(Ogre::Root* ogreRoot);
321
323 void RenderUpdate(const double* const adX, const double* adPosA, const double* adPosB);
324#endif
325
326 unsigned long m_numElements;
327 unsigned long m_numNodes;
328protected:
329 // Deletes all node forces.
330 void ResetAllNodeForces() const;
331
332 // Adds the forces from each cable element to the array of node forces.
333 void AddAllElementForces(const double* const adPosA,
334 const double* const adVelA,
335 const double* const adPosB,
336 const double* const adVelB,
337 const double* const adX,
338 double dT) const;
339
340 // Calculates the derivatives of the states of the cable.
341 void CalcDerivatives(const double* const adX,
342 double* const adXDot) const;
343
344 // Adds the forces from one element to the array of node forces.
345 virtual void AddElementForce(int cableElement,
346 const double adPosA[3],
347 const double adVelA[3],
348 const double adPosB[3],
349 const double adVelB[3],
350 double adForceA[3],
351 double adForceB[3],
352 double dT) const;
353
359 virtual void AddNodeForce(const double /*pos*/[3], const double /*vel*/[3], double /*force*/[3]) const { }
360
363 void MarkForceOutsideJacobian() const { m_forceOutsideJacobian = true; }
364
370 void AddBareElementForce(int cableElement,
371 const double posA[3], const double velA[3], const double posB[3], const double velB[3],
372 const double waterVel[3], double forceA[3], double forceB[3]) const;
373
376 double NodeInertia(unsigned long node) const;
377
381 bool SegmentEndBlocks(unsigned long segment,
382 const double* posA, const double* velA,
383 const double* posB, const double* velB,
384 const double* X, double dFA_dposB[9], double dFA_dvelA[9]) const;
385
386 unsigned long* m_iStatePos;
387 unsigned long* m_iStateVel;
388
389 // Member variables
391 double m_eA;
392 double m_meanTensionTime = std::numeric_limits<double>::quiet_NaN();
393
395 double** m_aadForceA;
396 double** m_aadForceB;
397
398 environment::wake::ElementFlowInteraction m_flow;
399 environment::EnvironmentProvider* m_environment = nullptr;
400 double m_elVelWater[3];
401 double m_elMeanPos[3];
402 double m_elMeanVel[3];
403
404#ifdef FH_VISUALIZATION
405 SCableRenderSpec* m_renderSpec;
406 Ogre::Root* m_ogreRoot;
407 Ogre::SceneManager* m_sceneMgr;
408 Ogre::Entity* m_renderElement;
409 Ogre::SceneNode* m_renderNode;
410 Ogre::ManualObject* m_cableRenderObj;
411 double m_drawDiam;
412# ifdef ATTACH_SPHERE
413 Ogre::Entity* m_renderSphere[2];
414 Ogre::SceneNode* m_renderNodeSphere[2];
415# endif
416#endif
417
418private:
419 mutable bool m_forceOutsideJacobian = false;
420};
421
422
423#endif
Definition CableElDynStiff.h:31
Definition InternalCable.h:191
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:391
double ** m_aadForceB
The force on the B nodes.
Definition InternalCable.h:396
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:359
double ** m_aadForceA
The force on the A nodes.
Definition InternalCable.h:395
bool HasForceOutsideJacobian() const
Definition InternalCable.h:213
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:363
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:327
void TakeWakes(const double *adPosA, const double *adPosB, const double *adX, double T)
SCableSpec m_CableSpec
The cable specification.
Definition InternalCable.h:390
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:398
double m_meanTensionTime
The time of the last AdvanceMeanTension.
Definition InternalCable.h:392
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:386
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:399
CableElDynStiff ** m_cableElements
An array holding the cable elements.
Definition InternalCable.h:394
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:326
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:387
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.
Contains some specifications and methods used for rendering cables.
Definition InternalCable.h:88
SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
Definition InternalCable.h:107
~SCableRenderSpec()
The destructor frees allocated memory.
Definition InternalCable.h:139
void Update(int element, const double *adElPosA, const double *adElPosB, const double *adDirection, double dL0)
Definition InternalCable.h:156
Contains some specifications used for simulating cables.
Definition InternalCable.h:36
void Reset()
Resets the specification to the defaults.
Definition InternalCable.h:60
double CalcEA()
Calculates the stiffness of the cable.
Definition InternalCable.h:80
SCableSpec()
The constructor sets some default values.
Definition InternalCable.h:55