예제 #1
0
def test_deflection_for_fixed_cantilevered_beam_with_load_at_any_point():
    P = -1000  # load in lbs down
    a = 7  # position of load in inches
    L = 25  # length of beam in inches
    E = 29e6  # Young's modulus in psi
    Ixx = 345  # area moment of inertia in in**4
    b = L - a

    # function to calculate deflection anywhere along the length of the beam
    d1 = lambda x: P * b**2 / (6 * E * Ixx) * (3 * L - 3 * x - b)  # x < a
    d2 = lambda x: P * (L - x)**2 / (6 * E * Ixx) * (3 * b - L + x)  # x > a
    d3 = lambda x: P * b**3 / (3 * E * Ixx)  # x == a

    beam = Beam(L, [PointLoad(P, a)], [FixedReaction(L)], E, Ixx)

    for x in [0, 7, 12.5, 25]:
        # check the deflection of the beam at both end points, and the center
        if x < a:
            exact = d1(x)
        elif x > a:
            exact = d2(x)
        else:
            exact = d3(x)
        assert pytest.approx(beam.deflection(x), rel=1e-12) == exact, \
            f"Calculated deflection does not match expected deflection at {x}"
예제 #2
0
def test_reaction_types():
    pr = PinnedReaction(0)
    fr = FixedReaction(0)

    assert pr.boundary == (
        0, None), "PinnedReaction only has one degree of freedom"
    assert fr.boundary == (
        0, 0), "FixedReaction does not have any degrees of freedom"
예제 #3
0
def test_stiffness_matrix_k():
    beam = Beam(25, [PointLoad(-100, 25)], [FixedReaction(0)], 29e6, 345)
    assert beam.K.shape == (4, 4), "stiffness matrix is not expected size"

    # add another point load and verify the stiffness matrix changes size
    # accordingly
    beam.loads.append(PointLoad(-500, 12))
    beam.remesh()
    assert beam.K.shape == (6, 6), "stiffness matrix size did not update"
예제 #4
0
def test_node_deflections_at_free_end():
    for load in [PointLoad(-100, 25), MomentLoad(-100, 25)]:
        beam = Beam(25, [load], [FixedReaction(0)], 29e6, 345)
        # check that the deflection at the free end is non-zero and negative
        msgs = [
            "displacement at free end is not negative",
            "angular displacement at free end is not negative",
        ]
        for i, msg in enumerate(msgs, 2):
            assert beam.node_deflections[i][0] < 0, msg
예제 #5
0
def test_node_deflections_at_fixed_end():
    for load in [PointLoad(-100, 25), MomentLoad(-100, 25)]:
        beam = Beam(25, [load], [FixedReaction(0)], 29e6, 345)
        # check that the deflection at the fixed end is 0
        msgs = [
            "displacement at fixed end is non-zero",
            "angular displacement at fixed end is non-zero",
        ]
        for i, msg in enumerate(msgs):
            assert beam.node_deflections[i][0] == 0, msg
예제 #6
0
def test_plot_default_labels():
    b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
    fig, axes = b.plot()
    x_labels = ("", "", "Beam position, x")
    y_labels = ("shear", "moment", "deflection")

    assert len(axes) == len(x_labels), "wrong number of sub-plots"
    for ax, x_label, y_label in zip(axes, x_labels, y_labels):
        assert ax.get_xlabel() == x_label
        assert ax.get_ylabel() == y_label
예제 #7
0
def test_invalid_deflection_location():
    beam = Beam(25, [PointLoad(-100, 25)], [FixedReaction(0)], 29e6, 345)

    with pytest.raises(ValueError):
        beam.deflection(-4)  # a value less than 0

    with pytest.raises(ValueError):
        beam.deflection(beam.length + 5)  # a value greater then the length

    with pytest.raises(TypeError):
        beam.deflection('a string (not a number)')
예제 #8
0
def test_plot_custom_labels():
    b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
    diagrams = ("deflection", "deflection", "moment", "shear")
    labels = ("def1", "def2", "M", "V")
    fig, axes = b.plot(diagrams=diagrams, diagram_labels=labels)
    assert len(axes) == len(diagrams), "wrong number of sub-plots"

    x_labels = ["" for _ in range(len(diagrams) - 1)]
    x_labels.append("Beam position, x")
    for ax, x_label, y_label in zip(axes, x_labels, labels):
        assert ax.get_xlabel() == x_label
        assert ax.get_ylabel() == y_label
