Пример #1
0
class UniformCantileverWithLinearTwist_Test:
    """Values from R.H. MacNeal, R.L. Harder: "Proposed standard set of
    problems to test FE accuracy"
    """
    length = 12.0
    width = 1.1
    depth = 0.32
    E = 29.0e6
    tip_twist = np.pi / 2
    num_elements = 12

    def setup(self):
        x = np.linspace(0, self.length, self.num_elements)
        twist = x * self.tip_twist / self.length
        EIy = self.E * self.width * self.depth**3 / 12
        EIz = self.E * self.depth * self.width**3 / 12
        self.fe = BeamFE(x, 0, 0, EIy, EIz, twist=twist)
        self.fe.set_boundary_conditions('C', 'F')

    def test_deflection_under_tip_load_y(self):
        Q = transverse_load(self.num_elements, magnitude=1, only_tip=True)
        defl, reactions = self.fe.static_deflection(Q=Q)
        assert_allclose(defl[-6:][1], 0.001754, atol=1e-5)

    def test_deflection_under_tip_load_z(self):
        Q = transverse_load(self.num_elements,
                            magnitude=1,
                            angle=(np.pi / 2),
                            only_tip=True)
        defl, reactions = self.fe.static_deflection(Q=Q)
        assert_allclose(defl[-6:][2], 0.005424, atol=1e-5)
