示例#1
0
    def test_imitating_lift_coefficient(self):
        # Try to set lift coefficient so that thrust force is equal to
        # expected value from momentum theory. This should mean the
        # calculation is already converged.

        # Choose some values
        U = 5.4     # wind speed
        w = 1.2     # rotor speed
        r = 15.3    # radius
        a = 0.14    # induction factor
        Nb = 3      # number of blades
        c = 1.9     # chord

        def lift_drag(alpha):
            # Thrust should be 2 rho A U^2 a (1-a)`
            #   for annulus, A = 2 pi r  dr
            # If no drag, then
            #   thrust on blade = 0.5 rho c (U(1-a)/sin(phi))^2 CL dr cos(phi)
            # So CL = (8 pi r a sin^2 phi) / ((1-a) Nb c cos(phi))
            CL = 8*pi*r * a * sin(alpha)**2 / ((1-a) * Nb * c * cos(alpha))
            return [CL[0], 0]

        LSR = w * r / U
        solidity = Nb * c / (2*pi*r)
        factors = np.array([[a, 0]])

        Wnorm, phi = inflow(LSR, factors)
        cphi, sphi = np.cos(phi[0]), np.sin(phi[0])
        A = array([[cphi, sphi], [-sphi, cphi]])
        force_coeffs = np.array([np.dot(A, lift_drag(phi))])
        factors = iterate_induction_factors(LSR, force_coeffs,
                                            solidity, 0, factors)
        assert_aae(a, factors[0, 0])
        assert np.all(factors[:, 1] > 0)
示例#2
0
    def test_solve_reactions(self):
        # Check it calls the Element method in the right order: down
        # the tree from leaves to base. It must also reset reactions.
        s = System()
        c0 = RigidConnection('c0')
        c1 = RigidConnection('c1')
        c2 = RigidConnection('c2')
        b1 = RigidBody('b1', 1)
        b2 = RigidBody('b2', 1)
        s.add_leaf(c0)
        c0.add_leaf(c1)
        c0.add_leaf(c2)
        c1.add_leaf(b1)
        c2.add_leaf(b2)
        s.setup()

        # Check elements' iter_reactions() are called
        def mock_iter_reactions(element):
            calls.append(element)
        calls = []
        import types
        for el in s.elements.values():
            el.iter_reactions = types.MethodType(mock_iter_reactions, el)

        # Test
        s.joint_reactions[:] = 3
        s.solve_reactions()
        self.assertEqual(calls, [b2, c2, b1, c1, c0])
        assert_aae(s.joint_reactions, 0)
示例#3
0
    def test_imitating_lift_coefficient(self):
        # Try to set lift coefficient so that thrust force is equal to
        # expected value from momentum theory. This should mean the
        # calculation is already converged.

        # Choose some values
        U = 5.4     # wind speed
        w = 1.2     # rotor speed
        r = 15.3    # radius
        a = 0.14    # induction factor
        Nb = 3      # number of blades
        c = 1.9     # chord

        def lift_drag(alpha):
            # Thrust should be 2 rho A U^2 a (1-a)`
            #   for annulus, A = 2 pi r  dr
            # If no drag, then
            #   thrust on blade = 0.5 rho c (U(1-a)/sin(phi))^2 CL dr cos(phi)
            # So CL = (8 pi r a sin^2 phi) / ((1-a) Nb c cos(phi))
            CL = 8*pi*r * a * sin(alpha)**2 / ((1-a) * Nb * c * cos(alpha))
            return [CL[0], 0]

        LSR = w * r / U
        solidity = Nb * c / (2*pi*r)
        factors = np.array([[a, 0]])

        Wnorm, phi = inflow(LSR, factors)
        cphi, sphi = np.cos(phi[0]), np.sin(phi[0])
        A = array([[cphi, sphi], [-sphi, cphi]])
        force_coeffs = np.array([np.dot(A, lift_drag(phi))])
        factors = iterate_induction_factors(LSR, force_coeffs,
                                            solidity, 0, factors)
        assert_aae(a, factors[0, 0])
        assert np.all(factors[:, 1] > 0)
示例#4
0
 def test_forces_with_one_annulus(self):
     args = (12.2, 12*pi/30, 0)
     factors = self.model.solve(*args)
     all_forces = self.model.forces(*args, rho=1.225, factors=factors)
     one_forces = self.model.forces(*args, rho=1.225, factors=factors[2:3],
                                    annuli=slice(2, 3))
     assert_aae(one_forces, all_forces[2:3, :])