예제 #9
0
def test_solve_method():
    beam = Beam(25, [PointLoad(-100, 25)], [FixedReaction(0)], 29e6, 345)

    reaction = beam.reactions[0]
    assert reaction.force is None, "Reaction force was not None before being solved"
    assert reaction.moment is None, "Reaction moment was not None before being solved"

    beam.solve()
    reaction = beam.reactions[0]
    assert reaction.force == 100, "Reaction force must be equal to and opposite load"
    assert (
        reaction.moment == 100 *
        25), "Reaction moment must be equal to the load times the moment arm"
예제 #10
0
def test_apply_boundary_conditions():
    beam = Beam(25,
                [PointLoad(-100, 25), PointLoad(-100, 12)], [FixedReaction(0)],
                29e6, 345)

    k = beam.K
    bcs = [(None, None), (0, 0)]
    initial_shape = beam.K.shape
    assert initial_shape == (
        6, 6), "stiffness matrix does not match expected size"
    ki = beam.apply_boundary_conditions(k, bcs)
    final_shape = ki.shape
    assert initial_shape == final_shape, ("stiffness matrix changed shape "
                                          "when applying boundary conditions")
예제 #11
0
def test_shear():
    beam = Beam(25, [PointLoad(-1000, 25)], [FixedReaction(0)])

    for x in [0.5, 5, 13, 20, 24.5]:
        assert pytest.approx(beam.shear(x), rel=1e-5) == 1000, \
            f"shear does not equal load at location {x}"

    # right now, the derivative function will try to calculate shear outside
    # of the beam when calculating shear at or near endpoints. Verify that
    # calculating shear at ends raises a ValueError. It should also raise a
    # ValueError when the input is outside the beam
    for x in [-5, 0, 25, 35]:
        with pytest.raises(ValueError):
            beam.shear(x)
예제 #12
0
def test_moment_for_fixed_cantilevered_beam_with_load_at_end():
    P = -1000  # load in lbs down
    L = 25  # length of beam in inches
    E = 29e6  # Young's modulus in psi
    Ixx = 345  # area moment of inertia in in**4

    # function to calculate moment anywhere along the length of the beam
    m = lambda x: P * x

    beam = Beam(L, [PointLoad(P, 0)], [FixedReaction(L)], E, Ixx)

    for x in [7, 12.5, 25]:
        # check the deflection of the beam at both end points, and the center
        assert pytest.approx(beam.moment(x), rel=0.01) == m(x), \
            f"Calculated moment does not match expected moment at {x}"

    with pytest.warns(UserWarning):
        beam.moment(0)
예제 #13
0
def example_1():
    """
    Cantilevered Beam with Fixed Support and End Loading
    """
    print("=" * 79)
    print("Example 1")
    print(
        "Show an example with a cantilevered beam with a fixed support and "
        "point load at the end\n"
    )

    beam_len = 10
    # Note that both the reaction and load are both lists. They must always be
    # given to Beam as a list,
    r = [FixedReaction(0)]  # define reactions as list
    p = [PointLoad(magnitude=-2, location=beam_len)]  # define loads as list

    b = Beam(beam_len, loads=p, reactions=r, E=29e6, Ixx=125)

    # an explicit solve is required to calculate the reaction values
    b.solve()
    print(b)
def test_cantilevered_beam_load_at_end():
    """fixed beam with concentrated load at free end
    case 13
    """

    R = -P
    M_max = P * L  # at fixed end

    d_max = P * L**3 / (3 * EI)  # at free end

    beam = Beam(
        length=L,
        loads=[PointLoad(magnitude=P, location=0)],
        reactions=[FixedReaction(L)],
        E=E,
        Ixx=Ixx,
    )
    beam.solve()

    validate(beam, loc=0, R=[(R, M_max)], M_loc=0, d_loc=d_max)

    assert pytest.approx(beam.moment(L), rel=TOL) == M_max
예제 #15
0
def test_invalid_load_placement():
    reactions = [PinnedReaction(x) for x in [0, 50, 100]]
    loads = [PointLoad(-100, x) for x in [0, 50, 100]]

    # there should be a warning indicating that the load position was moved
    # slightly so it does not line up with the reaction.
    with pytest.warns(UserWarning):
        beam = Beam(100, loads=loads, reactions=reactions)

    for load, reaction in zip(beam.loads, beam.reactions):
        assert (load.location != reaction.location
                ), "moved load is still the same as a reaction"


