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 <string>
26
27
28#define ATTACH_SPHERE
29
30
33{
34 int numElements;
35 double density;
36 double numericalDamping;
37 double diameter;
38 double dE;
39 double dampingRatio;
40 double fluidRho;
41 double maxStep;
42 double maxTension;
43 double stepSafetyFactor;
44 double dMeanTension0;
45 double eAdaptationPeriod;
46 std::string materialName;
47 int cableFaces;
48 std::string cableName;
49 double drawScale;
50
53 {
54 Reset();
55 }
57 void Reset()
58 {
59 numElements = 2;
60 density = 1100;
61 numericalDamping = 1;
62 diameter = 0.01;
63 dE = 1e9;
64 dampingRatio = 1;
65 fluidRho = 1025;
66 maxStep = 1e-10;
67 maxTension = 1e10;
68 stepSafetyFactor = 50;
69 dMeanTension0 = 0;
70 eAdaptationPeriod = 0;
71 materialName = "Trawl/SteelWire";
72 cableFaces = 5;
73 cableName = "";
74 drawScale = 1;
75 }
77 double CalcEA()
78 {
79 return sfh::pi * 0.25 * diameter * diameter * dE;
80 }
81};
82
85{
86 double deltaTheta;
87 double* adTheta;
88 double* adSinTheta;
89 double* adCosTheta;
90 double textureScale;
91 double* adCirclePos;
92 double* adFacePosNormal;
93 double* adTextureCoordU;
94 double* adTextureCoordV;
95 int numRenderEdges;
96 double drawDiam;
97 int* aiIndex;
98 int sizeIndexBuffer;
99
104 SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
105 {
106 drawDiam = drawDiameter;
107 numRenderEdges = numFaces + 1;
108 sizeIndexBuffer = numElements * numRenderEdges * 2;
109 textureScale = 5 * (sfh::pi * drawDiam);
110 aiIndex = new int[sizeIndexBuffer];
111 deltaTheta = 2 * sfh::pi / numFaces;
112 adTheta = new double[numRenderEdges];
113 adSinTheta = new double[numRenderEdges];
114 adCosTheta = new double[numRenderEdges];
115 adCirclePos = new double[(numElements + 1) * (numRenderEdges) * 3];
116 adFacePosNormal = new double[(numElements + 1) * (numRenderEdges) * 3];
117 adTextureCoordU = new double[numRenderEdges];
118 adTextureCoordV = new double[numElements + 1];
119 adTextureCoordV[0] = 0;
120 for (unsigned short i = 0; i < numRenderEdges; i++) {
121 adTheta[i] = i * deltaTheta;
122 adSinTheta[i] = sin(adTheta[i]);
123 adCosTheta[i] = cos(adTheta[i]);
124 adTextureCoordU[i] = adTheta[i] * (sfh::pi * drawDiam) / textureScale;
125 }
126 int i = 0;
127 for (int element = 0; element < numElements; element++) {
128 for (int edge = 0; edge < numRenderEdges; edge++) {
129 aiIndex[i++] = element * numRenderEdges + edge;
130 aiIndex[i++] = (element + 1) * numRenderEdges + edge;
131 }
132 }
133 }
134
137 {
138 delete[] adTheta;
139 delete[] adSinTheta;
140 delete[] adCosTheta;
141 delete[] adCirclePos;
142 delete[] adFacePosNormal;
143 delete[] adTextureCoordU;
144 delete[] adTextureCoordV;
145 }
146
153 void Update(int element, const double* adElPosA, const double* adElPosB, const double* adDirection, double dL0)
154 {
155 // Creating a vector not parallel to the direction of the element.
156 sfh::math::FindNotParallel(adDirection, 3, adNotParallel);
157
158 // Creating two vectors normal to each other and the direction of the element.
159 sfh::linalg::Cross(adDirection, adNotParallel, adNormal1);
160 sfh::linalg::Cross(adDirection, adNormal1, adNormal2);
161 sfh::math::Normalize3(adNormal1);
162 sfh::math::Normalize3(adNormal2);
163 sfh::math::ArrayMultiply(adNormal1, drawDiam / 2.0, 3);
164 sfh::math::ArrayMultiply(adNormal2, drawDiam / 2.0, 3);
165 adTextureCoordV[element + 1] = adTextureCoordV[element] + dL0 / textureScale * 3;
166
167 for (unsigned short face = 0; face < numRenderEdges; face++) {
168 for (unsigned short ind = 0; ind < 3; ind++) {
169 if (element == 0) {
170 adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
171 adCirclePos[element * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosA[ind] + adFacePosNormal[element * ((numRenderEdges) * 3) + 3 * face + ind];
172 }
173 adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adSinTheta[face] * adNormal1[ind] + adCosTheta[face] * adNormal2[ind];
174 adCirclePos[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind] = adElPosB[ind] + adFacePosNormal[(element + 1) * ((numRenderEdges) * 3) + 3 * face + ind];
175 }
176 }
177 }
178
179private:
180 // Varaiables to avoid excessive allocations
181 double adNotParallel[3];
182 double adNormal1[3];
183 double adNormal2[3];
184};
185
186// Class definition
188{
189public:
191 InternalCable(ISimObjectCreator* creator, const SCableSpec& CableSpec);
192
195
196 // Member functions
197 virtual void FinalSetup(const double dT, const double* const adX, ISimObjectCreator* const creator);
198
200 virtual void OdeFcn(const double* const adPosA,
201 const double* const adVelA,
202 const double* const adPosB,
203 const double* const adVelB,
204 const double* const adX,
205 double* const adXDot,
206 double dT) const;
207
213 const double* posA, const double* velA,
214 const double* posB, const double* velB,
215 const double* X, double* J, int nStates, int stateOffset) const;
216
237 const double* posA, const double* velA,
238 const double* posB, const double* velB,
239 int globalPosIdxA, int globalVelIdxA,
240 int globalPosIdxB, int globalVelIdxB,
241 double endInertiaA, double endInertiaB,
242 const double* X, double* J, int nStates, int stateOffset) const;
243
245 virtual bool InitializeStates(const double* const adPosA,
246 const double* const adVelA,
247 const double* const adPosB,
248 const double* const adVelB,
249 double* const adX);
250
252 void UpdateCable(double newLength, double dT);
253
256 double* const adEndForceA,
257 double* const adEndForceB,
258 double* const pdEndInertiaA,
259 double* const pdEndInertiaB,
260 const double* const adPosA,
261 const double* const adVelA,
262 const double* const adPosB,
263 const double* const adVelB,
264 const double* const adX,
265 double dT);
266
268 double GetLength();
269
270#ifdef FH_VISUALIZATION
272 void RenderInit(Ogre::Root* ogreRoot);
273
275 void RenderUpdate(const double* const adX, const double* adPosA, const double* adPosB);
276#endif
277
278 unsigned long m_numElements;
279 unsigned long m_numNodes;
280protected:
281 // Deletes all node forces.
282 void ResetAllNodeForces() const;
283
284 // Adds the forces from each cable element to the array of node forces.
285 void AddAllElementForces(const double* const adPosA,
286 const double* const adVelA,
287 const double* const adPosB,
288 const double* const adVelB,
289 const double* const adX,
290 double dT) const;
291
292 // Calculates the derivatives of the states of the cable.
293 void CalcDerivatives(const double* const adX,
294 double* const adXDot) const;
295
296 // Adds the forces from one element to the array of node forces.
297 virtual void AddElementForce(int cableElement,
298 const double adPosA[3],
299 const double adVelA[3],
300 const double adPosB[3],
301 const double adVelB[3],
302 double adForceA[3],
303 double adForceB[3],
304 double dT) const;
305
308
309 unsigned long* m_iStatePos;
310 unsigned long* m_iStateVel;
311
312 // Member variables
314 double m_eA;
315 sfh::timers::StopWatch m_StopWatch;
316
318 double* m_inertiaA;
319 double* m_inertiaB;
320 double** m_aadForceA;
321 double** m_aadForceB;
322
323 environment::EnvironmentProvider* m_environment;
324 double m_elVelWater[3];
325 double m_elMeanPos[3];
326 double m_elMeanVel[3];
327
328#ifdef FH_VISUALIZATION
329 SCableRenderSpec* m_renderSpec;
330 Ogre::Root* m_ogreRoot;
331 Ogre::SceneManager* m_sceneMgr;
332 Ogre::Entity* m_renderElement;
333 Ogre::SceneNode* m_renderNode;
334 Ogre::ManualObject* m_cableRenderObj;
335 double m_drawDiam;
336# ifdef ATTACH_SPHERE
337 Ogre::Entity* m_renderSphere[2];
338 Ogre::SceneNode* m_renderNodeSphere[2];
339# endif
340#endif
341};
342
343
344#endif
Definition CableElDynStiff.h:34
Definition InternalCable.h:188
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:314
double ** m_aadForceB
The force on the B nodes.
Definition InternalCable.h:321
~InternalCable()
The destructor deletes dynamically allocated memory.
double ** m_aadForceA
The force on the A nodes.
Definition InternalCable.h:320
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:279
SCableSpec m_CableSpec
The cable specification.
Definition InternalCable.h:313
void UpdateCable(double newLength, double dT)
Updates the cable for the next step.
double * m_inertiaB
The inertia of the B nodes.
Definition InternalCable.h:319
unsigned long * m_iStatePos
An array of indices to the node position states.
Definition InternalCable.h:309
CableElDynStiff ** m_cableElements
An array holding the cable elements.
Definition InternalCable.h:317
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...
double * m_inertiaA
The inertia of the A nodes.
Definition InternalCable.h:318
void UpdateInertia()
Updates the inertia of the cable according to the changing length.
unsigned long m_numElements
The number of elements to divide the cable into.
Definition InternalCable.h:278
double GetLength()
Calculates the length of the cable.
unsigned long * m_iStateVel
An array of indices to the node velocity states.
Definition InternalCable.h:310
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.
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:85
SCableRenderSpec(int numFaces, int numElements, double drawDiameter)
Definition InternalCable.h:104
~SCableRenderSpec()
The destructor frees allocated memory.
Definition InternalCable.h:136
void Update(int element, const double *adElPosA, const double *adElPosB, const double *adDirection, double dL0)
Definition InternalCable.h:153
Contains some specifications used for simulating cables.
Definition InternalCable.h:33
void Reset()
Resets the specification to the defaults.
Definition InternalCable.h:57
double CalcEA()
Calculates the stiffness of the cable.
Definition InternalCable.h:77
SCableSpec()
The constructor sets some default values.
Definition InternalCable.h:52