def testBladeOuterScalar(): # scalar to blade/ scalar to scalar B1 = Blade(np.eye(2)) B2 = Blade(1, s=2) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s assert np.allclose(2, result1.s), 'value' assert result1.blade.shape == (2, 2), 'shape' result2 = bd.outer(B2, B1) print 'B2 outer B1 s: ', result2.s assert np.allclose(2, result2.s), 'value' assert result2.blade.shape == (2, 2), 'shape' result3 = bd.outer(B2, B2) print 'B2 outer B2 s: ', result3.s assert np.allclose(result3.s, 4) B1 = Blade(1, s=2) B2 = Blade(1, s=-.5) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s assert np.allclose(-1, result1.s), 'value' assert result1.blade.shape == (1, 0), 'shape'
def testBladeOuterScaleMultplicative(): # multiplicative scaling B1 = Blade(np.array([2, 0])) B2 = Blade(np.array([0, 1])) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s print 'B1 outer B2 blade: ', result1.blade assert la.det(result1.blade) > 0, la.det(result1.blade) assert result1.blade.shape == (2, 2), result1.blade.shape assert np.allclose(np.eye(2), np.dot(result1.blade.T, result1.blade)) assert np.allclose(bd.inner(result1, result1).s, -4), bd.inner(result1, result1).s result2 = bd.outer(B2, B1) print 'B2 outer B1 s: ', result2.s print 'B2 outer B1 blade: ', result2.blade assert la.det(result2.blade) < 0, la.det(result2.blade) assert result2.blade.shape == (2, 2), result2.blade.shape assert np.allclose(np.eye(2), np.dot(result2.blade.T, result2.blade)) assert np.allclose(bd.inner(result2, result2).s, -4), bd.inner(result2, result2).s # result1 == inverse(result2) assert np.allclose(bd.inner(result1, result2).s, 4), bd.inner(result1, result2).s
def testBladeInitScalar(): " Testing scalar blade " B = Blade(1) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 1) assert B.k == 0 B = Blade(1, s=2) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 2) assert B.k == 0 B = Blade(2) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 2) assert B.k == 0 B = Blade(2, s=2) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 4) assert B.k == 0 B = Blade(1, s=0) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 0) assert B.k == 0
def testBladeDualEuclidean(): # s=0 B = Blade(0) try: D = bd.dual(B) except AttributeError as err: assert err[0] == 'Not dualizable, s=0' except: assert False, err # scalar, expect a 2-blade A = Blade(2) D = bd.dual(A, n=2) revPseudo = bd.outer(bd.inverse(A), D) shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(2)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 1-blade, expect 1-blade back A = Blade(np.array([1, 0])) D = bd.dual(A) revPseudo = bd.outer(bd.inverse(A), D) shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(2)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 2-blade, expect 0-blade back A = Blade(np.eye(2)) D = bd.dual(A) revPseudo = bd.outer(bd.inverse(A), D) shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(2)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s)
def testBladeUnDualEuclidean(): # s=0 B = Blade(0) try: D = bd.undual(B) except AttributeError as err: assert err[0] == 'Not dualizable, s=0' except: assert False, err # scalar, expect a 2-blade A = Blade(2) Aprime = bd.dual(bd.undual(A, n=2), n=2) print 'A: ', A.blade, A.s print 'APrimeInv: ', bd.inverse(Aprime).blade, bd.inverse(Aprime).s shouldBeOne = bd.outer(A, bd.inverse(Aprime)) print 'shouldBeOne: ', shouldBeOne.blade, shouldBeOne.s assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 1-blade, expect 1-blade back A = Blade(np.array([1, 0])) Aprime = bd.undual(bd.dual(A, n=2), n=2) shouldBeOne = bd.inner(A, bd.inverse(Aprime)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 2-blade, expect 0-blade back A = Blade(np.eye(2)) Aprime = bd.undual(bd.dual(A, n=2), n=2) print 'A: ', A.blade, A.s print 'APrimeInv: ', bd.inverse(Aprime).blade, bd.inverse(Aprime).s shouldBeOne = bd.inner(A, bd.inverse(Aprime)) print 'shouldBeOne: ', shouldBeOne.blade, shouldBeOne.s assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s)
def testBladeCopy(): B1 = Blade(np.eye(2)) B2 = bd.copy(B1) assert np.allclose(B1.blade, B2.blade) assert np.allclose(B1.s, B2.s) B1.blade[1, 1] = 2 assert not np.allclose(B1.blade, B2.blade)
def testBladeEqualityNotSameSubspace(): # 45-degree rotation in plane x-y A = Blade(np.array([[1, 0], [0, 1], [1, 0]])) B = Blade(np.array([[1, 1], [-1, 1], [0, 0]])) print 'join dim: ', bd.join(A, B).k print 'equal: ', bd.equality(A, B) assert not bd.subSpaceEquality(A, B) assert not bd.equality(A, B)
def testBladeLeftContractOrthoProj(): # orthogonal projection A = Blade(np.array([1, 1, 0])) B = Blade(np.array([[2, 0], [0, 0], [0, 2]])) Aproj = bd.leftContract(bd.leftContract(A, B), bd.inverse(B)) assert (np.allclose(Aproj.blade, np.array([[1], [0], [0]])) and \ np.allclose(Aproj.s * la.norm(np.array([1, 1, 0])), A.s)) or \ (np.allclose(-Aproj.blade, np.array([[-1], [0], [0]])) and \ np.allclose(-Aproj.s * la.norm(np.array([1, 1, 0])), A.s))
def testBladeInnerCommutativity(): # commutative for i in range(1, 5): B1 = Blade(np.eye(i, i)) B2 = Blade(-np.eye(i, i)) firstOrdering = bd.inner(B1, B2) secondOrdering = bd.inner(B2, B1) assert np.allclose(firstOrdering.s, secondOrdering.s), (firstOrdering.s, secondOrdering.s)
def testBladeLeftContractBasic(): # basic usage A = Blade(np.array([1, 0])) B = Blade(np.array([[1, 0], [0, 1]])) lc = bd.leftContract(A, B) assert np.allclose(lc.s, 1.0), (lc.blade, lc.s) assert (np.allclose(lc.blade, np.array([[0], [1]])) and \ np.allclose(lc.s, 1)) or \ (np.allclose(lc.blade, np.array([[0], [-1]])) and \ np.allclose(lc.s, -1)), (lc.blade, lc.s)
def testBladeInitQrScaling(): # testing qr scaling A = np.array([[2, 0], [0, 1], [0, 0]]) B = Blade(A) assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(2)) assert np.allclose(B.s, 2.0) B = Blade(A, s=2.0) assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(2)) assert np.allclose(B.s, 4.0)
def testBladeJoinBasic(): # two bases A = Blade(np.array([1, 0, 0])) B = Blade(np.array([0, 1, 0])) J = bd.join(A, B) assert J.blade.shape == (3, 2) assert J.s == 1 # add a third C = Blade(np.array([0, 0, 1])) J2 = bd.join(J, C) assert J2.blade.shape == (3, 3) assert J2.s == 1 # linearly dependent A = Blade(np.array([1, 0, 0])) B = Blade(np.array([1, 0, 0])) J = bd.join(A, B) assert J.blade.shape == (3, 1) assert J.s == 1 # linearly dependent A = Blade(np.array([1, 0, 0])) B = Blade(np.array([0, 1, 0])) J = bd.join(A, B) C = Blade(np.array([1, 1, 0])) D = Blade(np.array([1, -1, 2])) J2 = bd.join(C, D) J3 = bd.join(J, J2) assert J3.blade.shape == (3, 3) assert J3.s == 1
def testBladeInitNull(): " Testing null blade " B = Blade() assert B.blade.shape == (1, 0) assert np.allclose(B.s, 0) assert B.k == 0 B = Blade(s=0) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 0) assert B.k == 0
def testBladeInitQr(): " Testing qr " # testing qr A = np.array([[1, 0], [0, 1], [0, 0]]) B = Blade(A) print 'B.blade: ', B.blade assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(2)) assert np.allclose(B.s, 1) B = Blade(A, s=2.0) assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(2)) assert np.allclose(B.s, 2.0)
def testBladeInvolutio(): # sign B = Blade(1) assert np.allclose(B.s, (-1)**B.k * bd.involution(B).s) assert np.allclose(B.s, (-1)**B.k * bd.involutionScaling(B)) assert B.k == 0 for i in range(1, 5): B = Blade(np.eye(i)) assert np.allclose(B.s, (-1)**B.k * bd.involution(B).s) assert np.allclose(B.s, (-1)**B.k * bd.involutionScaling(B)) assert B.k == i
def testBladeEqualityAndSubEqualSelf(): # self equal A = Blade(np.array([[1, 2], [2, 3], [0, 0]])) B = Blade(np.array([[1, 2], [2, 3], [0, 0]])) assert bd.subSpaceEquality(A, B) assert bd.equality(A, B) # self equal A = Blade(np.array([[1, 2], [2, 3], [0, 0]])) B = Blade(2 * np.array([[1, 2], [2, 3], [0, 0]]), s=.25) assert bd.subSpaceEquality(A, B) assert bd.equality(A, B)
def testBladeEqualityRotation(): # 90-degree rotation in plane x-y A = Blade(np.array([[1, 0], [0, 1], [0, 0]])) B = Blade(np.array([[0, 1], [-1, 0], [0, 0]])) assert bd.subSpaceEquality(A, B) assert bd.equality(A, B) # with scaling now A = Blade(np.array([[1, 0], [0, 1], [0, 0]])) B = Blade(np.array([[0, 1], [-1, 0], [0, 0]]), s=2) assert bd.subSpaceEquality(A, B) assert not bd.equality(A, B)
def testBladeOuterSameSubspace(): B1 = Blade(np.eye(2)) B2 = Blade(np.eye(2)[:, 0]) result = bd.outer(B1, B2) print 'B1 outer B2: ', result.s assert np.allclose(0, result.s) B1 = Blade(np.eye(2)) B2 = Blade(np.eye(2)) result = bd.outer(B1, B2) print 'B1 outer B2: ', result.s assert np.allclose(0, result.s)
def testBladeReverse(): # sign B = Blade(1) assert np.allclose(B.s, (-1)**(B.k * (B.k - 1) / 2) * bd.reverse(B).s) assert np.allclose(B.s, (-1)**(B.k * (B.k - 1) / 2) * bd.reverseScaling(B)) assert B.k == 0 for i in range(1, 5): B = Blade(np.eye(i)) assert np.allclose(B.s, (-1)**(B.k * (B.k - 1) / 2) * bd.reverse(B).s) assert np.allclose(B.s, (-1)**(B.k * (B.k - 1) / 2) * bd.reverseScaling(B)) assert B.k == i
def testBladeInnerScale(): # scale A = np.array([[2, 0], [0, 1]]) print 'A.T A : ', np.dot(A.T, A) B = Blade(A) print 'B inner B: ', bd.inner(B, B).s assert np.allclose(-4, bd.inner(B, B).s) A = np.array([[-2, 0], [0, 1]]) print 'A.T A : ', np.dot(A.T, A) B = Blade(A) print 'B inner B: ', bd.inner(B, B).s assert np.allclose(-4, bd.inner(B, B).s)
def testBladeInitOneIndexVector(): # testing one-index (row-ish) vector c = np.array([2, 0, 0]) B = Blade(c) assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(1)) assert np.allclose(B.s, 2.0) assert B.k == 1
def testBladeInitOrthonormal(): " Testing orthonormal " # testing orthonormal A = np.array([[1, 0], [0, 1], [0, 0]]) B = Blade(A, orthonormal=True) assert np.allclose(B.blade, A) assert np.allclose(B.s, 1.0) B = Blade(A, orthonormal=True, s=2.0) assert np.allclose(B.blade, A) assert np.allclose(B.s, 2.0) B = Blade(A, orthonormal=True, s=0.0) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 0) assert B.k == 0
def testBladeInitColumnVector(): # testing column vector c = np.array([[2], [0], [0]]) B = Blade(c) print 's: ', B.s print 'blade: ', B.blade assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(1)) assert np.allclose(B.s, 2.0) assert B.k == 1 B = Blade(c, s=2.0) print 's: ', B.s print 'blade: ', B.blade assert np.allclose(np.dot(B.blade.T, B.blade), np.eye(1)) assert np.allclose(B.s, 4.0) assert B.k == 1
def start(self): logger.info("Starting Tryptofan...") self.opc_client = opc.Client('localhost:7890') apps = [ (r'/ws', handlers.ControllerHandler, { 'tryptofan': self }), (r'/(.*)', handlers.IndexStaticFileHandler, { 'path': settings.WEBROOT }), ] application = Application(apps) self.http_server = HTTPServer(application) self.updater = PeriodicCallback(self.update, 1000 / settings.FRAMERATE) for i in range(settings.BLADES): blade = Blade(self.pixels, i * settings.BLADE_PIXELS, self.state[i][0], self.state[i][1], self.state[i][2]) self.blades.append(blade) self.http_server.listen(settings.HTTP_PORT) self.updater.start() IOLoop.instance().start()
def testBladeLinearTransformScale(): # scale B = Blade(np.eye(2), s=2) T = np.array([[2, 0], [0, .75]]) result = bd.applyLinearTransform(T, B) assert result.k == 2, (result.blade, result.s) assert result.s == 3, (result.blade, result.s)
def testBladeLinearTransformUnit(): # unit transform B = Blade(np.eye(2), s=2) T = np.array([[1, 0], [0, 1]]) result = bd.applyLinearTransform(T, B) assert result.k == 2, (result.blade, result.s) assert result.s == 2, (result.blade, result.s)
def testBladeInnerSign(): # sign for i in range(1, 5): B = Blade(np.eye(i, i)) print 'B inner B: ', bd.inner(B, B).s assert np.allclose((-1)**((i * (i - 1)) / 2), bd.inner(B, B).s), 'value' assert bd.inner(B, B).blade.shape == (1, 0), 'shape'
def testBladeJoinScalar(): # scalars A = Blade(1, s=2) B = Blade(1, s=4) J = bd.join(A, B) assert J.blade.shape == (1, 0) assert J.s == 1 # scalar/blade B = Blade(np.array([1, 0, 1])) J = bd.join(A, B) assert J.blade.shape == (3, 1) assert J.s == 1 B = Blade(np.array([1, 0, 1])) J = bd.join(B, A) assert J.blade.shape == (3, 1) assert J.s == 1
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 testBladeInitRankDeficient(): # testing rank deficient A = np.array([[1, 0], [1, 0], [0, 0]]) B = Blade(A) print B.blade.shape assert B.blade.shape == (1, 0) assert np.allclose(B.s, 0) assert B.k == 0 B = Blade(A, s=2.0) assert B.blade.shape == (1, 0) assert np.allclose(B.s, 0) assert B.k == 0 # too many columns C = np.array([[1, 0, 1], [0, 1, 0]]) B2 = Blade(C) assert B2.blade.shape == (1, 0) assert np.allclose(B2.s, 0) assert B2.k == 0
def testBladeDualEuclideanRegression(): # regression test -- tests a bunch of functions and they all have to work # for many input dimensions for this to succeed fully for n in range(1, 10): for k in range(0, n + 1): if k == 0: blade = Blade(1, s=float(rn.rand(1)[0])) else: blade = Blade(rn.randn(n, k)) print 'blade n, k: ', blade.n, blade.k if np.allclose(blade.s, 0): # just skip this one for now... continue # measure 0 event but could happen D = bd.dual(blade, n=n) print 'D n, k: ', D.n, D.k revPseudo = bd.outer(bd.inverse(blade), D) print 'n, k: ', n, k print 'revPseudo blade, s: ', revPseudo.blade, revPseudo.s shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(n)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s)
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 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 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]])
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): # 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 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])
import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import dynamics from dynamics import System, ModalElement, Integrator, RigidConnection, rotmat_y from blade import Blade from loading import BladeLoading import dynvis dynamics.OPT_GRAVITY = False bladed_path = '/bladed/blade_nrel/parked' # Modal element using data from Bladed model print "Loading blade from '%s'..." % bladed_path blade = Blade(bladed_path+'.$pj') modes = blade.modal_rep() # Blade loading wind_table = np.array([ [0, 1, 2, 10], # time [0, 0, 20, 20], # x [0, 0, 0, 0 ], # y [0, 0, 0, 0 ], # z ]) loading = BladeLoading(blade, wind_table, None) # Modal element base = RigidConnection('base', rotation=rotmat_y(-np.pi/2)) el = ModalElement('el', modes, loading) base.add_leaf(el)