示例#5
0
    def test_prescribe_free(self):
        s = System()
        j = FreeJoint('joint')
        s.add_leaf(j)
        s.setup()
        s.time = 3.54

        # Initially all 6 joint motions are free
        self.assertEqual(len(s.q.dofs), 6)

        # Prescribing joint to be fixed results in no dofs
        s.prescribe(j)
        self.assertEqual(len(s.q.dofs), 0)

        # Freeing joint results in 6 dofs again
        s.free(j)
        self.assertEqual(len(s.q.dofs), 6)

        # Prescribing 2 of joint motions leaves 4 dofs
        s.prescribe(j, lambda t: t, [0, 2])
        self.assertEqual(len(s.q.dofs), 4)

        # Prescribing another joint motions leaves 3 dofs
        s.prescribe(j, 2.0, part=3)
        self.assertEqual(len(s.q.dofs), 3)

        # Check accelerations are applied to qdd
        assert_aae(s.qdd[j.istrain], 0)
        s.apply_prescribed_accelerations()
        assert_aae(s.qdd[j.istrain], [3.54, 0, 3.54, 2.0, 0, 0])

        # Freeing joint results in 6 dofs again
        s.free(j)
        self.assertEqual(len(s.q.dofs), 6)
示例#6
0
 def test_lift_drag_one_annulus(self):
     alpha = np.random.rand(len(self.model.radii)) * pi
     all_lift_drag = self.model.lift_drag(alpha)
     one_lift_drag = self.model.lift_drag(alpha[2:3], annuli=slice(2, 3))
     another_lift_drag = self.model.lift_drag(alpha[2:3], annuli=[2])
     self.assertIsInstance(one_lift_drag, np.ndarray)
     assert_aae(one_lift_drag, all_lift_drag[2:3, :])
     assert_aae(another_lift_drag, all_lift_drag[2:3, :])
示例#7
0
 def test_inflow_derivatives_with_one_annulus(self):
     args = (12.2, 12*pi/30, 0)
     factors = self.model.solve(*args)
     all_derivs = self.model.inflow_derivatives(*args, factors=factors*1.1)
     one_derivs = self.model.inflow_derivatives(*args,
                                                factors=factors[2:3]*1.1,
                                                annuli=slice(2, 3))
     assert_aae(one_derivs, all_derivs[2:3, :])
示例#8
0
 def test_lift_drag_one_annulus(self):
     alpha = np.random.rand(len(self.model.radii)) * pi
     all_lift_drag = self.model.lift_drag(alpha)
     one_lift_drag = self.model.lift_drag(alpha[2:3], annuli=slice(2, 3))
     another_lift_drag = self.model.lift_drag(alpha[2:3], annuli=[2])
     self.assertIsInstance(one_lift_drag, np.ndarray)
     assert_aae(one_lift_drag, all_lift_drag[2:3, :])
     assert_aae(another_lift_drag, all_lift_drag[2:3, :])
示例#9
0
def rotate(lon0, lat0, x, y, z):
    x2 = cos(lat0)*cos(lon0)*x - cos(lat0)*sin(lon0)*y + sin(lat0)*z
    y2 = sin(lon0)*x + cos(lon0)*y
    z2 = -sin(lat0)*cos(lon0)*x + sin(lat0)*sin(lon0)*y + cos(lat0)*z

    x3, y3, z3 = rotate_z(lon0, x, y, z)
    x4, y4, z4 = rotate_y(lat0, x3, y3, z3)

    assert_aae([x2,y2,z2], [x4,y4,z4], 15)

    return (x2,y2,z2)
    def test_distal_node_position_with_zero_strain(self):
        NTESTS = 5
        for i in range(NTESTS):
            el = _make_random_element(self.rdm)
            set_random_state(el, self.rdm, 1)
            el.xstrain[:] = 0
            el.calc_distal_pos()

            last_node_x0 = [el._params['length'], 0, 0]
            assert_aae(el.rd, el.rp + dot(el.Rp, last_node_x0))
            assert_aae(el.Rd, el.Rp)
    def test_distal_node_position_with_zero_strain(self):
        NTESTS = 5
        for i in range(NTESTS):
            el = _make_random_element(self.rdm)
            set_random_state(el, self.rdm, 1)
            el.xstrain[:] = 0
            el.calc_distal_pos()

            last_node_x0 = [el._params['length'], 0, 0]
            assert_aae(el.rd, el.rp + dot(el.Rp, last_node_x0))
            assert_aae(el.Rd, el.Rp)
示例#12
0
    def test_solve_wake_is_same_as_solve_with_extra_factors(self):
        args = (12.2, 12*pi/30, 0)
        wake = self.model.solve_wake(*args)
        extra_velocities = wake * 0.43
        extra_velocity_factors = extra_velocities / args[0]

        factors = self.model.solve(
            *args, extra_velocity_factors=extra_velocity_factors)
        wake = self.model.solve_wake(*args, extra_velocities=extra_velocities)

        assert_aae(factors[:, 0], wake[:, 0] / args[0])
        assert_aae(factors[:, 1], wake[:, 1] / args[1] / self.model.radii)
