springDamperTutorialNew.py

You can view and download this file on Github: springDamperTutorialNew.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 a SpringDamper
  5#
  6# Author:   Johannes Gerstmayr
  7# Date:     2023-05-15
  8# Update:   2024-06-04 (now fully using create functions)
  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
 14
 15import exudyn as exu
 16from exudyn.utilities import SensorBody, SensorObject
 17import exudyn.graphics as graphics #only import if it does not conflict
 18
 19import numpy as np #for postprocessing
 20
 21SC = exu.SystemContainer()
 22mbs = SC.AddSystem()
 23
 24print('EXUDYN version='+exu.GetVersionString())
 25
 26L=0.5
 27mass = 1.6          #mass in kg
 28spring = 4000       #stiffness of spring-damper in N/m
 29damper = 8          #damping constant in N/(m/s)
 30
 31u0=-0.08            #initial displacement
 32v0=1                #initial velocity
 33f =80               #force on mass
 34x0=f/spring         #static displacement
 35
 36print('resonance frequency = '+str(np.sqrt(spring/mass)))
 37print('static displacement = '+str(x0))
 38
 39oMass = mbs.CreateMassPoint(referencePosition=[L,0,0],
 40                            initialDisplacement = [u0,0,0],
 41                            initialVelocity= [v0,0,0],
 42                            physicsMass=mass) #force created via gravity
 43
 44oGround = mbs.CreateGround()
 45
 46#create spring damper with reference length computed from reference positions (=L)
 47oSD = mbs.CreateSpringDamper(bodyOrNodeList=[oMass, oGround],
 48                             stiffness = spring, damping = damper)
 49
 50#add load on body:
 51mbs.CreateForce(bodyNumber = oMass, loadVector = [f,0,0])
 52
 53#add sensors:
 54sForce = mbs.AddSensor(SensorObject(objectNumber=oSD, storeInternal=True,
 55                                    outputVariableType=exu.OutputVariableType.ForceLocal))
 56sDisp = mbs.AddSensor(SensorBody(bodyNumber=oMass, storeInternal=True,
 57                                  outputVariableType=exu.OutputVariableType.Displacement))
 58
 59print(mbs)
 60mbs.Assemble()
 61
 62tEnd = 1     #end time of simulation
 63h = 0.001    #step size; leads to 1000 steps
 64
 65simulationSettings = exu.SimulationSettings()
 66simulationSettings.solutionSettings.solutionWritePeriod = 5e-3  #output interval general
 67simulationSettings.solutionSettings.sensorsWritePeriod = 5e-3  #output interval of sensors
 68simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h) #must be integer
 69simulationSettings.timeIntegration.endTime = tEnd
 70
 71#add some drawing parameters for this example
 72SC.visualizationSettings.nodes.drawNodesAsPoint=False
 73SC.visualizationSettings.nodes.defaultSize=0.1
 74
 75exu.StartRenderer()              #start graphics visualization
 76mbs.WaitForUserToContinue()    #wait for pressing SPACE bar to continue
 77
 78#start solver:
 79mbs.SolveDynamic(simulationSettings,
 80                 solverType=exu.DynamicSolverType.TrapezoidalIndex2)
 81
 82SC.WaitForRenderEngineStopFlag()#wait for pressing 'Q' to quit
 83exu.StopRenderer()               #safely close rendering window!
 84
 85#evaluate final (=current) output values
 86u = mbs.GetNodeOutput(0, exu.OutputVariableType.Position) #Node 0 is first node
 87print('displacement=',u)
 88
 89#+++++++++++++++++++++++++++++++++++++++++++++++++++++
 90#compute exact solution:
 91
 92omega0 = np.sqrt(spring/mass)     #eigen frequency of undamped system
 93dRel = damper/(2*np.sqrt(spring*mass)) #dimensionless damping
 94omega = omega0*np.sqrt(1-dRel**2) #eigen frequency of damped system
 95C1 = u0-x0 #static solution needs to be considered!
 96C2 = (v0+omega0*dRel*C1) / omega #C1, C2 are coeffs for solution
 97steps = int(tEnd/h)
 98
 99refSol = np.zeros((steps+1,2))
100for i in range(0,steps+1):
101    t = tEnd*i/steps
102    refSol[i,0] = t
103    refSol[i,1] = np.exp(-omega0*dRel*t)*(C1*np.cos(omega*t) + C2*np.sin(omega*t))+x0
104
105#use PlotSensor functionality to plot data:
106mbs.PlotSensor(sensorNumbers=[refSol], components=[0], labels='displacement (m); exact solution',
107               colorCodeOffset=2, closeAll=True) #color code offset to have same colors as in original example
108mbs.PlotSensor(sensorNumbers=[sDisp], components=[0], labels='displacement (m); numerical solution',
109               colorCodeOffset=0, newFigure=False)
110
111mbs.PlotSensor(sensorNumbers=[sForce], labels='force (kN)',
112               colorCodeOffset=1, factors=[1e-3], newFigure=False)