flexibleRotor3Dtest.py

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

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  Flexible rotor test using two rigid bodies connected by 4 springs (corotating)
  5#           This test shows the unstable behavior if inner damping is larger than outer damping
  6#
  7# Author:   Johannes Gerstmayr
  8# Date:     2019-12-05
  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.itemInterface import *
 16from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
 17import exudyn.graphics as graphics #only import if it does not conflict
 18
 19import time
 20import numpy as np
 21
 22SC = exu.SystemContainer()
 23mbs = SC.AddSystem()
 24print('EXUDYN version='+exu.GetVersionString())
 25
 26useGraphics = True
 27
 28L=1                     #total rotor axis length
 29m = 1                   #mass of one disc in kg
 30r = 0.5                 #radius for disc mass distribution
 31lRotor = 0.1            #length of one half rotor disk
 32k = 800                 #stiffness of (all/both) springs in rotor in N/m
 33Jxx = 0.5*m*r**2        #polar moment of inertia
 34Jyyzz = 0.25*m*r**2 + 1/12.*m*lRotor**2      #moment of inertia for y and z axes
 35
 36omega0=np.sqrt(2*k/(2*m)) #linear system; without flexibility of rotor
 37
 38#case 1: external damping: D0=0.002, D0int=0
 39#case 2: external damping with small internal damping: D0=0.002, D0int=0.001
 40#case 3: external damping with larger internal damping: D0=0.002, D0int=0.1
 41#case 4: no external damping with small internal damping: D0=0, D0int=0.001
 42attr = 'g-' #color in plot
 43D0 = 0.002              #0.002 default; dimensionless damping
 44D0int = 0.001*200 #*200      #default 0.001; dimensionless damping (not fully); value > 0.08 gives instability
 45
 46d = 2*omega0*D0*(2*m)       #damping constant for external damping in N/(m/s)
 47
 48kInt = 4*800            #stiffness of (all/both) springs in rotor in N/m
 49omega0int = np.sqrt(kInt/m)
 50dInt = 2*omega0int*D0int*m    #damping constant in N/(m/s)
 51
 52f0 = 0*omega0/(2*np.pi) #frequency start (Hz)
 53f1 = 2.*omega0/(2*np.pi) #frequency end (Hz)
 54
 55torque = 0.5            #driving torque; Nm
 56eps = 2e-3              #excentricity of mass in y-direction
 57omegaInitial = 0*4*omega0 #initial rotation speed in rad/s
 58
 59print('resonance frequency (rad/s)= '+str(omega0))
 60tEnd = 80               #end time of simulation
 61steps = 10000         #number of steps
 62
 63
 64#draw RGB-frame at origin
 65p=[0,0,0]
 66lFrame = 0.8
 67tFrame = 0.01
 68backgroundX = graphics.Cylinder(p,[lFrame,0,0],tFrame,[0.9,0.3,0.3,1],12)
 69backgroundY = graphics.Cylinder(p,[0,lFrame,0],tFrame,[0.3,0.9,0.3,1],12)
 70backgroundZ = graphics.Cylinder(p,[0,0,lFrame],tFrame,[0.3,0.3,0.9,1],12)
 71#mbs.AddObject(ObjectGround(referencePosition= [0,0,0], visualization=VObjectGround(graphicsData= [backgroundX, backgroundY, backgroundZ])))
 72
 73#rotor is rotating around x-axis
 74ep0 = eulerParameters0 #no rotation
 75ep_t0 = AngularVelocity2EulerParameters_t([omegaInitial,0,0], ep0)
 76print(ep_t0)
 77
 78p0 = [-lRotor*0.5,eps,0] #reference position
 79p1 = [ lRotor*0.5,eps,0] #reference position
 80v0 = [0.,0.,0.] #initial translational velocity
 81
 82#node for Rigid2D body: px, py, phi:
 83n0=mbs.AddNode(RigidEP(referenceCoordinates = p0+ep0, initialVelocities=v0+list(ep_t0)))
 84n1=mbs.AddNode(RigidEP(referenceCoordinates = p1+ep0, initialVelocities=v0+list(ep_t0)))
 85
 86#ground nodes
 87nGround0=mbs.AddNode(NodePointGround(referenceCoordinates = [-L/2,0,0]))
 88nGround1=mbs.AddNode(NodePointGround(referenceCoordinates = [ L/2,0,0]))
 89
 90#add mass point (this is a 3D object with 3 coordinates):
 91transl = 0.9 #<1 gives transparent object
 92gRotor0 = graphics.Cylinder([-lRotor*0.5,0,0],[lRotor,0,0],r,[0.3,0.3,0.9,transl],32)
 93gRotor1 = graphics.Cylinder([-lRotor*0.5,0,0],[lRotor,0,0],r,[0.9,0.3,0.3,transl],32)
 94gRotor0Axis = graphics.Cylinder([-L*0.5+0.5*lRotor,0,0],[L*0.5,0,0],r*0.05,[0.3,0.3,0.9,1],16)
 95gRotor1Axis = graphics.Cylinder([-0.5*lRotor,0,0],[L*0.5,0,0],r*0.05,[0.3,0.3,0.9,1],16)
 96gRotorCS = [backgroundX, backgroundY, backgroundZ]
 97rigid0 = mbs.AddObject(RigidBody(physicsMass=m, physicsInertia=[Jxx,Jyyzz,Jyyzz,0,0,0], nodeNumber = n0, visualization=VObjectRigidBody2D(graphicsData=[gRotor0, gRotor0Axis]+gRotorCS)))
 98rigid1 = mbs.AddObject(RigidBody(physicsMass=m, physicsInertia=[Jxx,Jyyzz,Jyyzz,0,0,0], nodeNumber = n1, visualization=VObjectRigidBody2D(graphicsData=[gRotor1, gRotor1Axis]+gRotorCS)))
 99
