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 <limits>
26#include <string>
27
28
29#define ATTACH_SPHERE
30
31
34{
35 int numElements;
36 double density;
37 double numericalDamping;
38 double diameter;
39 double dE;
40 double dampingRatio;
41 double fluidRho;
42 double maxStep;
43 double maxTension;
44 double stepSafetyFactor;
45 double dMeanTension0;
46 double eAdaptationPeriod;
47 std::string materialName;
48 int cableFaces;
49 std::string cableName;
50 double drawScale;
51
54 {
55 Reset();
56 }
58 void Reset()
59 {
60 numElements = 2;
61 density = 1100;
62 numericalDamping = 1;
63 diameter = 0.01;
64 dE = 1e9;
65 dampingRatio = 1;
66 fluidRho = 1025;
67 maxStep = 1e-10;
68 maxTension = 1e10;
69 stepSafetyFactor = 50;
70 dMeanTension0 = 0;
71 eAdaptationPeriod = 0;
72 materialName = "Trawl/SteelWire";
73 cableFaces = 5;
74 cableName = "";
75 drawScale = 1;
76 }
78 double CalcEA()
79 {
80 return sfh::pi * 0.25 * diameter * diameter * dE;
81 }
82};
83
86{
87 double deltaTheta;
88 double* adTheta;
89 double* adSinTheta;
90 double* adCosTheta;
91 double textureScale;
92 double* adCirclePos;
93 double* adFacePosNormal;
94 double* adTextureCoordU;
95 double* adTextureCoordV;
96 int numRenderEdges;
97 double drawDiam;
98 int* aiIndex;
99 int sizeIndexBuffer;
100
105 SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
106 {
107 drawDiam = drawDiameter;
108 numRenderEdges = numFaces + 1;
109 sizeIndexBuffer = numElements * numRenderEdges * 2;
110 textureScale = 5 * (sfh::pi * drawDiam);
111 aiIndex = new int[sizeIndexBuffer];
112 deltaTheta = 2 * sfh::pi / numFaces;
113 adTheta = new double[numRenderEdges];
114 adSinTheta = new double[numRenderEdges];
115 adCosTheta = new double[numRenderEdges];
116 adCirclePos = new double[(numElements + 1) * (numRenderEdges) * 3];
117 adFacePosNormal = new double[(numElements + 1) * (numRenderEdges) * 3];
118 adTextureCoordU = new double[numRenderEdges];
119 adTextureCoordV = new double[numElements + 1];
120 adTextureCoordV[0] = 0;
121 for (unsigned short i = 0; i < numRenderEdges; i++) {
122 adTheta[i] = i * deltaTheta;
123 adSinTheta[i] = sin(adTheta[i]);
124 adCosTheta[i] = cos(adTheta[i]);
125 adTextureCoordU[i] = adTheta[i] * (sfh::pi * drawDiam) / textureScale;
126 }
127 int i = 0;
128 for (int element = 0; element < numElements; element++) {
129 for (int edge = 0; edge < numRenderEdges; edge++) {
130 aiIndex[i++] = element * numRenderEdges + edge;
131 aiIndex[i++] = (element + 1) * numRenderEdges + edge;
132 }
133 }
134 }
135
138 {
139 delete[] adTheta;
140 delete[] adSinTheta;
141 delete[] adCosTheta;
142 delete[] adCirclePos;
143 delete[] adFacePosNormal;
144 delete[] adTextureCoordU;
145 delete[] adTextureCoordV;
146 }
147
154 void Update(int element, const double* adElPosA, const double* adElPosB, const double* adDirection, double dL0)
155 {
156 // Creating a vector not parallel to the direction of the element.
157 sfh::math::FindNotParallel(adDirection, 3, adNotParallel);
158
159 // Creating two vectors normal to each other and the direction of the element.
160 sfh::linalg::Cross(adDirection, adNotParallel, adNormal1);
161 sfh::linalg::Cross(adDirection, adNormal1, adNormal2);
162 sfh::math::Normalize3(adNormal1);
163 sfh::math::Normalize3(adNormal2);
164 sfh::math::ArrayMultiply(adNormal1, drawDiam / 2.0, 3);
165 sfh::math::ArrayMultiply(adNormal2, drawDiam / 2.0, 3);
166 adTextureCoordV[element + 1] = adTextureCoordV[element] + dL0 / textureScale * 3;
167
168 for (unsigned short face = 0; face < numRenderEdges; face++) {
169 for (unsigned short ind = 0; ind < 3; ind++) {
170 if (element == 0) {
171 adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
172 adCirclePos[element * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosA[ind] + adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind];
173 }
174 adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
175 adCirclePos[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosB[ind] + adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind];
176 }
177 }
178 }
179
180private:
181 // Varaiables to avoid excessive allocations
182 double adNotParallel[3];
183 double adNormal1[3];
184 double adNormal2[3];
185};
186
187// Class definition
189{
190public:
192 InternalCable(ISimObjectCreator* creator, const SCableSpec& CableSpec);
193
196
197 // Member functions
198 virtual void FinalSetup(const double dT, const double* const adX, ISimObjectCreator* const creator);
199
201 virtual void OdeFcn(const double* const adPosA,
202 const double* const adVelA,
203 const double* const adPosB,
204 const double* const adVelB,
205 const double* const adX,
206 double* const adXDot,
207 double dT) const;
208
211 virtual bool InBottomContact() const { return false; }
212
223 void EvaluateElementsAt(const double* adPosA, const double* adVelA, const double* adPosB, const double* adVelB, const double* adX, double dT) const;
224
227 double EndInertia(int end) const;
228
234 const double* posA, const double* velA,
235 const double* posB, const double* velB,
236 const double* X, double* J, int nStates, int stateOffset) const;
237
258 const double* posA, const double* velA,
259 const double* posB, const double* velB,
260 int globalPosIdxA, int globalVelIdxA,
261 int globalPosIdxB, int globalVelIdxB,
262 double endInertiaA, double endInertiaB,
263 const double* X, double* J, int nStates, int stateOffset) const;
264
266 virtual bool InitializeStates(const double* const adPosA,
267 const double* const adVelA,
268 const double* const adPosB,
269 const double* const adVelB,
270 double* const adX);
271
273 void UpdateCable(double newLength);
274
285 void AdvanceMeanTension(const double* adPosA, const double* adPosB, const double* adX, double T);
286
289 double* const adEndForceA,
290 double* const adEndForceB,
291 double* const pdEndInertiaA,
292 double* const pdEndInertiaB,
293 const double* const adPosA,
294 const double* const adVelA,
295 const double* const adPosB,
296 const double* const adVelB,
297 const double* const adX,
298 double dT);
299
301 double GetLength();
302
303#ifdef FH_VISUALIZATION
305 void RenderInit(Ogre::Root* ogreRoot);
306
308 void RenderUpdate(const double* const adX, const double* adPosA, const double* adPosB);
309#endif
310
311 unsigned long m_numElements;
312 unsigned long m_numNodes;
313protected:
314 // Deletes all node forces.
315 void ResetAllNodeForces() const;
316
317 // Adds the forces from each cable element to the array of node forces.
318 void AddAllElementForces(const double* const adPosA,
319 const double* const adVelA,
320 const double* const adPosB,
321 const double* const adVelB,
322 const double* const adX,
323 double dT) const;
324
325 // Calculates the derivatives of the states of the cable.
326 void CalcDerivatives(const double* const adX,
327 double* const adXDot) const;
328
329 // Adds the forces from one element to the array of node forces.
330 virtual void AddElementForce(int cableElement,
331 const double adPosA[3],
332 const double adVelA[3],
333 const double adPosB[3],
334 const double adVelB[3],
335 double adForceA[3],
336 double adForceB[3],
337 double dT) const;
338
341 double NodeInertia(unsigned long node) const;
342
343 unsigned long* m_iStatePos;
344 unsigned long* m_iStateVel;
345
346 // Member variables
348 double m_eA;
349 double m_meanTensionTime = std::numeric_limits<double>::quiet_NaN();
350
352 double** m_aadForceA;
353 double** m_aadForceB;
354
355 environment::EnvironmentProvider* m_environment;
356 double m_elVelWater[3];
357 double m_elMeanPos[3];
358 double m_elMeanVel[3];
359
360#ifdef FH_VISUALIZATION
361 SCableRenderSpec* m_renderSpec;
362 Ogre::Root* m_ogreRoot;
363 Ogre::SceneManager* m_sceneMgr;
364 Ogre::Entity* m_renderElement;
365 Ogre::SceneNode* m_renderNode;
366 Ogre::ManualObject* m_cableRenderObj;
367 double m_drawDiam;
368# ifdef ATTACH_SPHERE
369 Ogre::Entity* m_renderSphere[2];
370 Ogre::SceneNode* m_renderNodeSphere[2];
371# endif
372#endif
373};
374
375
376#endif
Definition CableElDynStiff.h:31
Definition InternalCable.h:189
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:348
double ** m_aadForceB
The force on the B nodes.
Definition InternalCable.h:353
void EvaluateElementsAt(const double *adPosA, const double *adVelA, const double *adPosB, const double *adVelB, const double *adX, double dT) const
~InternalCable()
The destructor deletes dynamically allocated memory.
double ** m_aadForceA
The force on the A nodes.
Definition InternalCable.h:352
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
unsigned long m_numNodes
The number of nodes of the cable.
Definition InternalCable.h:312
SCableSpec m_CableSpec
The cable specification.
Definition InternalCable.h:347
double m_meanTensionTime
The time of the last AdvanceMeanTension.
Definition InternalCable.h:349
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:343
virtual bool InBottomContact() const
Definition InternalCable.h:211
CableElDynStiff ** m_cableElements
An array holding the cable elements.
Definition InternalCable.h:351
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.
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:311
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:344
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:86
SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
Definition InternalCable.h:105
~SCableRenderSpec()
The destructor frees allocated memory.
Definition InternalCable.h:137
void Update(int element, const double *adElPosA, const double *adElPosB, const double *adDirection, double dL0)
Definition InternalCable.h:154
Contains some specifications used for simulating cables.
Definition InternalCable.h:34
void Reset()
Resets the specification to the defaults.
Definition InternalCable.h:58
double CalcEA()
Calculates the stiffness of the cable.
Definition InternalCable.h:78
SCableSpec()
The constructor sets some default values.
Definition InternalCable.h:53