示例#13
0
    def test_solve_wake_is_same_as_solve_with_extra_factors(self):
        args = (12.2, 12 * pi / 30, 0)
        wake = self.model.solve_wake(*args)
        extra_velocities = wake * 0.43
        extra_velocity_factors = extra_velocities / args[0]

        factors = self.model.solve(
            *args, extra_velocity_factors=extra_velocity_factors)
        wake = self.model.solve_wake(*args, extra_velocities=extra_velocities)

        assert_aae(factors[:, 0], wake[:, 0] / args[0])
        assert_aae(factors[:, 1], wake[:, 1] / args[1] / self.model.radii)
示例#14
0
def test_point_equal():
    p1 = Point(0,0.001234567890123456786)
    p2 = Point(0,0.001234567890123456987)

    eq = p1.equals(p2)
    ok_(eq==False, eq) 

    aeq = p1.almost_equals(p2,18)
    ok_(aeq==True, aeq) 

    assert_aae(p1.coords[:][0], p2.coords[:][0],18)

    assert_ape(p1.coords[:][0][1], p2.coords[:][0][1],16)
示例#15
0
    def test_inertia_when_offset_axially(self):
        density = 230.4
        length = 20.0
        offset = 5.0
        element = _mock_rigid_uniform_beam(density, length)
        conn = RigidConnection('offset', offset=[offset, 0, 0])
        joint = FreeJoint('joint')

        system = System()
        system.add_leaf(joint)
        joint.add_leaf(conn)
        conn.add_leaf(element)
        system.setup()

        # Calculate reduced system to get rigid body matrices
        rsys = ReducedSystem(system)

        # Expected values: rod along x axis
        m = density * length
        Iy = m * (length**2 / 12 + (length/2 + offset)**2)
        expected_mass = m * eye(3)
        expected_inertia = diag([0, Iy, Iy])
        expected_offdiag = zeros((3, 3))

        # Y accel -> positive moment about Z
        # Z accel -> negative moment about Y
        expected_offdiag[2, 1] = +m * (length/2 + offset)
        expected_offdiag[1, 2] = -m * (length/2 + offset)

        assert_aae(rsys.M[:3, :3], expected_mass)
        assert_aae(rsys.M[3:, 3:], expected_inertia)
        assert_aae(rsys.M[3:, :3], expected_offdiag)
        assert_aae(rsys.M[:3, 3:], expected_offdiag.T)
示例#16
0
    def test_simple_prescribed_integration(self):
        s = System()
        h = Hinge('hinge', [0, 1, 0])
        s.add_leaf(h)
        s.setup()

        s.prescribe(h)
        w = h.vstrain[0] = 0.97  # rad/s

        integ = Integrator(s)
        t, y = integ.integrate(9.0, 0.1)

        # Check time vector and shape of result
        assert_array_equal(t, np.arange(0, 9.0, 0.1))
        self.assertEqual(len(y), 1)
        self.assertEqual(y[0].shape, (len(t), 1))

        # Result should be y = wt, but wrapped to [0, 2pi)
        assert_aae(y[0][:, 0], (w * t) % (2 * np.pi))

        # Check asking for velocity and acceleration works
        h.xstrain[0] = s.time = 0.0  # reset
        integ = Integrator(s, ('pos', 'vel', 'acc'))
        t, y = integ.integrate(1.0, 0.1)
        assert_array_equal(t, np.arange(0, 1.0, 0.1))
        self.assertEqual(len(y), 3)
        for yy in y:
            self.assertEqual(yy.shape, (len(t), 1))
        assert_aae(y[0][:, 0], w * t)
        assert_aae(y[1][:, 0], w)
        assert_aae(y[2][:, 0], 0)
示例#17
0
    def test_nonzero_prescribed_acceleration(self):
        # Test reduction where a prescribed acceleration is non-zero:
        # two sliders in series, with a mass on the end. If the second
        # slider's acceleration is prescribed, the first slider's DOF
        # sees an inertial force corresponding to the acceleration of
        # the mass.
        mass = 36.2
        s = System()
        s1 = PrismaticJoint('slider1', [1, 0, 0])
        s2 = PrismaticJoint('slider2', [1, 0, 0])
        b = RigidBody('body', mass)
        s.add_leaf(s1)
        s1.add_leaf(s2)
        s2.add_leaf(b)
        s.setup()

        s.prescribe(s2, acc=0)

        # With hinge angle = 0, no generalised inertial force
        rsys = ReducedSystem(s)
        assert_aae(rsys.M, mass)
        assert_aae(rsys.Q, 0)

        # With hinge angle = 90deg, do see generalised inertial force
        s.prescribe(s2, acc=2.3)
        rsys = ReducedSystem(s)
        assert_aae(rsys.M, mass)
        assert_aae(rsys.Q, -mass * 2.3)
