```{raw} latex \clearpage ``` (sec-item-objectjointsliding)= # 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: [](#sec-item-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](#sec-drawing-objectsjoint); a sphere of diameter `drawSize` at each marker. ## Output variables Available as `OutputVariableType` in sensors, `Get...Output()` and other functions: ```{tabularcolumns} \Y{0.25}\Y{0.25}\Y{0.5} ``` | 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) | (description-objectjointsliding)= ## 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{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} $$ No index 2 case exists, because no time derivative exists for $s_{el}$. The jacobian matrices for algebraic and {ref}`ODE2 ` coordinates read if `activeConnector = False`, the algebraic equations are changed to: $$ \begin{aligned} \lambda_0 &= 0, \\ \ldots && , \\ \lambda_5 &= 0, \\ s &= 0 \end{aligned} $$ 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{aligned} s_{el} < 0 \quad \ra \quad x_{data0}\;-\!\!=1 \\ s_{el} > L \quad \ra \quad x_{data0}\;+\!\!=1 \end{aligned} $$ 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. $$ (miniexample-objectjointsliding)= ## Mini example ```python #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`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/ANCFslidingJoint.py) (Ex), [`NGsolveFFRFSlidingJoint.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/NGsolveFFRFSlidingJoint.py) (Ex)