Пример #2
0
    def setUp(self):
        # FE model for beam - no modes, i.e. rigid
        x = linspace(0, self.length, 20)
        density = (2 * self.mass / self.length) * (1 - x / self.length)
        fe = BeamFE(x, density=density, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        self.beam = ModalElementFromFE('beam', fe, 0)

        # Set loading - in Z direction
        load = np.zeros((len(x), 3))
        load[:, 2] = self.force
        self.beam.loading = load

        # Offset from hinge axis
        self.conn = RigidConnection('offset', [self.offset, 0, 0])

        # Hinge with axis along Y axis
        self.hinge = Hinge('hinge', [0, 1, 0])

        # Build system
        self.system = System()
        self.system.add_leaf(self.hinge)
        self.hinge.add_leaf(self.conn)
        self.conn.add_leaf(self.beam)
        self.system.setup()
        self.system.update_kinematics()  # Set up nodal values initially
Пример #3
0
def _mock_rigid_uniform_beam(density, length, name='beam'):
    """Return empty modal representation of 20m long rigid beam"""
    x = linspace(0, length, 20)
    fe = BeamFE(x, density=density, EA=0, EIy=1, EIz=0)
    fe.set_boundary_conditions('C', 'F')
    beam = ModalElementFromFE(name, fe, 0)
    return beam
Пример #4
0
    def setUp(self):
        # FE model for beam
        x = linspace(0, self.length, 20)
        fe = BeamFE(x, density=self.density, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        self.beam = ModalElementFromFE('beam', fe, 0)

        # Set loading - in negative Z direction
        load = np.zeros((len(x), 3))
        load[:, 2] = -self.force
        self.beam.loading = load

        # Hinge with axis along Y axis
        self.hinge = Hinge('hinge', [0, 1, 0])
        self.hinge.internal_torque = self.hinge_torque

        # Build system
        self.system = System()
        self.system.add_leaf(self.hinge)
        self.hinge.add_leaf(self.beam)
        self.system.setup()

        if not self.free_beam:
            # Prescribe hinge to be fixed
            self.system.prescribe(self.hinge)

        # Initial calculations
        self.recalc()
Пример #5
0
    def setUp(self):
        # FE model for beam - no modes, i.e. rigid
        x = linspace(0, self.length, 20)
        density = (2 * self.mass / self.length) * (1 - x / self.length)
        fe = BeamFE(x, density=density, EA=0, EIy=1, EIz=0)
        fe.set_boundary_conditions('C', 'F')
        self.beam = ModalElementFromFE('beam', fe, 0)

        # Set loading - in Z direction
        load = np.zeros((len(x), 3))
        load[:, 2] = self.force
        self.beam.loading = load

        # Offset from hinge axis
        self.conn = RigidConnection('offset', [self.offset, 0, 0])

        # Hinge with axis along Y axis
        self.hinge = Hinge('hinge', [0, 1, 0])

        # Build system
        self.system = System()
        self.system.add_leaf(self.hinge)
        self.hinge.add_leaf(self.conn)
        self.conn.add_leaf(self.beam)
        self.system.setup()
        self.system.update_kinematics()    # Set up nodal values initially
Пример #6
0
class UniformCantileverWithLinearTwist_Test:
    """Values from R.H. MacNeal, R.L. Harder: "Proposed standard set of
    problems to test FE accuracy"
    """
    length = 12.0
    width = 1.1
    depth = 0.32
    E = 29.0e6
    tip_twist = np.pi / 2
    num_elements = 12

    def setup(self):
        x = np.linspace(0, self.length, self.num_elements)
        twist = x * self.tip_twist / self.length
        EIy = self.E * self.width * self.depth ** 3 / 12
        EIz = self.E * self.depth * self.width ** 3 / 12
        self.fe = BeamFE(x, 0, 0, EIy, EIz, twist=twist)
        self.fe.set_boundary_conditions('C', 'F')

    def test_deflection_under_tip_load_y(self):
        Q = transverse_load(self.num_elements, magnitude=1, only_tip=True)
        defl, reactions = self.fe.static_deflection(Q=Q)
        assert_allclose(defl[-6:][1], 0.001754, atol=1e-5)

    def test_deflection_under_tip_load_z(self):
        Q = transverse_load(self.num_elements, magnitude=1,
                            angle=(np.pi / 2), only_tip=True)
        defl, reactions = self.fe.static_deflection(Q=Q)
        assert_allclose(defl[-6:][2], 0.005424, atol=1e-5)
Пример #7
0
 def setup(self):
     x = np.linspace(0, self.length, self.num_elements)
     twist = x * self.tip_twist / self.length
     EIy = self.E * self.width * self.depth**3 / 12
     EIz = self.E * self.depth * self.width**3 / 12
     self.fe = BeamFE(x, 0, 0, EIy, EIz, twist=twist)
     self.fe.set_boundary_conditions('C', 'F')
Пример #8
0
 def setUp(self):
     x = 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.
     self.fe = BeamFE(x, density=1, EA=0, EIy=1, EIz=0)
     self.fe.set_boundary_conditions('C', 'F')
     self.fe.set_dofs([False, False, True, False, True, False])
Пример #9
0
 def setUp(self):
     data = np.loadtxt("tests/example_blade_data.txt")
     x, density, EA, EI_flap, EI_edge, twist = data.T
     # Twist has been saved in my convention (+ve X rotation), not Bladed
     self.fe = BeamFE(x, density, EA, EI_flap, EI_edge, twist=twist)
     self.fe.set_boundary_conditions('C', 'F')
     self.modal = ModalBeamFE(self.fe)
     self.answers = np.load("tests/example_blade_mode_results.npz")
Пример #10
0
 def setUp(self):
     x = array([0.0, 10.0, 22.0, 28.0])
     EI = array([[2e7, 2e7], [1e7, 1e7], [1e7, 1e7]])
     # Using the z axis as the transverse direction gives the same
     # sign convention as Reddy uses in 2D, namely that rotations
     # are positive clockwise.
     self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
     self.fe.set_boundary_conditions('C', 'C')
     self.fe.set_dofs([False, False, True, False, True, False])
Пример #11
0
 def setup(self):
     x = np.linspace(0, self.length, 10)
     self.fe = BeamFE(x,
                      self.density,
                      0,
                      self.EIy,
                      self.EIz,
                      twist=self.twist)
     self.fe.set_boundary_conditions('C', 'F')
Пример #12
0
 def test_uniform_tension_increases_stiffness(self):
     x = np.linspace(0, self.length, 10)
     fe1 = BeamFE(x, self.density, 0, self.EI, self.EI)
     fe2 = BeamFE(x,
                  self.density,
                  0,
                  self.EI,
                  self.EI,
                  axial_force=20 * np.ones(10))
     assert np.all(np.diag(fe2.Ks) >= np.diag(fe1.Ks))
Пример #13
0
def blade_fe(blade, root_length=0.0, spin=0.0):
    # positive blade twist is geometrically a negative x-rotation
    twist = -np.array(blade['twist'])
    x = blade['radii']
    qn = interleave(root_length + np.array(x), 6)
    N = BeamFE.centrifugal_force_distribution(qn, blade['density'])
    fe = BeamFE(x, blade['density'], blade['EA'],
                blade['EIyy'], blade['EIzz'], twist=twist,
                axial_force=N * spin**2)
    fe.set_boundary_conditions('C', 'F')
    return fe
Пример #14
0
class UniformCantileverWithConstantTwist_Test:
    length = 3.2
    density = 54.3
    EIy = 494.2
    EIz = 654.2
    twist = np.radians(76.4)

    def setup(self):
        x = np.linspace(0, self.length, 10)
        self.fe = BeamFE(x,
                         self.density,
                         0,
                         self.EIy,
                         self.EIz,
                         twist=self.twist)
        self.fe.set_boundary_conditions('C', 'F')

    def test_mass(self):
        mass = self.length * self.density
        assert_allclose(self.fe.mass, mass, atol=0.5)

    def test_moment_of_mass(self):
        I = self.density * self.length**2 / 2
        m = np.dot(self.fe.S1, self.fe.q0)
        assert_allclose(m[0], I, atol=0.5)

    def test_moment_of_inertia(self):
        Iyy = self.density * self.length**3 / 3
        J = np.einsum('p, ijpq, q -> ij', self.fe.q0, self.fe.S2, self.fe.q0)
        assert_allclose(J[0, 0], Iyy, atol=0.5)
        assert_allclose(J[1:, 1:], 0)

    def test_deflection_under_uniform_load(self):
        w = 34.2  # N/m
        Q = self.fe.distribute_load(transverse_load(10, w))
        defl, reactions = self.fe.static_deflection(Q)
        print(reactions)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        # Resolve into local blade coordinates
        tw = self.twist
        wy = +w * np.cos(tw)
        wz = -w * np.sin(tw)
        local_y = wy * self.length**4 / (8 * self.EIz)  # NB y defl -> EIzz
        local_z = wz * self.length**4 / (8 * self.EIy)

        assert_allclose(x, 0)
        assert_allclose(y[-1], local_y * np.cos(tw) - local_z * np.sin(tw))
        assert_allclose(z[-1], local_z * np.cos(tw) + local_y * np.sin(tw))

        assert_allclose(reactions[1], -w * self.length)
Пример #15
0
class TestBeamFE_Example62(unittest.TestCase):
    def setUp(self):
        x = 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.
        self.fe = BeamFE(x, density=1, EA=0, EIy=1, EIz=0)
        self.fe.set_boundary_conditions('C', 'F')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_mode_frequencies(self):
        modal = self.fe.modal_matrices()
        assert_allclose(modal.w[:4], [3.5160, 22.0345, 61.6972, 120.9019],
                        atol=1e-1)
Пример #16
0
class TestBeamFEAttachmentModes(unittest.TestCase):
    def setUp(self):
        x = array([0.0, 10.0, 22.0, 28.0])
        EI = array([[2e7, 2e7], [1e7, 1e7], [1e7, 1e7]])
        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
        self.fe.set_boundary_conditions('C', 'C')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_simple_model(self):
        am = self.fe.attachment_modes()
        self.assertEqual(am.shape, (4 * 6, 2 * 2))
    def setUp(self):
        x = linspace(0, self.L, 15)
        fe = BeamFE(x, density=self.m, EA=0, EIy=self.EI, EIz=0)
        fe.set_boundary_conditions('C', 'C')
        fe.set_dofs([False, False, True, False, True, False])
        beam = DistalModalElementFromFE('beam', fe, num_modes=1,
                                        damping=self.damping_coeff)

        system = System()
        system.add_leaf(beam)
        system.setup()
        system.update_kinematics()

        self.beam, self.system = beam, system
Пример #18
0
class ExampleBlade_Test(unittest.TestCase):
    def setUp(self):
        data = np.loadtxt("tests/example_blade_data.txt")
        x, density, EA, EI_flap, EI_edge, twist = data.T
        # Twist has been saved in my convention (+ve X rotation), not Bladed
        self.fe = BeamFE(x, density, EA, EI_flap, EI_edge, twist=twist)
        self.fe.set_boundary_conditions('C', 'F')
        self.modal = ModalBeamFE(self.fe)
        self.answers = np.load("tests/example_blade_mode_results.npz")

    def test_mass(self):
        assert_allclose(self.fe.mass, 6547, atol=0.5)

    def test_moment_of_mass(self):
        m = np.dot(self.fe.S1, self.fe.q0)
        assert_allclose(m[0], 84219, atol=0.5)

    def test_moment_of_inertia(self):
        J = np.einsum('p, ijpq, q -> ij', self.fe.q0, self.fe.S2, self.fe.q0)
        assert_allclose(J[0, 0], 1784881, atol=0.5)

    def test_first_four_modal_frequencies_match_saved_values(self):
        assert_allclose(self.modal.w[:4], self.answers['freqs'], atol=1e-3)

    def test_first_four_mode_shapes_match_saved_values(self):
        v = self.modal.shapes
        answer = self.answers['shapes']
        for i in range(4):
            assert_allclose_ignoring_sign(v[:, i], answer[:, i], atol=1e-5)

    def test_mode_shapes_are_normalised(self):
        w = self.modal.w
        v = self.modal.shapes
        M = self.fe.M
        K = self.fe.K
        for i in range(v.shape[1]):
            assert_allclose(dot(v[:, i].T, dot(M, v[:, i])), 1.0)
            assert_allclose(dot(v[:, i].T, dot(K, v[:, i])), w[i]**2)

    def test_mode_are_sorted(self):
        w = list(self.modal.w)
        self.assertEqual(w, sorted(w))

    def test_correct_number_of_modes_are_returned(self):
        w_all, v_all = self.fe.normal_modes()
        w, v = self.fe.normal_modes(4)
        assert_allclose(w, w_all[:4])
        for i in range(4):
            assert_allclose_ignoring_sign(v[:, i], v_all[:, i])
Пример #19
0
class TestBeamFE_Example62(unittest.TestCase):
    def setUp(self):
        x = 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.
        self.fe = BeamFE(x, density=1, EA=0, EIy=1, EIz=0)
        self.fe.set_boundary_conditions('C', 'F')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_mode_frequencies(self):
        modal = self.fe.modal_matrices()
        assert_allclose(modal.w[:4],
                        [3.5160, 22.0345, 61.6972, 120.9019],
                        atol=1e-1)
Пример #20
0
def blade_fe(blade, root_length=0.0, spin=0.0):
    # positive blade twist is geometrically a negative x-rotation
    twist = -np.array(blade['twist'])
    x = blade['radii']
    qn = interleave(root_length + np.array(x), 6)
    N = BeamFE.centrifugal_force_distribution(qn, blade['density'])
    fe = BeamFE(x,
                blade['density'],
                blade['EA'],
                blade['EIyy'],
                blade['EIzz'],
                twist=twist,
                axial_force=N * spin**2)
    fe.set_boundary_conditions('C', 'F')
    return fe
Пример #21
0
class TestBeamFEAttachmentModes(unittest.TestCase):
    def setUp(self):
        x = array([0.0, 10.0, 22.0, 28.0])
        EI = array([[2e7, 2e7],
                    [1e7, 1e7],
                    [1e7, 1e7]])
        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
        self.fe.set_boundary_conditions('C', 'C')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_simple_model(self):
        am = self.fe.attachment_modes()
        self.assertEqual(am.shape, (4*6, 2*2))
def _make_random_element(rdm):
    # Choose some parameters randomly
    length = rdm.uniform(1, 10)
    density = rdm.uniform(0.1, 100)
    EA = rdm.uniform(1e1, 1e8)
    EIy = rdm.uniform(1e5, 1e8)
    EIz = rdm.uniform(1e5, 1e8)

    x = np.linspace(0, length, 20)
    fe = BeamFE(x, density, EA, EIy, EIz)
    fe.set_boundary_conditions('C', 'C')
    beam = DistalModalElementFromFE('el', fe, 5)
    beam._params = dict(length=length,
                        density=density,
                        EA=EA, EIy=EIy, EIz=EIz)
    return beam
Пример #23
0
 def setup(self):
     x = np.linspace(0, self.length, self.num_elements)
     twist = x * self.tip_twist / self.length
     EIy = self.E * self.width * self.depth ** 3 / 12
     EIz = self.E * self.depth * self.width ** 3 / 12
     self.fe = BeamFE(x, 0, 0, EIy, EIz, twist=twist)
     self.fe.set_boundary_conditions('C', 'F')
Пример #24
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)
Пример #25
0
    def setUp(self):
        # FE model for beam - no modes, i.e. rigid
        self.x = x = linspace(0, self.length, 20)
        fe = BeamFE(x, density=2, EA=0, EIy=0, EIz=0)

        # Build the elements
        self.shaft = Hinge('shaft', [1, 0, 0])

        self.roots = []
        self.blades = []
        self.pitch_bearings = []
        for ib in range(1):
            R = rotations(('x', ib * 2 * pi / 3), ('y', -pi / 2))
            root_offset = dot(R, [self.root_length, 0, 0])
            root = RigidConnection('root%d' % (ib + 1), root_offset, R)
            bearing = Hinge('pitch%d' % (ib + 1), [1, 0, 0])
            blade = ModalElementFromFE('blade%d' % (ib + 1), fe, 0)

            self.shaft.add_leaf(root)
            root.add_leaf(bearing)
            bearing.add_leaf(blade)

            self.roots.append(root)
            self.blades.append(blade)
            self.pitch_bearings.append(bearing)

        # Build system
        self.system = System()
        self.system.add_leaf(self.shaft)
        self.system.setup()
        self.system.update_kinematics()  # Set up nodal values initially
        self.system.update_matrices()
Пример #26
0
class UniformCantileverWithConstantTwist_Test:
    length = 3.2
    density = 54.3
    EIy = 494.2
    EIz = 654.2
    twist = np.radians(76.4)

    def setup(self):
        x = np.linspace(0, self.length, 10)
        self.fe = BeamFE(x, self.density, 0, self.EIy, self.EIz,
                         twist=self.twist)
        self.fe.set_boundary_conditions('C', 'F')

    def test_mass(self):
        mass = self.length * self.density
        assert_allclose(self.fe.mass, mass, atol=0.5)

    def test_moment_of_mass(self):
        I = self.density * self.length ** 2 / 2
        m = np.dot(self.fe.S1, self.fe.q0)
        assert_allclose(m[0], I, atol=0.5)

    def test_moment_of_inertia(self):
        Iyy = self.density * self.length ** 3 / 3
        J = np.einsum('p, ijpq, q -> ij', self.fe.q0, self.fe.S2, self.fe.q0)
        assert_allclose(J[0, 0], Iyy, atol=0.5)
        assert_allclose(J[1:, 1:], 0)

    def test_deflection_under_uniform_load(self):
        w = 34.2  # N/m
        Q = self.fe.distribute_load(transverse_load(10, w))
        defl, reactions = self.fe.static_deflection(Q)
        print(reactions)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        # Resolve into local blade coordinates
        tw = self.twist
        wy = +w * np.cos(tw)
        wz = -w * np.sin(tw)
        local_y = wy * self.length**4 / (8 * self.EIz)  # NB y defl -> EIzz
        local_z = wz * self.length**4 / (8 * self.EIy)

        assert_allclose(x, 0)
        assert_allclose(y[-1], local_y * np.cos(tw) - local_z * np.sin(tw))
        assert_allclose(z[-1], local_z * np.cos(tw) + local_y * np.sin(tw))

        assert_allclose(reactions[1], -w * self.length)
Пример #27
0
 def setUp(self):
     x = 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.
     self.fe = BeamFE(x, density=1, EA=0, EIy=1, EIz=0)
     self.fe.set_boundary_conditions('C', 'F')
     self.fe.set_dofs([False, False, True, False, True, False])
def _make_random_element(rdm):
    # Choose some parameters randomly
    length = rdm.uniform(1, 10)
    density = rdm.uniform(0.1, 100)
    EA = rdm.uniform(1e1, 1e8)
    EIy = rdm.uniform(1e5, 1e8)
    EIz = rdm.uniform(1e5, 1e8)

    x = np.linspace(0, length, 20)
    fe = BeamFE(x, density, EA, EIy, EIz)
    fe.set_boundary_conditions('C', 'C')
    beam = DistalModalElementFromFE('el', fe, 5)
    beam._params = dict(length=length,
                        density=density,
                        EA=EA,
                        EIy=EIy,
                        EIz=EIz)
    return beam
Пример #29
0
 def setUp(self):
     x = array([0.0, 10.0, 22.0, 28.0])
     EI = array([[2e7, 2e7],
                 [1e7, 1e7],
                 [1e7, 1e7]])
     # Using the z axis as the transverse direction gives the same
     # sign convention as Reddy uses in 2D, namely that rotations
     # are positive clockwise.
     self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
     self.fe.set_boundary_conditions('P', 'C')
     self.fe.set_dofs([False, False, True, False, True, False])
Пример #30
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)
Пример #31
0
class AppliedLoads_Tests:
    def setup(self):
        self.fe = BeamFE(linspace(0, 10, 11), density=0, EA=0, EIy=1, EIz=1)

    def test_uniform_load(self):
        f = array([3.4, 5.6, 7.2])
        load = zeros(6 * 11)
        for i in range(3):
            load[i::6] = f[i]

        # Force
        F = dot(self.fe.F1, load)
        assert_allclose(F, f * 10)

        # Moment
        q = self.fe.q0
        I = np.vstack((
            dot(q.T, (self.fe.F2[1, 2] - self.fe.F2[2, 1])),
            dot(q.T, (self.fe.F2[2, 0] - self.fe.F2[0, 2])),
            dot(q.T, (self.fe.F2[0, 1] - self.fe.F2[1, 0])),
        ))
        Q = dot(I, load)
        assert_allclose(Q, [0, -f[2] * 10 * 5, f[1] * 10 * 5])

    def test_linear_load(self):
        f = array([3.4, 5.6, 7.2])
        load = zeros(6 * 11)
        for i in range(3):
            load[i::6] = linspace(0, f[i], 11)

        # Force
        F = dot(self.fe.F1, load)
        assert_allclose(F, f * 10 / 2)

        # Moment
        q = self.fe.q0
        I = np.vstack((
            dot(q.T, (self.fe.F2[1, 2] - self.fe.F2[2, 1])),
            dot(q.T, (self.fe.F2[2, 0] - self.fe.F2[0, 2])),
            dot(q.T, (self.fe.F2[0, 1] - self.fe.F2[1, 0])),
        ))
        Q = dot(I, load)
        assert_allclose(
            Q, [0, -f[2] * 10 / 2 * 10 * 2 / 3, f[1] * 10 / 2 * 10 * 2 / 3])

        # Check stresses
        assert_allclose(dot(self.fe.F, load), self.fe.distribute_load(load))