示例#18
0
    def test_nonzero_prescribed_acceleration(self):
        # Test reduction where a prescribed acceleration is non-zero:
        # two sliders in series, with a mass on the end. If the second
        # slider's acceleration is prescribed, the first slider's DOF
        # sees an inertial force corresponding to the acceleration of
        # the mass.
        mass = 36.2
        s = System()
        s1 = PrismaticJoint('slider1', [1, 0, 0])
        s2 = PrismaticJoint('slider2', [1, 0, 0])
        b = RigidBody('body', mass)
        s.add_leaf(s1)
        s1.add_leaf(s2)
        s2.add_leaf(b)
        s.setup()

        s.prescribe(s2, acc=0)

        # With hinge angle = 0, no generalised inertial force
        rsys = ReducedSystem(s)
        assert_aae(rsys.M, mass)
        assert_aae(rsys.Q, 0)

        # With hinge angle = 90deg, do see generalised inertial force
        s.prescribe(s2, acc=2.3)
        rsys = ReducedSystem(s)
        assert_aae(rsys.M, mass)
        assert_aae(rsys.Q, -mass * 2.3)
示例#19
0
    def test_reaction_on_hinged_beam(self):
        """Reaction force should balance applied force"""
        # Applied force and moment (+ve in +Z and +Y)
        Fa = -self.force * self.length
        Ma = -Fa * self.length / 2

        # Acceleration
        inertia = self.density * (self.length ** 3) / 3
        ang_acc = Ma / inertia
        assert_aae(self.hinge.astrain[0], ang_acc)

        # Inertial d'Alembert force and moment
        Mi = -Ma  # moments balance initially
        Fi = self.density * self.length**2 * ang_acc / 2

        # Check equilibrium. No applied forces on hinge, so both nodes
        # should be the same.
        assert_aae(self.system.joint_reactions['node-0'],
                   [0, 0, -(Fa + Fi), 0, -(Ma + Mi), 0])
        assert_aae(self.system.joint_reactions['ground'],
                   self.system.joint_reactions['node-0'])

        # The base of the beam should have zero linear acceleration
        # but should have an angular acceleration:
        assert_aae(self.beam.ap, [0, 0, 0, 0, ang_acc, 0])
    def test_distal_node_position(self):
        NTESTS = 5
        for i in range(NTESTS):
            el = _make_random_element(self.rdm)
            set_random_state(el, self.rdm, 1)

            last_node_x0 = [el._params['length'], 0, 0]
            Xd = dot(el.shapes[-6:], el.xstrain)
            last_node_defl = Xd[0:3]
            last_node_rotn = Xd[3:6]

            el.calc_distal_pos()
            assert_aae(el.rd,
                       el.rp + dot(el.Rp, last_node_x0 + last_node_defl))
            assert_aae(el.Rd, dot(el.Rp, np.eye(3) + skewmat(last_node_rotn)))
    def test_distal_node_position(self):
        NTESTS = 5
        for i in range(NTESTS):
            el = _make_random_element(self.rdm)
            set_random_state(el, self.rdm, 1)

            last_node_x0 = [el._params['length'], 0, 0]
            Xd = dot(el.shapes[-6:], el.xstrain)
            last_node_defl = Xd[0:3]
            last_node_rotn = Xd[3:6]

            el.calc_distal_pos()
            assert_aae(el.rd,
                       el.rp + dot(el.Rp, last_node_x0 + last_node_defl))
            assert_aae(el.Rd,
                       dot(el.Rp, np.eye(3) + skewmat(last_node_rotn)))