100#marker for ground (=fixed):
101groundMarker0=mbs.AddMarker(MarkerNodePosition(nodeNumber= nGround0))
102groundMarker1=mbs.AddMarker(MarkerNodePosition(nodeNumber= nGround1))
103
104#marker for rotor axis and support:
105rotorAxisMarker0 =mbs.AddMarker(MarkerBodyPosition(bodyNumber=rigid0, localPosition=[-0.5*L+0.5*lRotor,-eps,0]))
106rotorAxisMarker1 =mbs.AddMarker(MarkerBodyPosition(bodyNumber=rigid1, localPosition=[ 0.5*L-0.5*lRotor,-eps,0]))
107
108
109#++++++++++++++++++++++++++++++++++++
110#supports:
111mbs.AddObject(CartesianSpringDamper(markerNumbers=[groundMarker0, rotorAxisMarker0],
112                                    stiffness=[k,k,k], damping=[d, d, d]))
113mbs.AddObject(CartesianSpringDamper(markerNumbers=[groundMarker1, rotorAxisMarker1],
114                                   stiffness=[0,k,k], damping=[0, d, d])) #do not constrain x-axis twice
115
116#++++++++++++++++++++++++++++++++++++
117#flexible rotor:
118nSprings = 4
119for i in range(nSprings):
120    #add corresponding markers
121    phi = 2*np.pi*i/nSprings
122    rSpring = 0.5
123    yPos = rSpring*np.sin(phi)
124    zPos = rSpring*np.cos(phi)
125    rotorM0 =mbs.AddMarker(MarkerBodyPosition(bodyNumber=rigid0, localPosition=[ 0.5*lRotor,yPos,zPos]))
126    rotorM1 =mbs.AddMarker(MarkerBodyPosition(bodyNumber=rigid1, localPosition=[-0.5*lRotor,yPos,zPos]))
127
128    mbs.AddObject(CartesianSpringDamper(markerNumbers=[rotorM0, rotorM1],
129                                        stiffness=[kInt,kInt,kInt], damping=[dInt, dInt, dInt]))
130
131#coordinate markers for loads:
132rotorMarkerUy=mbs.AddMarker(MarkerNodeCoordinate(nodeNumber= n1, coordinate=1))
133rotorMarkerUz=mbs.AddMarker(MarkerNodeCoordinate(nodeNumber= n1, coordinate=2))
134
135#add torque:
136rotorRigidMarker =mbs.AddMarker(MarkerBodyRigid(bodyNumber=rigid0, localPosition=[0,0,0]))
137mbs.AddLoad(Torque(markerNumber=rotorRigidMarker, loadVector=[torque,0,0]))
138
139#print(mbs)
140mbs.Assemble()
141#mbs.systemData.Info()
142
143simulationSettings = exu.SimulationSettings()
144simulationSettings.solutionSettings.solutionWritePeriod = 1e-5  #output interval
145simulationSettings.timeIntegration.numberOfSteps = steps
146simulationSettings.timeIntegration.endTime = 30#tEnd
147simulationSettings.timeIntegration.newton.useModifiedNewton=True
148simulationSettings.timeIntegration.generalizedAlpha.useIndex2Constraints = True
149simulationSettings.timeIntegration.generalizedAlpha.useNewmark = True
150simulationSettings.timeIntegration.verboseMode = 1
151simulationSettings.displayStatistics = True
152simulationSettings.displayComputationTime = True
153simulationSettings.linearSolverType = exu.LinearSolverType.EXUdense
154
155simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 1
156SC.visualizationSettings.general.useMultiThreadedRendering = False
157
158if useGraphics:
159    exu.StartRenderer()              #start graphics visualization
160    mbs.WaitForUserToContinue()    #wait for pressing SPACE bar to continue
161
162#start solver:
163mbs.SolveDynamic(simulationSettings)
164
165if useGraphics:
166    SC.WaitForRenderEngineStopFlag()#wait for pressing 'Q' to quit
167    exu.StopRenderer()               #safely close rendering window!
168
169#evaluate final (=current) output values
170u = mbs.GetNodeOutput(n1, exu.OutputVariableType.AngularVelocity)
171print('omega=',u)
172
173
174##+++++++++++++++++++++++++++++++++++++++++++++++++++++
175import matplotlib.pyplot as plt
176import matplotlib.ticker as ticker
177
178if useGraphics:
179    data = np.loadtxt('coordinatesSolution.txt', comments='#', delimiter=',')
180    n=steps
181    plt.rcParams.update({'font.size': 24})
182
183    plt.plot(data[:,0], data[:,3], 'r-') #numerical solution
184
185    ax=plt.gca() # get current axes
186    ax.grid(True, 'major', 'both')
187    ax.xaxis.set_major_locator(ticker.MaxNLocator(10))
188    ax.yaxis.set_major_locator(ticker.MaxNLocator(10))
189    plt.tight_layout()
190    plt.show()