def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass Jz = radius**2 / 2 Jxy = (3 * radius**2 + length**2) / 12 inertia = mass * np.diag([Jxy, Jxy, Jz]) self.A = mass * Jxy + endmass * (length / 2)**2 self.C = mass * Jz self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [0, 0, 1]) self.body = RigidBody('body', mass, inertia) self.offset = RigidConnection('offset', [0, 0, length / 2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin x = np.linspace(0, length) modes = linearisation.ModalRepresentation( x=x, shapes=np.zeros((len(x), 3, 0)), rotations=np.zeros((len(x), 3, 0)), density=np.ones_like(x) * mass / length, mass_axis=np.zeros((len(x), 2)), section_inertia=np.ones_like(x) * radius**2 / 4, freqs=np.zeros((0, )), ) self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [1, 0, 0]) self.body = ModalElement('body', modes) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis.istrain, 0.0) # constant rotational speed
class BeamGyroscope(Gyroscope): def __init__(self, length, radius, mass, spin, endmass): self.length = length self.radius = radius self.mass = mass self.spin = spin self.endmass = endmass Jx = mass * radius**2 / 2 self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.offset = RigidConnection('offset', [-length/2,0,0]) self.axis = Hinge('axis', [1,0,0]) self.body = UniformBeam('body', length, mass/length, 1, 1, 1, Jx=Jx/2) # /2 because added to both ends self.endbody = RigidBody('end', endmass) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.axis) self.axis.add_leaf(self.body) self.offset.add_leaf(self.endbody) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed self.system.prescribe(self.body, acc=0.0) # rigid beam
def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass Jx = mass * radius**2 / 2 Jyz = mass * (3 * radius**2 + length**2) / 12 self.A = Jyz + endmass * (length / 2)**2 self.C = Jx self.pivot = Hinge('pivot', [0, 1, 0]) self.offset = RigidConnection('offset', [0, 0, -length / 2]) self.axis = Hinge('axis', [0, 0, 1], rotmat_y(-np.pi / 2)) self.body = UniformBeam('body', length, mass / length, 1, 1, 1, Jx=Jx / 2) # /2 because added to both ends self.endoffset = RigidConnection('endoffset', [0, 0, length / 2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.endoffset) self.endoffset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed self.system.prescribe(self.body, acc=0.0) # rigid beam
def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = mass * radius**2 / 2 self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [1, 0, 0]) self.body = UniformBeam('body', length, mass / length, 1, 1, 1, Jx=Jx / 2) # /2 because added to both ends self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis.istrain, 0.0) # constant rotational speed self.system.prescribe(self.body.istrain, 0.0) # rigid beam
class BeamGyroscope(Gyroscope): def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass Jx = mass * radius**2 / 2 Jyz = mass*(3*radius**2 + length**2) / 12 self.A = Jyz + endmass*(length/2)**2 self.C = Jx self.pivot = Hinge('pivot', [0,1,0]) self.offset = RigidConnection('offset', [0,0,-length/2]) self.axis = Hinge('axis', [0,0,1], rotmat_y(-np.pi/2)) self.body = UniformBeam('body', length, mass/length, 1, 1, 1, Jx=Jx/2) # /2 because added to both ends self.endoffset = RigidConnection('endoffset', [0,0,length/2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.endoffset) self.endoffset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed self.system.prescribe(self.body, acc=0.0) # rigid beam
def __init__(self, length, radius, mass, spin, endmass): self.length = length self.radius = radius self.mass = mass self.spin = spin self.endmass = endmass x = np.linspace(-length / 2, length / 2) modes = linearisation.ModalRepresentation( x=x, shapes=np.zeros((len(x), 3, 0)), rotations=np.zeros((len(x), 3, 0)), density=np.ones_like(x) * mass / length, mass_axis=np.zeros((len(x), 2)), section_inertia=np.ones_like(x) * radius**2 / 4, freqs=np.zeros((0, )), ) self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [0, 0, 1], rotmat_y(-np.pi / 2)) self.body = ModalElement('body', modes) self.offset = RigidConnection('offset', [0, 0, length / 2]) self.endbody = RigidBody('end', endmass) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
def __init__(self, length, radius, mass, spin, endmass): self.length = length self.radius = radius self.mass = mass self.spin = spin self.endmass = endmass Jx = mass * radius**2 / 2 self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.offset = RigidConnection('offset', [-length / 2, 0, 0]) self.axis = Hinge('axis', [1, 0, 0]) self.body = UniformBeam('body', length, mass / length, 1, 1, 1, Jx=Jx / 2) # /2 because added to both ends self.endbody = RigidBody('end', endmass) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.axis) self.axis.add_leaf(self.body) self.offset.add_leaf(self.endbody) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed self.system.prescribe(self.body, acc=0.0) # rigid beam
class ModalGyroscope(Gyroscope): def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin x = np.linspace(0, length) modes = linearisation.ModalRepresentation( x =x, shapes =np.zeros((len(x),3,0)), rotations =np.zeros((len(x),3,0)), density =np.ones_like(x) * mass/length, mass_axis =np.zeros((len(x),2)), section_inertia=np.ones_like(x) * radius**2 / 4, freqs =np.zeros((0,)), ) self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [1,0,0]) self.body = ModalElement('body', modes) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
class Gyroscope(object): def __init__(self, length, radius, mass, spin, endmass): self.length = length self.radius = radius self.mass = mass self.spin = spin self.endmass = endmass Jz = radius**2 / 2 Jxy = (3*radius**2 + length**2) / 12 inertia = mass * np.diag([Jxy, Jxy, Jz]) self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [0,0,1]) self.body = RigidBody('body', mass, inertia) self.offset = RigidConnection('offset', [0,0,length/2]) self.endbody = RigidBody('end', endmass) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed def simulate(self, xpivot=0.0, vprec=0.0, t1=10, dt=0.05): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q [self.pivot.istrain][0] = xpivot # initial elevation self.system.qd[self.bearing.istrain][0] = vprec # initial azimuth spd self.system.qd[self.axis.istrain][0] = self.spin # initial rotation speed self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.axis.iprox)) self.integ.add_output(dynamics.LoadOutput(self.pivot.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) #integ.add_output(dynamics.CustomOutput( # lambda s: np.dot(self.axis.mass_vv, self.system.qdd[el.iprox+el.idist]) + \ # np.dot(el.mass_ve, self.system.qdd[el.istrain]))) # simulate if t1 > 0: self.t, self.y = self.integ.integrate(t1, dt) for i,lab in enumerate(self.integ.labels()): print "%2d %s" % (i,lab) return self.t, self.y def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0,vs), (-l,l), (-l,l), velocities=False)
class Gyroscope(object): def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = radius**2 / 2 Jyz = (3 * radius**2 + length**2) / 12 Jyz_0 = Jyz + (length / 2)**2 # parallel axis theorem inertia = mass * np.diag([Jx, Jyz_0, Jyz_0]) self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [1, 0, 0]) self.body = RigidBody('body', mass, inertia, [length / 2, 0, 0]) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed def simulate(self, xpivot=0.0, vprec=0.0, t1=10, dt=0.05): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.pivot.istrain][0] = xpivot # initial elevation self.system.qd[ self.bearing.istrain][0] = vprec # initial elevation spd self.system.qd[ self.axis.istrain][0] = self.spin # initial rotation speed self.integ = Integrator(self.system, ('pos', 'vel')) self.integ.add_output(dynamics.LoadOutput(self.axis.iprox)) self.integ.add_output(dynamics.LoadOutput(self.pivot.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) # simulate if t1 > 0: self.t, self.y = self.integ.integrate(t1, dt) for i, lab in enumerate(self.integ.labels()): print "%2d %s" % (i, lab) return self.t, self.y def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0, vs), (-l, l), (-l, l), velocities=False)
class Gyroscope(object): def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = radius**2 / 2 Jyz = (3*radius**2 + length**2) / 12 Jyz_0 = Jyz + (length/2)**2 # parallel axis theorem inertia = mass * np.diag([Jx, Jyz_0, Jyz_0]) self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [1,0,0]) self.body = RigidBody('body', mass, inertia, [length/2, 0, 0]) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed def simulate(self, xpivot=0.0, vprec=0.0, t1=10, dt=0.05): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q [self.pivot.istrain][0] = xpivot # initial elevation self.system.qd[self.bearing.istrain][0] = vprec # initial elevation spd self.system.qd[self.axis .istrain][0] = self.spin # initial rotation speed self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.axis.iprox)) self.integ.add_output(dynamics.LoadOutput(self.pivot.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) # simulate if t1 > 0: self.t, self.y = self.integ.integrate(t1, dt) for i,lab in enumerate(self.integ.labels()): print "%2d %s" % (i,lab) return self.t, self.y def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0,vs), (-l,l), (-l,l), velocities=False)
def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) self.bearing = Hinge('bearing', [0, 0, 1]) self.offset = RigidConnection('offset', [root_length, 0, 0]) self.blade = ModalElement('blade', self.modes) self.bearing.add_leaf(self.offset) self.offset.add_leaf(self.blade) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # constant spin speed
def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass Jz = radius**2 / 2 Jxy = (3*radius**2 + length**2) / 12 inertia = mass * np.diag([Jxy, Jxy, Jz]) self.A = mass*Jxy + endmass*(length/2)**2 self.C = mass*Jz self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [0,0,1]) self.body = RigidBody('body', mass, inertia) self.offset = RigidConnection('offset', [0,0,length/2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
def __init__(self, length, radius, mass, spin, endmass): self.length = length self.radius = radius self.mass = mass self.spin = spin self.endmass = endmass x = np.linspace(-length/2, length/2) modes = linearisation.ModalRepresentation( x =x, shapes =np.zeros((len(x),3,0)), rotations =np.zeros((len(x),3,0)), density =np.ones_like(x) * mass/length, mass_axis =np.zeros((len(x),2)), section_inertia=np.ones_like(x) * radius**2 / 4, freqs =np.zeros((0,)), ) self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [0,0,1], rotmat_y(-np.pi/2)) self.body = ModalElement('body', modes) self.offset = RigidConnection('offset', [0,0,length/2]) self.endbody = RigidBody('end', endmass) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
class Gyroscope(object): def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = radius**2 / 2 Jyz = (3 * radius**2 + length**2) / 12 Jyz_0 = Jyz + (length / 2)**2 # parallel axis theorem inertia = mass * np.diag([Jx, Jyz_0, Jyz_0]) self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [1, 0, 0]) self.body = RigidBody('body', mass, inertia, [length / 2, 0, 0]) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis.istrain, 0.0) # constant rotational speed def simulate(self, xpivot=0.0, vpivot=0.0, t1=1.5, dt=0.01): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.pivot.istrain[0]] = xpivot # initial elevation self.system.qd[self.pivot.istrain[0]] = vpivot # initial elevation spd self.system.qd[ self.axis.istrain[0]] = self.spin # initial rotation speed # simulate self.t = np.arange(0, t1, dt) self.y = solve_system(self.system, self.t, outputs='vels') def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0, vs), (-l, l), (-l, l), velocities=False)
def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.CustomOutput(lambda s: b.station_positions()[-1], label="{} tip defl".format(b))) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.CustomOutput(lambda s: dot(b.Rp, b.station_positions()[-1]), label="{} tip pos".format(b)))
class Gyroscope(object): def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = radius**2 / 2 Jyz = (3*radius**2 + length**2) / 12 Jyz_0 = Jyz + (length/2)**2 # parallel axis theorem inertia = mass * np.diag([Jx, Jyz_0, Jyz_0]) self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [1,0,0]) self.body = RigidBody('body', mass, inertia, [length/2, 0, 0]) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis.istrain, 0.0) # constant rotational speed def simulate(self, xpivot=0.0, vpivot=0.0, t1=1.5, dt=0.01): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q [self.pivot.istrain[0]] = xpivot # initial elevation self.system.qd[self.pivot.istrain[0]] = vpivot # initial elevation spd self.system.qd[self.axis .istrain[0]] = self.spin # initial rotation speed # simulate self.t = np.arange(0, t1, dt) self.y = solve_system(self.system, self.t, outputs='vels') def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0,vs), (-l,l), (-l,l), velocities=False)
def __init__(self, bladed_file, root_length=0, rigid=False): # Modal element using data from Bladed model print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() #self.tmodes = self.tower.modal_rep() Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0,0,self.tower.hubheight]) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) if rigid: for b in (self.blade1, self.blade2, self.blade3): self.system.prescribe(b, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_deflections()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_positions()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.NodeOutput(b.iprox, local=True, deriv=2))
def __init__(self, mode_source_file, root_length=0, wind_table=None): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.blade = Blade(mode_source_file) self.modes = self.blade.modal_rep() if wind_table is not None: loading = BladeLoading(self.blade, wind_table, None) else: loading = None Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes, loading) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing, vel=0.0, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) self.integ.add_output(dynamics.LoadOutput(self.blade1.iprox, local=True)) self.integ.add_output(self.blade1.output_deflections()) self.integ.add_output(self.blade1.output_positions())
class LumpedGyroscope(Gyroscope): def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass # corrected radius for lumped masses mr = radius / np.sqrt(2) root3 = np.sqrt(3) self.A = 3 * (mass/3) * mr**2 / 2 + endmass*(length/2)**2 self.C = 3 * (mass/3) * mr**2 self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [0,0,1]) self.arm1 = RigidConnection('arm1', [mr,0,0]) self.arm2 = RigidConnection('arm2', [-mr/2, mr*root3/2,0]) self.arm3 = RigidConnection('arm3', [-mr/2,-mr*root3/2,0]) self.body = RigidBody('body', mass/3) self.body2 = RigidBody('body2', mass/3) self.body3 = RigidBody('body3', mass/3) self.offset = RigidConnection('offset', [0,0,length/2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.arm1) self.axis.add_leaf(self.arm2) self.axis.add_leaf(self.arm3) self.arm1.add_leaf(self.body) self.arm2.add_leaf(self.body2) self.arm3.add_leaf(self.body3) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
class LumpedGyroscope(Gyroscope): def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass # corrected radius for lumped masses mr = radius / np.sqrt(2) root3 = np.sqrt(3) self.A = 3 * (mass / 3) * mr**2 / 2 + endmass * (length / 2)**2 self.C = 3 * (mass / 3) * mr**2 self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [0, 0, 1]) self.arm1 = RigidConnection('arm1', [mr, 0, 0]) self.arm2 = RigidConnection('arm2', [-mr / 2, mr * root3 / 2, 0]) self.arm3 = RigidConnection('arm3', [-mr / 2, -mr * root3 / 2, 0]) self.body = RigidBody('body', mass / 3) self.body2 = RigidBody('body2', mass / 3) self.body3 = RigidBody('body3', mass / 3) self.offset = RigidConnection('offset', [0, 0, length / 2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.arm1) self.axis.add_leaf(self.arm2) self.axis.add_leaf(self.arm3) self.arm1.add_leaf(self.body) self.arm2.add_leaf(self.body2) self.arm3.add_leaf(self.body3) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
class BeamGyroscope(Gyroscope): def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = mass * radius**2 / 2 self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [1,0,0]) self.body = UniformBeam('body', length, mass/length, 1, 1, 1, Jx=Jx/2) # /2 because added to both ends self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis.istrain, 0.0) # constant rotational speed self.system.prescribe(self.body.istrain, 0.0) # rigid beam
def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) self.bearing = Hinge('bearing', [0,0,1]) self.offset = RigidConnection('offset', [root_length, 0, 0]) self.blade = ModalElement('blade', self.modes) self.bearing.add_leaf(self.offset) self.offset.add_leaf(self.blade) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # constant spin speed
def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = radius**2 / 2 Jyz = (3 * radius**2 + length**2) / 12 Jyz_0 = Jyz + (length / 2)**2 # parallel axis theorem inertia = mass * np.diag([Jx, Jyz_0, Jyz_0]) self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [1, 0, 0]) self.body = RigidBody('body', mass, inertia, [length / 2, 0, 0]) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
class Rotor(object): def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) self.bearing = Hinge('bearing', [0,0,1]) self.offset = RigidConnection('offset', [root_length, 0, 0]) self.blade = ModalElement('blade', self.modes) self.bearing.add_leaf(self.offset) self.offset.add_leaf(self.blade) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # constant spin speed def simulate(self, qm0, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.blade.istrain] = qm0 # initial modal amplitudes self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) #acc=spin/t1) # setup integrator self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) self.integ.add_output(dynamics.LoadOutput(self.blade.iprox)) self.integ.add_output(dynamics.LoadOutput(self.blade.iprox, local=True)) self.integ.add_output(dynamics.CustomOutput( lambda s: self.blade.station_positions()[-1], label="Tip pos")) self.integ.add_output(dynamics.CustomOutput( lambda s: self.blade.quad_stress, label="Quad stress")) # simulate self.t,self.y = self.integ.integrate(t1, dt) return self.t, self.y def lin(self, qm0, spin=10.0): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.blade.istrain] = qm0 # initial modal amplitudes self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) # constant speed linsys = linearisation.LinearisedSystem(self.system, qm0) return linsys def ani(self, vs=1): l = 40 return dynvis.anim(self.system, self.t, self.y, (0,vs), (-l,l), (-l,l), velocities=False, only_free=True)
def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.CustomOutput( lambda s: b.station_positions()[-1], label="{} tip defl".format(b))) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.CustomOutput( lambda s: dot(b.Rp, b.station_positions()[-1]), label="{} tip pos".format(b)))
def __init__(self, length, radius, mass, spin): self.length = length self.radius = radius self.mass = mass self.spin = spin Jx = radius**2 / 2 Jyz = (3*radius**2 + length**2) / 12 Jyz_0 = Jyz + (length/2)**2 # parallel axis theorem inertia = mass * np.diag([Jx, Jyz_0, Jyz_0]) self.bearing = Hinge('bearing', [0,0,1]) self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [1,0,0]) self.body = RigidBody('body', mass, inertia, [length/2, 0, 0]) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed
class Gyroscope(object): def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass Jz = radius**2 / 2 Jxy = (3 * radius**2 + length**2) / 12 inertia = mass * np.diag([Jxy, Jxy, Jz]) self.A = mass * Jxy + endmass * (length / 2)**2 self.C = mass * Jz self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [0, 0, 1]) self.body = RigidBody('body', mass, inertia) self.offset = RigidConnection('offset', [0, 0, length / 2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed def applied_torque(self, s): # applied torque about y axis, Q2 elevation = s.q[self.pivot.istrain][0] return self.endmass * dynamics.gravity * self.length / 2 * np.sin( elevation) def thetadotdot(self, s): # acceleration about y axis, thetadotdot Q2 = self.applied_torque(s) return Q2 / self.A def gyro_torque(self, s): # gyroscopic sideways torque, Q1 spin = s.qd[self.axis.istrain][0] # spin speed thetadot = s.qd[self.pivot.istrain][0] return self.C * spin * thetadot def simulate(self, xpivot=0.0, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.pivot.istrain][0] = xpivot # initial elevation self.system.qd[self.axis.istrain][0] = spin # initial rotation speed # setup integrator #self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ = Integrator(self.system, ()) for istrain in (self.pivot.istrain, self.axis.istrain): self.integ.add_output(dynamics.StrainOutput(istrain, deriv=0)) self.integ.add_output(dynamics.StrainOutput(istrain, deriv=1)) self.integ.add_output(dynamics.StrainOutput(istrain, deriv=2)) self.integ.add_output(dynamics.LoadOutput(self.pivot.idist[0])) self.integ.add_output( dynamics.LoadOutput(self.pivot.idist[0], local=True)) self.integ.add_output(dynamics.LoadOutput(self.body.iprox)) self.integ.add_output(dynamics.LoadOutput(self.endbody.iprox)) self.integ.add_output(dynamics.CustomOutput(self.applied_torque, "Q2")) self.integ.add_output( dynamics.CustomOutput(self.thetadotdot, "thetadotdot")) self.integ.add_output(dynamics.CustomOutput(self.gyro_torque, "Q1")) # simulate if t1 > 0: self.t, self.y = self.integ.integrate(t1, dt) def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0, vs), (-l, l), (-l, l), velocities=False, only_free=True)
# Blade loading wind_table = np.array([ [0, 1, 2, 10], # time [0, 0, 0, 0 ], # x [0, 0, 20, 20], # y [0, 0, 0, 0 ], # z ]) loading = BladeLoading(modes.x, wind_table, None) rotorspeed = 10 * np.pi/30 # 10 rpm # Modal element bearing = Hinge('bearing', [0,1,0]) el = ModalElement('el', modes, loading) bearing.add_leaf(el) system = System(bearing) # Prescribe rotation speed system.prescribe(bearing.istrain, 0.0) system.qd[bearing.istrain] = rotorspeed system.find_equilibrium() integ = Integrator(system, ()) integ.add_position_output(bearing.istrain) integ.add_custom_output(lambda s: el.modes.X(el.xstrain)[(16,32),1:3].flatten(), 'defl') integ.add_custom_output(lambda s: el._get_loading()[16,:], 'loading') integ.add_custom_output(lambda s: el.quad_forces, 'quad_forces') integ.add_custom_output(lambda s: el.quad_stress, 'quad_stress') # Load Bladed data for comparison
thrust_time = [0, 1, 2, 10] thrust_force = [0, 0, 10e3, 10e3] thrust = np.c_[thrust_force, np.zeros((4, 2))].T loadfunc = scipy.interpolate.interp1d(thrust_time, thrust) # Modal element base = RigidConnection('base', rotation=rotmat_y(-np.pi / 2)) el = DistalModalElement('el', modes, distal=True, damping_freqs=modes2.freqs) #el = ModalElement('el', modes, distal=True, damping_freqs=modes2.freqs) rna = RigidBody('rna', 24000, np.diag([6400003, 6400003, 4266667]), nodal_load=loadfunc) base.add_leaf(el) el.add_leaf(rna) system = System(base) system.prescribe(el, vel=0, part=[0, 3]) integ = Integrator(system) integ.add_output(el.output_deflections()) integ.add_output(el.output_rotations()) integ.add_output(dynamics.LoadOutput(rna.iprox)) linsys = LinearisedSystem(system) def ani_xy(s, t, y): return dynvis.anim(s, t, y, (0, 1), (-5, 45), (-5, 5), velocities=False)
class FlappedBladeTurbine(object): def __init__(self, bladed_file, root_length=0): # Load modes but use a simple flapped blade print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() # Calculate equivalent blade properties I1 = self.modes.I0[0] I2 = self.modes.J0[0, 0] print I1, I2 wflap = self.modes.freqs[0] bmass = self.modes.mass inertia = self.modes.inertia_tensor(np.zeros(len(self.modes.freqs))) Xc = [I1 / bmass, 0, 0] kflap = I2 * wflap**2 Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0, 0, self.tower.hubheight]) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.flap1 = Hinge('flap1', [0, 1, 0]) self.flap2 = Hinge('flap2', [0, 1, 0]) self.flap3 = Hinge('flap3', [0, 1, 0]) self.blade1 = RigidBody('blade1', bmass, inertia, Xc) self.blade2 = RigidBody('blade2', bmass, inertia, Xc) self.blade3 = RigidBody('blade3', bmass, inertia, Xc) self.flap1.stiffness = self.flap2.stiffness = self.flap3.stiffness = kflap self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.flap1) root2.add_leaf(self.flap2) root3.add_leaf(self.flap3) self.flap1.add_leaf(self.blade1) self.flap2.add_leaf(self.blade2) self.flap3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel', 'acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output( dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output( dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.NodeOutput(b.iprox, local=True, deriv=2)) def set_base_motion(self, dof, w, amp): self.base_motion = dof self.base_motion_amp = amp self.system.prescribe(self.base, part=dof, vel=lambda t: -w * amp * np.sin(w * t), acc=lambda t: -w**2 * amp * np.cos(w * t)) def set_initial_conditions(self, qm0=None, az0=None, rotor_speed=None): # initial conditions if qm0 is not None: # initial hinge angle self.system.q[self.flap1.istrain][0] = qm0 self.system.q[self.flap2.istrain][0] = qm0 self.system.q[self.flap3.istrain][0] = qm0 if az0 is not None: self.system.q[self.bearing.istrain][0] = az0 if self.base_motion is not None: self.system.q[self.base.istrain][ self.base_motion] = self.base_motion_amp if rotor_speed is not None: self.system.prescribe(self.bearing, vel=rotor_speed) def simulate(self, qm0=None, az0=0.0, rotor_speed=10.0, t1=None, dt=0.01, t0=0.0, init=False): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if t1 is None: t1 = 4 * pi / rotor_speed if (rotor_speed != 0.0) else 2 if init: self.system.find_equilibrium() # simulate t, y = self.integ.integrate(t1, dt, t0) #for i,lab in enumerate(self.integ.labels): # print "%2d %s" % (i,lab) #return self.t, self.y # Build results structure results = FlappedTurbineResults(t, y) return results def lin(self, qm0=None, az0=None, rotor_speed=None, init=False): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if init: self.system.find_equilibrium() # need initial amplitudes for linearisation point if qm0 is None: qm0 = self.system.q[self.blade1.istrain] linsys = linearisation.LinearisedSystem(self.system, np.tile(qm0, 3)) return linsys def ani(self, results, x=0, y=1): H = self.tower.hubheight + self.blade.radii[-1] limits = [(-H, H), (-H, H), (-5, H + 5)] return dynvis.anim(self.system, results.t, results.strains.as_matrix(), (x, y), limits[x], limits[y])
class Rotor(object): def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.blade = Blade(mode_source_file) self.modes = self.blade.modal_rep() Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) self.integ.add_output(dynamics.LoadOutput(self.blade1.iprox, local=True)) self.integ.add_output(self.blade1.output_deflections()) self.integ.add_output(self.blade1.output_positions()) def simulate(self, qm0=None, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 self.system.qd[self.bearing.istrain][0] = spin # simulate self.t,self.y = self.integ.integrate(t1, dt) for i,lab in enumerate(self.integ.labels()): print "%2d %s" % (i,lab) return self.t, self.y def lin(self, qm0=None, spin=10.0): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 else: qm0 = np.zeros(self.blade1._nstrain * 3) self.system.prescribe(self.bearing, vel=spin, acc=0.0) self.system.qd[self.bearing.istrain][0] = spin linsys = linearisation.LinearisedSystem(self.system, qm0) return linsys def ani(self, t=None, y=None, planview=True): if t is None: t = self.t if y is None: y = self.y l = 40 if planview: return dynvis.anim(self.system, t, y, (1,2), (-l,l), (-l,l)) else: return dynvis.anim(self.system, t, y, (0,1), (-l,l), (-5,5))
class Rotor(object): def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.blade = Blade(mode_source_file) self.modes = self.blade.modal_rep() Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) self.integ.add_output( dynamics.LoadOutput(self.blade1.iprox, local=True)) self.integ.add_output(self.blade1.output_deflections()) self.integ.add_output(self.blade1.output_positions()) def simulate(self, qm0=None, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 self.system.qd[self.bearing.istrain][0] = spin # simulate self.t, self.y = self.integ.integrate(t1, dt) for i, lab in enumerate(self.integ.labels()): print "%2d %s" % (i, lab) return self.t, self.y def lin(self, qm0=None, spin=10.0): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 else: qm0 = np.zeros(self.blade1._nstrain * 3) self.system.prescribe(self.bearing, vel=spin, acc=0.0) self.system.qd[self.bearing.istrain][0] = spin linsys = linearisation.LinearisedSystem(self.system, qm0) return linsys def ani(self, t=None, y=None, planview=True): if t is None: t = self.t if y is None: y = self.y l = 40 if planview: return dynvis.anim(self.system, t, y, (1, 2), (-l, l), (-l, l)) else: return dynvis.anim(self.system, t, y, (0, 1), (-l, l), (-5, 5))
some demographic stuff demo = initial total population of each node tot_pop total population of the graph then the dynamical system is initialized with the varaible F avg_population will be used in the evolution as an "escape parameter" in the markov process see dynamics.py """ demo = np.sum(Z0, 1).astype(int) tot_pop = np.sum(demo) avg_pop = tot_pop / communities print("Total initial populaiton: ", tot_pop) F = System(Z0) print(" ========= NET =========") """ this section builds the network matrix containing the weights they are initialized randomly with uniform distribution and then normalized in the tranport.py file in order to build the transport process network is a sparse scipy matrix, the networkx stuff is just for visualization see mat.py """ #network = random_network(communities,6000) network = scale_free_network(communities) G = nx.Graph(network)
# Modal element using data from Bladed model print "Loading modes from '%s'..." % bladedpath modes = ModalRepresentation.from_Bladed(bladedpath+'.$pj') rotorspeed = 10 * np.pi/30 # 10 rpm overhang = 1 # 1m # Modal element yaw = Hinge('yaw', [0,0,1]) overhang = RigidConnection('overhang', [-overhang,0,0]) bearing = Hinge('bearing', [1,0,0],np.dot(rotmat_y(-np.pi/2), rotmat_x(-np.pi/2))) el = ModalElement('el', modes) yaw.add_leaf(overhang) overhang.add_leaf(bearing) bearing.add_leaf(el) system = System(yaw) # Prescribe rotation speed system.prescribe(bearing.istrain, 0.0) system.qd[bearing.istrain] = rotorspeed # Prescribed yaw angle acc_period = 0.1 yaw_time1 = 3.0 yaw_time2 = 6.0 dvyaw = 10 * np.pi/180 system.prescribe(yaw.istrain, acc=lambda t: (t>=yaw_time1 and t<(yaw_time1+acc_period)) and dvyaw/acc_period or 0 +\ (t>yaw_time2 and t<=(yaw_time2+acc_period)) and -dvyaw/acc_period or 0) system.find_equilibrium()
#loading = PointLoading(blade, wind_table, None) thrust_time = [0, 1, 2, 10] thrust_force = [0, 0, 10e3, 10e3] thrust = np.c_[thrust_force, np.zeros((4, 2))].T loadfunc = scipy.interpolate.interp1d(thrust_time, thrust) # Modal element base = RigidConnection('base', rotation=rotmat_y(-np.pi / 2)) el = ModalElement('el', modes, distal=True, damping_freqs=[8.269, 10.248]) rna = RigidBody('rna', 24000, np.diag([6400003, 6400003, 4266667]), nodal_load=loadfunc) base.add_leaf(el) el.add_leaf(rna) system = System(base) integ = Integrator(system) integ.add_output(el.output_deflections()) integ.add_output(el.output_rotations()) integ.add_output(dynamics.LoadOutput(rna.iprox)) linsys = LinearisedSystem(system) def ani_xy(s, t, y): return dynvis.anim(s, t, y, (0, 1), (-5, 45), (-5, 5), velocities=False) def ani_xz(s, t, y): return dynvis.anim(s, t, y, (0, 2), (-5, 45), (-5, 5), velocities=False)
def __init__(self, bladed_file, root_length=0): # Load modes but use a simple flapped blade print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() # Calculate equivalent blade properties I1 = self.modes.I0[0] I2 = self.modes.J0[0, 0] print I1, I2 wflap = self.modes.freqs[0] bmass = self.modes.mass inertia = self.modes.inertia_tensor(np.zeros(len(self.modes.freqs))) Xc = [I1 / bmass, 0, 0] kflap = I2 * wflap**2 Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0, 0, self.tower.hubheight]) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.flap1 = Hinge('flap1', [0, 1, 0]) self.flap2 = Hinge('flap2', [0, 1, 0]) self.flap3 = Hinge('flap3', [0, 1, 0]) self.blade1 = RigidBody('blade1', bmass, inertia, Xc) self.blade2 = RigidBody('blade2', bmass, inertia, Xc) self.blade3 = RigidBody('blade3', bmass, inertia, Xc) self.flap1.stiffness = self.flap2.stiffness = self.flap3.stiffness = kflap self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.flap1) root2.add_leaf(self.flap2) root3.add_leaf(self.flap3) self.flap1.add_leaf(self.blade1) self.flap2.add_leaf(self.blade2) self.flap3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel', 'acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output( dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output( dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.NodeOutput(b.iprox, local=True, deriv=2))
print "Loading modes from '%s'..." % bladedpath modes = ModalRepresentation.from_Bladed(bladedpath + '.$pj') rotorspeed = 10 * np.pi / 30 # 10 rpm overhang = 1 # 1m # Modal element yaw = Hinge('yaw', [0, 0, 1]) overhang = RigidConnection('overhang', [-overhang, 0, 0]) bearing = Hinge('bearing', [1, 0, 0], np.dot(rotmat_y(-np.pi / 2), rotmat_x(-np.pi / 2))) el = ModalElement('el', modes) yaw.add_leaf(overhang) overhang.add_leaf(bearing) bearing.add_leaf(el) system = System(yaw) # Prescribe rotation speed system.prescribe(bearing.istrain, 0.0) system.qd[bearing.istrain] = rotorspeed # Prescribed yaw angle acc_period = 0.1 yaw_time1 = 3.0 yaw_time2 = 6.0 dvyaw = 10 * np.pi / 180 system.prescribe(yaw.istrain, acc=lambda t: (t>=yaw_time1 and t<(yaw_time1+acc_period)) and dvyaw/acc_period or 0 +\ (t>yaw_time2 and t<=(yaw_time2+acc_period)) and -dvyaw/acc_period or 0) system.find_equilibrium()
class Gyroscope(object): def __init__(self, length, radius, mass, endmass): self.length = length self.radius = radius self.mass = mass self.endmass = endmass Jz = radius**2 / 2 Jxy = (3*radius**2 + length**2) / 12 inertia = mass * np.diag([Jxy, Jxy, Jz]) self.A = mass*Jxy + endmass*(length/2)**2 self.C = mass*Jz self.pivot = Hinge('pivot', [0,1,0]) self.axis = Hinge('axis', [0,0,1]) self.body = RigidBody('body', mass, inertia) self.offset = RigidConnection('offset', [0,0,length/2]) self.endbody = RigidBody('end', endmass) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.pivot) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed def applied_torque(self, s): # applied torque about y axis, Q2 elevation = s.q[self.pivot.istrain][0] return self.endmass * dynamics.gravity * self.length/2 * np.sin(elevation) def thetadotdot(self, s): # acceleration about y axis, thetadotdot Q2 = self.applied_torque(s) return Q2 / self.A def gyro_torque(self, s): # gyroscopic sideways torque, Q1 spin = s.qd[self.axis.istrain][0] # spin speed thetadot = s.qd[self.pivot.istrain][0] return self.C * spin * thetadot def simulate(self, xpivot=0.0, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q [self.pivot.istrain][0] = xpivot # initial elevation self.system.qd[self.axis .istrain][0] = spin # initial rotation speed # setup integrator #self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ = Integrator(self.system, ()) for istrain in (self.pivot.istrain, self.axis.istrain): self.integ.add_output(dynamics.StrainOutput(istrain, deriv=0)) self.integ.add_output(dynamics.StrainOutput(istrain, deriv=1)) self.integ.add_output(dynamics.StrainOutput(istrain, deriv=2)) self.integ.add_output(dynamics.LoadOutput(self.pivot.idist[0])) self.integ.add_output(dynamics.LoadOutput(self.pivot.idist[0], local=True)) self.integ.add_output(dynamics.LoadOutput(self.body.iprox)) self.integ.add_output(dynamics.LoadOutput(self.endbody.iprox)) self.integ.add_output(dynamics.CustomOutput(self.applied_torque, "Q2")) self.integ.add_output(dynamics.CustomOutput(self.thetadotdot, "thetadotdot")) self.integ.add_output(dynamics.CustomOutput(self.gyro_torque, "Q1")) # simulate if t1 > 0: self.t,self.y = self.integ.integrate(t1, dt) def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0,vs), (-l,l), (-l,l), velocities=False, only_free=True)
class Rotor(object): def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos','vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.CustomOutput( lambda s: b.station_positions()[-1], label="{} tip defl".format(b))) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.CustomOutput( lambda s: dot(b.Rp, b.station_positions()[-1]), label="{} tip pos".format(b))) def simulate(self, qm0=None, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) # simulate self.t,self.y = self.integ.integrate(t1, dt) return self.t, self.y def lin(self, qm0=None, spin=10.0): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 else: qm0 = np.zeros(self.blade1._nstrain * 3) self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) linsys = linearisation.LinearisedSystem(self.system, qm0) return linsys def ani(self, vs=1): l = 40 return dynvis.anim(self.system, self.t, self.y, (0,vs), (-l,l), (-l,l))
class Rotor(object): def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) self.bearing = Hinge('bearing', [0, 0, 1]) self.offset = RigidConnection('offset', [root_length, 0, 0]) self.blade = ModalElement('blade', self.modes) self.bearing.add_leaf(self.offset) self.offset.add_leaf(self.blade) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # constant spin speed def simulate(self, qm0, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.blade.istrain] = qm0 # initial modal amplitudes self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) #acc=spin/t1) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) self.integ.add_output(dynamics.LoadOutput(self.blade.iprox)) self.integ.add_output(dynamics.LoadOutput(self.blade.iprox, local=True)) self.integ.add_output( dynamics.CustomOutput(lambda s: self.blade.station_positions()[-1], label="Tip pos")) self.integ.add_output( dynamics.CustomOutput(lambda s: self.blade.quad_stress, label="Quad stress")) # simulate self.t, self.y = self.integ.integrate(t1, dt) return self.t, self.y def lin(self, qm0, spin=10.0): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.blade.istrain] = qm0 # initial modal amplitudes self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) # constant speed linsys = linearisation.LinearisedSystem(self.system, qm0) return linsys def ani(self, vs=1): l = 40 return dynvis.anim(self.system, self.t, self.y, (0, vs), (-l, l), (-l, l), velocities=False, only_free=True)
# Options dynamics.OPT_GRAVITY = True dynamics.OPT_GEOMETRIC_STIFFNESS = False # Create model bladed_file = r'C:\Users\Rick Lupton\Dropbox\phd\Bladed\Models\OC3-Hywind_SparBuoy_NREL5MW.prj' print "Loading modes from '%s'..." % bladed_file towerdef = Tower(bladed_file) modes = towerdef.modal_rep() endmass = 100000 endinertia = 100 el1 = ModalElement('el', modes, distal=False) system1 = System(el1) el2 = ModalElement('el', modes, distal=True) body = RigidBody('body', endmass, inertia=endinertia * np.eye(3)) el2.add_leaf(body) system2 = System(el2) integ1 = Integrator(system1) integ1.add_output(el1.output_positions()) integ2 = Integrator(system2, outputs=('pos', 'vel', 'acc')) integ2.add_output(el2.output_positions()) integ2.add_output(dynamics.NodeOutput(body.iprox)) integ2.add_output(dynamics.NodeOutput(body.iprox, deriv=2)) integ2.add_output(dynamics.LoadOutput(body.iprox)) integ2.add_output(dynamics.StrainOutput(el2.imult))
class Gyroscope(object): def __init__(self, length, radius, mass, spin, endmass): self.length = length self.radius = radius self.mass = mass self.spin = spin self.endmass = endmass Jz = radius**2 / 2 Jxy = (3 * radius**2 + length**2) / 12 inertia = mass * np.diag([Jxy, Jxy, Jz]) self.bearing = Hinge('bearing', [0, 0, 1]) self.pivot = Hinge('pivot', [0, 1, 0]) self.axis = Hinge('axis', [0, 0, 1]) self.body = RigidBody('body', mass, inertia) self.offset = RigidConnection('offset', [0, 0, length / 2]) self.endbody = RigidBody('end', endmass) self.bearing.add_leaf(self.pivot) self.pivot.add_leaf(self.axis) self.axis.add_leaf(self.body) self.pivot.add_leaf(self.offset) self.offset.add_leaf(self.endbody) self.system = System(self.bearing) # Prescribed DOF accelerations self.system.prescribe(self.axis, acc=0.0) # constant rotational speed def simulate(self, xpivot=0.0, vprec=0.0, t1=10, dt=0.05): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions self.system.q[self.pivot.istrain][0] = xpivot # initial elevation self.system.qd[self.bearing.istrain][0] = vprec # initial azimuth spd self.system.qd[ self.axis.istrain][0] = self.spin # initial rotation speed self.integ = Integrator(self.system, ('pos', 'vel')) self.integ.add_output(dynamics.LoadOutput(self.axis.iprox)) self.integ.add_output(dynamics.LoadOutput(self.pivot.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) #integ.add_output(dynamics.CustomOutput( # lambda s: np.dot(self.axis.mass_vv, self.system.qdd[el.iprox+el.idist]) + \ # np.dot(el.mass_ve, self.system.qdd[el.istrain]))) # simulate if t1 > 0: self.t, self.y = self.integ.integrate(t1, dt) for i, lab in enumerate(self.integ.labels()): print "%2d %s" % (i, lab) return self.t, self.y def ani(self, vs=1): l = self.length * 1.1 return dynvis.anim(self.system, self.t, self.y, (0, vs), (-l, l), (-l, l), velocities=False)
class Turbine(object): def __init__(self, bladed_file, root_length=0, rigid=False): # Modal element using data from Bladed model print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() #self.tmodes = self.tower.modal_rep() Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0,0,self.tower.hubheight]) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) if rigid: for b in (self.blade1, self.blade2, self.blade3): self.system.prescribe(b, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_deflections()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_positions()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.NodeOutput(b.iprox, local=True, deriv=2)) @property def mass(self): """Total mass of turbine""" return self.tower.total_mass + self.modes.mass * 3 @property def inertia(self): """Total rotational inertia of turbine about base""" inertia = self.tower.total_inertia inertia[(0,1),(0,1)] = self.modes.mass * 3 * self.tower.hubheight return inertia # XXX neglecting rotor rotational inertia def set_base_motion(self, dof, w, amp): self.base_motion = dof self.base_motion_amp = amp self.system.prescribe(self.base, part=dof, vel=lambda t: -w *amp*np.sin(w*t), acc=lambda t: -w**2*amp*np.cos(w*t)) def set_initial_conditions(self, qm0=None, az0=None, rotor_speed=None): # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 if az0 is not None: self.system.q[self.bearing.istrain][0] = az0 if self.base_motion is not None: self.system.q[self.base.istrain][self.base_motion] = self.base_motion_amp if rotor_speed is not None: self.system.prescribe(self.bearing, vel=rotor_speed) def simulate(self, qm0=None, az0=0.0, rotor_speed=10.0, t1=None, dt=0.01, t0=0.0, init=False): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if t1 is None: t1 = 4*pi/rotor_speed if (rotor_speed != 0.0) else 2 if init: self.system.find_equilibrium() # simulate self.t,self.y = self.integ.integrate(t1, dt, t0) for i,lab in enumerate(self.integ.labels()): print "%2d %s" % (i,lab) return self.t, self.y def lin(self, qm0=None, az0=None, rotor_speed=None, init=False): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if init: self.system.find_equilibrium() linsys = linearisation.LinearisedSystem(self.system) return linsys def ani(self, vs=(0,1), t=None, y=None): if t is None: t = self.t if y is None: y = self.y limits = [(-10,10), (-42,42), (-5,110)] return dynvis.anim(self.system, t, y, vs, limits[vs[0]], limits[vs[1]])
import numpy as np from scipy.linalg import eig import matplotlib.pyplot as plt import dynamics from dynamics import System, ModalElement, solve_system from linearisation import LinearisedSystem, ModalRepresentation import dynvis dynamics.gravity = 0 # Modal element using data from Bladed model print "Loading modes from 'demo_a.prj'..." modes = ModalRepresentation.from_Bladed('demo_a_simplified.prj') el = ModalElement('el', modes) system = System(el) # Linearise system and find modes - should match with original print "Linearising..." linsys = LinearisedSystem(system) w, v = eig(linsys.K, linsys.M) order = np.argsort(w) w = np.sqrt(np.real(w[order])) f = w / 2 / np.pi v = v[:, order] # Check that modes come out matching what went in assert np.allclose(modes.freqs, w), "Linearised freqs should match" ventries = np.nonzero(abs(v) > 1e-2)[0] assert len(ventries) == len(w) and (ventries == np.arange(4)).all(), \ "Modes should be orthogonal"
class Turbine(object): def __init__(self, bladed_file, root_length=0, rigid=False): # Modal element using data from Bladed model print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0, 0, self.tower.hubheight]) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) if rigid: for b in (self.blade1, self.blade2, self.blade3): self.system.prescribe(b, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel', 'acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output( dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output( dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_deflections()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_positions()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.NodeOutput(b.iprox, local=True, deriv=2)) def set_base_motion(self, dof, w, amp): self.base_motion = dof self.base_motion_amp = amp self.system.prescribe(self.base, part=dof, vel=lambda t: -w * amp * np.sin(w * t), acc=lambda t: -w**2 * amp * np.cos(w * t)) def set_initial_conditions(self, qm0=None, az0=None, rotor_speed=None): # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 if az0 is not None: self.system.q[self.bearing.istrain][0] = az0 if self.base_motion is not None: self.system.q[self.base.istrain][ self.base_motion] = self.base_motion_amp if rotor_speed is not None: self.system.prescribe(self.bearing, vel=rotor_speed) def simulate(self, qm0=None, az0=0.0, rotor_speed=10.0, t1=None, dt=0.01, t0=0.0, init=False): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if t1 is None: t1 = 4 * pi / rotor_speed if (rotor_speed != 0.0) else 2 if init: self.system.find_equilibrium() # simulate t, y = self.integ.integrate(t1, dt, t0) #for i,lab in enumerate(self.integ.labels): # print "%2d %s" % (i,lab) #return self.t, self.y # Build results structure results = TurbineResults(t, y, self.modes.mode_names) return results def lin(self, qm0=None, az0=None, rotor_speed=None, init=False): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if init: self.system.find_equilibrium() # need initial amplitudes for linearisation point if qm0 is None: qm0 = self.system.q[self.blade1.istrain] linsys = linearisation.LinearisedSystem(self.system, np.tile(qm0, 3)) return linsys def ani(self, results, x=0, y=1): H = self.tower.hubheight + self.blade.radii[-1] limits = [(-H, H), (-H, H), (-5, H + 5)] return dynvis.anim(self.system, results.t, results.strains.as_matrix(), (x, y), limits[x], limits[y])
modes = ModalRepresentation.from_Bladed(path_damped+'.$pj') print "Loading modes from '%s'..." % path_undamped modes0 = ModalRepresentation.from_Bladed(path_undamped+'.$pj') # Blade loading wind_table = np.array([ [0, 1, 2, 10], # time [0, 0, 0, 0 ], # x [0, 0, 20, 20], # y [0, 0, 0, 0 ], # z ]) loading = BladeLoading(modes.x, wind_table, None) # Modal element el = ModalElement('el', modes, loading) system = System(el) el0 = ModalElement('el0', modes0, loading) system0 = System(el0) integ = Integrator(system) integ0 = Integrator(system0) integ.add_output(el.output_positions(stations=[16,32])) integ0.add_output(el0.output_positions(stations=[16,32])) #def simulate(system, t1=2.0, dt=0.005): # Load Bladed data for comparison import pybladed.data brun = pybladed.data.BladedRun(path_damped) bladed_defl = np.c_[ brun.get('blade 1 x-deflection;2'),
class Rotor(object): def __init__(self, mode_source_file, root_length=0): # Modal element using data from Bladed model print "Loading modes from '%s'..." % mode_source_file self.modes = ModalRepresentation.from_Bladed(mode_source_file) Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.bearing) # Prescribed DOF accelerations - constant rotor speed self.system.prescribe(self.bearing.istrain, vel=0.0, acc=0.0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel')) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.CustomOutput(lambda s: b.station_positions()[-1], label="{} tip defl".format(b))) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.CustomOutput(lambda s: dot(b.Rp, b.station_positions()[-1]), label="{} tip pos".format(b))) def simulate(self, qm0=None, spin=10.0, t1=1.5, dt=0.01): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) # simulate self.t, self.y = self.integ.integrate(t1, dt) return self.t, self.y def lin(self, qm0=None, spin=10.0): # reset self.system.q[:] = 0.0 self.system.qd[:] = 0.0 # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 else: qm0 = np.zeros(self.blade1._nstrain * 3) self.system.prescribe(self.bearing.istrain, vel=spin, acc=0.0) linsys = linearisation.LinearisedSystem(self.system, qm0) return linsys def ani(self, vs=1): l = 40 return dynvis.anim(self.system, self.t, self.y, (0, vs), (-l, l), (-l, l))
class FlappedBladeTurbine(object): def __init__(self, bladed_file, root_length=0): # Load modes but use a simple flapped blade print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() # Calculate equivalent blade properties I1 = self.modes.I0[0] I2 = self.modes.J0[0,0] print I1, I2 wflap = self.modes.freqs[0] bmass = self.modes.mass inertia = self.modes.inertia_tensor(np.zeros(len(self.modes.freqs))) Xc = [I1 / bmass, 0, 0] kflap = I2 * wflap**2 Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0,0,self.tower.hubheight]) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.flap1 = Hinge('flap1', [0,1,0]) self.flap2 = Hinge('flap2', [0,1,0]) self.flap3 = Hinge('flap3', [0,1,0]) self.blade1 = RigidBody('blade1', bmass, inertia, Xc) self.blade2 = RigidBody('blade2', bmass, inertia, Xc) self.blade3 = RigidBody('blade3', bmass, inertia, Xc) self.flap1.stiffness = self.flap2.stiffness = self.flap3.stiffness = kflap self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.flap1) root2.add_leaf(self.flap2) root3.add_leaf(self.flap3) self.flap1.add_leaf(self.blade1) self.flap2.add_leaf(self.blade2) self.flap3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output(dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.NodeOutput(b.iprox, local=True, deriv=2)) def set_base_motion(self, dof, w, amp): self.base_motion = dof self.base_motion_amp = amp self.system.prescribe(self.base, part=dof, vel=lambda t: -w *amp*np.sin(w*t), acc=lambda t: -w**2*amp*np.cos(w*t)) def set_initial_conditions(self, qm0=None, az0=None, rotor_speed=None): # initial conditions if qm0 is not None: # initial hinge angle self.system.q[self.flap1.istrain][0] = qm0 self.system.q[self.flap2.istrain][0] = qm0 self.system.q[self.flap3.istrain][0] = qm0 if az0 is not None: self.system.q[self.bearing.istrain][0] = az0 if self.base_motion is not None: self.system.q[self.base.istrain][self.base_motion] = self.base_motion_amp if rotor_speed is not None: self.system.prescribe(self.bearing, vel=rotor_speed) def simulate(self, qm0=None, az0=0.0, rotor_speed=10.0, t1=None, dt=0.01, t0=0.0, init=False): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if t1 is None: t1 = 4*pi/rotor_speed if (rotor_speed != 0.0) else 2 if init: self.system.find_equilibrium() # simulate t,y = self.integ.integrate(t1, dt, t0) #for i,lab in enumerate(self.integ.labels): # print "%2d %s" % (i,lab) #return self.t, self.y # Build results structure results = FlappedTurbineResults(t, y) return results def lin(self, qm0=None, az0=None, rotor_speed=None, init=False): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if init: self.system.find_equilibrium() # need initial amplitudes for linearisation point if qm0 is None: qm0 = self.system.q[self.blade1.istrain] linsys = linearisation.LinearisedSystem(self.system, np.tile(qm0, 3)) return linsys def ani(self, results, x=0, y=1): H = self.tower.hubheight + self.blade.radii[-1] limits = [(-H,H), (-H,H), (-5,H+5)] return dynvis.anim(self.system, results.t, results.strains.as_matrix(), (x, y), limits[x], limits[y])
b1 = EulerBeam('b1',blade_length, 250, 1000e6, EIy, EIz, 200e6) b2 = EulerBeam('b2',blade_length, 250, 1000e6, EIy, EIz, 200e6) b3 = EulerBeam('b3',blade_length, 250, 1000e6, EIy, EIz, 200e6) tower.damping = 0.05 foundation.add_leaf(tower) tower.add_leaf(nacelle) nacelle.add_leaf(bearing) bearing.add_leaf(hb1) bearing.add_leaf(hb2) bearing.add_leaf(hb3) hb1.add_leaf(b1) hb2.add_leaf(b2) hb3.add_leaf(b3) system = System(foundation) def thrust(xp, xd, xstrain, vp, vd, vstrain): f = zeros(NQD * 2) f[6] = -70000 return f def test1(): # Initial conditions system.qd[bearing.istrain[0]] = -10 * pi/180 # Prescribed DOFs #system.prescribe(foundation.istrain, 0.0) system.prescribe(tower.istrain, 0.0) system.prescribe(bearing.istrain, 0.0) system.prescribe(b1.istrain, 0.0)
bladed_defl = np.c_[brun.get("Nacelle fore-aft displacement"), brun.get("Nacelle nod angle")] # loading = PointLoading(blade, wind_table, None) thrust_time = [0, 1, 2, 10] thrust_force = [0, 0, 10e3, 10e3] thrust = np.c_[thrust_force, np.zeros((4, 2))].T loadfunc = scipy.interpolate.interp1d(thrust_time, thrust) # Modal element base = RigidConnection("base", rotation=rotmat_y(-np.pi / 2)) el = DistalModalElement("el", modes, distal=True, damping_freqs=modes2.freqs) # el = ModalElement('el', modes, distal=True, damping_freqs=modes2.freqs) rna = RigidBody("rna", 24000, np.diag([6400003, 6400003, 4266667]), nodal_load=loadfunc) base.add_leaf(el) el.add_leaf(rna) system = System(base) system.prescribe(el, vel=0, part=[0, 3]) integ = Integrator(system) integ.add_output(el.output_deflections()) integ.add_output(el.output_rotations()) integ.add_output(dynamics.LoadOutput(rna.iprox)) linsys = LinearisedSystem(system) def ani_xy(s, t, y): return dynvis.anim(s, t, y, (0, 1), (-5, 45), (-5, 5), velocities=False)
def __init__(self, bladed_file, root_length=0): # Load modes but use a simple flapped blade print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() # Calculate equivalent blade properties I1 = self.modes.I0[0] I2 = self.modes.J0[0,0] print I1, I2 wflap = self.modes.freqs[0] bmass = self.modes.mass inertia = self.modes.inertia_tensor(np.zeros(len(self.modes.freqs))) Xc = [I1 / bmass, 0, 0] kflap = I2 * wflap**2 Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0,0,self.tower.hubheight]) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.flap1 = Hinge('flap1', [0,1,0]) self.flap2 = Hinge('flap2', [0,1,0]) self.flap3 = Hinge('flap3', [0,1,0]) self.blade1 = RigidBody('blade1', bmass, inertia, Xc) self.blade2 = RigidBody('blade2', bmass, inertia, Xc) self.blade3 = RigidBody('blade3', bmass, inertia, Xc) self.flap1.stiffness = self.flap2.stiffness = self.flap3.stiffness = kflap self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.flap1) root2.add_leaf(self.flap2) root3.add_leaf(self.flap3) self.flap1.add_leaf(self.blade1) self.flap2.add_leaf(self.blade2) self.flap3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output(dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.NodeOutput(b.iprox, local=True, deriv=2))
class Turbine(object): def __init__(self, bladed_file, root_length=0, rigid=False): # Modal element using data from Bladed model print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() Ry = rotmat_y(-pi/2) Rhb1 = rotmat_x(0 * 2*pi/3) Rhb2 = rotmat_x(1 * 2*pi/3) Rhb3 = rotmat_x(2 * 2*pi/3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0,0,self.tower.hubheight]) self.bearing = Hinge('bearing', [1,0,0]) root1 = RigidConnection('root1', root_length*np.dot(Rhb1,[0,0,1]), dot(Rhb1,Ry)) root2 = RigidConnection('root2', root_length*np.dot(Rhb2,[0,0,1]), dot(Rhb2,Ry)) root3 = RigidConnection('root3', root_length*np.dot(Rhb3,[0,0,1]), dot(Rhb3,Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) if rigid: for b in (self.blade1, self.blade2, self.blade3): self.system.prescribe(b, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos','vel','acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output(dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output(dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_deflections()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_positions()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.NodeOutput(b.iprox, local=True, deriv=2)) def set_base_motion(self, dof, w, amp): self.base_motion = dof self.base_motion_amp = amp self.system.prescribe(self.base, part=dof, vel=lambda t: -w *amp*np.sin(w*t), acc=lambda t: -w**2*amp*np.cos(w*t)) def set_initial_conditions(self, qm0=None, az0=None, rotor_speed=None): # initial conditions if qm0 is not None: # initial modal amplitudes self.system.q[self.blade1.istrain] = qm0 self.system.q[self.blade2.istrain] = qm0 self.system.q[self.blade3.istrain] = qm0 if az0 is not None: self.system.q[self.bearing.istrain][0] = az0 if self.base_motion is not None: self.system.q[self.base.istrain][self.base_motion] = self.base_motion_amp if rotor_speed is not None: self.system.prescribe(self.bearing, vel=rotor_speed) def simulate(self, qm0=None, az0=0.0, rotor_speed=10.0, t1=None, dt=0.01, t0=0.0, init=False): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if t1 is None: t1 = 4*pi/rotor_speed if (rotor_speed != 0.0) else 2 if init: self.system.find_equilibrium() # simulate t,y = self.integ.integrate(t1, dt, t0) #for i,lab in enumerate(self.integ.labels): # print "%2d %s" % (i,lab) #return self.t, self.y # Build results structure results = TurbineResults(t, y, self.modes.mode_names) return results def lin(self, qm0=None, az0=None, rotor_speed=None, init=False): # reset self.system.q [:] = 0.0 self.system.qd[:] = 0.0 self.set_initial_conditions(qm0, az0, rotor_speed) if init: self.system.find_equilibrium() # need initial amplitudes for linearisation point if qm0 is None: qm0 = self.system.q[self.blade1.istrain] linsys = linearisation.LinearisedSystem(self.system, np.tile(qm0, 3)) return linsys def ani(self, results, x=0, y=1): H = self.tower.hubheight + self.blade.radii[-1] limits = [(-H,H), (-H,H), (-5,H+5)] return dynvis.anim(self.system, results.t, results.strains.as_matrix(), (x, y), limits[x], limits[y])
def __init__(self, bladed_file, root_length=0, rigid=False): # Modal element using data from Bladed model print "Loading modes from '%s'..." % bladed_file self.blade = Blade(bladed_file) self.tower = Tower(bladed_file) self.modes = self.blade.modal_rep() Ry = rotmat_y(-pi / 2) Rhb1 = rotmat_x(0 * 2 * pi / 3) Rhb2 = rotmat_x(1 * 2 * pi / 3) Rhb3 = rotmat_x(2 * 2 * pi / 3) self.base = FreeJoint('base') self.towerlink = RigidConnection('tower', [0, 0, self.tower.hubheight]) self.bearing = Hinge('bearing', [1, 0, 0]) root1 = RigidConnection('root1', root_length * np.dot(Rhb1, [0, 0, 1]), dot(Rhb1, Ry)) root2 = RigidConnection('root2', root_length * np.dot(Rhb2, [0, 0, 1]), dot(Rhb2, Ry)) root3 = RigidConnection('root3', root_length * np.dot(Rhb3, [0, 0, 1]), dot(Rhb3, Ry)) self.blade1 = ModalElement('blade1', self.modes) self.blade2 = ModalElement('blade2', self.modes) self.blade3 = ModalElement('blade3', self.modes) self.base.add_leaf(self.towerlink) self.towerlink.add_leaf(self.bearing) self.bearing.add_leaf(root1) self.bearing.add_leaf(root2) self.bearing.add_leaf(root3) root1.add_leaf(self.blade1) root2.add_leaf(self.blade2) root3.add_leaf(self.blade3) self.system = System(self.base) # Prescribed DOF accelerations - constant rotor speed self.base_motion = None self.base_motion_amp = 0 self.system.prescribe(self.bearing, vel=0) self.system.prescribe(self.base, vel=0) if rigid: for b in (self.blade1, self.blade2, self.blade3): self.system.prescribe(b, vel=0) # setup integrator self.integ = Integrator(self.system, ('pos', 'vel', 'acc')) self.integ.add_output(dynamics.LoadOutput(self.base.iprox)) self.integ.add_output(dynamics.LoadOutput(self.towerlink.iprox)) self.integ.add_output( dynamics.LoadOutput(self.bearing.iprox, local=True)) self.integ.add_output( dynamics.LoadOutput(self.bearing.idist[0], local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(dynamics.LoadOutput(b.iprox, local=True)) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_deflections()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output(b.output_positions()) for b in (self.blade1, self.blade2, self.blade3): self.integ.add_output( dynamics.NodeOutput(b.iprox, local=True, deriv=2))