pendulum2Dconstraint.py
You can view and download this file on Github: pendulum2Dconstraint.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: Mathematical pendulum with constraint;
5# Remark: update from pendulum.py example
6#
7# Author: Johannes Gerstmayr
8# Date: 2019-12-26
9#
10# 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.
11#
12#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
14import exudyn as exu
15from exudyn.utilities import *
16
17SC = exu.SystemContainer()
18mbs = SC.AddSystem()
19
20L = 0.8 #distance
21mass = 2.5
22g = 9.81
23
24r = 0.05 #just for graphics
25graphicsBackground = GraphicsDataRectangle(-1.2*L,-1.2*L, 1.2*L, 0.2*L, [1,1,1,1]) #for appropriate zoom
26graphicsSphere = GraphicsDataSphere(point=[0,0,0], radius=r, color=[1.,0.2,0.2,1], nTiles = 16)
27
28#add ground object and mass point:
29oGround = mbs.AddObject(ObjectGround(referencePosition = [0,0,0],
30 visualization = VObjectGround(graphicsData = [graphicsBackground])))
31nMass = mbs.AddNode(NodePoint2D(referenceCoordinates=[L,0],
32 initialCoordinates=[0,0],
33 initialVelocities=[0,0]))
34oMass = mbs.AddObject(MassPoint2D(physicsMass = mass, nodeNumber = nMass,
35 visualization = VObjectMassPoint2D(graphicsData = [graphicsSphere])))
36
37mMass = mbs.AddMarker(MarkerNodePosition(nodeNumber=nMass))
38mGround = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oGround, localPosition = [0,0,0]))
39oDistance = mbs.AddObject(DistanceConstraint(markerNumbers = [mGround, mMass], distance = L))
40
41#add loads:
42mbs.AddLoad(Force(markerNumber = mMass, loadVector = [0, -mass*g, 0]))
43
44sDist = mbs.AddSensor(SensorObject(objectNumber=oDistance, storeInternal=True,
45 outputVariableType=exu.OutputVariableType.Distance))
46
47#print(mbs)
48
49mbs.Assemble()
50
51simulationSettings = exu.SimulationSettings()
52
53f = 1000000
54simulationSettings.timeIntegration.numberOfSteps = int(1*f)
55simulationSettings.timeIntegration.endTime = 0.001*f
56simulationSettings.solutionSettings.solutionWritePeriod = simulationSettings.timeIntegration.endTime/5000
57simulationSettings.solutionSettings.sensorsWritePeriod = simulationSettings.timeIntegration.endTime/50000
58#simulationSettings.displayComputationTime = True
59simulationSettings.timeIntegration.verboseMode = 1
60simulationSettings.timeIntegration.verboseModeFile = 0
61
62#these Newton settings are slightly faster than full Newton:
63simulationSettings.timeIntegration.newton.useModifiedNewton = True
64simulationSettings.timeIntegration.newton.modifiedNewtonJacUpdatePerStep = True
65
66simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.60 #0.62 is approx. the limit
67simulationSettings.timeIntegration.adaptiveStep = False
68
69simulationSettings.timeIntegration.generalizedAlpha.computeInitialAccelerations = True
70simulationSettings.solutionSettings.coordinatesSolutionFileName= "coordinatesSolution.txt"
71
72simulationSettings.displayStatistics = True
73#simulationSettings.solutionSettings.recordImagesInterval = 0.04
74
75SC.visualizationSettings.nodes.defaultSize = 0.05
76exu.StartRenderer()
77
78#mbs.WaitForUserToContinue()
79#exu.InfoStat()
80mbs.SolveDynamic(simulationSettings,
81 # solverType=exu.DynamicSolverType.TrapezoidalIndex2
82 )
83#exu.InfoStat()
84
85SC.WaitForRenderEngineStopFlag()
86exu.StopRenderer() #safely close rendering window!
87
88nODE2 = len(mbs.systemData.GetODE2Coordinates())
89print("ODE2=",nODE2)
90
91#plot constraint error:
92
93mbs.PlotSensor(sensorNumbers=sDist, offsets=[-L], closeAll=True)
94
95#old way, better use PlotSensor:
96import matplotlib.pyplot as plt
97import matplotlib.ticker as ticker
98
99#plot y-acceleration:
100data = np.loadtxt('coordinatesSolution.txt', comments='#', delimiter=',')
101plt.figure()
102plt.plot(data[:,0], data[:,1+2*nODE2+1], 'b-')
103
104ax=plt.gca() # get current axes
105ax.grid(True, 'major', 'both')
106ax.xaxis.set_major_locator(ticker.MaxNLocator(10))
107ax.yaxis.set_major_locator(ticker.MaxNLocator(10))
108plt.tight_layout()
109plt.show()