Distributed Load on Beam#

../../../../_images/distributed_load_on_beam.png

Modelling L-frame beam under distributed load with evaluation of the stresses:

  • Create L-frame using beams with rectangular cross-section

  • Apply a distributed load to the horizontal beam

  • Retrieve Young Modulus from material properties

  • Evaluate the maximum normal stress from member strains

Keywords:
L-frame rectangular cross-section distributed load material properties basic stresses
from math import inf, pi
from dlubal.api import rfem, common

# -------------------------------------------------------
# This example demonstrates how to model two perpendicular
# beams with a rectangular cross-section. The top
# (horizontal) beam is loaded by a distributed load.
# While neglecting self-weight, the maximum normal stress
# on the horizontal beam is evaluated from member forces.
# -------------------------------------------------------

# Editable parameters (SI units)
MATERIAL = "S235"
CROSS_SECTION_WIDTH = 0.025
CROSS_SECTION_HEIGHT = 0.05
VERTICAL_BEAM_LENGTH = 1.0
HORIZONTAL_BEAM_LENGTH = 1.0
DISTRIBUTED_LOAD = 10000.0


def define_structure() -> list:
    """Define and return a list of structural objects."""

    return [
        rfem.structure_core.Material(
            no=1,
            name=MATERIAL,
        ),

        rfem.structure_core.CrossSection(
            no=1,
            type=rfem.structure_core.CrossSection.TYPE_PARAMETRIC_MASSIVE_I,
            material=1,
            b=CROSS_SECTION_WIDTH,
            h=CROSS_SECTION_HEIGHT,
            shear_stiffness_deactivated=True,
        ),

        rfem.structure_core.Node(no=1, coordinate_1=0.0, coordinate_2=0.0, coordinate_3=0.0),
        rfem.structure_core.Node(no=2, coordinate_1=0.0, coordinate_2=0.0, coordinate_3=-VERTICAL_BEAM_LENGTH),
        rfem.structure_core.Node(no=3, coordinate_1=HORIZONTAL_BEAM_LENGTH, coordinate_2=0.0, coordinate_3=-VERTICAL_BEAM_LENGTH),

        rfem.structure_core.Line(no=1, definition_nodes=[1, 2]),
        rfem.structure_core.Line(no=2, definition_nodes=[2, 3]),

        rfem.structure_core.Member(
            no=1,
            line=1,
            cross_section_start=1,
            #rotation_angle=pi / 2,
        ),
        rfem.structure_core.Member(
            no=2,
            line=2,
            cross_section_start=1,
            #rotation_angle=pi / 2,
        ),

        rfem.types_for_nodes.NodalSupport(
            no=1,
            nodes=[1, 3],
            spring=common.Vector3d(x=inf, y=inf, z=inf),
            rotational_restraint=common.Vector3d(x=inf, y=0, z=inf),
        )
    ]


def define_loading() -> list:
    """Define and return a list of loading objects."""

    return [
        rfem.loading.StaticAnalysisSettings(no=1),

        rfem.loading.LoadCase(
            no=1,
            static_analysis_settings=1,
            self_weight_active=False,
        ),

        rfem.loads.MemberLoad(
            no=1,
            members=[2],
            load_case=1,
            load_type=rfem.loads.MemberLoad.LOAD_TYPE_FORCE,
            load_distribution=rfem.loads.MemberLoad.LOAD_DISTRIBUTION_UNIFORM,
            magnitude=DISTRIBUTED_LOAD,
        ),
    ]


with rfem.Application() as rfem_app:

    app_info = rfem_app.get_application_info()
    print(f"\nApplication Info:\n{app_info}")

    # Modelling
    rfem_app.create_model(name='distributed_load_on_beam')

    base_data = rfem_app.get_base_data()
    base_data.addons.multilayer_surfaces_active = True
    rfem_app.set_base_data(base_data=base_data)

    rfem_app.delete_all_objects()
    rfem_app.create_object_list(define_structure() + define_loading())

    # Calculation
    calculation_info = rfem_app.calculate_all(skip_warnings=True)
    print(f"\nCalculation Info:\n{calculation_info}")

    # Results
    member_strains_df = rfem_app.get_results(
        results_type=rfem.results.STATIC_ANALYSIS_MEMBERS_STRAINS,
        filters=[
            rfem.results.ResultsFilter(column_id="member_no", filter_expression="2"),
            rfem.results.ResultsFilter(column_id="loading", filter_expression="LC1"),
        ],
    ).data

    # Material Properties
    material = rfem_app.get_object(
        rfem.structure_core.Material(no=1)
    )
    material_values_tree = material.material_values.rows[0].material_values_tree
    young_modulus = common.tree_table.get_values_by_key(
        tree=material_values_tree,
        key='e', # young_modulus
        occurrence=1
    )
    print(f"young_modulus: {young_modulus}")


    # Stress evaluation (horizontal beam):
    # use axial strain epsilon_x and bending curvature kappa_y only
    # at top and bottom fibers (z = +/- h/2).
    required_columns = ["epsilon_x", "kappa_z"]
    half_height = CROSS_SECTION_HEIGHT / 2
    sigma_top = young_modulus * (member_strains_df["epsilon_x"] - member_strains_df["kappa_y"] * half_height)
    sigma_bottom = young_modulus * (member_strains_df["epsilon_x"] + member_strains_df["kappa_y"] * half_height)

    sigma_max = max(sigma_top.abs().max(), sigma_bottom.abs().max())
    print(f"sigma_max: {sigma_max}")