Пример #32
0
class TestBeamFE_Example42(unittest.TestCase):
    def setUp(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.
        self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
        self.fe.set_boundary_conditions('C', 'F')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_stiffness(self):
        # Reddy1993, p 164
        expected = array([
            [27, 0, 0, 0, 0, 0],
            [-54, 144, 0, 0, 0, 0],
            [-27, 54, 27 + 8, 0, 0, 0],
            [-54, 72, 54 - 24, 144 + 96, 0, 0],
            [0, 0, -8, 24, 8, 0],
            [0, 0, -24, 48, 24, 96],
        ])
        expected += expected.T - np.diag(expected.diagonal())  # make symmetric
        expected_II = expected[2:6, 2:6]
        expected_IB = expected[2:6, 0:2]
        assert_allclose(self.fe.K_II, expected_II)
        assert_allclose(self.fe.K_IB, expected_IB)

    def test_distributed_load(self):
        # Distributed force on second element:
        load = array([0, 0, 0, 0, 0, 0, 0, 0, -100, 0, 0, 0])
        Q = self.fe.distribute_load_on_element(1, load)
        Q = Q[[2, 4, 8, 10, 14, 16]]
        assert_allclose(Q, [0, 0, -90, 120, -210, -180])

    def test_solution_without_spring(self):
        # Distributed force on first element:
        load = array([0, 0, 0, 0, 0, 0, 0, 0, -100, 0, 0, 0])
        QF = self.fe.distribute_load_on_element(1, load)

        # Solve static deflection
        deflections, reactions = self.fe.static_deflection(QF)

        # Expected values from Reddy
        expected_deflections = zeros_like(deflections)
        expected_deflections[[
            8, 10, 14, 16
        ]] = array([-1.6, 0.72, -7.108, 0.99]) * 1e4 / 143.0
        assert_allclose(deflections, expected_deflections, atol=1e1)
Пример #33
0
class TestBeamFE_Example42(unittest.TestCase):
    def setUp(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.
        self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
        self.fe.set_boundary_conditions('C', 'F')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_stiffness(self):
        # Reddy1993, p 164
        expected = array([
            [27,  0,   0,     0,      0,  0],
            [-54, 144, 0,     0,      0,  0],
            [-27, 54,  27+8,  0,      0,  0],
            [-54, 72,  54-24, 144+96, 0,  0],
            [0,   0,   -8,    24,     8,  0],
            [0,   0,   -24,   48,     24, 96],
        ])
        expected += expected.T - np.diag(expected.diagonal())  # make symmetric
        expected_II = expected[2:6, 2:6]
        expected_IB = expected[2:6, 0:2]
        assert_allclose(self.fe.K_II, expected_II)
        assert_allclose(self.fe.K_IB, expected_IB)

    def test_distributed_load(self):
        # Distributed force on second element:
        load = array([0, 0, 0, 0, 0, 0, 0, 0, -100, 0, 0, 0])
        Q = self.fe.distribute_load_on_element(1, load)
        Q = Q[[2, 4, 8, 10, 14, 16]]
        assert_allclose(Q, [0, 0, -90, 120, -210, -180])

    def test_solution_without_spring(self):
        # Distributed force on first element:
        load = array([0, 0, 0, 0, 0, 0, 0, 0, -100, 0, 0, 0])
        QF = self.fe.distribute_load_on_element(1, load)

        # Solve static deflection
        deflections, reactions = self.fe.static_deflection(QF)

        # Expected values from Reddy
        expected_deflections = zeros_like(deflections)
        expected_deflections[[8, 10, 14, 16]] = array(
            [-1.6, 0.72, -7.108, 0.99]) * 1e4 / 143.0
        assert_allclose(deflections, expected_deflections, atol=1e1)
Пример #34
0
class AppliedLoads_Tests:
    def setup(self):
        self.fe = BeamFE(linspace(0, 10, 11), density=0, EA=0, EIy=1, EIz=1)

    def test_uniform_load(self):
        f = array([3.4, 5.6, 7.2])
        load = zeros(6 * 11)
        for i in range(3): load[i::6] = f[i]

        # Force
        F = dot(self.fe.F1, load)
        assert_allclose(F, f * 10)

        # Moment
        q = self.fe.q0
        I = np.vstack((
            dot(q.T, (self.fe.F2[1, 2] - self.fe.F2[2, 1])),
            dot(q.T, (self.fe.F2[2, 0] - self.fe.F2[0, 2])),
            dot(q.T, (self.fe.F2[0, 1] - self.fe.F2[1, 0])),
        ))
        Q = dot(I, load)
        assert_allclose(Q, [0, -f[2]*10*5, f[1]*10*5])

    def test_linear_load(self):
        f = array([3.4, 5.6, 7.2])
        load = zeros(6 * 11)
        for i in range(3): load[i::6] = linspace(0, f[i], 11)

        # Force
        F = dot(self.fe.F1, load)
        assert_allclose(F, f * 10 / 2)

        # Moment
        q = self.fe.q0
        I = np.vstack((
            dot(q.T, (self.fe.F2[1, 2] - self.fe.F2[2, 1])),
            dot(q.T, (self.fe.F2[2, 0] - self.fe.F2[0, 2])),
            dot(q.T, (self.fe.F2[0, 1] - self.fe.F2[1, 0])),
        ))
        Q = dot(I, load)
        assert_allclose(Q, [0, -f[2]*10/2 * 10*2/3, f[1]*10/2 * 10*2/3])

        # Check stresses
        assert_allclose(dot(self.fe.F, load), self.fe.distribute_load(load))
Пример #35
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)
    def setUp(self):
        x = linspace(0, self.L, 15)
        fe = BeamFE(x, density=self.m, EA=0, EIy=self.EI, EIz=0)
        fe.set_boundary_conditions('C', 'C')
        fe.set_dofs([False, False, True, False, True, False])
        beam = DistalModalElementFromFE('beam',
                                        fe,
                                        num_modes=1,
                                        damping=self.damping_coeff)

        system = System()
        system.add_leaf(beam)
        system.setup()
        system.update_kinematics()

        self.beam, self.system = beam, system
Пример #37
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)
Пример #38
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)
Пример #39
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)
Пример #40
0
 def setup(self):
     self.fe = BeamFE(linspace(0, 10, 11), density=0, EA=0, EIy=1, EIz=1)
