inactiveConnectorForceTest.py

You can view and download this file on Github: inactiveConnectorForceTest.py

 1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2# This is an EXUDYN example
 3#
 4# Details:  An inactive connector (activeConnector = False) adds no force, and reports none (#984):
 5#           each penalty connector and contact between the ground and a rigid body that is displaced,
 6#           rotated and moving, built once inactive - its Force, ForceLocal, Torque and TorqueLocal
 7#           output must be zero - and once active, where they are not.
 8#
 9# Author:   Johannes Gerstmayr
10# Date:     2026-10-05
11#
12# 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.
13#
14#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
16import exudyn as exu
17from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
18
19import numpy as np
20
21testIsActive = exu.sys.get('testIsActive', False)
22
23forceTypes = [exu.OutputVariableType.Force, exu.OutputVariableType.ForceLocal,
24              exu.OutputVariableType.Torque, exu.OutputVariableType.TorqueLocal]
25
26
27def DataNode(mbs, n):
28    #the first data coordinate of the contacts is the gap of the last step: negative, in contact
29    return mbs.AddNode(NodeGenericData(numberOfDataCoordinates=n, initialCoordinates=[-0.1]+[0]*(n-1)))
30
31
32#each connector between a ground marker and a body marker (rigid or coordinate), with a force where it is active
33connectors = {
34    'SpringDamper': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(SpringDamper(markerNumbers=[mG, mB],
35        stiffness=100, damping=1, referenceLength=1, activeConnector=active)),
36    'CartesianSpringDamper': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(CartesianSpringDamper(
37        markerNumbers=[mG, mB], stiffness=[100]*3, damping=[1]*3, activeConnector=active)),
38    'RigidBodySpringDamper': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(RigidBodySpringDamper(
39        markerNumbers=[mG, mB], stiffness=100*np.eye(6), damping=np.eye(6), activeConnector=active)),
40    'TorsionalSpringDamper': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(TorsionalSpringDamper(
41        markerNumbers=[mG, mB], stiffness=100, damping=1, activeConnector=active)),
42    'LinearSpringDamper': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(LinearSpringDamper(
43        markerNumbers=[mG, mB], stiffness=100, damping=1, activeConnector=active)),
44    'CoordinateSpringDamper': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(CoordinateSpringDamper(
45        markerNumbers=[cG, cB], stiffness=100, damping=1, activeConnector=active)),
46    'ConnectorGravity': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(ObjectConnectorGravity(
47        markerNumbers=[mG, mB], mass0=1e10, mass1=1, activeConnector=active)),
48    'ContactSphereSphere': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(ObjectContactSphereSphere(
49        markerNumbers=[mG, mB], nodeNumber=DataNode(mbs, 4), spheresRadii=[1, 1], contactStiffness=100,
50        contactDamping=1, dynamicFriction=0.2, activeConnector=active)),
51    'ContactSphereTriangle': lambda mbs, mG, mB, cG, cB, active: mbs.AddObject(ObjectContactSphereTriangle(
52        markerNumbers=[mB, mG], nodeNumber=DataNode(mbs, 4), sphereRadius=1,
53        trianglePoints=exu.Vector3DList([[0, -2, 0], [3, -2, 0], [0, 2, 0]]), contactStiffness=100,
54        contactDamping=1, dynamicFriction=0.2, activeConnector=active)),
55    }
56
57
58def ForceOutputs(build, active):
59    """the norms of the force and torque outputs a connector has, as a dict"""
60    SC = exu.SystemContainer()
61    mbs = SC.AddSystem()
62    oGround = mbs.AddObject(ObjectGround())
63    node = mbs.AddNode(NodeRigidBodyEP(referenceCoordinates=[1.2, 0.1, -0.05] + list(RotXYZ2EulerParameters([0.1, 0.2, 0.3])),
64                                       initialVelocities=[0.3, 0.2, 0.1, 0, 0, 0, 0]))
65    body = mbs.AddObject(ObjectRigidBody(nodeNumber=node, mass=1, inertia=[1, 1, 1, 0, 0, 0]))
66    mG = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oGround))
67    mB = mbs.AddMarker(MarkerBodyRigid(bodyNumber=body))
68    cG = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=mbs.AddNode(NodePointGround()), coordinate=0))
69    cB = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=node, coordinate=0))
70    connector = build(mbs, mG, mB, cG, cB, active)
71    mbs.Assemble()
72    outputs = {}
73    for variableType in forceTypes:
74        try:
75            outputs[variableType] = np.linalg.norm(mbs.GetObjectOutput(connector, variableType))
76        except Exception:
77            pass    #the connector does not have this output variable
78    return outputs
79
80
81testResult = 0
82for (name, build) in connectors.items():
83    inactive = ForceOutputs(build, False)
84    active = ForceOutputs(build, True)
85    exu.Print(name + ': inactive', sum(inactive.values()), ', active', sum(active.values()))
86    testResult += 1000*sum(inactive.values()) + sum(active.values())    #an inactive force spoils the result
87
88exu.Print('solution of inactiveConnectorForceTest=', testResult)
89exu.sys['testResult'] = testResult