@pytest.mark.parametrize("invalid_load",
                         ["a string", FixedReaction(0), [], 10])
def test_invalid_load_errors(invalid_load):
    # Check for a TypeError for a variety of invalid loads
    with pytest.raises(TypeError):
        Beam(25, loads=[invalid_load], reactions=[FixedReaction(0)])


@pytest.mark.parametrize("invalid_reaction",
                         ["a string", PointLoad(25, 15), [], 10])
def test_invalid_reaction_errors(invalid_reaction):
    # Check for an TypeError for a variety of invalid reactions
    with pytest.raises(TypeError):
        Beam(25, loads=[PointLoad(-100, 15)], reactions=[invalid_reaction])


def test_shape_function():
예제 #16
0
def beam_fixed(length):
    yield Beam(length=length,
               loads=[PointLoad(-100, length)],
               reactions=[FixedReaction(0)])
예제 #17
0
def reaction_fixed():
    """common fixed reaction at 0"""
    yield [FixedReaction(0)]
예제 #18
0
def test_bending_stress_depreciation_warning():
    with pytest.warns(DeprecationWarning):
        b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
        b.bending_stress(x=5, c=1)
예제 #19
0
def test_invalid_load_errors():
    # Check for a TypeError for a variety of invalid loads
    for invalid_load in ['a string', FixedReaction(0), [], 10]:
        with pytest.raises(TypeError):
            Beam(25, loads=[invalid_load], reactions=[FixedReaction(0)])
예제 #20
0
def test_plot_one_diagram():
    b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
    fig, axes = b.plot(diagrams=("deflection", ))
    assert len(axes) == 1, "expected length of axes was 1"
    for ax, y_label in zip(axes, ("deflection", )):
        assert ax.get_ylabel() == y_label
예제 #21
0
import pytest

from femethods.loads import PointLoad
from femethods.mesh import Mesh
from femethods.reactions import FixedReaction

LOADS = [PointLoad(magnitude=-1000, location=15)]
REACTIONS = [FixedReaction(0)]
LENGTH = 25


@pytest.fixture
def mesh():
    return Mesh(LENGTH, LOADS, REACTIONS, dof=2)


def test_mesh_properties(mesh):
    # there should be a node at the start and end of the beam, as well as a
    # node for any loads
    assert mesh.nodes == [0, 15, 25], "Mesh nodes do not match expected"
    assert mesh.dof == 6, "Wrong number of global degrees-of-freedom"
    assert mesh.lengths == [15,
                            10], "Mesh elements do not have expected lengths"
    assert mesh.num_elements == 2, "Mesh element count does not match"
    assert mesh.num_elements == len(mesh.lengths)

    with pytest.raises(AttributeError):
        mesh.nodes = "Mesh nodes property is read-only"
    with pytest.raises(AttributeError):
        mesh.dof = "Mesh dof should be read-only"
    with pytest.raises(AttributeError):
예제 #22
0
def test_plot_diagram_labels_without_diagrams():
    with pytest.raises(ValueError):
        b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
        b.plot(diagram_labels=("V, lb", "M, in/lb", "delta, in"))
예제 #23
0
def test_plot_diagrams_diagrams_label_mismatch():
    with pytest.raises(ValueError):
        b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
        b.plot(diagrams=("shear", ), diagram_labels=("shear", "moment"))
예제 #24
0
def test_plot_diagrams_invalid_value():
    with pytest.raises(ValueError):
        b = Beam(10, [PointLoad(10, 10)], [FixedReaction(0)])
        b.plot(diagrams=("shear", "bad value"))
예제 #25
0
def test_invalid_load_errors(invalid_load):
    # Check for a TypeError for a variety of invalid loads
    with pytest.raises(TypeError):
        Beam(25, loads=[invalid_load], reactions=[FixedReaction(0)])
예제 #26
0
def test_shape_of_node_deflections():
    beam = Beam(25, [PointLoad(-100, 25)], [FixedReaction(0)], 29e6, 345)
    assert beam.node_deflections.shape == (4, 1), \
        "nodal deflections shape is not expected"