Пример #41
0
class TestBeamFE_Example41(unittest.TestCase):
    def setUp(self):
        x = array([0.0, 10.0, 22.0, 28.0])
        EI = array([[2e7, 2e7], [1e7, 1e7], [1e7, 1e7]])
        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
        self.fe.set_boundary_conditions('P', 'C')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_stiffness(self):
        # Reddy1993, pp 161-162
        expected = 1e7 * array([
            [0.024, -0.12, -0.024, -0.12, 0, 0, 0, 0],
            [0, 0.80, 0.12, 0.40, 0, 0, 0, 0],
            [0, 0, 0.0309, 0.0783, -0.00694, -0.04167, 0, 0],
            [0, 0, 0, 1.133, 0.0417, 0.167, 0, 0],
            [0, 0, 0, 0, 0.0625, -0.125, -0.0556, -0.167],
            [0, 0, 0, 0, 0, 1, 0.1667, 0.333],
            [0, 0, 0, 0, 0, 0, 0.0556, 0.1667],
            [0, 0, 0, 0, 0, 0, 0, 0.6667],
        ])
        expected += expected.T - np.diag(expected.diagonal())  # make symmetric
        expected_II = expected[1:6, 1:6]
        expected_IB = expected[1:6, [0, 6, 7]]
        assert_allclose(expected_II, self.fe.K_II, atol=1e-2 * 1e7)
        assert_allclose(expected_IB, self.fe.K_IB, atol=1e-3 * 1e7)

    def test_distributed_load(self):
        # Distributed force on first element:
        load = array([0, 0, -2400, 0, 0, 0, 0, 0, -2400, 0, 0, 0])
        Q = self.fe.distribute_load_on_element(0, load)
        Q = Q[[2, 4, 8, 10, 14, 16, 20, 22]]
        assert_allclose(Q / 1e3, [-12, 20, -12, -20, 0, 0, 0, 0])

    def test_solution(self):
        # Distributed force on first element:
        load = array([0, 0, -2400, 0, 0, 0, 0, 0, -2400, 0, 0, 0])
        QF = self.fe.distribute_load_on_element(0, load)

        # Nodal forces:
        Q = np.zeros(self.fe.K.shape[0])
        Q[14] = -10000  # z force at 3rd node

        # Solve static deflection
        deflections, reactions = self.fe.static_deflection(QF + Q)

        # Expected values from Reddy
        expected_deflections = zeros_like(deflections)
        expected_deflections[[4, 8, 10, 14, 16]] = [
            0.03856, -0.2808, 0.01214, -0.1103, -0.02752
        ]
        assert_allclose(deflections, expected_deflections, atol=1e-4)
        expected_reactions = zeros_like(reactions)
        expected_reactions[[2, 20, 22]] = [18565.54, 15434.46, 92164.83]
        assert_allclose(reactions, expected_reactions, atol=1e-2)

    def test_load_matrix_gives_same_result_as_method(self):
        # Distributed force on all elements
        load = np.zeros(4 * 6)
        load[2::6] = [350, 324, 654, 54]  # Z component

        Q1 = self.fe.distribute_load(load)
        Q2 = dot(self.fe.F, load)

        assert_allclose(Q1, Q2)
