springDamperTutorial.py

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

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  This is the file for the EXUDYN first tutorial example showing a simple masspoint with coordinateSpringDamper connector
  5#
  6# Author:   Johannes Gerstmayr
  7# Date:     2019-11-15
  8#
  9# 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.
 10#
 11#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 12
 13#%%++++++++++++++++++++++++++++++++++
 14import exudyn as exu
 15from exudyn.utilities import Point, NodePointGround, MassPoint, MarkerNodeCoordinate,\
 16                             CoordinateSpringDamper, LoadCoordinate, SensorObject
 17#to be sure to have all items and functions imported, just do:
 18#from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
 19import exudyn.graphics as graphics #only import if it does not conflict
 20import numpy as np #for postprocessing
 21
 22SC = exu.SystemContainer()
 23mbs = SC.AddSystem()
 24
 25print('EXUDYN version='+exu.GetVersionString(True))
 26
 27L=0.5
 28mass = 1.6          #mass in kg
 29spring = 4000       #stiffness of spring-damper in N/m
 30damper = 8          #damping constant in N/(m/s)
 31
 32u0=-0.08            #initial displacement
 33v0=1                #initial velocity
 34f =80               #force on mass
 35x0=f/spring         #static displacement
 36
 37print('resonance frequency = '+str(np.sqrt(spring/mass)))
 38print('static displacement = '+str(x0))
 39
 40#node for 3D mass point:
 41n1=mbs.AddNode(Point(referenceCoordinates = [L,0,0],
 42                     initialCoordinates = [u0,0,0],
 43                     initialVelocities= [v0,0,0]))
 44
 45#ground node
 46nGround=mbs.AddNode(NodePointGround(referenceCoordinates = [0,0,0]))
 47
 48#add mass point (this is a 3D object with 3 coordinates):
 49massPoint = mbs.AddObject(MassPoint(physicsMass = mass, nodeNumber = n1))
 50
 51#marker for ground (=fixed):
 52groundMarker=mbs.AddMarker(MarkerNodeCoordinate(nodeNumber= nGround, coordinate = 0))
 53#marker for springDamper for first (x-)coordinate:
 54nodeMarker  =mbs.AddMarker(MarkerNodeCoordinate(nodeNumber= n1, coordinate = 0))
 55
 56#spring-damper between two marker coordinates
 57nC = mbs.AddObject(CoordinateSpringDamper(markerNumbers = [groundMarker, nodeMarker],
 58                                          stiffness = spring, damping = damper))
 59
 60#add load:
 61mbs.AddLoad(LoadCoordinate(markerNumber = nodeMarker,
 62                                         load = f))
 63
 64#add sensor:
 65mbs.AddSensor(SensorObject(objectNumber=nC, fileName='solution/groundForce.txt',
 66                           outputVariableType=exu.OutputVariableType.Force))
 67
 68print(mbs) #show system properties
 69mbs.Assemble()
 70
 71tEnd = 1     #end time of simulation
 72h = 0.001    #step size; leads to 1000 steps
 73
 74simulationSettings = exu.SimulationSettings()
 75simulationSettings.solutionSettings.solutionWritePeriod = 5e-3 #output interval general
 76simulationSettings.solutionSettings.sensorsWritePeriod = 5e-3  #output interval of sensors
 77simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h) #must be integer
 78simulationSettings.timeIntegration.endTime = tEnd
 79
 80simulationSettings.timeIntegration.verboseMode = 1             #show some solver output
 81simulationSettings.displayComputationTime = True               #show how fast
 82
 83simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 1
 84
 85#add some drawing parameters for this example
 86SC.visualizationSettings.nodes.drawNodesAsPoint=False
 87SC.visualizationSettings.nodes.defaultSize=0.1
 88
 89exu.StartRenderer()            #start graphics visualization
 90#mbs.WaitForUserToContinue()    #wait for pressing SPACE bar or 'Q' to continue
 91
 92#start solver:
 93mbs.SolveDynamic(simulationSettings)
 94
 95#SC.WaitForRenderEngineStopFlag() #wait for pressing 'Q' to quit
 96exu.StopRenderer()               #safely close rendering window!
 97
 98#evaluate final (=current) output values
 99u = mbs.GetNodeOutput(n1, exu.OutputVariableType.Position)
100print('displacement=',u)
101
102#%%+++++++++++++++++++++++++++++++++++++++++++++++++++++
103#compute exact solution:
104import matplotlib.pyplot as plt
105import matplotlib.ticker as ticker
106
107omega0 = np.sqrt(spring/mass)     #eigen frequency of undamped system
108dRel = damper/(2*np.sqrt(spring*mass)) #dimensionless damping
109omega = omega0*np.sqrt(1-dRel**2) #eigen frequency of damped system
110C1 = u0-x0 #static solution needs to be considered!
111C2 = (v0+omega0*dRel*C1) / omega #C1, C2 are coeffs for solution
112steps = int(tEnd/h)
113
114refSol = np.zeros((steps+1,2))
115for i in range(0,steps+1):
116    t = tEnd*i/steps
117    refSol[i,0] = t
118    refSol[i,1] = np.exp(-omega0*dRel*t)*(C1*np.cos(omega*t) + C2*np.sin(omega*t))+x0
119
120data = np.loadtxt('coordinatesSolution.txt', comments='#', delimiter=',')
121plt.plot(data[:,0], data[:,1], 'b-', label='displacement (m); numerical solution')
122plt.plot(refSol[:,0], refSol[:,1], 'r-', label='displacement (m); exact solution')
123
124#show force in constraint/support:
125data = np.loadtxt('solution/groundForce.txt', comments='#', delimiter=',')
126plt.plot(data[:,0], data[:,1]*1e-3, 'g-', label='force (kN)') #numerical solution
127
128ax=plt.gca() # get current axes
129ax.grid(True, 'major', 'both')
130ax.xaxis.set_major_locator(ticker.MaxNLocator(10))
131ax.yaxis.set_major_locator(ticker.MaxNLocator(10))
132plt.legend() #show labels as legend
133plt.tight_layout()
134plt.show()