```{raw} latex \clearpage ``` (sec-item-objectcontactcoordinate)= # ObjectContactCoordinate A penalty-based contact condition for one coordinate: a force upon penetration of the gap between the coordinates of two markers, with the contact law of ObjectContactSphereSphere - linear by default, with a stiffness exponent and impact models; the contact state is kept in a data node (active set strategy). ## Interface - Nodes it takes: [](#sec-item-nodegenericdata) - Markers it acts on: those providing `Coordinate`: [](#sec-item-markernodecoordinate), [](#sec-item-markernodeode1coordinate), [](#sec-item-markernoderotationcoordinate), [](#sec-item-markerbodiesrelativetranslationcoordinate), [](#sec-item-markerbodiesrelativerotationcoordinate), [](#sec-item-markerbodycable2dshape), [](#sec-item-markerbodycable2dcoordinates) ## Parameters The parameters of the item; in a dictionary, its type is 'ContactCoordinate': | name | type | size | default | description | |---|---|---|---|---| | **name** | String | | '' | connector's unique name | | **markerNumbers** | ArrayMarkerIndex | | [ invalid (-1), invalid (-1) ] | markers define contact gap | | **nodeNumber** | NodeIndex | | invalid (-1) | node number of a NodeGenericData with 1 data coordinate, the gap of the last discontinuous iteration (active set strategy), and a second one, the last impact velocity, if impactModel is not 0 | | **contactStiffness** | UReal | | 0. | contact (penalty) stiffness [SI:N/m]; acts only upon penetration | | **contactDamping** | UReal | | 0. | contact damping [SI:N/(m s)]; acts only upon penetration | | **contactStiffnessExponent** | PReal | | 1. | (symbol: $n_\mathrm{exp}$) exponent in the contact law [SI:1], as in ObjectContactSphereSphere; 1 is linear | | **restitutionCoefficient** | PReal | | 1. | (symbol: $e_\mathrm{res}$) coefficient of restitution [SI:1], used by impactModel 1 and 2; must be > 0 | | **minimumImpactVelocity** | UReal | | 0. | (symbol: $\dot g_\mathrm{-,min}$) lower bound [SI:m/s] of the impact velocity in the impact models; a larger damping at low impact velocities and in permanent contact | | **impactModel** | UInt | | 0 | (symbol: $m_\mathrm{impact}$) impact model, as in ObjectContactSphereSphere: 0) linear damping only; 1) Hunt-Crossley; 2) Gonthier et al. / Carvalho-Martins; contactDamping is added in all of them | | **offset** | Real | | 0. | offset [SI:m] of contact | | **activeConnector** | Bool | | True | flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint | | **visualization** | VObjectContactCoordinate | | | parameters for visualization of item | ## Visualization parameters The parameters of `VObjectContactCoordinate`, 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 = diameter of spring; 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 connectors](#sec-drawing-objectsconnector); with `connectors.showContact`, a circle at each marker of diameter `drawSize` (or `contact.contactPointsDefaultSize`), red while in contact. Settings beyond those of all connectors: [`connectors.showContact`](#sec-vsettingsconnectors), [`contact.contactPointsDefaultSize`](#sec-vsettingscontact). ## 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 | |---|---|---| | Distance | $g$ | the gap, coordinate of marker 1 minus coordinate of marker 0 minus offset; negative in contact | (description-objectcontactcoordinate)= ## Detailed description ### Definition of quantities | intermediate variables | symbol | description | |---|---|---| | marker values | $c_{m0}$, $c_{m1}$ | the coordinates the two coordinate markers provide | | data coordinate | $x_0$ | the gap of the last post Newton step, which decides on contact | ### Geometric relations The gap and its velocity are $$ g = c_{m1} - c_{m0} - \mathrm{offset} , \quad \dot g = \dot c_{m1} - \dot c_{m0} ; $$ $g > 0$ is no contact, $g \le 0$ penetration. ### Connector forces With the contact state from the data coordinate - contact if $x_0 \le 0$ - and the penetration $\delta = -g$, the law is the one of `ObjectContactSphereSphere`: $$ f_c = \begin{cases} -\left(k_c\, \delta^{n_\mathrm{exp}} - d_c\, \dot g + \lambda\, \delta^{n_\mathrm{exp}} \dot g \right) & \mathrm{contact} \\ 0 & \mathrm{else} \end{cases} $$ with $\delta^{n_\mathrm{exp}}$ keeping the sign of $\delta$. For `impactModel = 0` it is $\lambda = 0$, and for $n_\mathrm{exp} = 1$ the linear law $f_c = k_c\, g + d_c\, \dot g$. For the impact models, with the impact velocity $v_-$ - the gap velocity when the contact began, bounded below by `minimumImpactVelocity`, kept in the second data coordinate - $$ \lambda = \frac{k_c}{v_-} \cdot \begin{cases} \frac{3}{2}(e_\mathrm{res} - 1) & \mathrm{Hunt\text{-}Crossley} \\ \frac{3}{2}(e_\mathrm{res} - 1)\frac{11 - e_\mathrm{res}}{1 + 9 e_\mathrm{res}} \; (e_\mathrm{res} > \frac{1}{3}), \quad \frac{e_\mathrm{res}^2 - 1}{e_\mathrm{res}} \; (\mathrm{else}) & \mathrm{Gonthier / Carvalho\text{-}Martins} \end{cases} $$ acts on the coordinate of marker 1 with $+f_c$ and on that of marker 0 with $-f_c$, through the Jacobians of the coordinate markers. The data coordinate is updated to the current gap in the post Newton step, and a change of the contact state repeats the step (active set strategy); the step size recommended for the next step is the time to reach $g = 0$ with the current gap velocity. With `activeConnector = False` the force is zero. (miniexample-objectcontactcoordinate)= ## Mini example ```python #a coordinate that contacts a stop: a 1D mass falls onto the ground coordinate (gap = q1 - q0 - offset) node = mbs.AddNode(Node1D(referenceCoordinates=[0], initialCoordinates=[0.1])) mbs.AddObject(ObjectMass1D(nodeNumber=node, mass=1)) mCoord = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=node, coordinate=0)) mGround = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nGround, coordinate=0)) nData = mbs.AddNode(NodeGenericData(numberOfDataCoordinates=1, initialCoordinates=[0.1])) #the gap mbs.AddObject(ObjectContactCoordinate(markerNumbers=[mGround, mCoord], nodeNumber=nData, contactStiffness=1e4, contactDamping=100)) mbs.AddLoad(LoadCoordinate(markerNumber=mCoord, load=-10)) mbs.Assemble() mbs.SolveDynamic() #at rest on the stop, pressed in by F/k exu.sys['testResult'] = mbs.GetNodeOutput(node, exu.OutputVariableType.Coordinates) #-0.001 ``` Relevant Examples (Ex) and TestModels (TM) with weblink to github: [`ANCFcontactCircle.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/ANCFcontactCircle.py) (Ex), [`ANCFcontactCircle2.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/ANCFcontactCircle2.py) (Ex), [`ANCFcontactCircleTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/ANCFcontactCircleTest.py) (TM), [`connectorOutputVariablesTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/connectorOutputVariablesTest.py) (TM), [`contactComparisonTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/contactComparisonTest.py) (TM), [`contactCoordinateTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/contactCoordinateTest.py) (TM), [`explicitSolversPostNewtonTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/explicitSolversPostNewtonTest.py) (TM)