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: ObjectJointSliding or SlidingJoint, and VSlidingJoint for its visualization

  • Nodes 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

\[ s_{el} = s + x_{data1} - d_{m1} = s_g - d_{m1}. \]

The vector (=difference; error) between the marker \(m0\) and the marker \(m1\) (=\(\rv_{ANCF}\)) positions reads

\[ \LU{0}{\Delta\pv} = \LUR{0}{\rv}{ANCF} - \LU{0}{\pv}_{m0} \]

The vector (=difference; error) between the marker \(m0\) and the marker \(m1\) velocities reads

\[ \LU{0}{\Delta\vv} = \LUR{0}{\dot\rv}{ANCF} - \LU{0}{\vv}_{m0} \]

Connector constraint equations (useClassicalFormulation=True)

The 3D sliding joint is implemented having 7 equations, using the special algebraic coordinates \(\zv\). The algebraic equations read

\[\begin{split} \begin{aligned} \LU{0}{\Delta\pv} \!&=\! \Null, \quad \mbox{... three index 3 eqs $\ra$ sliding body stays on cable}\\ \vr{\lambda_1}{\lambda_2}{\lambda_3} \cdot \LURU{0}{\rv}{ANCF}{\prime} - |\LURU{0}{\rv}{ANCF}{\prime}| \cdot f_\mathrm{ax} \!&=\! 0, \quad \mbox{... three index 1 equ. $\ra$ force in sliding dir.=$f_\mathrm{ax}$} \\ \end{aligned} \end{split}\]

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:

\[\begin{split} \begin{aligned} \lambda_0 &= 0, \\ \ldots && , \\ \lambda_5 &= 0, \\ s &= 0 \end{aligned} \end{split}\]

In case that constrainRotations=[0,0,0], the Lagrange multipliers for rotations are set

\[ \left[\lambda_3,\lambda_4,\lambda_5\right] = \Null \]

In case that any flag in constrainRotations is equal to 1, the constraints read for constrainRotations[0] = 1:

\[ \LURU{0}{\rv}{ANCF,y}{\mathrm{T}} \LU{0,m0}{\Rot} \vr{0}{0}{1} = 0 \]

for constrainRotations[1] = 1:

\[ \LURU{0}{\rv}{ANCF}{\prime\mathrm{T}} \LU{0,m0}{\Rot} \vr{0}{0}{1} = 0 \]

for constrainRotations[2] = 0:

\[ \LURU{0}{\rv}{ANCF}{\prime\mathrm{T}} \LU{0,m0}{\Rot} \vr{0}{1}{0} = 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.

\[\begin{split} \begin{aligned} s_{el} < 0 \quad \ra \quad x_{data0}\;-\!\!=1 \\ s_{el} > L \quad \ra \quad x_{data0}\;+\!\!=1 \end{aligned} \end{split}\]

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,

\[ x_{data1} \;+\!\!= s. \]

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)