Пример #42
0
class UniformCantilever_Test:
    length = 3.2
    density = 54.3
    EI = 494.2

    def setup(self):
        x = np.linspace(0, self.length, 10)
        self.fe = BeamFE(x, self.density, 0, self.EI, self.EI)
        self.fe.set_boundary_conditions('C', 'F')

    def test_mass(self):
        mass = self.length * self.density
        assert_allclose(self.fe.mass, mass, atol=0.5)

    def test_moment_of_mass(self):
        I = self.density * self.length**2 / 2
        m = np.dot(self.fe.S1, self.fe.q0)
        assert_allclose(m[0], I, atol=0.5)

    def test_moment_of_inertia(self):
        Iyy = self.density * self.length**3 / 3
        J = np.einsum('p, ijpq, q -> ij', self.fe.q0, self.fe.S2, self.fe.q0)
        assert_allclose(J[0, 0], Iyy, atol=0.5)
        assert_allclose(J[1:, 1:], 0)

    def test_deflection_with_tip_load(self):
        # Simple tip load should produce databook tip deflection
        W = 54.1  # N
        Q = transverse_load(10, W, only_tip=True)
        defl, reactions = self.fe.static_deflection(Q=Q)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        assert_allclose(x, 0)
        assert_allclose(z, 0)
        assert_allclose(y[-1], W * self.length**3 / (3 * self.EI))

    def test_deflection_under_uniform_load(self):
        # Simple uniform load should produce databook tip deflection
        w = 34.2  # N/m
        Q = self.fe.distribute_load(transverse_load(10, magnitude=w))
        defl, reactions = self.fe.static_deflection(Q)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        assert_allclose(x, 0)
        assert_allclose(z, 0)
        assert_allclose(y[-1], w * self.length**4 / (8 * self.EI))

    def test_deflection_is_parallel_to_uniform_loading(self):
        w = 67.4  # distributed load (N/m)
        theta = np.radians(35.4)  # angle from y axis of load
        Q = self.fe.distribute_load(transverse_load(10, w, theta))
        defl, reactions = self.fe.static_deflection(Q)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        assert_allclose(x, 0)
        load_angle = np.arctan2(z, y)
        assert_allclose(load_angle[1:], theta)

    def test_reaction_force(self):
        # Simple uniform load should produce databook tip deflection
        w = 34.2  # N/m
        F = transverse_load(10, w)
        # Reaction force is F1 * F
        R = np.dot(self.fe.F1, F)
        assert_allclose(R, [0, w * self.length, 0])
