ObjectJointSliding
A specialized 3D sliding joint between a list of beam elements (updated marker1) and a position-based marker (marker0); the data coordinate x[0] provides the current index in slidingMarkerNumbers, and x[1] the local position in the cable element at the beginning of the timestep.
Interface
Python names:
ObjectJointSlidingorSlidingJoint, andVSlidingJointfor its visualizationNodes it takes: NodeGenericData
Parameters
The parameters of the item; in a dictionary, its type is ‘JointSliding’:
name |
type |
size |
default |
description |
|---|---|---|---|---|
name |
String |
‘’ |
constraints’s unique name |
|
markerNumbers |
ArrayMarkerIndex |
[ invalid (-1), invalid (-1) ] |
(symbol: \([m0,m1]\tp\)) marker m0: position or rigid body marker of mass point or rigid body; marker m1: updated marker to Cable2D element, where the sliding joint currently is attached to; must be initialized with an appropriate (global) marker number according to the starting position of the sliding object; this marker changes with time (PostNewtonStep) |
|
slidingMarkerNumbers |
ArrayMarkerIndex |
[] |
(symbol: \([m_{s0}, \ldots, m_{sn}]\tp\)) these markers are used to update marker m1, if the sliding position exceeds the current cable’s range; the markers must be sorted such that marker \(m_{si}\) at x=cable(i).length is equal to marker(i+1) at x=0 of cable(i+1) |
|
slidingMarkerOffsets |
Vector |
[] |
(symbol: \([d_{s0}, \ldots, d_{sn}]\)) this list contains the offsets of every sliding object (given by slidingMarkerNumbers) w.r.t. to the initial position (0): marker m0: offset=0, marker m1: offset=Length(cable0), marker m2: offset=Length(cable0)+Length(cable1), … |
|
nodeNumber |
NodeIndex |
invalid (-1) |
(symbol: \(n_{GD}\)) node number of a NodeGenericData for 1 dataCoordinate showing the according marker number which is currently active and the start-of-step (global) sliding position |
|
constrainRotations |
ArrayIndex |
3 |
[1,1,1] |
flags for constrained rotation about x, y and z-axis: if flag=1, add constraint on rotation of marker m0 relative to respective axis; flag=0: sliding body can rotate freely about this axis; for ANCFCable, rotation about x-axis cannot be constrained |
constrainTranslations |
ArrayIndex |
3 |
[1,1,1] |
flags for constrained translation in x, y and z-direction: if flag=1, add constraint on translation of marker m0 relative to respective axis; flag=0: sliding body can translate freely about this axis; along x-axis this should be usually 0, except for driven motion |
axialForce |
Real |
0 |
(symbol: \(f_\mathrm{ax}\)) ONLY APPLIES if useClassicalFormulation==True; axialForce represents an additional sliding force acting between beam and marker m0 body in axial (beam) direction; this force can be used to drive a body on a beam, but can only be changed with user functions. |
|
activeConnector |
Bool |
True |
flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint |
|
visualization |
VObjectJointSliding |
parameters for visualization of item |
Visualization parameters
The parameters of VObjectJointSliding, given as visualization:
name |
type |
size |
default |
description |
|---|---|---|---|---|
show |
Bool |
True |
set true, if item is shown in visualization and false if it is not shown |
|
drawSize |
float |
-1. |
drawing size = radius of revolute joint; size == -1.f means that default connector size is used |
|
color |
Float4 |
4 |
[-1.,-1.,-1.,-1.] |
RGBA connector color; if R==-1, use default color |
Drawing
Drawn as all joints; a sphere of diameter drawSize at each marker.
Output variables
Available as OutputVariableType in sensors, Get...Output() and other functions:
output variable |
symbol |
description |
|---|---|---|
Position |
position vector of joint given by marker0 |
|
Velocity |
velocity vector of joint given by marker0 |
|
SlidingCoordinate |
global sliding coordinate along all elements; the maximum sliding coordinate is equivalent to the reference lengths of all sliding elements |
|
Force |
joint force vector (3D) |
Detailed description
Definition of quantities
intermediate variables |
symbol |
description |
|---|---|---|
data node |
\(\xv=[x_{data0},\,x_{data1}]\tp\) |
coordinates of node with node number \(n_{GD}\) |
data coordinate 0 |
\(x_{data0}\) |
the current index in slidingMarkerNumbers |
data coordinate 1 |
\(x_{data1}\) |
the global sliding coordinate (ranging from 0 to the total length of all sliding elements) at start-of-step - beginning of the timestep |
marker m0 position |
\(\LU{0}{\pv}_{m0}\) |
current global position which is provided by marker m0 |
marker m0 velocity |
\(\LU{0}{\vv}_{m0}\) |
current global velocity which is provided by marker m0 |
marker m0 orientation |
\(\LU{0,m0}{\Rot}\) |
current rotation matrix provided by marker m0 (assumed to be rigid body) |
marker m0 angular velocity |
\(\LU{0}{\tomega}_{m0}\) |
current angular velocity vector provided by marker m0 (assumed to be rigid body) |
sliding position |
\(\LUR{0}{\rv}{ANCF} = \Sm(s_{el})\qv_{ANCF,m1}\) |
current global position at the ANCF cable element, evaluated at local sliding position \(s_{el}\) |
sliding position slope |
\(\LURU{0}{\rv}{ANCF}{\prime} = \Sm^\prime(s_{el})\qv_{ANCF,m1} = [r^\prime_0,\,r^\prime_1,\,r^\prime_2]\tp\) |
current global slope vector of the ANCF cable element, evaluated at local sliding position \(s_{el}\) |
sliding velocity |
\(\LUR{0}{\vv}{ANCF} = \Sm(s_{el})\dot\qv_{ANCF,m1}\) |
current global velocity at the ANCF cable element, evaluated at local sliding position \(s_{el}\) (\(s_{el}\) not differentiated!!!) |
sliding velocity slope |
\(\LURU{0}{\vv}{ANCF}{\prime} = \Sm^\prime(s_{el})\dot\qv_{ANCF,m1}\) |
current global slope velocity vector of the ANCF cable element, evaluated at local sliding position \(s_{el}\) |
algebraic coordinates |
\(\zv=[\lambda_0,\,\ldots,\,\lambda_5,\, s]\tp\) |
algebraic coordinates composed of 3 Lagrange multipliers for forces \(\lambda_{0..2}\), 3 multipliers for torques \(\lambda_{3..5}\) and the current sliding coordinate \(s\), which is local in the current cable element. |
local sliding coordinate |
\(s\) |
local incremental sliding coordinate \(s\): the (algebraic) sliding coordinate relative to the start-of-step value. Thus, \(s\) only contains small local increments. |
output variables |
symbol |
formula |
|---|---|---|
Position |
\(\LU{0}{\pv}_{m0}\) |
current global position of position marker \(m0\) |
Velocity |
\(\LU{0}{\vv}_{m0}\) |
current global velocity of position marker \(m0\) |
SlidingCoordinate |
\(s_g = s + x_{data1}\) |
current value of the global sliding coordinate |
Force |
\(\fv\) |
see below |
Geometric relations
Assume we have given the sliding coordinate \(s\) (e.g., as a guess of the Newton method or beginning of the time step). The element sliding coordinate (in the local coordinates of the current sliding element) is computed as
The vector (=difference; error) between the marker \(m0\) and the marker \(m1\) (=\(\rv_{ANCF}\)) positions reads
The vector (=difference; error) between the marker \(m0\) and the marker \(m1\) velocities reads
Connector constraint equations (useClassicalFormulation=True)
The 3D sliding joint is implemented having 7 equations, using the special algebraic coordinates \(\zv\). The algebraic equations read
No index 2 case exists, because no time derivative exists for \(s_{el}\). The jacobian matrices for algebraic and ODE2 coordinates read
if activeConnector = False, the algebraic equations are changed to:
In case that constrainRotations=[0,0,0], the Lagrange multipliers for rotations are set
In case that any flag in constrainRotations is equal to 1, the constraints read
for constrainRotations[0] = 1:
for constrainRotations[1] = 1:
for constrainRotations[2] = 0:
Post Newton Step
After the Newton solver has converged, a PostNewtonStep is performed for the element, which updates the marker \(m1\) index if necessary.
Furthermore, it is checked, if \(x_{data0}\) becomes smaller than zero, which raises a warning and keeps \(x_{data0}=0\). The same results if \(x_{data0}\ge sn\), then \(x_{data0} = sn\). Finally, the data coordinate is updated in order to provide the starting value for the next step,
Mini example
#the shape of 3D ANCF cable elements for a sliding joint: a mass point slides along a clamped, stiff cable
from exudyn.beams import GenerateBeamElementsAlongLine
cable = ObjectANCFCable(massPerLength=1, bendingStiffness=1e4, axialStiffness=1e6)
beamInfo = GenerateBeamElementsAlongLine(mbs, positionStart=[0,0,0], positionEnd=[2,0,0],
numberOfElements=4, beamTemplate=cable,
groundConstraintsStart=[1,1,1, 1,1,1], groundConstraintsEnd=[1,1,1, 1,1,1])
nodes, elements = beamInfo['nodes'], beamInfo['elements']
nMass = mbs.AddNode(NodePoint(referenceCoordinates=[0.6,0,0]))
mbs.AddObject(ObjectMassPoint(nodeNumber=nMass, mass=1))
mMass = mbs.AddMarker(MarkerNodePosition(nodeNumber=nMass))
mbs.AddLoad(LoadForceVector(markerNumber=mMass, loadVector=[1,0,0]))
cableMarkers = [mbs.AddMarker(MarkerBodyBeamShape(bodyNumber=e)) for e in elements]
offsets = [0.5*i for i in range(4)] #the element length is 0.5
nData = mbs.AddNode(NodeGenericData(numberOfDataCoordinates=2, initialCoordinates=[1, 0.6])) #element 1, sliding coordinate
mbs.AddObject(ObjectJointSliding(markerNumbers=[mMass, cableMarkers[1]], slidingMarkerNumbers=cableMarkers,
slidingMarkerOffsets=offsets, nodeNumber=nData, constrainRotations=[0,0,0]))
mbs.Assemble()
mbs.SolveDynamic()
#the mass slides: x = 0.6 + F/(2m)*t^2 at t=1, the stiff cable deflects little
exu.sys['testResult'] = mbs.GetNodeOutput(nMass, exu.OutputVariableType.Position)[0] #1.1
Relevant Examples (Ex) and TestModels (TM) with weblink to github: ANCFslidingJoint.py (Ex), NGsolveFFRFSlidingJoint.py (Ex)