createLinearSpringDamperTest.py
You can view and download this file on Github: createLinearSpringDamperTest.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: mbs.CreateLinearSpringDamper (#1953, #1954): a rigid body on a prismatic joint along an inclined
5# axis, held by a linear spring-damper along the same axis against gravity. The static deflection
6# along the axis is m g_axis / k; the spring-damper given with the axis in global coordinates, in the
7# frame of a turned body 0 (useGlobalFrame=False), and between two markers gives it. A dynamic run
8# checks the damping: the oscillation decays towards the static deflection.
9#
10# Author: Johannes Gerstmayr
11# Date: 2026-10-05
12#
13# 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.
14#
15#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
17import exudyn as exu
18from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
19import numpy as np
20
21testIsActive = exu.sys.get('testIsActive', False)
22
23axis = np.array([1.,1.,0.])/np.sqrt(2.) #the axis of the joint and the spring
24gravity = np.array([0.,-9.81,0.])
25stiffness = 2e3
26inertia = InertiaCuboid(density=1000, sideLengths=[0.2,0.1,0.1])
27deflectionExpected = inertia.mass * (gravity @ axis) / stiffness
28
29def Model(variant, dynamic=False):
30 """the displacement of the body along the axis, static or after 2 s"""
31 SC = exu.SystemContainer()
32 mbs = SC.AddSystem()
33 rotation0 = RotationMatrixZ(0.3) #a turned ground body, for the axis in its frame
34 oBase = mbs.CreateRigidBody(inertia=inertia, referencePosition=[0,0,0], referenceRotationMatrix=rotation0)
35 mbs.CreateGenericJoint(itemNumbers=[mbs.CreateGround(), oBase], position=[0,0,0]) #fixed
36 oBody = mbs.CreateRigidBody(inertia=inertia, referencePosition=[1,1,0], gravity=gravity)
37 mbs.CreatePrismaticJoint(itemNumbers=[oBase, oBody], position=[1,1,0], axis=axis)
38 if variant == 'global':
39 mbs.CreateLinearSpringDamper(itemNumbers=[oBase, oBody], position=[1,1,0], axis=axis,
40 stiffness=stiffness, damping=20)
41 elif variant == 'local':
42 mbs.CreateLinearSpringDamper(itemNumbers=[oBase, oBody], position=rotation0.T @ np.array([1,1,0]),
43 axis=rotation0.T @ axis, useGlobalFrame=False, stiffness=stiffness, damping=20)
44 elif variant == 'markers':
45 m0 = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oBase, localPosition=rotation0.T @ np.array([1,1,0])))
46 m1 = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oBody, localPosition=[0,0,0]))
47 mbs.CreateLinearSpringDamper(itemNumbers=[m0, m1], position=[], axis=axis, stiffness=stiffness, damping=20)
48 mbs.Assemble()
49 simulationSettings = exu.SimulationSettings()
50 simulationSettings.solution.file.write = False
51 simulationSettings.timeIntegration.verboseMode = 0
52 simulationSettings.staticSolver.verboseMode = 0
53 if dynamic:
54 simulationSettings.timeIntegration.numberOfSteps = 2000
55 simulationSettings.timeIntegration.endTime = 2
56 mbs.SolveDynamic(simulationSettings)
57 else:
58 mbs.SolveStatic(simulationSettings)
59 return mbs.GetObjectOutputBody(oBody, exu.OutputVariableType.Displacement, localPosition=[0,0,0]) @ axis
60
61u = 0
62for variant in ['global', 'local', 'markers']:
63 deflection = Model(variant)
64 exu.Print(variant, ': deflection', deflection, ', expected', deflectionExpected)
65 u += abs(deflection - deflectionExpected) < 1e-10
66deflectionDynamic = Model('global', dynamic=True)
67exu.Print('dynamic: deflection after 2 s', deflectionDynamic)
68u += deflectionDynamic
69
70exu.Print('solution of createLinearSpringDamperTest=', u)
71
72exu.sys['testResult'] = u