Пример #43
0
class UniformCantilever_Test:
    length = 3.2
    density = 54.3
    EI = 494.2

    def setup(self):
        x = np.linspace(0, self.length, 10)
        self.fe = BeamFE(x, self.density, 0, self.EI, self.EI)
        self.fe.set_boundary_conditions('C', 'F')

    def test_mass(self):
        mass = self.length * self.density
        assert_allclose(self.fe.mass, mass, atol=0.5)

    def test_moment_of_mass(self):
        I = self.density * self.length ** 2 / 2
        m = np.dot(self.fe.S1, self.fe.q0)
        assert_allclose(m[0], I, atol=0.5)

    def test_moment_of_inertia(self):
        Iyy = self.density * self.length ** 3 / 3
        J = np.einsum('p, ijpq, q -> ij', self.fe.q0, self.fe.S2, self.fe.q0)
        assert_allclose(J[0, 0], Iyy, atol=0.5)
        assert_allclose(J[1:, 1:], 0)

    def test_deflection_with_tip_load(self):
        # Simple tip load should produce databook tip deflection
        W = 54.1  # N
        Q = transverse_load(10, W, only_tip=True)
        defl, reactions = self.fe.static_deflection(Q=Q)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        assert_allclose(x, 0)
        assert_allclose(z, 0)
        assert_allclose(y[-1], W * self.length**3 / (3 * self.EI))

    def test_deflection_under_uniform_load(self):
        # Simple uniform load should produce databook tip deflection
        w = 34.2  # N/m
        Q = self.fe.distribute_load(transverse_load(10, magnitude=w))
        defl, reactions = self.fe.static_deflection(Q)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        assert_allclose(x, 0)
        assert_allclose(z, 0)
        assert_allclose(y[-1], w * self.length**4 / (8 * self.EI))

    def test_deflection_is_parallel_to_uniform_loading(self):
        w = 67.4                  # distributed load (N/m)
        theta = np.radians(35.4)  # angle from y axis of load
        Q = self.fe.distribute_load(transverse_load(10, w, theta))
        defl, reactions = self.fe.static_deflection(Q)
        x, y, z = defl[0::6], defl[1::6], defl[2::6]

        assert_allclose(x, 0)
        load_angle = np.arctan2(z, y)
        assert_allclose(load_angle[1:], theta)

    def test_reaction_force(self):
        # Simple uniform load should produce databook tip deflection
        w = 34.2  # N/m
        F = transverse_load(10, w)
        # Reaction force is F1 * F
        R = np.dot(self.fe.F1, F)
        assert_allclose(R, [0, w * self.length, 0])
