(testmodels-accessfunctionstest)= # accessFunctionsTest.py You can view and download this file on Github: [accessFunctionsTest.py](https://github.com/jgerstmayr/EXUDYN/tree/master/python/TestModels/accessFunctionsTest.py) ```{code-block} python :linenos: #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # This is an EXUDYN example # # Details: A body marker places a force, a torque or a connector at a local position of a body, and the # body computes the Jacobians there (its access functions, #2744). Some bodies define them at # restricted local positions only: ObjectANCFCable at the centerline, ObjectANCFThinPlate at the # midsurface, ObjectBeamGeometricallyExact2D at the axis. Assemble() checks the markers through which # a connector or a load acts: # (1) a rotating table, ObjectRotationalMass1D, driven by a torque on its axis and by a force at its # rim, fixed to the table and tangential, whose moment about the axis it takes (#2775); # (2) a cantilever ANCF cable under a force at its tip, on the centerline; # (3) what Assemble() refuses: a force off the centerline of the cable. # # Author: Johannes Gerstmayr # Date: 2026-10-02 # # Copyright:This file is part of Exudyn. Exudyn is free software. You can redistribute it and/or modify it under the terms of the Exudyn license. See 'LICENSE.txt' for more details. # #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import exudyn as exu from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities import numpy as np testIsActive = exu.sys.get('testIsActive', False) def TableModel(): """a rotating table with inertia 0.5, driven by a torque 1 about its axis and a tangential force 1, fixed to the table, at its rim at radius 0.2""" SC = exu.SystemContainer() mbs = SC.AddSystem() nTable = mbs.AddNode(Node1D(referenceCoordinates=[0])) oTable = mbs.AddObject(ObjectRotationalMass1D(inertia=0.5, nodeNumber=nTable, referencePosition=[0, 0, 0])) mAxis = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oTable, localPosition=[0, 0, 0])) mRim = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oTable, localPosition=[0.2, 0, 0])) mbs.AddLoad(LoadTorqueVector(markerNumber=mAxis, loadVector=[0, 0, 1])) mbs.AddLoad(LoadForceVector(markerNumber=mRim, loadVector=[0, 1, 0], bodyFixed=True)) sRim = mbs.AddSensor(SensorMarker(markerNumber=mRim, outputVariableType=exu.OutputVariableType.Position, storeInternal=True)) mbs.Assemble() return (mbs, sRim) def CableModel(offset): """a cantilever ANCF cable, one element of length 1 with EI = 1, a force -0.01 in y at the tip, at offset from the centerline; clamped: the position and the lateral slopes of node 0 fixed""" SC = exu.SystemContainer() mbs = SC.AddSystem() nodes = [mbs.AddNode(NodePointSlope1(referenceCoordinates=[x, 0, 0, 1, 0, 0])) for x in [0, 1]] oCable = mbs.AddObject(ObjectANCFCable(nodeNumbers=nodes, length=1, massPerLength=1, bendingStiffness=1, axialStiffness=1e4)) oGround = mbs.AddObject(ObjectGround()) nGround = mbs.AddNode(NodePointGround()) mGround = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nGround, coordinate=0)) for coordinate in [0, 1, 2, 4, 5]: mCoordinate = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodes[0], coordinate=coordinate)) mbs.AddObject(CoordinateConstraint(markerNumbers=[mGround, mCoordinate])) mTip = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oCable, localPosition=[1, offset, 0])) mbs.AddLoad(LoadForceVector(markerNumber=mTip, loadVector=[0, -0.01, 0])) mbs.Assemble() return (mbs, nodes[-1]) #(1) the torque 1 + 0.2*1 turns the table by phi = t^2/2 * 1.2/0.5 = 1.2 rad after 1 s; the rim follows (mbs, sRim) = TableModel() simulationSettings = exu.SimulationSettings() simulationSettings.timeIntegration.numberOfSteps = 100 simulationSettings.timeIntegration.endTime = 1 mbs.SolveDynamic(simulationSettings) rim = mbs.GetSensorValues(sRim) exu.Print('position of the rim after 1 s:', rim, ', expected', 0.2*np.array([np.cos(1.2), np.sin(1.2), 0])) #(2) the tip deflection, F L^3/(3 EI) = 0.01/3 for the Euler-Bernoulli beam (mbs, nTip) = CableModel(offset=0) mbs.SolveStatic() tip = mbs.GetNodeOutput(nTip, exu.OutputVariableType.Displacement) exu.Print('tip deflection of the cable:', tip[1], ', expected', -0.01/3) #(3) refused at Assemble(), with the reason refused = 0 for (name, Build) in [('force off the centerline of the cable', lambda: CableModel(offset=0.1))]: try: Build() exu.Print(name + ': accepted') except Exception as error: exu.Print(name + ': refused,', str(error).split(' [Python file')[0].strip()) refused += 1 testResult = rim[0] + rim[1] + tip[1] + refused exu.Print('solution of accessFunctionsTest=', testResult) exu.sys['testResult'] = testResult ```