示例#22
0
    def test_first_mode_frequency(self):
        # From Reddy1993, p. 160
        x = np.linspace(0, 1, 16)

        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        fe = BeamFE(x, density=1, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        fe.set_dofs([False, False, True, False, True, False])
        element = ModalElementFromFE('elem', fe)

        Mmodal = element.mass_ee
        Kmodal = element.K
        w = np.sqrt(np.diag(Kmodal) / np.diag(Mmodal))
        assert_aae(w[0], 3.5160, decimal=4)
    def test_first_mode_frequency(self):
        # From Reddy1993, p. 160
        x = np.linspace(0, 1, 16)

        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        fe = BeamFE(x, density=1, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        fe.set_dofs([False, False, True, False, True, False])
        element = ModalElementFromFE('elem', fe)

        Mmodal = element.mass_ee
        Kmodal = element.K
        w = np.sqrt(np.diag(Kmodal) / np.diag(Mmodal))
        assert_aae(w[0], 3.5160, decimal=4)
示例#24
0
    def test_coordinate_frames(self):
        """Beam loading is in local frame, while reaction forces are
        global. So by rotating the beam, the reaction forces should
        change.
        """
        self.hinge.xstrain[0] = pi / 2
        self.recalc()

        # Applied force and moment
        Fx = -self.force * self.length   # in -X direction
        My = -Fx * self.length / 2       # in +Y direction

        # Check equilibrium. No applied forces on hinge, so both nodes
        # should be the same.
        assert_aae(self.system.joint_reactions['node-0'],
                   [-Fx, 0, 0, 0, -My, 0])
        assert_aae(self.system.joint_reactions['ground'],
                   self.system.joint_reactions['node-0'])
示例#25
0
 def test_rotations(self):
     assert_aae(rotations(('z', pi / 2)),
                [[0, -1, 0], [1, 0, 0], [0, 0, 1]])
     # Work these two examples out by hand: apply the rotations in
     # turn about the updated axes, and see where the body axes end
     # up pointing.
     assert_aae(rotations(('z', pi / 2), ('x', pi / 2)),
                [[0, 0, 1], [1, 0, 0], [0, 1, 0]])
     assert_aae(rotations(('z', pi / 2), ('x', pi / 2), ('z', pi / 2)),
                [[0, 0, 1], [0, -1, 0], [1, 0, 0]])
     assert_aae(rotations(('x', pi / 2), ('z', pi / 2)),
                [[0, -1, 0], [0, 0, -1], [1, 0, 0]])
示例#26
0
    def test_callback(self):
        s = System()
        s.setup()

        # Exponential decay: qd = -A q
        def callback(system, ti, q_struct, q_other):
            self.assertIs(system, s)
            self.assertEqual(len(q_other), 1)
            return -q_other

        integ = Integrator(s)
        t, y = integ.integrate(9.0, 0.1, extra_states=np.ones(1),
                               callback=callback)

        # Check time vector and shape of result
        assert_array_equal(t, np.arange(0, 9.0, 0.1))
        self.assertEqual(len(y), 1)
        self.assertEqual(y[0].shape, (len(t), 1))
        assert_aae(y[0][:, 0], np.exp(-t))
示例#27
0
    def test_assemble(self):
        # Test system:
        #
        #                   /-- m2
        #  m1 -----conn----|
        #                   \-- m3
        s = System()
        m1 = RigidBody('m1', 1.3)
        m2 = RigidBody('m2', 3.4)
        m3 = RigidBody('m3', 7.5)
        conn = RigidConnection('conn')
        s.add_leaf(conn)
        s.add_leaf(m1)
        conn.add_leaf(m2)
        conn.add_leaf(m3)
        s.setup()

        # Check starting mass matrices of elements are as expected
        assert_aae(np.diag(m1.mass_vv[:3, :3]), 1.3)
        assert_aae(np.diag(m2.mass_vv[:3, :3]), 3.4)
        assert_aae(np.diag(m3.mass_vv[:3, :3]), 7.5)

        # Initially make system matrix empty for testing
        s.lhs[:, :] = 0
        assert_aae(s.lhs, 0)

        # After assembly, the mass matrices are put in the correct places:
        #   0:6  -> m1 node
        #   6:12 -> conn constraints
        #  12:18 -> m2 node
        #  12:18 -> m3 node
        s.assemble()
        M = s.lhs.copy()
        # Subtract expected mass
        M[0:6, 0:6] -= m1.mass_vv
        M[12:18, 12:18] -= m2.mass_vv + m3.mass_vv
        # Subtract expected constraints
        M[0:6, 6:12] -= conn.F_vp
        M[6:12, 0:6] -= conn.F_vp
        M[12:18, 6:12] -= conn.F_vd
        M[6:12, 12:18] -= conn.F_vd
        assert_aae(M, 0)
    def test_static_deflection(self):
        x = array([0.0, 4.0, 10.0])
        EI = 144.0
        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        fe = BeamFE(x, density=10, EA=0, EIy=EI, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        fe.set_dofs([False, False, True, False, True, False])
        element = ModalElementFromFE('elem', fe)

        # Distributed load, linearly interpolated
        load = np.zeros((3, 3))
        load[-1, 2] = -100        # Load in z direction at tip
        element.apply_distributed_loading(load)
        defl = -element.applied_stress / np.diag(element.K)

        # Check against directly calculating static deflection from FE
        Q = fe.distribute_load(interleave(load, 6))
        defl_fe, reactions_fe = fe.static_deflection(Q)
        assert_aae(dot(element.shapes, defl), defl_fe, decimal=2)
示例#29
0
    def test_static_deflection(self):
        x = array([0.0, 4.0, 10.0])
        EI = 144.0
        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        fe = BeamFE(x, density=10, EA=0, EIy=EI, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        fe.set_dofs([False, False, True, False, True, False])
        element = ModalElementFromFE('elem', fe)

        # Distributed load, linearly interpolated
        load = np.zeros((3, 3))
        load[-1, 2] = -100  # Load in z direction at tip
        element.apply_distributed_loading(load)
        defl = -element.applied_stress / np.diag(element.K)

        # Check against directly calculating static deflection from FE
        Q = fe.distribute_load(interleave(load, 6))
        defl_fe, reactions_fe = fe.static_deflection(Q)
        assert_aae(dot(element.shapes, defl), defl_fe, decimal=2)
示例#30
0
    def test_solve_accelerations_coupling(self):
        # Further to test above, check that coupling between prescribed
        # accelerations and other dofs is correct. For example, if there
        # is a rigid body vertically offset from the joint, then a
        # prescribed horizontal acceleration should cause an angular
        # acceleration as well as the translational acceleration.
        s = System()
        j = FreeJoint('joint')
        c = RigidConnection('conn', [0, 0, 1.7])
        b = RigidBody('body', mass=23.54, inertia=74.1 * np.eye(3))
        s.add_leaf(j)
        j.add_leaf(c)
        c.add_leaf(b)
        s.setup()

        # Prescribe horizontal acceleration, solve other accelerations
        s.prescribe(j, 2.3, part=[0])  # x acceleration
        s.update_kinematics()          # update system to show prescribed acc
        s.solve_accelerations()        # solve free accelerations
        s.update_kinematics()          # update system to show solution

        # Ground shouldn't move
        assert_aae(j.ap, 0)

        # Need angular acceleration = (m a_x L) / I0
        I0 = 74.1 + (23.54 * 1.7**2)
        expected_angular_acc = -(23.54 * 2.3 * 1.7) / I0
        assert_aae(j.ad, [2.3, 0, 0, 0, expected_angular_acc, 0])
        assert_aae(j.astrain, j.ad)  # not always true, but works for FreeJoint
示例#31
0
    def test_step_response(self):
        # Calculate system parameters
        zeta = self.damping_coeff
        wn = np.sqrt(self.K / self.M)
        wd = wn * np.sqrt(1 - zeta**2)
        psi = np.arcsin(zeta)

        # Forcing - step function
        force_amp = 3.4
        t0 = 2.3
        force_func = lambda t: (force_amp if t >= t0 else 0)

        def callback(system, time, q_struct, q_other):
            self.body.nodal_load = [0, 0, force_func(time)]
            return []
        t, solution = integrate(self.system, callback)

        decay = np.exp(-zeta * wn * (t - t0))
        expected_defl = 1 - decay * np.cos(wd * (t - t0) - psi) / np.cos(psi)
        X = force_amp / self.K
        expected_defl[t < t0] = 0
        assert_aae(solution[:, 0], X * expected_defl)
示例#32
0
 def test_distributed_loading_uniform_loading_aligned_with_mode(self):
     P = self._uniform_force(1, 3.4)
     Qr, Qw, Qe = self.modes.distributed_loading(P, [0])
     assert_aae(Qr, [0, 3.4 * 10, 0])
     assert_aae(Qw, [0, 0, 3.4 * self.L**2 / 2])
     # Generalised force should be integral of applied
     # force and deflection. Integral of x^2 if L^3 / 3
     assert_aae(Qe, [3.4 * trapz(self.x**2, self.x)])
示例#33
0
 def test_distributed_loading_uniform_loading_aligned_with_mode(self):
     P = self._uniform_force(1, 3.4)
     Qr, Qw, Qe = self.modes.distributed_loading(P, [0])
     assert_aae(Qr, [0, 3.4 * 10, 0])
     assert_aae(Qw, [0, 0, 3.4 * self.L**2 / 2])
     # Generalised force should be integral of applied
     # force and deflection. Integral of x^2 if L^3 / 3
     assert_aae(Qe, [3.4 * trapz(self.x**2, self.x)])
示例#34
0
    def test_step_response(self):
        # Calculate system parameters
        zeta = self.damping_coeff
        wn = np.sqrt(self.K / self.M)
        wd = wn * np.sqrt(1 - zeta**2)
        psi = np.arcsin(zeta)

        # Forcing - step function
        force_amp = 3.4
        t0 = 2.3
        force_func = lambda t: (force_amp if t >= t0 else 0)

        def callback(system, time, q_struct, q_other):
            self.body.nodal_load = [0, 0, force_func(time)]
            return []

        t, solution = integrate(self.system, callback)

        decay = np.exp(-zeta * wn * (t - t0))
        expected_defl = 1 - decay * np.cos(wd * (t - t0) - psi) / np.cos(psi)
        X = force_amp / self.K
        expected_defl[t < t0] = 0
        assert_aae(solution[:, 0], X * expected_defl)
示例#35
0
    def test_rotmats(self):
        assert_array_equal(rotmat_x(0), eye(3))
        assert_array_equal(rotmat_y(0), eye(3))
        assert_array_equal(rotmat_z(0), eye(3))

        # Rotate 45 deg about each axis
        assert_aae(dot(rotmat_x(pi / 4), [1, 1, 1]), [1, 0, sqrt(2)])
        assert_aae(dot(rotmat_y(pi / 4), [1, 1, 1]), [sqrt(2), 1, 0])
        assert_aae(dot(rotmat_z(pi / 4), [1, 1, 1]), [0, sqrt(2), 1])
示例#36
0
    def test_rotmats(self):
        assert_array_equal(rotmat_x(0), eye(3))
        assert_array_equal(rotmat_y(0), eye(3))
        assert_array_equal(rotmat_z(0), eye(3))

        # Rotate 45 deg about each axis
        assert_aae(dot(rotmat_x(pi / 4), [1, 1, 1]), [1, 0, sqrt(2)])
        assert_aae(dot(rotmat_y(pi / 4), [1, 1, 1]), [sqrt(2), 1, 0])
        assert_aae(dot(rotmat_z(pi / 4), [1, 1, 1]), [0, sqrt(2), 1])
示例#37
0
    def test_rigid_element_reference_loading(self):
        # Make an element with no modes (rigid)
        fe = BeamFE(np.linspace(0, 1, 11), density=1, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        fe.set_dofs([False, False, True, False, True, False])
        element = ModalElementFromFE('elem', fe, 0)

        # Distributed load, linearly interpolated
        load = np.zeros((11, 3))
        load[:, 2] = -100  # Uniform load in z direction
        element.apply_distributed_loading(load)
        assert_aae(element.applied_stress, [])
        assert_aae(element.applied_forces[0:6], [0, 0, -100 * 1, 0, 50, 0])
        assert_aae(element.applied_forces[6:12], 0)

        # Distributed load, triangle at tip
        load = np.zeros((11, 3))
        load[-1, 2] = -100  # tapered load in z direction
        element.applied_forces[:] = 0  # reset
        element.apply_distributed_loading(load)
        F = -100 * 0.1 / 2
        assert_aae(element.applied_forces[0:6],
                   [0, 0, F, 0, -F * (0.9 + 0.1 * 2 / 3), 0])
        assert_aae(element.applied_forces[6:12], 0)
    def test_rigid_element_reference_loading(self):
        # Make an element with no modes (rigid)
        fe = BeamFE(np.linspace(0, 1, 11), density=1, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        fe.set_dofs([False, False, True, False, True, False])
        element = ModalElementFromFE('elem', fe, 0)

        # Distributed load, linearly interpolated
        load = np.zeros((11, 3))
        load[:, 2] = -100        # Uniform load in z direction
        element.apply_distributed_loading(load)
        assert_aae(element.applied_stress, [])
        assert_aae(element.applied_forces[0:6], [0, 0, -100 * 1, 0, 50, 0])
        assert_aae(element.applied_forces[6:12], 0)

        # Distributed load, triangle at tip
        load = np.zeros((11, 3))
        load[-1, 2] = -100             # tapered load in z direction
        element.applied_forces[:] = 0  # reset
        element.apply_distributed_loading(load)
        F = -100 * 0.1 / 2
        assert_aae(element.applied_forces[0:6],
                   [0, 0, F, 0, -F * (0.9 + 0.1 * 2 / 3), 0])
        assert_aae(element.applied_forces[6:12], 0)
示例#39
0
 def test_rotations(self):
     assert_aae(rotations(('z', pi/2)),
                [[0, -1, 0],
                 [1,  0, 0],
                 [0,  0, 1]])
     # Work these two examples out by hand: apply the rotations in
     # turn about the updated axes, and see where the body axes end
     # up pointing.
     assert_aae(rotations(('z', pi/2), ('x', pi/2)),
                [[0, 0, 1],
                 [1, 0, 0],
                 [0, 1, 0]])
     assert_aae(rotations(('z', pi/2), ('x', pi/2), ('z', pi/2)),
                [[0,  0, 1],
                 [0, -1, 0],
                 [1,  0, 0]])
     assert_aae(rotations(('x', pi/2), ('z', pi/2)),
                [[0, -1,  0],
                 [0,  0, -1],
                 [1,  0,  0]])
示例#40
0
    def test_reaction_on_fixed_beam(self):
        """Reaction force should balance applied force"""
        # Applied force and moment (+ve in +Z and +Y)
        Fa = -self.force * self.length
        Ma = -Fa * self.length / 2

        # Check equilibrium. No applied forces on hinge, so both nodes
        # should be the same.
        assert_aae(self.system.joint_reactions['node-0'],
                   [0, 0, -Fa, 0, -Ma, 0])
        assert_aae(self.system.joint_reactions['ground'],
                   self.system.joint_reactions['node-0'])

        # The base of the beam should have zero acceleration:
        assert_aae(self.beam.ap, 0)
示例#41
0
    def test_reaction_on_forced_beam(self):
        # Acceleration
        inertia = self.density * (self.length ** 3) / 3
        ang_acc = self.hinge_torque / inertia
        assert_aae(self.hinge.astrain[0], ang_acc)

        # Inertial d'Alembert force and moment
        Mi = -inertia * ang_acc
        Fi = self.density * self.length**2 * ang_acc / 2

        # Check equilibrium.
        assert_aae(self.system.joint_reactions['node-0'],
                   [0, 0, -Fi, 0, -Mi, 0])
        assert_aae(self.system.joint_reactions['ground'],
                   [0, 0, -Fi, 0, -Mi, 0])
示例#42
0
    def test_three_elements_forming_a_disc_about_X_have_correct_inertia(self):
        density = 5
        length = 20.0
        offset = 1.25
        m = density * length  # mass of one beam

        joint = FreeJoint('joint')

        # Make 3 elements spaced by 120 deg about z axis
        for i in range(3):
            # Rotation of -pi/2 about y aligns local x axis of ModalElement
            rotmat = rotations(('x', i * 2*pi/3), ('y', -pi/2))
            offset_vector = dot(rotmat, [offset, 0, 0])  # offset // local x
            conn = RigidConnection('offset%d' % i, offset_vector, rotmat)
            element = _mock_rigid_uniform_beam(density, length,
                                               'element%d' % i)
            joint.add_leaf(conn)
            conn.add_leaf(element)

        system = System()
        system.add_leaf(joint)
        system.setup()

        # Calculate reduced system to get rigid body matrices
        rsys = ReducedSystem(system)

        # Expected values: perp inertia using projected lengths of beams
        Iy = m * (length**2 / 12 + (length/2 + offset)**2)
        Iperp = Iy + Iy/4 + Iy/4
        Iaxial = 3 * Iy
        expected_mass = 3 * m * eye(3)
        expected_inertia = diag([Iaxial, Iperp, Iperp])
        expected_offdiag = zeros((3, 3))

        assert_aae(rsys.M[:3, :3], expected_mass)
        assert_aae(rsys.M[3:, 3:], expected_inertia)
        assert_aae(rsys.M[3:, :3], expected_offdiag)
        assert_aae(rsys.M[:3, 3:], expected_offdiag.T)
示例#43
0
    def test_find_equilibrium(self):
        g = 9.81
        m = 23.1
        k = 45.2
        s = System(gravity=g)
        slider = PrismaticJoint('slider', [0, 0, 1])
        slider.stiffness = k
        body = RigidBody('body', mass=m)
        s.add_leaf(slider)
        slider.add_leaf(body)
        s.setup()

        # Initially position should be zero and acceleration nonzero
        s.solve_accelerations()
        assert_aae(slider.xstrain, 0)
        assert_aae(slider.astrain, -g)

        # At equilibrium, position should be nozero and force on body zero
        s.find_equilibrium()
        s.update_matrices()      # recalculate stiffness force
        s.solve_accelerations()
        assert_aae(slider.xstrain, -m * g / k)
        assert_aae(slider.astrain, 0)
 def interpolated_by_thickness(self):
     # Interpolate between 13% and 17% data
     lift_drag_values = self.db.for_thickness(0.15)
     lift_drag = interp1d(self.db.alpha, lift_drag_values, axis=0)
     assert_aae(lift_drag(10 * pi / 180), [(1.460 + 1.500) / 2,
                                           (0.016 + 0.014) / 2])
 def test_thirteen_percent_foil_interpolated_by_alpha(self):
     # Interpolate between 4 and 6 deg alpha
     lift_drag_values = self.db.for_thickness(0.13)
     lift_drag = interp1d(self.db.alpha, lift_drag_values, axis=0)
     assert_aae(lift_drag(5 * pi / 180), [(0.890 + 1.100) / 2,
                                          (0.009 + 0.012) / 2])