Пример #44
0
 def setup(self):
     x = np.linspace(0, self.length, 10)
     self.fe = BeamFE(x, self.density, 0, self.EIy, self.EIz,
                      twist=self.twist)
     self.fe.set_boundary_conditions('C', 'F')
Пример #45
0
 def setup(self):
     self.fe = BeamFE(linspace(0, 10, 11), density=0, EA=0, EIy=1, EIz=1)
Пример #46
0
class TestBeamFE_Example41(unittest.TestCase):
    def setUp(self):
        x = array([0.0, 10.0, 22.0, 28.0])
        EI = array([[2e7, 2e7],
                    [1e7, 1e7],
                    [1e7, 1e7]])
        # Using the z axis as the transverse direction gives the same
        # sign convention as Reddy uses in 2D, namely that rotations
        # are positive clockwise.
        self.fe = BeamFE(x, density=0, EA=0, EIy=EI, EIz=0)
        self.fe.set_boundary_conditions('P', 'C')
        self.fe.set_dofs([False, False, True, False, True, False])

    def test_stiffness(self):
        # Reddy1993, pp 161-162
        expected = 1e7 * array([
            [0.024, -0.12, -0.024, -0.12,  0,        0,        0,       0],
            [0,     0.80,  0.12,   0.40,   0,        0,        0,       0],
            [0,     0,     0.0309, 0.0783, -0.00694, -0.04167, 0,       0],
            [0,     0,     0,      1.133,  0.0417,   0.167,    0,       0],
            [0,     0,     0,      0,      0.0625,   -0.125,   -0.0556, -0.167],
            [0,     0,     0,      0,      0,        1,        0.1667,  0.333],
            [0,     0,     0,      0,      0,        0,        0.0556,  0.1667],
            [0,     0,     0,      0,      0,        0,        0,       0.6667],
        ])
        expected += expected.T - np.diag(expected.diagonal())  # make symmetric
        expected_II = expected[1:6, 1:6]
        expected_IB = expected[1:6, [0, 6, 7]]
        assert_allclose(expected_II, self.fe.K_II, atol=1e-2 * 1e7)
        assert_allclose(expected_IB, self.fe.K_IB, atol=1e-3 * 1e7)

    def test_distributed_load(self):
        # Distributed force on first element:
        load = array([0, 0, -2400, 0, 0, 0, 0, 0, -2400, 0, 0, 0])
        Q = self.fe.distribute_load_on_element(0, load)
        Q = Q[[2, 4, 8, 10, 14, 16, 20, 22]]
        assert_allclose(Q / 1e3, [-12, 20, -12, -20, 0, 0, 0, 0])

    def test_solution(self):
        # Distributed force on first element:
        load = array([0, 0, -2400, 0, 0, 0, 0, 0, -2400, 0, 0, 0])
        QF = self.fe.distribute_load_on_element(0, load)

        # Nodal forces:
        Q = np.zeros(self.fe.K.shape[0])
        Q[14] = -10000     # z force at 3rd node

        # Solve static deflection
        deflections, reactions = self.fe.static_deflection(QF + Q)

        # Expected values from Reddy
        expected_deflections = zeros_like(deflections)
        expected_deflections[[4, 8, 10, 14, 16]] = [0.03856, -0.2808, 0.01214,
                                                    -0.1103, -0.02752]
        assert_allclose(deflections, expected_deflections, atol=1e-4)
        expected_reactions = zeros_like(reactions)
        expected_reactions[[2, 20, 22]] = [18565.54, 15434.46, 92164.83]
        assert_allclose(reactions, expected_reactions, atol=1e-2)

    def test_load_matrix_gives_same_result_as_method(self):
        # Distributed force on all elements
        load = np.zeros(4 * 6)
        load[2::6] = [350, 324, 654, 54]  # Z component

        Q1 = self.fe.distribute_load(load)
        Q2 = dot(self.fe.F, load)

        assert_allclose(Q1, Q2)